功能:
0.本系统采用STC89C52作为单片机
1.LCD1602液晶实时显示当前检测的温度值
2.循环显示多路热电偶检测值
3.当温度超过设定温度值一定范围以后,蜂鸣器报警,同时启动升温或降温装置
4.支持热电偶校验,当待测热电偶与标准热电偶出现检测温度偏离5℃时,对应界面显示Error
5.按键可设定预设温度值。
6.采用DC002作为电源接口可直接输入5V给整个系统供电
原理图:

PCB :

主程序:
#include <reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include <stdio.h>
#include "lcd1602.h"
#include "delay.h"
#include "max6675.h"
#include "key.h"
#include "cd4051.h"
#define ON 0
#define OFF 1
bit setFlag = 0;
bit refreshFlag = 1;
volatile unsigned int tempBuf = 0; //读取温度值
int tempLimit = 200;
float temperature = 0.0; //实际温度值
float stdTemperature = 0.0; //标准检测温度值
float stdVolt = 0.0; //标准检测电压
float Volt = 0.0; //实际检测电压
unsigned char channel = 1;
char xdata dis0[16]; //定义显示区域临时存储数组
void DispNormal(unsigned char ch);
void DispSetTempLimit(void);
void CheckKey(void);
void Timer0_Init(void); //定时器初始化
void main(void)
{
Timer0_Init();
LCD_Init(); //初始化液晶
DelayMs(200); //延时有助于稳定
LCD_Clear(); //清屏
while (1) //主循环
{
if (refreshFlag == 1) //2s获取数据并发送
{
refreshFlag = 0;
TR0 = 0;
if (setFlag == 0)
{
DispNormal(channel);
channel++;
if (channel > 7)
{
channel = 1;
}
}
TR0 = 1;
}
KeyProcess();
}
}
void DispNormal(unsigned char ch)
{
unsigned char timeCnt = 0;
CD5051_SelChannel(0);
DelayMs(100);
timeCnt = 10;
//获取标准温度
ET0 = 0;
do {
tempBuf = ReadMAX6675_0();
timeCnt--;
DelayMs(10);
} while (GetCurrentTemp(tempBuf) && timeCnt); //检测到热电偶或倒计时结束后跳出循环
ET0 = 1;
tempBuf &= 0x7ff8;
tempBuf >>= 3; //取D14~D3有效数据
stdTemperature = (float)tempBuf * 1023.75 / 4096 - 24.5; //减去合适的环境温度
stdVolt = (float)tempBuf * 5 / 4096;
//液晶显示
sprintf(dis0, "T0:%6.1f", stdTemperature); //打印温度值
LCD_DispStr(0, 0, dis0); //显示第一行
LCD_DispOneChar(9, 0, 0xdf); //写入温度右上角点
LCD_DispOneChar(10, 0, 'C'); //写入温度C
sprintf(dis0, " %3.1fV", stdVolt); //打印电压值
LCD_DispStr(11, 0, dis0); //显示第一行
timeCnt = 10;
CD5051_SelChannel(ch);
DelayMs(100);
do {
tempBuf = ReadMAX6675_0();
timeCnt--;
DelayMs(10);
} while (GetCurrentTemp(tempBuf) && timeCnt); //检测到热电偶或倒计时结束后跳出循环
tempBuf &= 0x7ff8;
tempBuf >>= 3; //取D14~D3有效数据
temperature = (float)tempBuf * 1023.75 / 4096 - 24.5; //减去合适的环境温度
Volt = (float)tempBuf * 5 / 4096;
//液晶显示
sprintf(dis0, "T%d:%6.1f", (int)ch, temperature); //打印温度值
LCD_DispStr(0, 1, dis0); //显示第二行
LCD_DispOneChar(9, 1, 0xdf); //写入温度右上角点
LCD_DispOneChar(10, 1, 'C'); //写入温度C
if (stdTemperature > tempLimit + 20) //超过阈值20度
{
RELAY_COOL = ON;
RELAY_HEAT = OFF;
BUZZER = ON;
}
else if (stdTemperature < tempLimit - 20) //超过阈值20度
{
RELAY_HEAT = ON;
RELAY_COOL = OFF;
BUZZER = ON;
}
else if ((stdTemperature >= tempLimit - 5) && (stdTemperature <= tempLimit + 5)) //±5度以内
{
RELAY_HEAT = OFF;
RELAY_COOL = OFF;
BUZZER = OFF;
}
if (temperature > stdTemperature + 5 || temperature < stdTemperature - 5)
{
LCD_DispStr(11, 1, "Error"); //显示第二行
}
else
{
sprintf(dis0, " %3.1fV", Volt); //打印电压值
LCD_DispStr(11, 1, dis0); //显示第二行
}
}
void DispSetTempLimit(void)
{
LCD_DispStr(0, 0, "Set Temperature ");
sprintf(dis0, " %4d ", tempLimit);
LCD_DispStr(0, 1, dis0);
LCD_DispOneChar(9, 1, 0xdf); //写入温度右上角点
LCD_DispOneChar(10, 1, 'C'); //写入温度C
}
/*------------------------------------------------
定时器初始化子程序
------------------------------------------------*/
void Timer0_Init(void)
{
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 >= 200) // 2s
{
time10ms = 0;
refreshFlag = ~refreshFlag;
}
}
342



被折叠的 条评论
为什么被折叠?



