标题:
基于51单片机的温度采集显示系统
[打印本页]
作者:
wdq7
时间:
2018-2-1 14:44
标题:
基于51单片机的温度采集显示系统
新手,小试牛刀,通过18b20采集温度,然后通过四位数码管显示出来。
以下是proteus仿真和源程序。
大家多多指教
仿真图.png
(94.49 KB, 下载次数: 92)
下载附件
2018-2-1 14:42 上传
单片机源程序:
#include <REGX52.H>
#define uint8 unsigned char
#define uint16 unsigned int
sbit DQ =P3^7;//DS18B20数据端
sbit KEY1=P1^0;
sbit KEY2=P1^1;
sbit KEY3=P1^2;
uint16 Temperature;
uint16 TemperatureSave;
uint8 ReadFlag;//温度读取标志位
uint16 RecTemperature[10];//记录的温度
uint8 RecSum=0;//记录的数量最多10
uint8 Fin;
uint8 mode=0;
uint8 code DuCode[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //共阴数码管段选码表,0-F无小数点
uint8 code WeiCode[4]={0xFE,0xFD,0xFB,0xF7};//
uint8 SegBus[4]={0x40,0x40,0x40,0x40};//数码管显示缓存
code uint8 DecimalNum[16]={0,1,1,2,3,3,4,
4,5,6,6,7,8,8,9,9};//DS18B20读取的16bit数据最低4位对应的小数4舍5入取一位
void SegShow(void);//数码管显示函数
void Timer0Init(void);//定时器初始化函数
uint16 ReadTemp(uint8 mode);//读取温度函数
void ShowTemperature(uint16 temperature,uint8* str);
void main(void)
{Timer0Init();
ReadTemp(0);
while(1)
{
if(KEY1==0)
{
mode=(mode+1)%2;//模式
while(KEY1==0);
}
if(mode==1)//温度查询 +
{
if(KEY2==0)
{
Fin=(Fin+1)%10;
while(KEY2==0);
}
if(KEY3==0)
{
if(--Fin==255)Fin=0;
while(KEY3==0);
}
}
if(ReadFlag)//已经读取到温度
{
ReadFlag=0;
if(TemperatureSave!=Temperature)
{
TemperatureSave=Temperature;
RecTemperature[RecSum++]=Temperature;
RecSum=RecSum%10;
}
if(mode==0)
{
ShowTemperature(Temperature,SegBus);
}
else
{
ShowTemperature(RecTemperature[Fin],SegBus);
}
SegBus[2]|=0x80;//添加小数点;
}
SegShow();
}
}
/**************************************************
定时器初始化函数50ms定时中断
**************************************************/
void Timer0Init(void)
{
TMOD=0x01;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
TR0=1;
ET0=1;
EA=1;
}
/**************************************************
定时器中断函数
**************************************************/
void Timer0_ISR(void) interrupt 1
{
static uint8 cnt=0;
TH0=(65536-50000)/256;
TL0=(65536-50000)%256;
cnt++;
if(cnt>15)//每隔750ms读取一次温度
{
Temperature=ReadTemp(1);//读取温度
cnt=0;
ReadTemp(0);//启动温度转换
ReadFlag=1;
}
}
/**************************************************
数码管用延时函数
**************************************************/
void DelaySeg(void)
{
uint8 i;
for(i=0;i<110;i--);
}
/**************************************************
1位十进制转数码管段码
**************************************************/
void Dec1ToSeg(uint8 dec,uint8 *str)
{
str[0]=0;//百位不显示
str[1]=0;//个位不显示
str[2]=DuCode[dec];
}
/**************************************************
2位十进制转数码管段码
**************************************************/
void Dec2ToSeg(uint8 dec,uint8 *str)
{
str[0]=0;
str[1]=DuCode[dec/10];
str[2]=DuCode[dec%10];
}
/**************************************************
3位十进制转数码管段码
**************************************************/
void Dec3ToSeg(uint8 dec,uint8 *str)
{
str[0]=DuCode[dec/100];
str[1]=DuCode[dec%100/10];
str[2]=DuCode[dec%10];
}
/**************************************************
显示温度信息
**************************************************/
void ShowTemperature(uint16 temperature,uint8* str)
{
if(temperature&0x8000)//负温度
{
temperature=~temperature+1;
str[3]=DuCode[DecimalNum[temperature&0x0f]];//计算小数部分
temperature=temperature>>4;
if(temperature>9)//负温度的时候最多只有2位整数部分
{
Dec3ToSeg(temperature,str);
str[0]=0x40;//-
}
else
{
Dec2ToSeg(temperature,str);
str[1]=0x40;//-;
}
}
else
{
str[3]=DuCode[DecimalNum[temperature&0x0f]];//计算小数部分
temperature=temperature>>4;
if(temperature>99)
{
Dec3ToSeg(temperature,str);
}
else if(temperature>9)
{
Dec2ToSeg(temperature,str);
}
else
{
Dec1ToSeg(temperature,str);
}
}
}
/**************************************************
数码管显示
**************************************************/
void SegShow(void)
{
P0=0x00;
P2=WeiCode[0];
P0=SegBus[0];
DelaySeg();
P0=0x00;
P2=WeiCode[1];
P0=SegBus[1];
DelaySeg();
P0=0x00;
P2=WeiCode[2];
P0=SegBus[2];
DelaySeg();
P0=0x00;
P2=WeiCode[3];
P0=SegBus[3];
DelaySeg();
}
/**************************************************
大致延时一次延时2*t+7us
**************************************************/
void DelayUs(uint8 t)
{
while(--t);
}
/**************************************************
DS18B20初始化
**************************************************/
void DS18B20Init(void)
{
DQ = 1; //DQ复位
DelayUs(10); //稍做延时
DQ = 0; //单片机将DQ拉低
DelayUs(200);//精确延时 大于 480us 小于960us
DelayUs(200);
DQ = 1; //拉高总线
DelayUs(75); //15~60us 后 接收60-240us的存在脉冲
DelayUs(75);
}
/**************************************************
读取一个字节数据,返回uchar类型数据
**************************************************/
uint8 DS18B20Read(void)
{
uint8 i=0;
uint8 cdat=0;
for(i=8;i>0;i--)
{
DQ=0;//给脉冲信号
cdat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
cdat|=0x80;
DelayUs(50);
}
return (cdat);
}
/**************************************************
* 功能描述: 向DS18B20写一个字节数据
**************************************************/
void DS18B20Write(uint8 cdat)
{
unsigned char i=0;
for(i=8;i>0;i--)
{
DQ=0;
DQ=cdat&0x01;
DelayUs(50);
DQ=1;
cdat>>=1;
}
DelayUs(50);
}
/**************************************************
* 功能描述: 读取温度值,返回uint类型数据
**************************************************/
uint16 ReadTemp(uint8 mode)
{
unsigned char a=0;
unsigned int b,t;
DS18B20Init();
DS18B20Write(0xCC); // 跳过读序号列号的操作
switch(mode)
{
case 0:
DS18B20Write(0x44); // 启动温度转换
return 0;
case 1:
DS18B20Write(0xBE); //读取温度寄存器
a=DS18B20Read(); //低位
b=DS18B20Read(); //高位
b<<=8;
t=a+b;
return (t);
default:return 0;
}
return (0);
}
复制代码
0.png
(41.64 KB, 下载次数: 54)
下载附件
2018-2-1 15:47 上传
下载:
数码管DS18B20温度整点记录.zip
(70.75 KB, 下载次数: 122)
2018-2-1 14:43 上传
点击文件名下载附件
下载积分: 黑币 -5
作者:
xy160628
时间:
2018-5-28 08:46
仿真呢?
作者:
aking991
时间:
2018-5-30 09:00
测试了,显示都不正常,确定程序可行?
作者:
ai52
时间:
2018-7-3 11:18
用的是51 为什么定义为52
作者:
daddad
时间:
2018-7-3 15:01
大哥你这张图11和12引脚后面连得什么,看不了啊
作者:
daddad
时间:
2018-7-3 15:14
后面是不是接电源和地
作者:
daddad
时间:
2018-7-3 15:14
还是有什么附加功能吗
作者:
2753013982
时间:
2018-7-3 19:22
我仿真18B20输出数据都是0
作者:
李嘉智
时间:
2018-7-17 16:16
下载的文件会详尽一点么
作者:
拉屎特炫
时间:
2019-12-24 10:42
为什么仿真的时候温度只显示一个数据呢?我的只显示8
作者:
guardianl97
时间:
2020-4-28 08:50
感谢!
作者:
一羊迁徙
时间:
2020-11-9 16:00
10、11脚连什么阿,楼主,急!!!!
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1