| 单总线数字温度传感器18B20使用时出现读出温度不变 |
 |
|
|
| 出处:21ic
发布: 2007-11-06 |
|
zhushuping 发布于 2007-11-5 13:40:00 刚开始的时候是正确读出的的,大约过了20分钟后就只显示一个温度值,我用的18B20是八脚的,空脚都边连在一起,这应该没问题吧
sanwa_chen 发布于 2007-11-5 15:33:00 看看你读写18B20的时序有没有问题。 读写功能程序是自己写的,还是网上down的,不妨用示波器看看。 大多是时序问题
zhushuping 发布于 2007-11-5 15:44:00 //此为用18B20做传感器,三个数码管做显示的,并可设定温度,高低两个 温度值,到点后可报警输出;*/ /*作者:祝富龙 */ /*日期:07年10月30日*/ /*资源配置:P0作显示数据输出,P1.0, P1.1, P1.2 分别控制三个数码管 P1.3为18B20数据,P1.4,P1.5用于到设定值时的控制信号输出,P2.0,P2.1,P2.2分别分按键UP,SET,DOWN*/
#include "AT89X51.H" #include <intrins.h> #define nop10us _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_(); #define uchar unsigned char #define uint unsigned int #define up P2_0 //上调 #define set P2_1// 设定 #define down P2_2 //下调 sbit one=P1^0;//个位显示 sbit two=P1^1;//十位显示 sbit three=P1^2;//符号显示 sbit DQ=P1^3; //18B20数据位 delay11us(uint n); //11us延时函数 delay10ms(uchar n);//10ms延时函数 bit b20init(); //18b20初始化函数 b20write(uchar n);//写18b20函数 key(); //按键判断 处理程序 b20read(); //读18b20函数 display(); //显示温度函数 zhuanhuan();//转换一次温度,并读出温度放在buf中 shangdianinit();//上电初始化 uchar displaytable[]={0x28,0x7e,0xa2,0x62,0x74,0x61,0x21,0x7a,0x20,0x60}; uint temp,buf,baojingzhi=100,fuhao; //存放温度数据 uchar rr,num=0; //定时中断计数
//*********** 主程序 **************************** main() { shangdianinit();//上电初始化 while(1) { display(); zhuanhuan();//转换一次温度,并读出温度放在buf中 fuhao=buf&0xf800; if(fuhao==0xf800) three=0; else three=1; buf=buf&0x7ff; key();//按键判断 处理程序 } }
//********* 18b20初始化函数 ********************** bit b20init() { DQ=0; delay11us(60); DQ=1; nop10us;nop10us;nop10us;nop10us; if(DQ==1) { return 0; } else { nop10us;nop10us;nop10us;nop10us;nop10us;nop10us;nop10us;nop10us;nop10us;nop10us; DQ=1; delay11us(50); return 1; } }
//********** 写18b20函数 ************ b20write(uchar n) { uint i; for(i=0;i<8;i++) { DQ=0; nop10us; DQ=n&0x01; n=n>>1; nop10us;nop10us;nop10us;nop10us;nop10us;nop10us; DQ=1; _nop_();_nop_(); } }
//******** 读18b20函数 ******************** b20read() { uchar i; uint n; for(i=0;i<16;i++) { DQ=0; _nop_(); _nop_(); DQ=1; _nop_();_nop_();_nop_(); n=n>>1; if(DQ==0) { n=n&0x7fff; } else { n=n|0x8000; } nop10us;nop10us;nop10us;nop10us;nop10us;nop10us; DQ=1; _nop_(); _nop_(); } buf=n; }
//********** 显示温度函数 ***************** display() { uchar a,b,i; temp=buf * 0.0625; if(temp>100) { a=8;b=8; } else { a=temp/10; b=temp%10; } for(i=10;i>0;i--) { P0=displaytable[b]; one=0; delay11us(150); one=1; P0=displaytable[a]; two=0; delay11us(150); two=1; } }
//******** 10us延时函数 *********** delay11us(uint n) { for(;n>0;n--);
}
//******** 10ms延时函数 ******* delay10ms(uchar n) { unsigned int i; for(;n>0;n--) for(i=1250;i>0;i--) ; } //************ 按键判断 处理程序 ***************** key() { if(0xff!=P2) {delay11us(800); if(0xff!=P2) { if(set==0) { EA=0; TR0=0; while(!set); while(1) { display(); display(); if(set==0) {delay11us(800); if(set==0) {while(!set); goto loop; } } if(up==0) { delay11us(800); if(up==0) {while(!up); if(temp<60&&temp>0) buf=buf+10; baojingzhi=temp+1; } } if(down==0) { delay11us(2000); if(down==0) {while(!down); if(temp<60&&temp>0) buf=buf-10; baojingzhi=temp-1; } } display(); display(); delay10ms(50); } } } } else loop:display(); EA=1; TR0=1; }
//************ 定时中断函数 ******************** time0() interrupt 1 using 0 { EA=0; TR0=0; TH0=0x3c; TL0=0xb0; num++; if(num==20) { if(three) { if(temp>baojingzhi) P1_4=0; else P1_4=1; } else { if(temp>baojingzhi) P1_5=0; else P1_5=1; } num=0; } EA=1; TR0=1; }
zhuanhuan() { while(b20init()==0);//等待18B20初始化 b20write(0xcc); b20write(0x44); for(rr=0;rr<40;rr++) display(); while(b20init()==0);//等待18B20初始化 b20write(0xcc); b20write(0xbe); b20read(); }
shangdianinit()// shangdianinit();//上电初始化 { P1=0xff; P2=0xff; TMOD=0x01; TH0=0x3c; TL0=0xb0; EA=1; ET0=1; TR0=1; while(b20init()==0);//等待18B20初始化 b20write(0xcc);//跳过ROM b20write(0x44);//发出温度转换命令 delay10ms(70) ; while(b20init()==0);//等待18B20初始化 b20write(0xcc); b20write(0xbe); //发出读温度命令 b20read(); //读温度数据 buf=buf&0x7ff; display(); }
问渠 发布于 2007-11-5 21:24:00 即使找出原因你也收获不大,其实这个很成熟了,完全不用自己写,自己写也只要时序对不会有问题,你的温度是85吗?如果是上次的正常测量值那你这次的温度开始肯定没开始啊,你操作时关了中断了?说你有没有打断时序的可能,
sanwa_chen 发布于 2007-11-6 9:42:00 简单看了下,结构不是很好,有点累。 首先不知道你晶振多少,时序上你自己好好看看,你那些延时到底符不符合时序要求。 其次你用display 自程序做 转换温度 和 读取温度的延时,在默认分辨率下转换温度最多可能要500ms,你的延时是否不够,不然能读出准确的温度算你好运气。 再者你处理18B20的时候没有关中断,这是不行的。
zhushuping 发布于 2007-11-6 12:57:00 非常感谢“sanwa_chen”,谢谢你说的这些话,发自内心的感谢!!!
zhushuping 发布于 2007-11-6 13:01:00 晶振是12M的,现在的现象是一开始能正常显示温度,大约过了1到2个小时候后就只停留在一个温度点上,不会变化。
|
| 【关闭】 【打印】 |
|
|
|
|