基于51单片机的八路多路温度测控系统proteus仿真原理图PCB

功能介绍:
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;
    }
    
}

仿真演示视频:
https://www.bilibili.com/video/BV1V5411X7ZJ/

实物演示视频:
https://www.bilibili.com/video/BV1YR4y1w7MX/

  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值