基于51单片机的数字温度计
(仿真+程序+设计报告)
功能介绍
具体功能:
1.DS18B20测温,数码管显示温度;
2.测量范围-55~125°C;
3.当前温度超过设定上下限会发生声光报警;
4.按键可设定上下限;
演示视频:
基于51单片机的数字温度计—可显示负数
按键功能:
K1是用来进入上下限调节模式的,当按一下K1进入上限调节模式,再按一下进入下限调节模式,再按一下退出调节模式。
在调节上下限温度模式下,K2是实现加1功能,K3是实现减1功能,K4是用来设定上下限温度正负的。
在正常模式下,按一下K2进入查看上限温度模式,显示1s左右自动退出;按一下K3进入查看下限温度模式,显示1s左右自动退出。
K4正常模式下用来设置和取消按键音。上下限设置模式下是用来设置温度的正负。
程序
/********************************************************************
* 程序名; 基于DS18B20的测温系统
* 功 能: 实时测量温度,超过上下限报警,报警温度可手动调整。K1是用来
* 进入上下限调节模式的,当按一下K1进入上限调节模式,再按一下进入下限
* 调节模式。在正常模式下,按一下K2进入查看上限温度模式,显示1s左右自动
* 退出;按一下K3进入查看下限温度模式,显示1s左右自动退出;按一下K4消除
* 按键音,再按一下启动按键音。在调节上下限温度模式下,K2是实现加1功能,
* K1是实现减1功能,K3是用来设定上下限温度正负的。
*********************************************************************/
#include<AT89X52.h> //将AT89X52.h头文件包含到主程序
#include<intrins.h> //将intrins.h头文件包含到主程序(调用其中的_nop_()空操作函数延时)
#define uint unsigned int //变量类型宏定义,用uint表示无符号整形(16位)
#define uchar unsigned char //变量类型宏定义,用uchar表示无符号字符型(8位)
/***微信公众号:木子单片机****/
uchar max=0x00,min=0x00; //max是上限报警温度,min是下限报警温度
bit s=0; //s是调整上下限温度时温度闪烁的标志位,s=0不显示200ms,s=1显示1s左右
bit s1=0; //s1标志位用于上下限查看时的显示
void display1(uint z); //声明display1()函数(display.h头文件中的函数,ds18b20.h要用应先声明)
#include"ds18b20.h" //将ds18b20.h头文件包含到主程序
#include"keyscan.h" //将keyscan.h头文件包含到主程序
#include"display.h" //将display.h头文件包含到主程序
/***********************主函数************************/
void main()
{
beer=1; //关闭蜂鸣器
led=1; //关闭LED灯
timer1_init(0); // . //初始化定时器1(未启动定时器1)
get_temperature(1); //首次启动DS18B20获取温度(DS18B20上点后自动将EEPROM中的上下限温度复制到TH和TL寄存器)
while(1) //主循环
{
keyscan(); //按键扫面函数
get_temperature(0); //获取温度函数
//keyscan(); //按键扫面函数
display(temp,temp_d*0.625);//显示函数
alarm(); //报警函数
//keyscan(); //按键扫面函数
}
}
****//完整资料
***/***微信公众号:木子单片机****/
/********************************************************************
* 程序名; __ds18b20_h__
* 功 能: DS18B20的c51编程头文件
*
* 说 明:用到的全局变量是:无符号字符型变量temp(测得的温度整数部分),temp_d
* (测得的温度小数部分),标志位f(测量温度的标志位‘0’表示“正温度”‘1’表
* 示“负温度”),标志位f_max(上限温度的标志位‘0’表示“正温度”、‘1’表
* 示“负温度”),标志位f_min(下限温度的标志位‘0’表示“正温度”、‘1’表
* 示“负温度”),标志位w(报警标志位‘1’启动报警‘0’关闭报警)。
*********************************************************************/
#ifndef __ds18b20_h__ //定义头文件
#define __ds18b20_h__
#define uint unsigned int //变量类型宏定义,用uint表示无符号整形(16位)
#define uchar unsigned char //变量类型宏定义,用uchar表示无符号字符型(8位)
sbit DQ= P2^3; //可位寻址变量定义,用DQ表示P2.3口
sbit beer=P1^0; //用beer表示P1.0
sbit led=P1^1; //用led表示P1.1
uchar temp=0; //测量温度的整数部分
uchar temp_d=0; //测量温度的小数部
bit f=0; //测量温度的标志位,0’表示“正温度”‘1’表示“负温度”)
bit f_max=0; //上限温度的标志位‘0’表示“正温度”‘1’表示“负温度”)
bit f_min=0; //下限温度的标志位‘0’表示“正温度”、‘1’表示“负温度”)
bit w=0; //报警标志位‘1’启动报警‘0’关闭报警)
/*****************************延时子函数******************************/
void ds18b20_delayus(uint t) //延时几μs
{
while(t--);
}
void ds18b20_delayms(uint t) //延时1ms左右
{
uint i,j;
for(i=t;i>0;i--)
for(j=120;j>0;j--);
}
/**************************ds18b20初始化函数*************************/
void ds18b20_init() // DS18B20初始化
{
uchar c=0;
DQ=1;
DQ=0; //控制器向DS18B20发低电平脉冲
ds18b20_delayus(80); //延时15-80μs
DQ=1; //控制器拉高总线,
while(DQ); //等待DS18B20拉低总线,在60-240μs之间
ds18b20_delayus(150); //延时,等待上拉电阻拉高总线
DQ=1; //拉高数据线,准备数据传输;
}
/***************************ds18b20字节读函数************************/
uchar ds18b20_read() //DS18B20 字节读取
{
uchar i;
uchar d = 0;
DQ = 1; //准备读;
for(i=8;i>0;i--)
{
d >>= 1; //低位先发;
DQ = 0;
_nop_();
_nop_();
DQ = 1; //必须写1,否则读出来的将是不预期的数据;
if(DQ) //在12us处读取数据;
d |= 0x80;
ds18b20_delayus(10);
}
return d; //返回读取的值
}
/*************************ds18b20字节写函数**************************/
void ds18b20_write(uchar d) // ds18b20字节写
{
uchar i;
for(i=8;i>0;i--)
{
DQ=0;
DQ=d&0x01;
ds18b20_delayus(5);
DQ=1;
d >>= 1;
}
}
/***************************获取温度函数****************************/
void get_temperature(bit flag)
{
uchar a=0,b=0,c=0,d=0;
uint i;
ds18b20_init(); //DS18B20初始化
ds18b20_write(0xcc); //向DS18B20发跳过读ROM命令
ds18b20_write(0x44); //写启动DS18B20进行温度转换命令,转换结果存入内部RAM
if(flag==1)
{ //首次启动DS18B20进行温度转换需要500ms,若转换时间不够就出错,读出的是85度的错误值。
display1(1); //用开机动画耗时
}
else
ds18b20_delayms(1);
ds18b20_init(); //DS18B20初始化
ds18b20_write(0xcc); //向DS18B20发跳过读ROM命令
ds18b20_write(0xbe); //写读内部RAM中9字节的内容命令
a=ds18b20_read(); //读内部RAM (LSB)
b=ds18b20_read(); //读内部RAM (MSB)
if(flag==1) //局部位变量f=1时读上下线报警温度
{
max=ds18b20_read(); //读内部RAM (TH)
min=ds18b20_read(); //读内部RAM (Tl)
}
if((max&0x80)==0x80) //若读取的上限温度的最高位(符号位)为‘1’表明是负温度
{f_max=1;max=(max-0x80);} //将上限温度符号标志位置‘1’表示负温度,将上限温度装换成无符号数。
if((min&0x80)==0x80) //若读取的下限温度的最高位(符号位)为‘1’表明是负温度
{f_min=1;min=(min-0x80);} //将下限温度符号标志位置‘1’表示负温度,将下限温度装换成无符号数。
i=b;
i>>=4;
if (i==0)
{
f=0; //i为0,正温度,设立正温度标记
temp=((a>>4)|(b<<4)); //整数部分
a=(a&0x0f);
temp_d=a; //小数部分
}
else
{
f=1; //i为1,负温度,设立负温度标记
a=~a+1;
b=~b;
temp=((a>>4)|(b<<4)); //整数部分
a=(a&0x0f); //小数部分
temp_d=a;
}
}
/*************************存储极限温度函数***************************/
void store_t()
{
if(f_max==1) //若上限温度为负,将上限温度转换成有符号数(最高位为1是负,为0是正)
max=max+0x80;
if(f_min==1) //若下限温度为负,将上限温度转换成有符号数
min=min+0x80;
ds18b20_init(); //DS18B20初始化
ds18b20_write(0xcc); //向DS18B20发跳过读ROM命令
ds18b20_write(0x4e); //向DS18B20发写字节至暂存器2和3(TH和TL)命令
ds18b20_write(max); //向暂存器TH(上限温度暂存器)写温度
ds18b20_write(min); //向暂存器TL(下限温度暂存器)写温度
ds18b20_write(0xff); //向配置寄存器写命令,进行温度值分辨率设置
ds18b20_init(); //DS18B20初始化
ds18b20_write(0xcc); //向DS18B20发跳过读ROM命令
ds18b20_write(0x48); //向DS18B20发将RAM中2、3字节的内容写入EEPROM
} //DS18B20上电后会自动将EEPROM中的上下限温度拷贝到TH、TL暂存器
/**************************温度超限报警函数*************************/
void alarm()
{ //若上限值是正值
if(f_max==0)
{
if(f_min==0) //若下限值是正值
{
if(f==0) //若测量值是正值
{
if(temp<=min||temp>=max)
{w=1;TR1=1;} //当测量值小于最小值或大于最大值时报警
if((temp<max)&&(temp>min))
{w=0;} //当测量值大于最小值且小于最大值时不报警
}
if(f==1){w=1;TR1=1;} //若测量值是负值时报警
}
if(f_min==1) //若下限值是负值
{
if(f==0) //若测量值是正值
{
if(temp>=max)//当测量值大于最大值时报警
{w=1;TR1=1;}
if(temp<max )//当测量值小于最大值时不报警
{w=0;}
}
if(f==1) //若测量值是负值
{
if(temp>=min)//当测量值大于最小值时报警
{w=1;TR1=1;}
if(temp<min)//当测量值小于最小值时不报警
{w=0;}
}
}
}
if(f_max==1) //若下限值是负值
{
if(f_min==1) //若下限值是负值
{
if(f==1) //若测量值是负值
{
if((temp<=max)||(temp>=min))
{w=1;TR1=1;} //当测量值小于最大值或大于最小值时报警
if((temp<min)&&(temp>max))
{w=0;} //当测量值小于最小值且大于最大值时不报警
}
if(f==0){w=1;TR1=1;} //若测量值是正值时报警
}
}
}
#endif
添加图片注释,不超过 140 字(可选)
硬件设计
使用元器件:
单片机:STC89C52;
(注意:单片机是通用的,无论51还是52、无论stc还是at都一样,引脚功能都一样。程序也是一样的。)
传感器:DS18B20;
晶振:11.0592MHz;
电容:33pf;蜂鸣器;
电阻:10k、4.7k、1k;
四位一体共阴极数码管;
排阻:4.7k 9脚;
红色发光二极管;
22uf电解电容;
PNP三极管;
轻触按钮;
导线:若干;
结构框图:
添加图片注释,不超过 140 字(可选)
设计资料
01仿真图
本设计使用Proteus7.8和Proteus8.9两个版本设计!具体如图!
添加图片注释,不超过 140 字(可选)
02程序
本设计使用软件keil4和keil5两个版本编程设计!具体如图!
添加图片注释,不超过 140 字(可选)
03设计报告
六千字设计报告,具体如下!
添加图片注释,不超过 140 字(可选)
04设计资料
资料获取请看前面演示视频,全部资料包括仿真源文件 、程序(含注释)、设计报告、元件清单等。具体内容如下,全网最全! !
操作演示请观看前面演示视频!
点赞分享一起学习成长。