找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5788|回复: 9
收起左侧

一个读温度不闪的18B20数码管温度计

[复制链接]
ID:113376 发表于 2016-7-24 00:07 | 显示全部楼层 |阅读模式
本帖最后由 cyy998 于 2016-7-24 14:25 编辑

初学单片机,学着做一个18B20温度计,开始在网上找了很多这方面的程序来学习,但是发现一个共同的问题,就是在18B20读取温度的时候数码管都会闪一下,经过研究发现原来是18B20读取温度需要的时间是毫秒级的,而数码管显示是实时扫描的,所以会造成显示中断。经过几天的折腾后,把显示程序改进了一下,达到了预期效果,现在已经看不到一点闪了,现把程序分享出来,跟同学们交流交流。
先上几张实物:
1.jpg

2.jpg

3.jpg

4.jpg


贴上程序(显示程序是自己写的,18B20程序是网上找的现成的)
main.c
  1. /*
  2. 程序:18B20数码管显示
  3. MCU:STC89C52RC
  4. 晶振:11.0592MHz
  5. */
  6. #include<reg52.h>
  7. #include "delay.h"
  8. #include "ds18b20.h"
  9. #define uchar unsigned char
  10. #define uint unsigned int
  11. #define duan P2
  12. #define wei P3
  13. sbit dp=P2^7;                                                        //小数点
  14. int temp;                                                                        //温度缓存
  15. //*******************************显示函数*****************************
  16. void Display()
  17. {
  18.         uchar code table[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};//共阳码表0~9、负号、不显,共12位
  19.         uchar code wf[5]={0xff,0xfe,0xfd,0xfb,0xf7};//位选表(只用到后4位)
  20.         uchar data df[5];                                //用来存取温度各位数的值(只用到1-4)
  21.         uchar i;
  22.         uint j;
  23.         j=temp;
  24.   if(temp<0)j=-temp;                        //如果是负数转换成正数
  25.         for(i=4;i>0;i--)                                //循环次数等于温度值的位数
  26.                 {
  27.                         df[i]=j%10;                                        //取出各位数的值
  28.                         j/=10;
  29.                 }
  30.         if(temp<0)df[1]=10;                        //如果温度是负数,千位显示负号
  31.         if(df[1]==0)df[1]=11;                //如果千位是0不显示空
  32.         for(i=4;i>0;i--)                                //循环次数等于数码管的位数
  33.                 {
  34.                         delaynms(15);                                //先延时,跳出循环后马上读取温度,避免读温度时数码管闪
  35.                         duan=0xff;                                        //先关段显
  36.                         duan=table[df[i]];        //送出段码
  37.                         if(i==3)dp=0;                                //显示小数点
  38.                         wei=wf[i];                                        //送出位码                        
  39.                 }
  40. }
  41. //*********************************主函数*********************************
  42. void main()
  43. {
  44.         reset();                                                                //18b20初始化
  45.         while(1)
  46.         {
  47.                 Display();                                                //显示温度
  48.     temp=get_temp();                        //读取温度
  49.         }        
  50. }
复制代码
18b20.c
  1. #include <reg52.h>
  2. #include <intrins.h>
  3. #include "ds18b20.h"
  4. #include "delay.h"
  5. //**************************初始化函数************************
  6. void reset()
  7. {
  8.         uchar x=0;
  9.         DQ = 1;
  10.         delayus(1);
  11.         DQ = 0;
  12.         delayus(50);        //延时600us
  13.         DQ = 1;
  14.         delayus(6);                //延时80us
  15.         x=DQ;        
  16.         delayus(45);        //延时420us        
  17. }
  18. //**************************写字节函数************************
  19. void write_byte(uchar wByte)
  20. {
  21.         uchar i;
  22.         for(i=8; i>0; i--)
  23.         {
  24.                 DQ = 0;
  25.                 _nop_();
  26.                 _nop_();
  27.                 _nop_();
  28.                 _nop_();
  29.                 DQ = wByte & 0x01;
  30.                 delayus(6);        
  31.                 DQ = 1;               
  32.                 wByte >>= 1;
  33.         }        
  34.         delayus(1);
  35. }
  36. //***********************读字节函数************************
  37. uchar read_byte(void)
  38. {
  39.         uchar i,rByte;
  40.         for(i=8; i>0; i--)
  41.         {
  42.                 DQ = 0;
  43.                 _nop_();
  44.                 rByte >>= 1;
  45.                 DQ = 1;
  46.                 _nop_();
  47.                 _nop_();
  48.                 _nop_();
  49.                 _nop_();        
  50.                 if(DQ)
  51.                 rByte |= 0x80;
  52.                 delayus(6);
  53.         }
  54.         return rByte;
  55. }
  56. //************************读取温度函数************************
  57. uint get_temp(void)
  58. {
  59.         uchar a=0;
  60.         uchar b=0;
  61.         int t=0;                                                        //温度
  62.         uint tt=0;
  63.         reset();                                                        //复位
  64.         write_byte(0xcc);                        //忽略ROM
  65.         write_byte(0x44);                        //发送温度转化命令
  66.         reset();                                                         //再次复位
  67.         write_byte(0xcc);                        //忽略ROM
  68.         write_byte(0xbe);
  69.         a= read_byte();                                //读温度低字节
  70.         b= read_byte();                                //读温度高字节
  71.   tt=(b<<8)|a;                                        //合并
  72.   if(b>200)tt=~tt+1;                //如果是负温度取反,加一
  73.   t=tt*0.625;                                                //转换成十进制
  74.   if(b>200)t=~t;                                //如果是负温度转换成负数
  75.         return(t);                                                //返回温度值
  76. }
复制代码
18b20.h
  1. #ifndef _DS18B20_H_
  2. #define _DS18B20_H_

  3. #define uchar unsigned char
  4. #define uint unsigned int

  5. sbit DQ        =        P0^7;

  6. void reset(void);//复位
  7. void write_byte(uchar wByte);//写字节
  8. uchar read_byte(void);//读字节
  9. uint get_temp(void);//读温度

  10. #endif
复制代码
delay.c
  1. #include "delay.h"
  2. //**************************10us延时函数************************
  3. void delayus(uint us)   
  4. {
  5.    while(us--);
  6. }
  7. //**************************nms延时函数************************
  8. void delaynms(uint n)
  9. {
  10.   uint a;
  11.         uchar b;
  12.         for(a=n;a>0;a--)
  13.                 for(b=110;b>0;b--);
  14. }
复制代码
delay.h
  1. #ifndef _DELAY_H_
  2. #define _DELAY_H_
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. void delayus(uint us);//延时10微秒
  6. void delaynms(uint n);//延时若干毫秒

  7. #endif
复制代码
最后附上源文件(有仿真)
18B20.rar (64.82 KB, 下载次数: 85)
回复

使用道具 举报

ID:79544 发表于 2016-7-25 08:32 | 显示全部楼层
谢谢楼主分享,值得学习!!!!!
回复

使用道具 举报

ID:92231 发表于 2016-8-12 07:39 来自手机 | 显示全部楼层
菜鸟需要补充知识,所以下载,学习中
回复

使用道具 举报

ID:108622 发表于 2016-10-12 19:29 来自手机 | 显示全部楼层
总能找到好东西
回复

使用道具 举报

ID:141595 发表于 2016-10-18 12:29 | 显示全部楼层
好东西。。。。。。。。。
回复

使用道具 举报

ID:147631 发表于 2016-11-21 12:28 | 显示全部楼层
您好,请问您写过间隔一定时间测量温度的吗
回复

使用道具 举报

ID:61002 发表于 2016-11-21 13:09 | 显示全部楼层
数码管显示还可以继续优化,现在看着有余晖
回复

使用道具 举报

ID:99130 发表于 2016-11-25 16:48 | 显示全部楼层
腾飞的龙 发表于 2016-7-25 08:32
谢谢楼主分享,值得学习!!!!!

这几段程序怎么组合
回复

使用道具 举报

ID:150416 发表于 2016-11-26 22:13 | 显示全部楼层
这个DS18B20测的是管子的温度,跟实际温度差距很大的
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表