迅维网

查看: 1435|回复: 1
打印 上一主题 下一主题

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

[复制链接]
跳转到指定楼层
1#
发表于 2016-7-24 07:59:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式 来自: 山西运城 来自 山西运城

马上注册,获取阅读精华内容及下载权限

您需要 登录 才可以下载或查看,没有帐号?注册

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

                               
登录/注册后看高清大图



                               
登录/注册后看高清大图



                               
登录/注册后看高清大图



                               
登录/注册后看高清大图



贴上程序
main.c
  • /*
  • 程序:18B20数码管显示
  • MCU:STC89C52RC
  • 晶振:11.0592MHz
  • */
  • #include<reg52.h>
  • #include "delay.h"
  • #include "ds18b20.h"
  • #define uchar unsigned char
  • #define uint unsigned int
  • #define duan P2
  • #define wei P3
  • sbit dp=P2^7;                                                        //小数点
  • int temp;                                                                        //温度缓存
  • //*******************************显示函数*****************************
  • void Display()
  • {
  •         uchar code table[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};//共阳码表0~9、负号、不显,共12位
  •         uchar code wf[5]={0xff,0xfe,0xfd,0xfb,0xf7};//位选表(只用到后4位)
  •         uchar data df[5];                                //用来存取温度各位数的值(只用到1-4)
  •         uchar i;
  •         uint j;
  •         j=temp;
  •   if(temp<0)j=-temp;                        //如果是负数转换成正数
  •         for(i=4;i>0;i--)                                //循环次数等于温度值的位数
  •                 {
  •                         df=j%10;                                        //取出各位数的值
  •                         j/=10;
  •                 }
  •         if(temp<0)df[1]=10;                        //如果温度是负数,千位显示负号
  •         if(df[1]==0)df[1]=11;                //如果千位是0不显示空
  •         for(i=4;i>0;i--)                                //循环次数等于数码管的位数
  •                 {
  •                         delaynms(15);                                //先延时,跳出循环后马上读取温度,避免读温度时数码管闪
  •                         duan=0xff;                                        //先关段显
  •                         duan=table[df];        //送出段码
  •                         if(i==3)dp=0;                                //显示小数点
  •                         wei=wf;                                        //送出位码
  •                 }
  • }
  • //*********************************主函数*********************************
  • void main()
  • {
  •         reset();                                                                //18b20初始化
  •         while(1)
  •         {
  •                 Display();                                                //显示温度
  •     temp=get_temp();                        //读取温度
  •         }
  • }


复制代码
18b20.c
  • #include <reg52.h>
  • #include <intrins.h>
  • #include "ds18b20.h"
  • #include "delay.h"
  • //**************************初始化函数************************
  • void reset()
  • {
  •         uchar x=0;
  •         DQ = 1;
  •         delayus(1);
  •         DQ = 0;
  •         delayus(50);        //延时600us
  •         DQ = 1;
  •         delayus(6);                //延时80us
  •         x=DQ;
  •         delayus(45);        //延时420us
  • }
  • //**************************写字节函数************************
  • void write_byte(uchar wByte)
  • {
  •         uchar i;
  •         for(i=8; i>0; i--)
  •         {
  •                 DQ = 0;
  •                 _nop_();
  •                 _nop_();
  •                 _nop_();
  •                 _nop_();
  •                 DQ = wByte & 0x01;
  •                 delayus(6);
  •                 DQ = 1;
  •                 wByte >>= 1;
  •         }
  •         delayus(1);
  • }
  • //***********************读字节函数************************
  • uchar read_byte(void)
  • {
  •         uchar i,rByte;
  •         for(i=8; i>0; i--)
  •         {
  •                 DQ = 0;
  •                 _nop_();
  •                 rByte >>= 1;
  •                 DQ = 1;
  •                 _nop_();
  •                 _nop_();
  •                 _nop_();
  •                 _nop_();
  •                 if(DQ)
  •                 rByte |= 0x80;
  •                 delayus(6);
  •         }
  •         return rByte;
  • }
  • //************************读取温度函数************************
  • uint get_temp(void)
  • {
  •         uchar a=0;
  •         uchar b=0;
  •         int t=0;                                                        //温度
  •         uint tt=0;
  •         reset();                                                        //复位
  •         write_byte(0xcc);                        //忽略ROM
  •         write_byte(0x44);                        //发送温度转化命令
  •         reset();                                                         //再次复位
  •         write_byte(0xcc);                        //忽略ROM
  •         write_byte(0xbe);
  •         a= read_byte();                                //读温度低字节
  •         b= read_byte();                                //读温度高字节
  •   tt=(b<<8)|a;                                        //合并
  •   if(b>200)tt=~tt+1;                //如果是负温度取反,加一
  •   t=tt*0.625;                                                //转换成十进制
  •   if(b>200)t=~t;                                //如果是负温度转换成负数
  •         return(t);                                                //返回温度值
  • }

复制代码
18b20.h
  • #ifndef _DS18B20_H_
  • #define _DS18B20_H_
  • #define uchar unsigned char
  • #define uint unsigned int
  • sbit DQ        =        P0^7;
  • void reset(void);//复位
  • void write_byte(uchar wByte);//写字节
  • uchar read_byte(void);//读字节
  • uint get_temp(void);//读温度
  • #endif

复制代码
delay.c
  • #include "delay.h"
  • //**************************10us延时函数************************
  • void delayus(uint us)
  • {
  •    while(us--);
  • }
  • //**************************nms延时函数************************
  • void delaynms(uint n)
  • {
  •   uint a;
  •         uchar b;
  •         for(a=n;a>0;a--)
  •                 for(b=110;b>0;b--);
  • }

复制代码
delay.h
  • #ifndef _DELAY_H_
  • #define _DELAY_H_
  • #define uchar unsigned char
  • #define uint unsigned int
  • void delayus(uint us);//延时10微秒
  • void delaynms(uint n);//延时若干毫秒

  • #endif




2#
发表于 2016-7-24 12:37:19 | 只看该作者 来自: 海南海口 来自 海南海口
楼主总是在牛A与牛C之间徘徊

回复 支持 反对

使用道具 举报

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

本版积分规则

快速回复 返回顶部 返回列表
附近
店铺
微信扫码查看附近店铺
维修
报价
扫码查看手机版报价
信号元
件查询
点位图


芯片搜索

快速回复