ds2431通信示程范序
- 格式:doc
- 大小:99.50 KB
- 文档页数:9
接线说明,以Arduinouno r3为例:SCL→A5SDA→A4VCC→5VGND→GND代码部分:#include <reg51.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit SDA=P3^6; //模拟I2C数据传送位SDA**************sbit SCL=P3^7; //模拟I2C时钟控制位SCL**************sbit INT=P3^2;sbit RESET=P3^3;//**************sbit led0=P1^0;sbit led1=P1^1;sbit led2=P1^2;sbit led3=P1^3;sbit led4=P1^4;sbit led5=P1^5;sbit led6=P1^6;sbit led7=P1^7;//**************bit ack; //应答标志位#define DS3231_WriteAddress 0xD0 //器件写地址************** #define DS3231_ReadAddress 0xD1 //器件读地址************** #define DS3231_SECOND 0x00 //秒#define DS3231_MINUTE 0x01 //分#define DS3231_HOUR 0x02 //时#define DS3231_WEEK 0x03 //星期#define DS3231_DAY 0x04 //日#define DS3231_MONTH 0x05 //月#define DS3231_YEAR 0x06 //年//闹铃1#define DS3231_SALARM1ECOND 0x07 //秒#define DS3231_ALARM1MINUTE 0x08 //分#define DS3231_ALARM1HOUR 0x09 //时#define DS3231_ALARM1WEEK 0x0A //星期/日//闹铃2#define DS3231_ALARM2MINUTE 0x0b //分#define DS3231_ALARM2HOUR 0x0c //时#define DS3231_ALARM2WEEK 0x0d //星期/日#define DS3231_CONTROL 0x0e //控制寄存器#define DS3231_STATUS 0x0f //状态寄存器#define BSY 2 //忙#define OSF 7 //振荡器停止标志#define DS3231_XTAL 0x10 //晶体老化寄存器#define DS3231_TEMPERATUREH 0x11 //温度寄存器高字节(8位)#define DS3231_TEMPERATUREL 0x12 //温度寄存器低字节(高2位)//**************uchar code dis_code[11]={0xc0,0xf9,0xa4,0xb0, // 0,1,2,30x99,0x92,0x82,0xf8,0x80,0x90, 0xff}; //4,5,6,7,8,9,offuchar data dis_buf[8];uchar data dis_index;uchar data dis_digit;//**************uchar BCD2HEX(ucharval) //BCD转换为Byte{uchar temp;temp=val&0x0f;val>>=4;val&=0x0f;val*=10;temp+=val;return temp;}uchar HEX2BCD(ucharval) //B码转换为BCD码{uchari,j,k;i=val/10;j=val-i*10;**************k=j+(i<<4);return k;}void delayus(uint us) 注:单片机型号不同{while (us--);}void Start_I2C(){SDA=1; //发送起始条件的数据信号delayus(1);SCL=1;delayus(5); //起始条件建立时间大于4.7us,延时SDA=0; //发送起始信号delayus(5); // 起始条件锁定时间大于4μsSCL=0; //钳住I2C总线,准备发送或接收数据delayus(2);}void Stop_I2C(){SDA=0; //发送结束条件的数据信号delayus(1); //发送结束条件的时钟信号SCL=1; //结束条件建立时间大于4usdelayus(5);SDA=1; //发送I2C总线结束信号delayus(4);}void SendByte(uchar c){ucharBitCnt;for(BitCnt=0;BitCnt<8;BitCnt++) //要传送的数据长度为8位 {if((c<<BitCnt)&0x80)SDA=1;//判断发送位elseSDA=0;delayus(1);SCL=1;//置时钟线为高,通知被控器开始接收数据位delayus(5); //保证时钟高电平周期大于4μsSCL=0;}SDA=1;//8位发送完后释放数据线,准备接收应答位delayus(2);SCL=1;delayus(3);if(SDA==1)ack=0;elseack=1;//判断是否接收到应答信号SCL=0;delayus(2);}ucharRcvByte(){ucharretc;ucharBitCnt;retc=0;SDA=1; //置数据线为输入方式for(BitCnt=0;BitCnt<8;BitCnt++){delayus(1);SCL=0; //置时钟线为低,准备接收数据位delayus(5); //时钟低电平周期大于4.7μsSCL=1; //置时钟线为高使数据线上数据有效delayus(3);retc=retc<<1;if(SDA==1)retc=retc+1; //读数据位,接收的数据位放入retc中delayus(2);}SCL=0;delayus(2);}void Ack_I2C(bit a){if(a==0)SDA=0; //在此发出应答或非应答信号 elseSDA=1;delayus(3);SCL=1;delayus(5); //时钟低电平周期大于4μsSCL=0; //清时钟线,钳住I2C总线以便继续接收delayus(2);}ucharwrite_byte(ucharaddr, ucharwrite_data){Start_I2C();SendByte(DS3231_WriteAddress);if (ack == 0)return 0;SendByte(addr);if (ack == 0)return 0;SendByte(write_data);if (ack == 0)return 0;Stop_I2C();delayus(10);return 1;}ucharread_current(){ucharread_data;Start_I2C();SendByte(DS3231_ReadAddress);if(ack==0)return(0);read_data = RcvByte();Ack_I2C(1);Stop_I2C();return read_data;}ucharread_random(ucharrandom_addr){Start_I2C();SendByte(DS3231_WriteAddress);if(ack==0)return(0);SendByte(random_addr);if(ack==0)return(0);return(read_current());}void ModifyTime(ucharyea,ucharmon,ucharda,ucharhou,ucharmin,uchar sec) {uchar temp=0;temp=HEX2BCD(yea);write_byte(DS3231_YEAR,temp); //修改年temp=HEX2BCD(mon);write_byte(DS3231_MONTH,temp); //修改月temp=HEX2BCD(da);write_byte(DS3231_DAY,temp); //修改日temp=HEX2BCD(hou);write_byte(DS3231_HOUR,temp); //修改时temp=HEX2BCD(min);write_byte(DS3231_MINUTE,temp); //修改分temp=HEX2BCD(sec);write_byte(DS3231_SECOND,temp); //修改秒}void TimeDisplay(ucharDhour,ucharDmin,ucharDsec)**************{dis_buf[7]=dis_code[Dhour / 10]; // 时十位dis_buf[6]=dis_code[Dhour % 10]; // 时个位dis_buf[4]=dis_code[Dmin / 10]; // 分十位dis_buf[3]=dis_code[Dmin % 10]; // 分个位dis_buf[1]=dis_code[Dsec / 10]; // 秒十位dis_buf[0]=dis_code[Dsec % 10]; // 秒个位dis_buf[2]=0xbf; // 显示"-"dis_buf[5]=0xbf;}void DateDisplay(ucharDyear,ucharDmonth,ucharDday)**************{dis_buf[7]=dis_code[Dyear / 10]; // 年十位dis_buf[6]=dis_code[Dyear % 10]; // 年个位dis_buf[4]=dis_code[Dmonth / 10]; // 月十位dis_buf[3]=dis_code[Dmonth % 10]; // 月个位dis_buf[1]=dis_code[Dday / 10]; // 天十位dis_buf[0]=dis_code[Dday % 10]; // 天个位dis_buf[2]=0xbf; // 显示"-"dis_buf[5]=0xbf;}void get_show_time(void){uchar Htemp1,Htemp2,Mtemp1,Mtemp2,Stemp1,Stemp2;Htemp1=read_random(DS3231_HOUR); //时 24小时制Htemp1&=0x3f;Htemp2=BCD2HEX(Htemp1);Mtemp1=read_random(DS3231_MINUTE); //分Mtemp2=BCD2HEX(Mtemp1);Stemp1=read_random(DS3231_SECOND); //秒Stemp2=BCD2HEX(Stemp1);TimeDisplay(Htemp2,Mtemp2,Stemp2);}void get_show_date(void){uchar Ytemp1,Ytemp2,Mtemp1,Mtemp2,Dtemp1,Dtemp2;Ytemp1=read_random(DS3231_YEAR); //年Ytemp2=BCD2HEX(Ytemp1);Mtemp1=read_random(DS3231_MONTH); //月Mtemp2=BCD2HEX(Mtemp1);Dtemp1=read_random(DS3231_DAY); //日Dtemp2=BCD2HEX(Dtemp1);DateDisplay(Ytemp2,Mtemp2,Dtemp2);}void get_show_Temperature(void){uchar Ttemp1,Ttemp2,Ttemp3,Ttemp4;Ttemp1=read_random(DS3231_TEMPERATUREH); //温度高字节 Ttemp2=BCD2HEX(Ttemp1);Ttemp3=read_random(DS3231_TEMPERATUREL); //温度低字节Ttemp4=BCD2HEX(Ttemp3);DateDisplay(0,Ttemp2,Ttemp4);}void timer0() interrupt 1{TL0=0x17;P2=0xff; // 先关闭所有数码管P0=dis_buf[dis_index]; // 显示代码传送到P0口P2=dis_digit;if (dis_digit& 0x80)dis_digit=(dis_digit<< 1) | 0x1;elsedis_digit=(dis_digit<< 1);dis_index++;dis_index&=0x07; // 8个数码管全部扫描完一遍之后,再回到第一个开始下一次扫描}void main(){uint ii = 0;RESET=0x1; //DS3231复位操作,正常操作下不需要每次都复位delayus(5000);led0=0;led1=0;led2=0;led3=0;led4=0;P0=0xff;P2=0xff;dis_digit=0xfe;dis_index=0;TimeDisplay(12, 5, 18);TMOD=0x11; // 定时器0, 1工作模式1, 16位定时方式TH0=0xFC;TCON=0x01;IE=0x82; // 使能timer0,1 中断TR0=1;if (write_byte(DS3231_CONTROL, 0x1C) == 0)led0=1;if (write_byte(DS3231_STATUS, 0x00) == 0)led1=1;ModifyTime(10,6,13,15,30,00); //初始化时钟,2010/6/13,15/30/00//小时采用24小时制while(1){//get_show_date(); //显示日期//get_show_Temperature(); //显示温度get_show_time(); //显示时间delayus(50000);}}。
三菱FX系列PLC编程口通信协议总览三菱FX系列PLC编程口通信协议总览该协议实际上适用于PLC编程端口以及 FX-232AW 模块的通信。
感谢网友visualboy提供。
通讯格式:命令命令码目标设备DEVICE READ CMD "0" X,Y,M,S,T,C,DDEVICE WRITE CMD "1" X,Y,M,S,T,C,DFORCE ON CMD " 7" X,Y,M,S,T,CFORCE OFF CMD "8" X,Y,M,S,T,C传输格式: RS232C波特率: 9600bps奇偶: even校验: 累加方式(和校验)字符: ASCII16进制代码:ENQ 05H 请求ACK 06H PLC正确响应NAK 15H PLC错误响应STX 02H 报文开始ETX 03H 报文结束帧格式:STX CMD DATA ...... DATA ETX SUM(upper) SUM(lower)例子:STX ,CMD ,ADDRESS, BYTES, ETX, SUM02H, 30H, 31H,30H,46H,36H, 30H,34H, 03H, 37H,34HSUM=CMD+......+ETX;30h+31h+30h+46h+36h+30h+34h+03h=74h;累加和超过两位取低两位三菱FX系列PLC编程口通信协议举例三菱FX系列PLC专用协议通信指令一览FX系列PLC专用协议通信指令一览以下将详细列出PLC专用协议通信的指令:指令注释BR 以1点为单位,读出位元件的状态WR 以16点为单位,读出位元件的状态,或以1字为单位,读出字元件的值BW 以1点为单位,写入位元件的状态WW 以16点为单位,写入位元件的状态,或以1字为单位,写入值到字元件BT 以1点为单位,SET/RESET位元件WT 以16点为单位,SET/RESET位元件,或写入值到字元件RR 控制PLC运行RUNRS 控制PLC停止STOPPC 读出PLC设备类型TT 连接测试注:位元件包括X,Y,M,S以及T,C的线圈等;字元件包括D,T,C,KnX,KnY,KnM等。
代码部分:#in elude <reg51.h> #in elude vintrin s.h>#defi ne uehar un signed char#defi ne uintun sig ned int// 模拟 I2C 数据传送位 SDA************** // 模拟 I2C 时钟控制位 SCL**************sbit INT=P3A2; sbit RESET=P3A3; 〃 ************** sbit led0=P1A0; sbit led 1=P1A1; sbit led2=P1A2; sbit led3=P1A3; sbit led4=P1A4; sbit led5=P1A5; sbit led6=P"6; sbit led7=P1A7; 〃 **************接线说明,以 Ardui no uno r3 为例:sbit SDA=P3A 6; sbit SCL=P3A7;bit ack; //应答标志位#defi ne DS3231 WriteAddress OxDO //器件写地址**************#defi ne DS3231 ReadAddress 0xD1 //器件读地址**************#defi ne DS3231 SECOND 0x00 //秒#defi ne DS3231 MINUTE 0x01 //分#defi neDS3231 HOUR 0x02 //时#defi neDS3231 WEEK 0x03 //星期#defi neDS3231 DAY 0x04 //#defi neDS3231 MONTH 0x05 //月#defi neDS3231 YEAR 0x06 //〃闹铃1#defi neDS3231 SALARM1ECOND 0x07 //秒#defi ne DS3231 ALARM1MINUTE 0x08 //分#defi ne DS3231 ALARM1HOUR 0x09 //时#defi ne DS3231 ALARM1WEEK 0x0A //星期/日〃闹铃2#define DS3231 ALARM2MINUTE 0x0b //分#defi ne DS3231 ALARM2HOUR 0x0c //时#define DS3231 ALARM2WEEK 0x0d //星期/日#defi neDS3231 CONTROL 0x0e //控制寄存器#defi neDS3231 STATUS 0x0f //状态寄存器#defi ne BSY2 〃忙#defi ne DS3231_TEMPERATUREH 0x11 #defi ne DS3231 TEMPERATUREL 0x12uchar code dis_code[11]={0xc0,0xf9,0xa4,0xb0.0x99,0x92,0x82,0xf8,0x80,0x90, 0xff};uchar data dis_buf[8]; uchar data dis_i ndex; uchar data dis_digit; // **************uchar temp; temp=val&0x0f; val>>=4; val&=0x0f; val*=10; temp+=val;#defi ne OSF7 //振荡器停止标志 #defi ne DS3231_XTAL0x10//晶体老化寄存器// **************//温度寄存器高字节(8位) //温度寄存器低字节(高2位)// 0,1,2,3 // 4,5,6,7,8,9,offuchar BCD2HEX(uchar val) //BCD 转换为Bytereturn temp;}uchar HEX2BCD(uchar val) 〃B 码转换为 BCD 码{uchar i,j,k;i=val/10;j=val-i*10 ; **************k=j+(i<<4);return k;}void delayus(ui nt us) 注:单片机型号不同{while (us--);} void Start_I2C(){SDA=1; //发送起始条件的数据信号delayus(1);SCL=1;delayus(5); //起始条件建立时间大于 4.7us,延时SDA=O; //发送起始信号delayus(5); //起始条件锁定时间大于4阴SCL=O; //钳住I2C总线,准备发送或接收数据delayus(2);} void Stop_l2C(){SDA=0; //发送结束条件的数据信号delayus(1); //发送结束条件的时钟信号SCL=1; //结束条件建立时间大于4usdelayus(5);SDA=1; //发送I2C总线结束信号delayus(4);}void Sen dByte(uchar c){uchar BitC nt;for(BitCnt=O;BitCnt<8;BitCnt++) // 要传送的数据长度为8 位{if((c<<BitC nt)&0x80)SDA=1; //判断发送位elseSDA=0;delayus(1);SCL=1; //置时钟线为高,通知被控器开始接收数据位delayus(5); //保证时钟高电平周期大于 4阴SCL=0;}delayus(2);SDA=1; //8位发送完后释放数据线,准备接收应答位delayus(2);SCL=1;delayus (3);if(SDA==1)ack=0;elseack=1; //判断是否接收到应答信号SCL=O;delayus(2);}uchar RcvByte(){uchar retc;uchar BitC nt;retc=0;SDA=1; //置数据线为输入方式for(BitC nt=O;BitC nt<8;BitC nt++){delayus(1);SCL=0; //置时钟线为低,准备接收数据位delayus(5); //时钟低电平周期大于 4.7阴SCL=1; //置时钟线为高使数据线上数据有效delayus (3);retc=retc<<1;if(SDA==1)retc=retc+1; //读数据位,接收的数据位放入retc 中delayus(2);}SCL=O;delayus(2);return(retc);}void Ack_l2C(bit a){if(a==0)SDA=0; //在此发出应答或非应答信号elseSDA=1;delayus (3);SCL=1;delayus(5); //时钟低电平周期大于 4 qSCL=O; //清时钟线,钳住I2C总线以便继续接收delayus(2);}uchar write_byte(uchar addr, uchar write_data){Start_I2C();Se ndByte(DS3231_WriteAddress);if (ack == 0)return 0;Se ndByte(addr);if (ack == 0)return 0;Sen dByte(write_data);if (ack == 0)return 0;Stop_I2C();delayus(10);return 1;}uchar read_curre nt(){uchar read_data;Start_l2C();Sen dByte(DS3231_ReadAddress); if(ack==O) return(O);read_data = RcvByte();Ack_I2C(1);Stop_I2C();return read_data;}uchar read_ra ndom(uchar ran dom_addr){Start_I2C();。
•带有以太网卡的PC机上,安装了STEP 7 和SIMATIC NET软件。
步骤1:将CP243-1配置为SERVER使用STEP 7 Micro/WIN32中的向导程序。
软件的版本应该为V3.2 SP1或以上。
在命令菜单中选择Tools--> Ethernet Wizard。
1. 点击Next>按钮,系统会提示您在使用向导程序之前,要先对程序进行编译。
2. 点击Yes编译程序。
1. 在此处选择模块的位置。
2. 在线的情况下,您也可以用Read Modules按钮搜寻在线的CP243-1模块。
3. 点击Next>按钮。
1. 在此处填写IP地址。
2. 在此处填写子网掩码。
3. 选择模块的通讯类型。
4. 点击Next>按钮。
1. 在此处填写模块占用的输出地址,建议使用缺省值。
2. 配置模块的连接个数。
3. 点击Next>按钮。
1. 配置该模块为SERVER。
2. 在此处填写CLIENT端的IP地址。
3. 在此处填写TSAP地址,请使用10.11 。
4. 点击OK按钮。
1. 选择CRC校验。
2. 使用缺省的时间间隔30秒。
3. 点击Next>按钮。
1. 填写模块所占用的V存储区的起始地址。
2. 你也可以通过Suggest Address按钮来获得系统建议的V存储区的起始地址。
3. 点击Next>按钮。
点击Finish 按钮,完成对该模块的配置。
步骤2:在SERVER上编写通讯程序您可以使用向导程序为您提供的子程序,在SERVER上编写图中的通讯程序。
然后,将整个项目下载到作SERVER的CPU上。
步骤3:设置PG/PC接口将PG/PC接口该为S7ONLINE(STEP 7)-->PC internal(local). 步骤4:用STEP 7软件配置您的PC站在一个新的项目中插入一个PC站。
在1号槽位中插入OPC Server,在3号槽位中插入IE General。
DS2401硅序列号特性与DS2400引脚兼容的升级产品— 外部供电电源范围:2.8V至6.0V— 多个DS2401可以连接在一条公共的1-Wire®总线工厂刻入、经过检测的64位注册码(8位家族码 + 48位序列码 + 8位CRC校验码);保证没有任何两个器件的注册码是相同的内部多点控制器确保与其他1-Wire网络产品兼容8位家族码表明DS2401通信需要读取装置读取装置首次上电时将产生在线脉冲应答低成本TO-92、SOT-223和 TSOC表面贴封装将控制、地址、数据和供电集于一个引脚零待机电源直接与微处理器的一个口线连接,通信速率达16.3kbpsTO-92卷带包装具有倾斜引脚,间隔100mil (默认) 或直引脚 (DS2401T-SL)应用— PCB识别— 网络节点ID— 设备注册工作在扩展工业级温度范围: -40°C至+85°C引脚配置TO-92TSOC PACKAGETOP VIEW3.7mm x4.0mm x 1.5mm1 2 3TOP VIEWSee Mech. DrawingsSectionBOTTOM VIEW1 2Flip Chip, Top Viewwith Laser Mark,Contacts Not Visible.“rrd” = Revision/DateSee 56-G7009-001 for package outline.引脚说明TO-92,SOT-223 TSOC 倒装芯片引脚 1 地地数据(DQ)引脚2 数据 (DQ)数据(DQ) 地引脚3 无连接无连接—引脚4 地无连接—引脚5-6— 无连接—1-Wire是Dallas Semiconductor的注册商标。
定购信息型号无铅封装说明DS2401 DS2401+ TO-92封装DS2401/T&R DS2401+T&R TO-92 封装, 卷带包装DS2401/T&R/SL DS2401-SL+T&R TO-92 封装,直引脚,卷带包装DS2401Z DS2401Z+ SOT-223表面贴封装DS2401Z/T&R DS2401Z+T&R SOT-223表面贴封装, 卷带包装DS2401P DS2401P+ TSOC 表面贴封装DS2401P/T&R DS2401P+T&R TSOC表面贴封装, 卷带包装DS2401X1[JP1]— 晶片级封装, 卷带包装概述DS2401增强型硅序列号是一款低成本的电子注册码,以最少的电接口(通常只需一个微处理器端口)提供绝对、唯一的识别功能。
ds3231程序(精校版本)#include#include#define uchar unsigned char#define uint unsigned intsbit SDA=P3^6; //模拟I2C数据传送位SDAsbit SCL=P3^7; //模拟I2C时钟控制位SCL//sbit INT=P3^2;//sbit RESET=P3^3;sbit led0=P1^0;sbit led1=P1^1;sbit led2=P1^2;sbit led3=P1^3;sbit led4=P1^4;sbit led5=P1^5;sbit led6=P1^6;sbit led7=P1^7;bit ack; //应答标志位#define DS3231_WriteAddress 0xD0 //器件写地址#define DS3231_ReadAddress 0xD1 //器件读地址#define DS3231_SECOND 0x00 //秒#define DS3231_MINUTE 0x01 //分#define DS3231_HOUR 0x02 //时#define DS3231_WEEK 0x03 //星期#define DS3231_DAY 0x04 //日#define DS3231_MONTH 0x05 //月#define DS3231_YEAR 0x06 //年//闹铃1#define DS3231_SALARM1ECOND 0x07 //秒#define DS3231_ALARM1MINUTE 0x08 //分#define DS3231_ALARM1HOUR 0x09 //时#define DS3231_ALARM1WEEK 0x0A //星期/日//闹铃2#define DS3231_ALARM2MINUTE 0x0b //分#define DS3231_ALARM2HOUR 0x0c //时#define DS3231_ALARM2WEEK 0x0d //星期/日#define DS3231_CONTROL 0x0e //控制寄存器#define DS3231_STATUS 0x0f //状态寄存器#define BSY 2 //忙#define OSF 7 //振荡器停止标志#define DS3231_XTAL 0x10 //晶体老化寄存器#define DS3231_TEMPERATUREH 0x11 //温度寄存器高字节(8位)#define DS3231_TEMPERATUREL 0x12 //温度寄存器低字节(高2位)uchar code dis_code[11]={0xc0,0xf9,0xa4,0xb0, // 0,1,2,30x99,0x92,0x82,0xf8,0x80,0x90, 0xff}; // 4,5,6,7,8,9,off uchar data dis_buf[8];uchar data dis_index;uchar data dis_digit;uchar BCD2HEX(uchar val) //BCD转换为Byte{uchar temp;temp=val&0x0f;val>>=4;val&=0x0f;val*=10;temp+=val;return temp;}uchar HEX2BCD(uchar val) //B码转换为BCD码{uchar i,j,k;i=val/10;j=val;k=j+(i<<4);return k;}void delayus(uint us){while (us--);}void Start_I2C(){SDA=1; //发送起始条件的数据信号delayus(1);SCL=1;delayus(5); //起始条件建立时间大于4.7us,延时SDA=0; //发送起始信号delayus(5); // 起始条件锁定时间大于4μsSCL=0; //钳住I2C总线,准备发送或接收数据delayus(2);}void Stop_I2C(){SDA=0; //发送结束条件的数据信号delayus(1); //发送结束条件的时钟信号SCL=1; //结束条件建立时间大于4usdelayus(5);SDA=1; //发送I2C总线结束信号delayus(4);}void SendByte(uchar c){uchar BitCnt;for(BitCnt=0;BitCnt<8;BitCnt++) //要传送的数据长度为8位{if((c<<bitcnt)&0x80)< p="">SDA=1; //判断发送位elseSDA=0;delayus(1);SCL=1; //置时钟线为高,通知被控器开始接收数据位delayus(5); //保证时钟高电平周期大于4μsSCL=0;}delayus(2);SDA=1; //8位发送完后释放数据线,准备接收应答位delayus(2);SCL=1;</bitcnt)&0x80)<>。
用软件实现1-Wire®通信摘要:在没有专用总线主机(如DS2480B、DS2482)的情况下,微处理器可以轻松地产生1-Wire时序信号。
本应用笔记给出了一个采用‘C’语言编写、支持标准速率的1-Wire主机通信基本子程序实例。
1-Wire总线的四个基本操作是:复位、写“1”、写“0”和读数据位。
字节操作可以通过反复调用位操作实现,本文提供了通过各种传输线与1-Wire器件进行可靠通信的时间参数。
引言在没有专用总线主机的情况下,微处理器可以轻松地产生1-Wire时序信号。
本应用笔记给出了一个采用C语言编写、支持标准速率的1-Wire主机通信基本子程序实例。
此外,本文也讨论了高速通信模式。
要使该实例中的代码正常运行,系统必须满足以下几点要求:1. 微处理器的通信端口必须是双向的,其输出为漏极开路,且线上具有弱上拉。
这也是所有1-Wire总线的基本要求。
关于简单的1-Wire主机微处理器电路实例,请参见应用笔记4206:"为嵌入式应用选择合适的1-Wire主机"中的1类部分。
2. 微处理器必须能产生标准速度1-Wire通信所需的精确1µs延时和高速通信所需要的0.25µs延时。
3. 通信过程不能被中断。
1-Wire总线有四种基本操作:复位、写1位、写0位和读位操作。
在数据资料中,将完成一位传输的时间称为一个时隙。
于是字节传输可以通过多次调用位操作来实现,下面的表1是各个操作的简要说明以及实现这些操作所必须的步骤列表。
图1为其时序波形图。
表2给出了通常线路条件下1-Wire主机与1-Wire器件通信的推荐时间。
如果与1-Wire主机相连的器件比较特殊或者线路条件比较特殊,则可以采用最值。
请参考可下载的工作表中的系统和器件参数,确定最小值和最大值。
表1. 1-Wire操作Write 1 bit Send a '1' bit to the 1-Wire slaves (Write 1 time slot) Drive bus low, delay A Release bus, delay BWrite 0 bit send a '0' bit to the 1-Wire slaves (Write 0 time slot) Drive bus low, delay C Release bus, delay DRead bit Read a bit from the 1-Wire slaves (Read time slot) Drive bus low, delay ARelease bus, delay ESample bus to read bit from slave Delay FReset Reset the 1-Wire bus slave devices and ready themfor a commandDelay GDrive bus low, delay HRelease bus, delay ISample bus, 0 = device(s) present, 1 = nodevice presentDelay J图1. 1-Wire时序图表2. 1-Wire主机时序Parameter Speed Recommended (µs)A Standard 6 Overdrive 1.0B Standard 64 Overdrive 7.5C Standard 60 Overdrive 7.5D Standard 10 Overdrive 2.5E Standard 9 Overdrive 1.0F Standard 55 Overdrive 7G Standard 0 Overdrive 2.5H Standard 480 Overdrive 70I Standard 70 Overdrive 8.5J Standard 410计算这些值的工作表可供下载。
代码实例下面代码实例都依赖于两个通用的'C'函数outp和inp,从IO端口读写字节数据。
他们通常位于<conio.h>标准库中。
当应用于其它平台时,可以采用合适的函数来替代它们。
// send 'databyte' to 'port' //设定发送数据字节的端口int outp(unsigned port, int databyte);// read byte from 'port'//定义读字节的端口int inp(unsigned port);代码中的常量PORTADDRESS (图3)用来定义通信端口的地址。
这里我们假定使用通信端口的第0位控制1-Wire总线。
设定该位为1,将使1-Wire总线变为低电平;设定该位为0,1-Wire总线将被释放,此时1-Wire 总线被电阻上拉,或被1-Wire从器件下拉。
代码中的tickDelay函数是一个用户编制的子程序,此函数用于产生一个1/4µs整数倍的延时。
在不同的平台下,该函数的实现也是不同的,故在此不做具体描述。
以下是tickDelay函数声明代码,以及一个SetSpeed函数,用于设定标准速度和高速模式的延时时间。
实例1. 1-Wire时序的生成// Pause for exactly 'tick' number of ticks = 0.25us//定义延时时间的函数void tickDelay(int tick); // Implementation is platform specific// 'tick' values//定义延时时间变量int A,B,C,D,E,F,G,H,I,J;//----------------------------------------------------------------------------- // Set the 1-Wire timing to 'standard' (standard=1) or 'overdrive' (standard=0). //定义一线制的通信时间模式,当变量standard=1时,为普通通讯模式,当standard=0时为高速通信模式。
//设定通信速度void SetSpeed(int standard){// Adjust tick values depending on speedif (standard){// Standard Speed 标准速度A = 6 * 4;B = 64 * 4;C = 60 * 4;D = 10 * 4;E = 9 * 4;F = 55 * 4;G = 0;H = 480 * 4;I = 70 * 4;J = 410 * 4;}else{// Overdrive Speed 高速模式A = 1.5 * 4;B = 7.5 * 4;C = 7.5 * 4;D = 2.5 * 4;E = 0.75 * 4;F = 7 * 4;G = 2.5 * 4;H = 70 * 4;I = 8.5 * 4;J = 40 * 4;}}1-Wire基本操作的代码程序如实例2所示。
实例2. 基本的1-Wire函数//----------------------------------------------------------------------------- // Generate a 1-Wire reset, return 1 if no presence detect was found,对一线制元器件复位,如果没有检测到元器件的话将会返回1// return 0 otherwise.其他情况返回0// (NOTE: Does not handle alarm presence from DS2404/DS1994)//将总线上的器件进行复位int OWTouchReset(void){int result;tickDelay(G);outp(PORTADDRESS,0x00); // Drives DQ lowtickDelay(H);outp(PORTADDRESS,0x01); // Releases the bustickDelay(I);result = inp(PORTADDRESS) ^ 0x01; // Sample for presence pulse from slave tickDelay(J); // Complete the reset sequence recoveryreturn result; // Return sample presence pulse result}//----------------------------------------------------------------------------- // Send a 1-Wire write bit. Provide 10us recovery time.//发送一位数据到一线制总线上,恢复时间为10us// void OWWriteBit(int bit){if (bit) //如果需要发送的值为1,则写“1”到数据总线上,然后释放总线{// Write '1' bitoutp(PORTADDRESS,0x00); // Drives DQ lowtickDelay(A);outp(PORTADDRESS,0x01); // Releases the bustickDelay(B); // Complete the time slot and 10us recovery}Else //否则,将数据“0”发送到数据总线上,然后释放总线{// Write '0' bitoutp(PORTADDRESS,0x00); // Drives DQ lowtickDelay(C);outp(PORTADDRESS,0x01); // Releases the bustickDelay(D);}}//----------------------------------------------------------------------------- // Read a bit from the 1-Wire bus and return it. Provide 10us recovery time.//int OWReadBit(void){int result;outp(PORTADDRESS,0x00); // Drives DQ lowtickDelay(A);outp(PORTADDRESS,0x01); // Releases the bustickDelay(E);result = inp(PORTADDRESS) & 0x01; // Sample the bit value from the slave //对从机的值进行采样tickDelay(F); // Complete the time slot and 10us recovery//延时,完成全部的时间过程和10us的复位时间return result; //返回所读到的从机值。