|
本帖最后由 cyy998 于 2016-7-24 14:25 编辑
初学单片机,学着做一个18B20温度计,开始在网上找了很多这方面的程序来学习,但是发现一个共同的问题,就是在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[i]=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[i]]; //送出段码
- if(i==3)dp=0; //显示小数点
- wei=wf[i]; //送出位码
- }
- }
- //*********************************主函数*********************************
- 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
复制代码 最后附上源文件(有仿真)
18B20.rar
(64.82 KB, 下载次数: 85)
|
|