完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
大家好!我自己动手做了一个数字温度计。用的是STC12C2052AD单片机,而温度传感器用的是DS18B20,12M晶振,用C语言写(移植)的程序,但是现在温度可以测出来,只是显示有时是对的,有是错的。规律是:显示正确温度2-3秒,跳成850约一秒,然后又显示正确温度。对这个现象,我真是百思不得其解,如果是时序的问题,那为什么可以测得正确的温度?
还有,资料上说STC12系列的单片机是不分频的,那是不是说比如我用12M的晶振,那么执行一条指令的时间不再是1us,而是1/12 us?还是要通过反汇编再查stc的指令表得知? DS18B20是数字传感器,读出的是一个16bit的数据,前5bit表示符号,中间八位表示温度的整数部分,我是把中间8位取出来,然后用分离出百、十、个位,送到数码管显示,刚开始用定时器中断扫描数码管,但因这个传感器对时序要求很严格,便改用了软件延时,可是用定时器与用软件延时效果是一样的都是对错对错循还。 是不是在读的时候时序错了呢?读的数据刚好错位了?如果在每次读温度前对它进行读忙呢?是否可以解决? 以下是我的程序,请论坛高手多多指点,在下感激不尽! (程序可以显示正确的温度,只是会跳动) #include #include #define uchar unsigned char #define uint unsigned int void ow_reset(void); void delay(uint t); void write_byte(uchar val); uint read_temp(); uchar read_byte(void); work_temp(uint tem); void chuli(uchar wd); void delayms(uint ms); void displays(); uchar wei=0; uint temp=0; uchar wendu=0; uchar b,s,g,x; //百位,十位,个位,小数 ***it d4=P3^2; //位选信号端 ***it d3=P3^4; ***it d2=P3^3; ***it d1=P3^5; ***it DQ=P3^7; //接传感 器 uchar code disdu[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf}; //段选列表 //共阳LED段码表 "0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "不亮" "-" uchar data temp_data[2]={0x00,0x00}; //读出温度暂放 uchar code ditab[16]= {0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,0x07,0x08,0x08,0x09,0x09}; //小数部分直接查表 void main() { ow_reset(); write_byte(0xcc); //Skip ROM write_byte(0x44); //发转换命令 while(1) { work_temp(read_temp()); displays(); } } void ow_reset(void) //复位 { char presence=1; while(presence) { while(presence) { DQ=1;_nop_();_nop_();//从高拉倒低 DQ=0; delay(50); //550 us DQ=1; delay(6); //66 us presence=DQ; //presence=0 复位成功,继续下一步 } delay(45); //延时500 us presence=~DQ; } DQ=1; //拉高电平 } /****************DS18B20写命令函数************************/ //向1-WIRE 总线上写1个字节 void write_byte(uchar val) { uchar i; for(i=8;i>0;i--) { DQ=1;_nop_();_nop_(); //从高拉倒低 DQ=0;_nop_();_nop_();_nop_();_nop_(); //5 us DQ=val&0x01; //最低位移出 delay(6); //66 us val=val/2; //右移1位 } DQ=1; delay(1); } /****************DS18B20读1字节函数************************/ //从总线上取1个字节 uchar read_byte(void) { uchar i; uchar value=0; for(i=8;i>0;i--) { DQ=1;_nop_();_nop_(); value>>=1; DQ=0;_nop_();_nop_();_nop_();_nop_(); //4 us DQ=1;_nop_();_nop_();_nop_();_nop_(); //4 us if(DQ)value|=0x80; delay(6); //66 us } DQ=1; return(value); } uint read_temp() { ow_reset(); //总线复位 delay(200); write_byte(0xcc); //发命令 write_byte(0x44); //发转换命令 ow_reset(); delay(1); write_byte(0xcc); //发命令 write_byte(0xbe); temp_data[0]=read_byte(); //读温度值的第字节 delay(3); temp_data[1]=read_byte(); //读温度值的高字节 temp=temp_data[1]; temp<<=8; temp=temp|temp_data[0]; // 两字节合成一个整型变量。 return(temp); //返回温度值 } /****************温度数据处理函数************************/ //二进制高字节的低半字节和低字节的高半字节组成一字节,这个 //字节的二进制转换为十进制后,就是温度值的百、十、个位值,而剩 //下的低字节的低半字节转化成十进制后,就是温度值的小数部分 /********************************************************/ work_temp(uint tem) { uchar n=0; if(tem>6348) // 温度值正负判断 { tem=65536-tem; n=1; } x=tem&0x0f; // 取小数部分的值 wendu=tem>>4; // 取中间八位,即整数部分的值 chuli(wendu); if(n) b=0x0b; //负温度时最高位显示"-" } void delay(uint t) { t=t*12; //stc12系列单片机不分频,乘以8-12时,延时约10us for (;t>0;t--); } void delayms(uint ms) { ms=120*2*ms; //取这个参数显示比较稳定(数码管不闪烁,也有较高亮度) for(;ms>0;ms--) ; } void displays() //显示温度 { P1=disdu[ditab[x]]; d1=0; delayms(5); d1=1; P1=disdu[g]; P1^7=0; //点亮小数点 d2=0; delayms(5); d2=1; P1=disdu[s]; d3=0; delayms(5); d3=1; P1=disdu[b]; d4=0; delayms(5); d4=1; } void chuli(uchar wd) //处埋温度数据 { b=wd/100; s=wd%100/10; g=wd%100%10; if(b==0) b=10; if(s==0) s=10; } |
|
相关推荐
4个回答
|
|
应该是你的温度转换的太频繁了吧!精度为12位的话转换时间为750ms,在这750ms期间读温度的话可能读到的是错误值吧!一般来说温度变化都是比较缓慢的,用不着时时刻刻转换,你设置五秒转换一次,十秒转换一次,一分钟转换一次问题都不大,只是个人看法。
|
|
|
|
谢谢您的回复,问题正如你所说。 |
|
|
|
h414984185 发表于 2012-11-13 14:48 刚才在弄定时器的数码管动态扫描,加上18b20之后怎么的都不好用,看了你的话茅塞顿开啊,18b20不实时转换就什么问题都没有了,太感谢了 |
|
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
182 浏览 0 评论
如何用OpenCV的相机捕捉视频进行人脸检测--基于米尔NXP i.MX93开发板
1207 浏览 0 评论
《DNK210使用指南 -CanMV版 V1.0》第四十章 YOLO2人手检测实验
493 浏览 0 评论
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-网络编程示例之开发板测试
420 浏览 0 评论
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-网络编程示例之网络socket程序编程
957 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
11743 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-19 09:34 , Processed in 0.600578 second(s), Total 76, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号