功能介绍:
0.本系统采用STC89C52作为单片机
1.LCD1602液晶实时滚动显示8路温度传感器检测的温度值及设定温度值
2.当8路平均温度超过设定温度阈值范围,蜂鸣器报警,同时启动加热或降温装置
3.按键可更改温度上下限阈值
4.支持显示哪一路温度超过阈值
5.采用DC002作为电源接口可直接输入5V给整个系统供电
原理图:
PCB :
主程序:
#include "main.h"
enum _MODE_DF_ dispMode;
bit dispFlag = 1;
bit refreshFlag = 1;
xdata float f_temp[8] = 0.0; //温度值
float f_tempAverage; //温度平均值
unsigned int tempMax = 40; //温度上限
unsigned int tempMin = 20; //温度下限
unsigned char channel = 0;
unsigned char setIndex = 0;
char xdata dis0[16]; //定义显示区域临时存储数组
void main(void)
{
Timer0_Init();
LCD_Init(); //初始化液晶
DelayMs(200); //延时有助于稳定
LCD_Clear(); //清屏
while (1) //主循环
{
if (refreshFlag == 1) //刷新数据
{
unsigned char i;
refreshFlag = 0;
//TR0 = 0;
f_tempAverage = 0;
for (i = 0; i < 8; i++)
{
ReadTemp(i);
f_tempAverage = f_tempAverage + f_temp[i]; //累加
}
f_tempAverage = f_tempAverage / 8; //求平均
//TR0 = 1;
if (f_tempAverage < tempMin) //超过温度下限
{
RELAY_COOL = OFF;
RELAY_HEAT = ON;
BUZZER = ON;
}
else if (f_tempAverage > tempMax) //超过温度上限
{
RELAY_COOL = ON;
RELAY_HEAT = OFF;
BUZZER = ON;
}
else
{
RELAY_COOL = OFF;
RELAY_HEAT = OFF;
BUZZER = OFF;
}
}
if (dispFlag == 1) //2s获取数据并发送
{
dispFlag = 0;
if (dispMode == NORMAL)
{
TR0 = 0;
DispNormal(channel); //显示对应通道温度
TR0 = 1;
channel++;
if (channel > 7)
{
channel = 0;
}
}
}
KeyProcess();
}
}
void ReadTemp(unsigned char ch)
{
float current = 0;
float Rt = 0;
float f_tempVolt = 0; //温度对应电压
CD4051_SelChannel(ch);
f_tempVolt = 5 * (float)ReadADC(AIN0_GND) / 255; //读取电压
current = (5 - f_tempVolt) / Rp; //计算电流值
Rt = f_tempVolt / current; //计算电阻值
f_temp[ch] = ((Bx * T25) / (T25 * (log(Rt) - log(ntcR25)) + Bx)) - Ka;
DelayMs(10);
}
void DispNormal(unsigned char ch)
{
//液晶显示
sprintf(dis0, "H:%3d", tempMax); //打印温度值
LCD_DispStr(0, 0, dis0); //显示第一行
LCD_DispOneChar(5, 0, 0xdf); //写入温度右上角点
LCD_DispOneChar(6, 0, 'C'); //写入温度C
sprintf(dis0, "L:%3d", tempMin); //打印温度值
LCD_DispStr(9, 0, dis0); //显示第一行
LCD_DispOneChar(14, 0, 0xdf); //写入温度右上角点
LCD_DispOneChar(15, 0, 'C'); //写入温度C
//液晶显示
sprintf(dis0, "T%d:%6.1f", (int)(ch+1), f_temp[ch]); //打印温度值
LCD_DispStr(0, 1, dis0); //显示第二行
LCD_DispOneChar(9, 1, 0xdf); //温度右上角点
LCD_DispOneChar(10, 1, 'C'); //温度C
if (f_temp[ch] > tempMax || f_temp[ch] < tempMin)
{
LCD_DispStr(11, 1, " Err "); //显示
}
else
{
LCD_DispStr(11, 1, " "); //显示
}
}
/************************* 温度阈值设置显示 *************************/
void DispSetTemp(unsigned char setIndex)
{
LCD_DispStr(0, 0, "Set Temperature ");
sprintf(dis0, " H:%3d L:%3d ", tempMax, tempMin);
LCD_DispStr(0, 1, dis0);
switch (setIndex)
{
case 1: LCD_SetCursor(7, 1, 1); break;
case 2: LCD_SetCursor(13, 1, 1); break;
default:;
}
}
/*------------------------------------------------
定时器初始化子程序
------------------------------------------------*/
void Timer0_Init(void)
{
TMOD &= 0xF0; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
TH0 = (65536 - 10000) / 256; //重新赋值 10ms
TL0 = (65536 - 10000) % 256;
EA = 1; //总中断打开
ET0 = 1; //定时器中断打开
TR0 = 1; //定时器开关打开
}
/*------------------------------------------------
定时器中断子程序
------------------------------------------------*/
void Timer0_Interrupt(void) interrupt 1
{
static unsigned char time10ms = 0;
TH0 = (65536 - 10000) / 256; //重新赋值 10ms
TL0 = (65536 - 10000) % 256;
time10ms++;
if (time10ms % 10 == 0) // 100ms
{
refreshFlag = 1;
}
if (time10ms >= 200) // 2s
{
time10ms = 0;
dispFlag = 1;
}
}