基于51单片机的多功能温度监测系统
这篇博客用HC6800-EM3开发板(一种普中科技的51单片机开发板)搭建了一个多功能的温度监测系统,具体功能如下:
- 按键key1为系统开关,key1按下时,单片机开始工作,再按一下,系统停止工作;
- 按键key2按下时,开启实时检测温度模式,每秒检测一次DS18B20温度传感器的温度,并将温度显示在LCD1602显示屏上;
- 按键key3按下时,每秒记录存储一次温度值,连续存储十次,即存储下这十秒的温度值;
- 按键key4,key5按下时,读取按下key3时存储的温度,key4表示显示存储的前一个温度,key5表示显示存储的下一个温度;
- 按键key6按下时,清除记录的温度;
- 无论什么时候,温度超过37摄氏度,系统报警(LED灯不停闪烁);
HC6800-EM3开发板图片来源:单片机已有程序,勿做
代码如下:
#include "reg51.h" //此文件中定义了单片机的一些特殊功能寄存器
#include "lcd1602.h" //lcd1602显示的函数,里面也定义了LCD的控制引脚
#include "temp.h" //DS18B20温度传感器的函数,里面也定义了DS18B20的控制引脚,这些文件买开发板时应该都有
typedef unsigned int u16; //对数据类型进行声明定义
typedef unsigned char u8;
sbit k1 = P1^0; //定义6个独立按键
sbit k2 = P1^1;
sbit k3 = P1^2;
sbit k4 = P1^3;
sbit k5 = P1^4;
sbit k6 = P1^5;
sbit led=P2^3; //led灯
int f; //转换前的温度值
unsigned int temp;//转换后的温度值,单位℃,因为显示要保留2位小数,因此这个值是100倍温度值
char state = 0; //0表示关,1表示开
unsigned char lcd[11]; //存储lcd显示的东西
unsigned char lcd_data[9][5]; //存储10次记录下的温度值
char key_state=0; //该值为1, 开启实时显示温度模式
char local = 1;// 读取存储的温度时,读取第local个值
void delay(u16 i) //延时函数,延迟的时间较短,led闪烁时用
{
while(i--);
}
void Delay1s() //延时函数,延迟的时间较长,key3记录十秒十次温度时用
{
unsigned char i, j, k;
i = 21;
j = 12;
k = 155;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
/*******************************************************************************
* 函数名 :Keypros()
* 函数功能 :按键处理函数
* 输入 : 无
* 输出 : 无
*******************************************************************************/
void Keypros()
{
int n=1;
if(k1==0)
{
delay(1000); //消抖处理
if(k1==0) //如果key1按下,切换工作状态,开/关
{
TR0=0;
if(state==0)
{
key_state=0;
state = 1;
lcd[0] = '0';
lcd[1] = '0';
lcd[2] = '.';
lcd[3] = '0';
lcd[4] = '0';
lcd[5] = ' ';
LCD_Display(0,0,lcd); //状态开,显示00.00
}
else
{
key_state=0;
state = 0;
lcd[0] = ' ';
lcd[1] = ' ';
lcd[2] = ' ';
lcd[3] = ' ';
lcd[4] = ' ';
lcd[5] = ' ';
LCD_Display(0,0,lcd);//状态关,不显示
}
}
while(!k1);
}
if(k2==0) //如果key2按下,key_state切换状态,开/关,key_state开启时(1),定时器中断工作,每秒显示一次温度值
{
delay(1000); //消抖处理
if(k2==0)
{
if(state==1)
{
if(key_state==0)
{
key_state=1; //key_state=1开启实时计数,否则停止实时计数
}
else
{
key_state=0;
}
}
}
while(!k2);
}
if(k3==0) //key3按下时,记录十次温度值,并将其存储在二维数组lcd_data中
{
delay(1000); //消抖处理
if(k3==0)
{
TR0=0;
key_state=0;
if(state==1)
{
for(n=1;n<=10;n++)
{
f=Ds18b20ReadTemp(); //读取10次DS18B20的温度,写进去
temp=f*0.0625*100+0.5;
lcd[0] = temp % 10000 / 1000+'0';
lcd[1] = temp % 1000 / 100+'0';
lcd[2] = '.';
lcd[3] = temp % 100 / 10+'0';
lcd[4] = temp % 10+'0';
LCD_Display(0,0,lcd);//显示第10个数
if(temp>=3700)
{
while(1)
{
delay(50000);
led=~led;
}
}
lcd_data[n-1][0] = lcd[0];
lcd_data[n-1][1] = lcd[1];
lcd_data[n-1][2] = lcd[2];
lcd_data[n-1][3] = lcd[3];
lcd_data[n-1][4] = lcd[4];
Delay1s();
}
}
}
while(!k3);
}
if(k4==0)//k4按下时,将存储的温度值用LCD1602显示,每按一下,local值减1,表示显示上一个存储的值
{
delay(1000); //消抖处理
if(k4==0)
{
TR0=0;
key_state=0;
if(state==1)
{
if(local==10)
{
local=1;
}
else
{
local=local+1;
}
lcd[0] = lcd_data[local-1][0];
lcd[1] = lcd_data[local-1][1];
lcd[2] = lcd_data[local-1][2];
lcd[3] = lcd_data[local-1][3];
lcd[4] = lcd_data[local-1][4];
LCD_Display(0,0,lcd);//显示
}
}
while(!k4);
}
if(k5==0)//k5按下时,将存储的温度值用LCD1602显示,每按一下,local值加1,表示显示下一个存储的值
{
delay(1000); //消抖处理
if(k5==0)
{
TR0=0;
key_state=0;
if(state==1)
{
if(local==1)
{
local=10;
}
else
{
local=local-1;
}
lcd[0] = lcd_data[local-1][0];
lcd[1] = lcd_data[local-1][1];
lcd[2] = lcd_data[local-1][2];
lcd[3] = lcd_data[local-1][3];
lcd[4] = lcd_data[local-1][4];
LCD_Display(0,0,lcd);//显示
}
}
while(!k5);
}
if(k6==0)//k6按下时,存储的值全部清0
{
delay(1000); //消抖处理
if(k6==0)
{
TR0=0;
key_state=0;
for(n=1;n<=10;n++)
{
lcd[0] = '0';
lcd[1] = '0';
lcd[2] = '.';
lcd[3] = '0';
lcd[4] = '0';
lcd_data[n-1][0] = lcd[0];
lcd_data[n-1][1] = lcd[1];
lcd_data[n-1][2] = lcd[2];
lcd_data[n-1][3] = lcd[3];
lcd_data[n-1][4] = lcd[4];
}
LCD_Display(0,0,lcd); //显示00.00
}
while(!k6);
}
}
void Timer0Init()
{
TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。
TH0=0XFC; //给定时器赋初值,定时1ms
TL0=0X18;
ET0=1;//打开定时器0中断允许
EA=1;//打开总中断
TR0=1;//打开定时器
}
void T0Function() interrupt 1 //定时器中断,key2按下时,开启定时器中断,每秒检测显示一次温度
{
static int m=0;
if(m<500)
{
m++;
}
else
{
TR0=0;//定时器中断会干扰DS18B20的读取,因此读取时关闭定时器中断
f=Ds18b20ReadTemp(); //读取10次DS18B20的温度,写进去
temp=f*0.0625*100+0.5;
lcd[0] = temp % 10000 / 1000+'0';
lcd[1] = temp % 1000 / 100+'0';
lcd[2] = '.';
lcd[3] = temp % 100 / 10+'0';
lcd[4] = temp % 10+'0';
LCD_Display(0,0,lcd);//显示第10个数
if(temp>=3700)//温度超过37时,led闪烁报警
{
while(1)
{
delay(50000);
led=~led;
}
}
m=0;
TR0=1;
}
TH0=0XFC; //给定时器赋初值,定时1ms
TL0=0X18;
}
void main()//主函数
{
LCD_Init();//LCD1602初始化
led = 0;
Timer0Init();//T0定时器中断
EA=1;
TR0=0;
f==Ds18b20ReadTemp();
while(1)
{
if(key_state==1)//是否实时显示?
{
TR0=1;
}
else
{
TR0=0;
}
Keypros();//按键检测
}
}
代码:
全部代码都在这篇博客了,里面#include的一些.h文件都是买板子的时候会有的驱动函数,网上都能搜到,都差不多;
有需要的可以下载包含.h文件的完整工程文件(含开发板原理图):基于51单片机的多功能温度监测系统