标题:
DS18B20温度传感器程序
[打印本页]
作者:
海小阳
时间:
2021-4-27 11:21
标题:
DS18B20温度传感器程序
#include<reg52.h> //包含头文件
#include<math.h>
#define ui unsigned int
#define uc unsigned char //宏定义
sbit DQ =P3^7; //定义DS18B20总线I/O
sbit LEDR=P1^2;
sbit LEDG=P1^1;
sbit LEDB=P1^0;
bit bdata fuhao; //符号
uc qian,bai,shi,ge; //读取温度值的千、百、十和个位(例如实际温度是123.4摄氏度,在程序里处理数据时会放大10倍,就是小数点右移一位,方便处理,就是处理的是1234)
uc code led[] = {0x5F,0x44,0x9D,0xD5,0xC6,0xD3,0xDB,0x47,0xDF,0xD7}; //数码管对应的数字的段码
uc code led_dian[] = {0x7f,0x64,0xbd,0xf5,0xe6,0xf3,0xfb,0x67,0xff,0xf7}; //有小数点的数字段码表
uc m;
uc NUM_R=0,NUM_G=0,NUM_B=0;
uc DIS;
ui zan=25;
//============================================================================================
//====================================DS18B20=================================================
//============================================================================================
/*****延时子程序*****/
void Delay(int num)
{
while(num--) ; //num减占用系统资源,用于延时
}
/*****初始化DS18B20*****/
void Init_DS18B20()
{
DQ = 1; //DQ复位,就是拉高电平
Delay(8); //稍做延时
DQ = 0; //单片机将DQ拉低
Delay(80); //精确延时,大于480us
DQ = 1; //拉高总线
Delay(40); //延时
}
/*****读一个字节*****/
uc ReadOneChar()
{
uc i=0;
uc dat = 0; //定义变量用于循环和读取数据
for (i=8;i>0;i--) //循环8次
{
DQ = 0; //拉低
dat>>=1; //数据右移一位
DQ = 1; //拉高
if(DQ) //判断是否是高电平
dat|=0x80; //是高电平的话,就让dat的最好为为1
Delay(4); //延时
}
return(dat); //返回读取到的数据
}
/*****写一个字节*****/
void WriteOneChar(uc dat)
{
uc i=0; //定义变量用于循环
for (i=8; i>0; i--) //循环八次
{
DQ = 0; //低电平
DQ = dat&0x01; //最低位是0的话,DQ就等于0;最低位是1的话,DQ就等于1
Delay(5); //延时
DQ = 1; //拉高
dat>>=1; //右移一位
}
}
/*****读取温度*****/
ui ReadTemperature()
{
ui a=0,b=0,t=0;
float tt=0; //定义读取温度变量
Init_DS18B20(); //初始化18B20
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0x44); //启动温度转换
Init_DS18B20(); //初始化18B20
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器
a=ReadOneChar(); //读低8位
b=ReadOneChar(); //读高8位
t=b; //高八位的数据提取到t
t<<=8; //高八位数据左移八位
t=t|a; //高位和低八位数据组成一个数据
if(t&0xf800) //判断是否是负温度
{
t=~t+1; //将负温度值取反加一得到实际温度值
fuhao=1; //符号位为负
}
else //如果是正温度
fuhao=0; //符号位为正
tt=t*0.0625; //乘以0.0625得到实际温度
t=tt*10+0.5; //放大10倍输出并四舍五入
return(t); //返回温度数据
}
/*****读取温度*****/
void check_wendu()
{
ui f;
// TR0=0;
// zan=f;
f=ReadTemperature(); //获取温度值并减去DS18B20的温漂误差
// TR0=1;
// if(abs(f-zan)>50) f=zan;
qian=f/1000; //计算得到实际的百位数字
bai=(f%1000)/100; //计算得到实际的十位数字
shi=((f%1000)%100)/10; //计算得到实际的个位数字
ge=((f%1000)%100)%10; //计算得到实际的小数位
}
/*****显示开机初始化等待画面*****/
void Disp_init()
{
P0 = 0x7f; //显示----
P2 = 0x7f;
Delay(100);
P2 = 0xdf;
Delay(100);
P2 = 0xf7;
Delay(100);
P2 = 0xfd;
Delay(100);
P2 = 0xff; //关闭显示
}
/*****显示温度子程序*****/
void Disp_Temperature() //显示温度
{
if(qian==0) //千位等于0
{
if(fuhao==1) //是负温度
P0=0x7f; //显示-
else //是正温度
P0=0xff; //不显示
}
else if(qian!=0) //千位不等于0
P0 =~led[qian]; //显示千位数据
P2 = 0xfd; //打开第一位位选
Delay(10);
P2 = 0xff; //关闭位选
if((bai==0)&&(qian==0))//百位千位都是0
P0=0xff; //不显示
else if((bai!=0)||(qian!=0))//千位或者百位不等于0
P0=~led[bai]; //正常显示百位数据
P2=0xf7; //打开第二位
Delay(10);
P2 = 0xff; //关闭位选
P0=~led_dian[shi]; //显示十位数据
P2=0xdf; //打开第三位
Delay(10);
P2 = 0xff; //关闭位选
P0=~led[ge]; //显示个位数据
P2=0x7f; //打开第四位
Delay(10);
P2 = 0xff; //关闭位选
}
/*****主函数*****/
void main()
{
uc z; //定义变量用于for循环
for(z=0;z<100;z++) //循环100次读取温度并显示开机画面,防止开机显示85
{
Disp_init(); //开机初始化显示
ReadTemperature();
}
while(1) //进入while循环
{
check_wendu(); //读取温度
// Delay(20000);
if(fuhao==0)
{
if((qian*100+bai*10+shi)>=0&&(qian*100+bai*10+shi)<10) {NUM_R=0; NUM_G=2; NUM_B=8;} //温度在0-10度之间,颜色:青色偏蓝,状态:寒冷
else if((qian*100+bai*10+shi)>=10&&(qian*100+bai*10+shi)<20) {NUM_R=0; NUM_G=3; NUM_B=5;} //温度在10-20度之间,颜色:青色,状态:冷
else if((qian*100+bai*10+shi)>=20&&(qian*100+bai*10+shi)<30) {NUM_R=0; NUM_G=5; NUM_B=0;} //温度在20-30度之间,颜色:绿色,状态:舒适
else if((qian*100+bai*10+shi)>=30&&(qian*100+bai*10+shi)<35) {NUM_R=7; NUM_G=2; NUM_B=0;} //温度在30-35度之间,颜色:黄色,状态:热
else if((qian*100+bai*10+shi)>=35) {NUM_R=10; NUM_G=0; NUM_B=0;} //温度在35度以上,颜色:红色,状态:炎热
// if((qian*100+bai*10+shi)>=24&&(qian*100+bai*10+shi)<25) {NUM_R=0; NUM_G=2; NUM_B=8;} //温度在0-10度之间,颜色:青色偏蓝,状态:寒冷
// else if((qian*100+bai*10+shi)>=25&&(qian*100+bai*10+shi)<26) {NUM_R=0; NUM_G=3; NUM_B=5;} //温度在10-20度之间,颜色:青色,状态:冷
// else if((qian*100+bai*10+shi)>=26&&(qian*100+bai*10+shi)<27) {NUM_R=0; NUM_G=5; NUM_B=0;} //温度在20-30度之间,颜色:绿色,状态:舒适
// else if((qian*100+bai*10+shi)>=27&&(qian*100+bai*10+shi)<28) {NUM_R=7; NUM_G=2; NUM_B=0;} //温度在30-35度之间,颜色:黄色,状态:热
// else if((qian*100+bai*10+shi)>=28) {NUM_R=10; NUM_G=0; NUM_B=0;} //温度在35度以上,颜色:红色,状态:炎热
// else if((qian*100+bai*10+shi)<24) {NUM_R=0;NUM_G=0;NUM_B=10;}
}
else //温度为负值,零下,颜色:蓝色,状态:冰冻
{
NUM_R=0;NUM_G=0;NUM_B=10;
}
for(z=0;z<10;z++) //显示10次
{
Disp_Temperature(); //调用显示函数
m++;
if(m<NUM_R) LEDR=0;
else LEDR=1;
if(m<NUM_G) LEDG=0;
else LEDG=1;
if(m<NUM_B) LEDB=0;
else LEDB=1;
if(m>=10) m=0;
}
}
}
复制代码
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1