完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
在ARM7系统下,将两个以上ds18b20测温芯片挂在一根单总线上测温度时,需要匹配芯片的序列号。对芯片的温度寄存器进行读取前又需要读取芯片序列号。有高人能说说”匹配序列号”和”读芯片序列号”的程序代码怎么写,若会写希望能帮帮忙写一下给我看看,我先在这里谢过了
|
|
相关推荐
3个回答
|
|
/*总算搞定了,这一个是读18B20序列号的程序,
能够正常读取显示器是1602液晶。现将程序贴出来:**/ #include #define uchar unsigned char #define uint unsigned int /********************************************************************/ ***it DQ = P3^2; //温度传感器信号线 ***it rs = P2^2; //LCD数据/命令选择端(H/L)位声明 ***it rw = P2^1; //LCD读写控制,写为0,读为1 ***it lcden = P2^0; //LCD使能信号端位声明 /********************************************************************/ //uint temp; //定义整型的温度数据 //float f_temp; //定义浮点型的温度数据 //uint warn_11 = 270; //定义温度设定值,是温度值乘以10后的结果 //uint warn_12 = 250; //定义温度下限值 //uint warn_h1 = 300; //定义温度上限值 /********************************************************************/ void delay(uint z); //延时函数 void DS18B20_Reset(void); //DQ18B20复位,初始化函数 bit DS18B20_Readbit(void); //读1位数据函数 uchar DS18B20_ReadByte(void); //读1个字节数据函数 void DS18B20_WriteByte(uchar dat); //向DQ18B20写一个字节数据函数 void LCD_WriteCom(uchar com); //1602液晶命令写入函数 void LCD_WriteData(uchar dat); //1602液晶数据写入函数 void LCD_Init(); //LCD初始化函数 void Display18B20Rom(char Rom); //显示18B20序列号函数 /**********************************************/ /* 主函数 */ /**********************************************/ void main() { uchar a,b,c,d,e,f,g,h; LCD_Init(); rw = 0; DS18B20_Reset(); delay(1); DS18B20_WriteByte(0x33); delay(1); a = DS18B20_ReadByte(); b = DS18B20_ReadByte(); c = DS18B20_ReadByte(); d = DS18B20_ReadByte(); e = DS18B20_ReadByte(); f = DS18B20_ReadByte(); g = DS18B20_ReadByte(); h = DS18B20_ReadByte(); LCD_WriteCom(0x80+0x40); Display18B20Rom(h); Display18B20Rom(g); Display18B20Rom(f); Display18B20Rom(e); Display18B20Rom(d); Display18B20Rom(c); Display18B20Rom(b); Display18B20Rom(a); while(1); } /***************************************************/ /* 延时函数:void delay() */ /* 功能:延时函数 */ /***************************************************/ void delay(uint z)//延时函数 { uint x,y; for( x = z; x > 0; x-- ) for( y = 110; y > 0; y-- ); } /***************************************************/ /* DS18B20函数:void DS18B20_Reset() */ /* 功能:复位18B20 */ /***************************************************/ void DS18B20_Reset(void)//DQ18B20复位,初始化函数 { uint i; DQ = 0; i = 103; while( i > 0 ) i--; DQ = 1; i = 4; while( i > 0 ) i--; } /***************************************************/ /* DS18B20函数:void DS18B20_Readbit() */ /* 功能:读1个字节数据函数 */ /***************************************************/ bit DS18B20_Readbit(void) //读1位数据函数 { uint i; bit dat; DQ = 0; i++; //i++起延时作用 DQ = 1; i++; i++; dat = DQ; i = 8; while( i > 0 )i--; return( dat ); } /***************************************************/ /* DS18B20函数:void DS18B20_ReadByte() */ /* 功能:读1个字节数据函数 */ /***************************************************/ uchar DS18B20_ReadByte(void) //读1个字节数据函数 { uchar i,j,dat; dat = 0; for( i = 1; i <= 8; i++ ) { j = DS18B20_Readbit(); dat = ( j << 7 ) | ( dat >> 1 ); } return(dat); } /***************************************************/ /* DS18B20函数:void DS18B20_WriteByte() */ /* 功能:向DQ18B20写一个字节数据函数 */ /***************************************************/ void DS18B20_WriteByte(uchar dat) //向DQ18B20写一个字节数据函数 { uint i; uchar j; bit testb; for( j=1; j<=8; j++) { testb = dat&0x01; dat= dat>>1; if(testb) //写1 { DQ = 0; i++;i++; DQ = 1; i = 8;while(i>0)i--; } else { DQ = 0; //写0 i = 8;while(i>0)i--; DQ = 1; i++;i++; } } } /***********************************************/ /* LCD函数:void LCD_WriteCom() */ /* 功能:向LCD写入命令 */ /***********************************************/ void LCD_WriteCom(uchar com) { rs = 0; rw = 0; P0 = com; delay(5); lcden = 0; delay(5); lcden = 1; delay(5); lcden = 0; } /***********************************************/ /* LCD函数:void LCD_WriteData(uchar dat) */ /* 功能:向LCD写入数据 */ /***********************************************/ void LCD_WriteData(uchar dat) { rs = 1; //选择LCD为写入数据状态 rw = 0; lcden = 0; P0 = dat; //将待写入数据放到总线上 delay(5); lcden = 1; //给LCD使能端一个脉冲 delay(5); //信号将之前放到总线上 lcden = 0; //的数据写入LCD delay(5); } /***********************************************/ /* LCD函数:void LCD_Init() */ /* 功能:初始化LCD,设定LCD的初始状态 */ /***********************************************/ void LCD_Init() { LCD_WriteCom(0x38); //LCD显示模式设定 delay(15); LCD_WriteCom(0x08); //关闭LCD显示 delay(3); LCD_WriteCom(0x01); //LCD显示清屏 delay(3); LCD_WriteCom(0x06); //设定光标地址指针为自动加1 delay(3); LCD_WriteCom(0x0c); //打开LCD显示,但不显示光标 } /**********************************************/ /* */ /* 显示18B20序列号 */ /* */ /**********************************************/ void Display18B20Rom(char Rom) { uchar h,l; l = Rom & 0x0f; //取低4位 h = Rom & 0xf0; //取高4位 h >>= 4; if( ( h >= 0x00 )&&( h <= 0x09 ) ) LCD_WriteData(h+0x30); //取ASCII码 else LCD_WriteData(h+0x37); //取ASCII码 if( ( l >= 0x00 )&&( l <= 0x09 ) ) LCD_WriteData(l+0x30); //取ASCII码 else LCD_WriteData(l+0x37); //取ASCII码 } //第二个程序:匹配序列号,并读温度。 //关键问题是序列号的排例方式,是先发送低位数据。 //比如上个程序测出序列号为:8c00.0003.ba83.2a28 //在程序中ROM值就为uchar code str1[]={0x28,0x2a,0x83,0xba,0x03,0x00,0x00,0x8c}; #include #include #define uchar unsigned char #define uint unsigned int ***it RS=P2^2; ***it RW=P2^1; ***it EN=P2^0; ***it DQ=P3^2; uchar code str1[]={0x28,0x2a,0x83,0xba,0x03,0x00,0x00,0x8c}; //ROM 1 uchar code str2[]={0x28,0x05,0x76,0xba,0x03,0x00,0x00,0x6a}; //ROM2 uchar code table[8]={0x0c,0x12,0x12,0x0c,0x00,0x00,0x00,0x00}; // 摄氏温度符号 uchar data disdata[5]; uint tvalue;//温度值 uchar tflag;//温度正负标志 /*************************lcd1602程序**************************/ void delay1ms(uint ms)//延时1毫秒(不够精确的) { uint i,j; for(i=0;i } void wr_com(uchar com)//写指令// { delay1ms(1); RS=0; RW=0; EN=0; P0=com; delay1ms(1); EN=1; delay1ms(1); EN=0; } void wr_dat(uchar dat)//写数据// { delay1ms(1); RS=1; RW=0; EN=0; P0=dat; delay1ms(1); EN=1; delay1ms(1); EN=0; } void wr_new() //写新字符 { uchar i; wr_com(0x40); for(i=0;i<8;i++) { wr_dat(table[i]); } } void lcd_init()//初始化设置// { delay1ms(15); wr_com(0x38);delay1ms(5); wr_com(0x08);delay1ms(5); wr_com(0x01);delay1ms(5); wr_com(0x06);delay1ms(5); wr_com(0x0c);delay1ms(5); wr_new(); wr_com(0x80); wr_dat('A'); wr_com(0x81); wr_dat(':'); wr_com(0x89); wr_dat(0x00); wr_com(0x8a); wr_dat('C'); wr_com(0xc9); wr_dat(0x00); //摄氏温度字符 wr_com(0xca); wr_dat('C'); wr_com(0xc0); wr_dat('B'); wr_com(0xc1); wr_dat(':'); } /******************************ds1820程序***************************************/ void delay_18B20(uint i)//延时1微秒 { while(i--); } void ds1820rst()/*ds1820复位*/ { uchar x=0; DQ = 1; //DQ复位 delay_18B20(4); //延时 DQ = 0; //DQ拉低 delay_18B20(100); //精确延时大于480us DQ = 1; //拉高 delay_18B20(40); } uchar ds1820rd()/*读数据*/ { uchar i=0; uchar dat = 0; for (i=0;i<8;i++) { DQ = 0; //给脉冲信号 dat>>=1; DQ = 1; //给脉冲信号 if(DQ) dat|=0x80; delay_18B20(10); } return(dat); } void ds1820wr(uchar dat)/*写数据*/ { uchar i=0; for (i=0; i<8; i++) { DQ = 0; DQ = dat&0x01; delay_18B20(10); DQ = 1; dat>>=1; } } void b20_Matchrom(uchar a) //匹配ROM { char j; ds1820wr(0x55); //发送匹配ROM命令 if(a==1) { for(j=0;j<8;j++) ds1820wr(str1[j]); //发送18B20的序列号,先发送低字节 } if(a==2) { for(j=0;j<8;j++) ds1820wr(str2[j]); //发送18B20的序列号,先发送低字节 } } read_temp(uchar z)/*读取温度值并转换*/ { uchar a,b; float tt; ds1820rst(); ds1820wr(0xcc); //读序列号 ds1820rst(); if(z==1) { b20_Matchrom(1); //匹配ROM 1 } if(z==2) { b20_Matchrom(2); //匹配ROM 2 } ds1820wr(0x44);//*启动温度转换*/ delay1ms(5); ds1820rst(); ds1820wr(0xcc); //读序列号 ds1820rst(); if(z==1) { b20_Matchrom(1); //匹配ROM 1 } if(z==2) { b20_Matchrom(2); //匹配ROM 2 } ds1820wr(0xbe);//*读取温度*/ a=ds1820rd(); b=ds1820rd(); tvalue=b; tvalue<<=8; tvalue=tvalue|a; if(tvalue<0x0fff) tflag=0; else { tvalue=~tvalue+1; tflag=1; } tt=tvalue*0.0625; tvalue=tt*10; return(tvalue); } /*****************显示函数******************************/ void ds1820disp(uchar z)//温度值显示 { uchar flagdat; disdata[0]=tvalue/1000+0x30;//百位数 disdata[1]=tvalue%1000/100+0x30;//十位数 disdata[2]=tvalue%100/10+0x30;//个位数 disdata[3]=tvalue%10+0x30;//小数位 if(tflag==0) flagdat=0x20;//正温度不显示符号 else flagdat=0x2d;//负温度显示负号:- if(disdata[0]==0x30) {disdata[0]=0x20;//如果百位为0,不显示 if(disdata[1]==0x30) {disdata[1]=0x20;//如果百位为0,十位为0也不显示 } } if(z==1) { wr_com(0x82); wr_dat(flagdat);//显示符号位 wr_com(0x83); wr_dat(disdata[0]);//显示百位 wr_com(0x84); wr_dat(disdata[1]);//显示十位 wr_com(0x85); wr_dat(disdata[2]);//显示个位 wr_com(0x86); wr_dat(0x2e);//显示小数点 wr_com(0x87); wr_dat(disdata[3]);//显示小数位 } if(z==2) { wr_com(0xc2); wr_dat(flagdat);//显示符号位 wr_com(0xc3); wr_dat(disdata[0]);//显示百位 wr_com(0xc4); wr_dat(disdata[1]);//显示十位 wr_com(0xc5); wr_dat(disdata[2]);//显示个位 wr_com(0xc6); wr_dat(0x2e);//显示小数点 wr_com(0xc7); wr_dat(disdata[3]);//显示小数位 } } /********************主程序***********************************/ void main() { lcd_init();//初始化显示 while(1) { read_temp(1);//读取温度 ds1820disp(1);//显示 read_temp(2);//读取温度 ds1820disp(2);//显示 // delay1ms(10000); } } 评分
|
||
|
||
嗯!这个是可以用的,因为我也是参考的这个程序,先读出ROM中的数据,再在程序中加入ROM,进行匹配
|
|
|
|
想了解一下,我同时读9根DS18B20的温度 该怎么实现
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
imx6ull裸机编程,使用宏定义无法驱动,使用指针就可以驱动
227 浏览 0 评论
《DNK210使用指南 -CanMV版 V1.0》第三十二章 音频FFT实验
186 浏览 0 评论
飞凌嵌入式ElfBoard EL 1板卡-i2c与从设备通讯编程示例之i2c-tools工具使用
1243 浏览 0 评论
stc15f2k60s2利用串口传输字模存储到eeprom并进行点阵显示
1567 浏览 1 评论
1540 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
11614 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-5 12:17 , Processed in 0.648003 second(s), Total 80, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号