目录
简介
该系统是基于 51 单片机的温度检测系统。主要通过使用 DS18B20 数字温度传感器来测量环境温度,并通过数码管进行实时显示。同时,系统还具备温度报警功能,可以根据设定的温度阈值进行报警提示。
系统框架图
系统设计图
实现效果
DS18B20初始化
1.DQ低电平 ,延迟600us
2.拉高总线,延迟60us
3.读取DQ状态
写时序
1.低电平延迟60us
2.释放总线
读时序
1.低电平延迟15us后拉高总线
2.读取数据
3.延迟45us
温度转换
获取数据后对温度进行转换
全部代码
#include <REGX52.H>
#include <REGX52.H>
#include "intrins.h"
unsigned char code SMG[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//共阴极数码管字码
unsigned char show[8];
unsigned char flag1,flag2,flag3;
int AlarmLow=15; // 默认报警的温度下限值是15度
int AlarmHig=36; // 默认报警的温度上限值是30度
sbit DS18B20_DQ=P3^7;
sbit key1 = P3^1; // 设置按键
sbit key2 = P3^0; // 加按键
sbit key3 = P3^2; // 减按键
sbit Buzzer=P2^5;
//各种延迟函数
void daley( unsigned int i){
while(i--);
}
//延时函数(毫秒级)
void Delay(unsigned int xms) //@12.000MHz
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
{
while (--j);
} while (--i);
}
}
// 600微秒延时
void delay600us(void) //600us
{
unsigned char a,b;
for(b=119;b>0;b--)
for(a=1;a>0;a--);
}
// 45微秒延时
void delay45us(void) //45us
{
unsigned char a;
for(a=20;a>0;a--);
}
// 60微秒延时
void delay60us(void) //60us
{
unsigned char a,b;
for(b=11;b>0;b--)
for(a=1;a>0;a--);
}
// 15微秒延时
void delay15us(void) //15us
{
unsigned char a;
for(a=5;a>0;a--);
}
// DS18B20初始化
unsigned char DS18B20_Reset()
{
unsigned char flag=0;
DS18B20_DQ=0;
delay600us();
DS18B20_DQ=1;
delay60us();
flag=DS18B20_DQ;
return flag;
}
//读时序
unsigned char DS18B20_ReadData()
{
unsigned int i;
unsigned char dat,j;
for(i=8;i>0;i--)
{
DS18B20_DQ=0;
delay15us();
DS18B20_DQ=1;
j=DS18B20_DQ;
dat = (dat >> 1) | (j<< 7);
delay45us();
}
return dat;
}
//写时序
void DS18B20_WriteData(unsigned char dat)
{
unsigned int j;
for(j=8;j>0;j--){
DS18B20_DQ=0;
DS18B20_DQ=dat&0x01;//获取最低位
delay60us();
DS18B20_DQ=1;
dat>>=1; //dat右移一位
}
}
//温度转换
int temperature_conversion(){
unsigned int L,H,temp=0;
DS18B20_Reset();
Delay(1);
DS18B20_WriteData(0xcc);//发送忽略ROM指令
DS18B20_WriteData(0x44);//发送完指令后,DS18B20开始转换并且存储到高速寄存器
DS18B20_Reset();
Delay(1);
DS18B20_WriteData(0xcc);//发送忽略ROM指令
DS18B20_WriteData(0xbe);//读取DS18B20暂存器指令
L = DS18B20_ReadData(); // 读取低八位
H = DS18B20_ReadData(); // 读取高八位
temp=H;
temp<<=8;
temp|=L;
return temp;
}
//数码管显示数据
void Display(int date){
unsigned char i;
if(date<0)
{
show[0]=0x40;
date=date-1;
date=~date;
date=date*0.0625*100+0.5;
}
else
{
show[0]=0x00;
date=date*0.0625*100+0.5;
}
show[1] = SMG[date / 10000]; //第一位
show[2] = SMG[date % 10000 / 1000]; //第二位
show[3] = SMG[date % 1000 / 100] | 0x80; //第三位
show[4] = SMG[date % 100 / 10]; //第四位
show[5] = SMG[date % 10]; //第五位
for(i=0;i<6;i++)
{
switch(i)
{
case(0): P2_2=0;P2_3=0;P2_4=0;break;
case(1): P2_2=1;P2_3=0;P2_4=0;break;
case(2): P2_2=0;P2_3=1;P2_4=0;break;
case(3): P2_2=1;P2_3=1;P2_4=0;break;
case(4): P2_2=0;P2_3=0;P2_4=1;break;
case(5): P2_2=1;P2_3=0;P2_4=1;break;
case (6):P2_4=0;P2_3=1;P2_2=1;break;
case (7):P2_4=1;P2_3=1;P2_2=1;break;
}
P0=show[5-i];
daley(100);
P0=0x00;
}
}
// 报警判断
void AlarmJudge(float dat)
{
float date = dat * 0.0625;
int i;
P2= ~0x01;
if (date < AlarmLow) // 判断温度是否过低
{
for (i = 0; i < 7; i++) {
P2 = _crol_(P2,1); // 左移一位,灯全亮
Delay(4);
Buzzer = 0; // 蜂鸣器报警
}
}
else if (date > AlarmHig) // 判断温度是否过高
{
for (i = 0; i < 7; i++) {
P2 = _crol_(P2,1); // 左移一位,灯全亮
Delay(4);
Buzzer = 0; // 蜂鸣器报警
}
}
else // 温度正常
{
Buzzer = 1; // 蜂鸣器停止报警
}
}
// 按键扫描
/*===================================
功能:温度范围设定函数
====================================*/
void key()
{
if(key1==0) // 温度范围设定选择键,按第一次设定上限,按第二次设定下限
{
daley(20);// 延时消抖动
if(key1==0)
{
flag1++;
}
while(!key1); // 按键松手检测
daley(20);
while(!key1);
}
if(key2==0) // 温度加按键
{
daley(20);
if(key2==0)
{
flag2=1;
}
while(!key2);
daley(20);
while(!key2);
}
if(key3==0) // 温度减键
{
daley(20);
if(key3==0)
{
flag3=1;
}
while(!key3);
daley(20);
while(!key3);
}
if(flag1==1) // 按第一次设定 温度上限
{
if(flag2==1) // 温度上限加
{
flag2=0;
AlarmHig++;
if(AlarmHig>125){AlarmHig=125;}
}
if(flag3==1) // 温度上限减
{
flag3=0;
AlarmHig--;
if(AlarmHig<=AlarmLow){AlarmHig++;}
}
else {
flag3=0;
flag2=0;
AlarmHig=AlarmHig;
}
Display(AlarmHig/0.0625); //daley(10);
}
if(flag1==2) // 按第二次设定温度下限
{
if(flag2==1) // 温度下限加
{
flag2=0;
AlarmLow++;
if(AlarmLow>=AlarmHig){AlarmLow--;}
}
if(flag3==1) // 温度下限减
{
flag3=0;
AlarmLow--;
if(AlarmLow<-55){AlarmLow=-55;}
}
else {
flag3=0;
flag2=0;
AlarmLow=AlarmLow;
}
Display(AlarmLow/0.0625); //daley(10);
}
if(flag1==3) //退出温度设定显示
{
flag1=0;
AlarmLow=AlarmLow;
AlarmHig=AlarmHig;
}
}
void main(){
int date1,i;
// TimerInit();
for(i=0;i<8;i++) // 由于传感器刚上电读出的温度不稳定,因此先进行几次温度的读取并丢弃
{
temperature_conversion(); //
Delay(10);
}
while(1)
{
// Buzzer = 0;
if(flag1==0) //设置按键没按下时显示温度
{
date1=temperature_conversion();//获取温度
Display(date1); //显示温度
}
key();
AlarmJudge(date1); //判断是否报警
//按键扫描
}
}