DS2431 DS18B20 one wire 读写程序
最近公司有一个产品用到了DS2431,我就将先前一个DS18B20的程序中加入了DS2431的按规定函数。先传给大家分享.大家可以使用,转载时请说明出处. 此程序不够完善,希望能支持多节点设备连接。
单总线适用于单主机系统,能够控制一个或多个从机设备。主机可以是微控制器,从机可以是单总线器件,它们之间的数据交换只通过一条信号线。当只有一个从机设备时,系统可按单节点系统操作;当有多个从机设备时,系统则按多节点系统操作。
以下是程序:
#include \"system.h\"
#include \"one wire.h\"
unsigned char a_DS2431[8];
//code by lyx and RyanHsiung
#define DS_DQ_IN PORTAbits.RA4
#define DS_DQ_OUT LATAbits.LATA4
#define DS_DQ_TRISD TRISAbits.TRISA4
void delay_us(unsigned char time)
{//delayms=1us of 20Mhz osc //不准确1us
while(time--);
}
/*********************************************
CRC校验
*********************************************/
unsigned char crccheck(unsigned char *p,unsigned char len)
{
unsigned char bit0,cbit,r,temp,i,j,byte;
temp=0;
for (j=0;j byte=p[j]; for(i=0;i<8;i++) { cbit=temp&0x01; bit0=byte&0x01; temp=temp>>1; r=cbit^bit0; if(r==1) temp=temp^0x8c; byte=byte>>1; } } return temp; } /********************************************* 检查DS1820是否存在: 如果DS1820不存在返回1,否则返回0 *********************************************/ unsigned char OneWire_ack(void) { unsigned char ack; DS_DQ_TRISD=0; //输出 DS_DQ_OUT=0; //输出LOW //delay_us(500); delay_us(250); delay_us(250); delay_us(100); DS_DQ_OUT=1;//输出HIGH DS_DQ_TRISD=1;//RE2输入 delay_us(40);//delay_us(45); if(DS_DQ_IN==1) ack=1; // else ack=0;// //delay_us(500); delay_us(250); delay_us(250); delay_us(100); return ack; } /********************************************* 从DS1820读1字节数据 *********************************************/ unsigned char OneWire_read(void) { unsigned char i,byte,temp; byte=0x00; for (i=0;i<8;i++) { DS_DQ_TRISD=0;//RE2输出 DS_DQ_OUT=0;//输出LOW delay_us(1);//delay_us(3); DS_DQ_OUT=1;//输出HIGH DS_DQ_TRISD=1;//RE2输入 delay_us(5);//delay_us(10); if(DS_DQ_IN) byte|=0x80; // 读入 if (i<7) byte=byte>>1; delay_us(120);//delay_us(100); DS_DQ_TRISD=0;//RE2输出 delay_us(2);//delay_us(5); } return byte; } /********************************************* 写ROM或存贮器命令到DS1820 *********************************************/ void OneWire_write(unsigned char cmd) { unsigned char i,j; DS_DQ_TRISD=0;//RE2输出 for (j=0;j<=7;j++) { i=cmd&0x01; if (i==0x01) { DS_DQ_OUT=0;//输出LOW delay_us(5); DS_DQ_OUT=1;//输出HIGH delay_us(120); } else { DS_DQ_OUT=0;//输出LOW delay_us(120); DS_DQ_OUT=1;//输出HIGH delay_us(5); } cmd=cmd>>1; } } /********************************************* 匹配DS1820 *********************************************/ void OneWire_match(unsigned char *p) { unsigned char i; do i=OneWire_ack(); while (i==0x01); OneWire_write(0x55); for(i=0;i<8;i++) OneWire_write(p[i]); } uint8 DS2431_WriteOneByte(uint16 address, uint8 * p_data) { uint8 tem8h,tem8l,i,data,errors,temp8; tem8h=(unsigned char)(address>>=4); tem8l =(unsigned char)address; if(OneWire_ack()) return; OneWire_write(0xcc); //跳过ROM匹配 OneWire_write(0x0f); //发送写暂存器命令 OneWire_write(tem8l); //发送地址低位 OneWire_write(tem8h); //发送地址高位 for(i=0;i<8;i++) { data=*p_data; p_data++; OneWire_write(data); // ClrWDT(); } delay_us(25); if(OneWire_ack()) return; OneWire_write(0xcc); OneWire_write(0xAA); temp8=OneWire_read(); temp8<<=8; temp8+=OneWire_read(); errors=OneWire_read(); if(errors!=0x07) //跳过ROM匹配 //复制暂存器数据到存储器中 return 0; if(OneWire_ack()) return; OneWire_write(0xcc); //跳过ROM匹配 OneWire_write(0x55); //发出启动转换命令 OneWire_write(tem8l); //发送地址低位 OneWire_write(tem8h); //发送地址高位 OneWire_write(errors); for(i=0;i<50;i++) delay_us(100); //等待写时序结束 510us if(OneWire_read()!=0xAA) return 0; return 1; /* unsigned char i=1; if(OneWire_ack()) return; OneWire_write(0xcc);//跳过ROM匹配 OneWire_write(0x0f); // write scrachpad OneWire_write(0x20); // ta1 OneWire_write(0x00); // ta2 OneWire_write(data); // data a_DS2431[0] = OneWire_read(); a_DS2431[1] = OneWire_read(); crccheck(a_DS2431,2); */ } uint8 DS2431_WriteString(uint16 address, uint8 * p_data) { uint8 tem8h,tem8l,i,data,errors,temp8; tem8h=(unsigned char)(address>>=4); tem8l =(unsigned char)address; if(OneWire_ack()) return; OneWire_write(0xcc); //跳过ROM匹配 OneWire_write(0x0f); //发送写暂存器命令 OneWire_write(tem8l); //发送地址低位 OneWire_write(tem8h); //发送地址高位 for(i=0;i<8;i++) { data=*p_data; p_data++; OneWire_write(data); } delay_us(25); if(OneWire_ack()) return; OneWire_write(0xcc); OneWire_write(0xAA); temp8=OneWire_read(); temp8<<=8; temp8+=OneWire_read(); errors=OneWire_read(); if(errors!=0x07) return 0; if(OneWire_ack()) return; //跳过ROM匹配 //复制暂存器数据到存储器中 OneWire_write(0xcc); //跳过ROM匹配 OneWire_write(0x55); //发出启动转换命令 OneWire_write(tem8l); //发送地址低位 OneWire_write(tem8h); //发送地址高位 OneWire_write(errors); for(i=0;i<50;i++) delay_us(100); //等待写时序结束 510us if(OneWire_read()!=0xAA) return 0; return 1; /* unsigned char i=1; if(OneWire_ack()) return; OneWire_write(0xcc);//跳过ROM匹配 OneWire_write(0x0f); // write scrachpad OneWire_write(0x20); // ta1 OneWire_write(0x00); // ta2 OneWire_write(data); // data a_DS2431[0] = OneWire_read(); a_DS2431[1] = OneWire_read(); crccheck(a_DS2431,2); */ } uint8 DS2431_ReadOneByte(uint16 address ) { if(OneWire_ack()) return; OneWire_write(0xcc);//跳过ROM匹配 OneWire_write(0xf0);//发出读存储器命令 OneWire_write(LS_BYTE(address) );//地址低8位 OneWire_write(HS_BYTE(address));//地址高8位 a_DS2431[0] = OneWire_read(); // read data return a_DS2431[0]; /* unsigned char i=1; if(OneWire_ack()) return; OneWire_write(0xcc);//跳过ROM匹配 OneWire_write(0xaa); // a_DS2431[0] = OneWire_read(); // read ta1 a_DS2431[1] = OneWire_read(); // read ta2 a_DS2431[2] = OneWire_read(); // read es a_DS2431[3] = OneWire_read(); //read data a_DS2431[4] = OneWire_read(); //crc a_DS2431[5] = OneWire_read(); //CRC crccheck(&a_DS2431[4],2); */ } uint8* DS2431_ReadString(uint16 address) { uint8 i; if(OneWire_ack()) return; OneWire_write(0xcc);//跳过ROM匹配 OneWire_write(0xf0);//发出读存储器命令 OneWire_write(LS_BYTE(address) );//地址低8位 OneWire_write(HS_BYTE(address));//地址高8位 for(i=8;i>0;i--) { a_DS2431[8-i]=OneWire_read(); // ClrWDT(); } return a_DS2431; } void Start_convert_ds18b20(void) { unsigned char i=1; if(OneWire_ack()) return; OneWire_write(0xcc);//跳过ROM匹配 OneWire_write(0x44); //启动DS1820转换 } unsigned int Read_convert_ds18b20(unsigned char flag_language) { unsigned char i; unsigned char OneWire[9];//存放从DS18B20读取的9字节数据 unsigned int OneWire_temp; unsigned char flag_temp=0; if(OneWire_ack()) return 0x5fff; OneWire_write(0xcc);//跳过ROM匹配 OneWire_write(0xbe); //读转换后温度值 for (i=0;i<9;i++) { OneWire[i]=OneWire_read(); } OneWire_temp=OneWire[1]; OneWire_temp=OneWire_temp<<8; OneWire_temp+=OneWire[0]; if ((OneWire_temp&0xf800)!=0)//判断是否小于0度 { OneWire_temp=~OneWire_temp; OneWire_temp++; flag_temp=1; } OneWire_temp+=8; //四舍五入 8*0.0625=0.5 2k90717 OneWire_temp>>=4; if(OneWire_temp>0) OneWire_temp--; if(flag_language!=0) { OneWire_temp=OneWire_temp*9/5; if(flag_temp==1) { if(OneWire_temp>=32) OneWire_temp=OneWire_temp-32; else { OneWire_temp=32-OneWire_temp; flag_temp=0; } } else OneWire_temp=OneWire_temp+32; } OneWire_temp&=0x00ff; if(flag_temp==1) OneWire_temp|=0xff00; return(OneWire_temp); } 因篇幅问题不能全部显示,请点此查看更多更全内容