单片机
返回首页

基于51单片机的温度控制proteus仿真

2025-11-07 来源:bilibili

功能介绍: 0.本系统采用STC89C52作为单片机 1.LCD1602液晶实时显示当前温度及温度范围设定 2.超过温度设定范围将启动加热棒加热或风扇冷却 3.超过设定温度将声光报警 4.按键可设置温度范围 5.采用DC002作为电源接口可直接输入5V给整个系统供电

原理图:

PCB:

主程序:

#include <reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义

#include <stdio.h>

#include "18b20.h"

#include "lcd1602.h"

#include "delay.h"


#define SETDOWN 0x01

#define SETUP 0x02


sbit KEY_SET = P3^3; //引脚定义

sbit KEY_SUB = P3^6;

sbit KEY_ADD = P3^4;


sbit RELAY_HOT = P2^1;

sbit RELAY_FAN = P2^0;

sbit BUZZER = P2^3;


unsigned int setLow = 20;    //下限

unsigned int setHigh = 50;   //上限

unsigned char dispFlag = 0; //更新显示标志

unsigned char setFlag = 0; //设置参数标志


unsigned int buzzerLater = 0; //蜂鸣器计时报


int tempBuf = 0;                   //读取温度值

float temperature;              //实际温度值

unsigned char readTempFlag = 0; //定义读时间标志


char dis0[16]; //定义显示区域临时存储数组

char dis1[16]; //定义显示区域临时存储数组


void CheckKey(void);

void Timer0_Init(void); //定时器初始化


void main(void)

{

    bit ack = 0;


    RELAY_HOT = 1; //打开

    RELAY_FAN = 1; //打开

    BUZZER = 0; //打开


    Timer0_Init();

    LCD_Init();   //初始化液晶

    DelayMs(200); //延时有助于稳定

    LCD_Clear();  //清屏


    RELAY_HOT = 0; //关闭

    RELAY_FAN = 0; //关闭

    BUZZER = 1; //关闭


    while (1) //主循环

    {


        if (readTempFlag == 1) //读取温度标志

        {

            readTempFlag = 0;

            DS18B20_Start();

            ack  = DS18B20_GetTemp(&tempBuf);

            if (ack == 1)

            {

                temperature = (float)tempBuf * 0.0625; //温度值转换

            }

            else

            {

                temperature = 0;

            }


        }

        if (dispFlag == 1)

        {

            dispFlag = 0;

            if ((temperature >= 0) && (temperature < 150))

            {

                sprintf(dis0, "Temp:%4.1f", temperature); //打印温度值

                LCD_DispStr(0, 0, dis0);                    //显示第二行

                LCD_DispOneChar(9, 0, 0xdf);                //写入温度右上角点

                LCD_DispOneChar(10, 0, 'C');                //写入温度右上角点


                if (temperature < setLow) //温度过低

                {

                    RELAY_HOT = 0; //开启升温 关闭降温

                    RELAY_FAN = 1;

                }

                else if ((temperature) > setHigh) //温度超高

                {

                    RELAY_HOT = 1; //关闭升温 开启降温

                    RELAY_FAN = 0;

                    buzzerLater = 100; //温度超高,立即报警

                }

                else //正常温度

                {

                    RELAY_HOT = 1; //关闭升温 关闭降温

                    RELAY_FAN = 1;

                    buzzerLater = 0;

                }

                if (buzzerLater >= 60) //正常清零 否则过高过低都会累加 超过1min

                {

                    BUZZER = 0;

                } //打开蜂鸣器

                else

                {

                    BUZZER = 1;

                } //关闭蜂鸣器

            }

            sprintf(dis1, "Set : %03d-- %03d", setLow, setHigh);

            LCD_DispStr(0, 1, dis1); //初始化显示


            if (setFlag == 0) //按键设置标志

            {

                LCD_DispOneChar(5, 1, ' ');

                LCD_DispOneChar(11, 1, ' '); //更新显示标志

            }

            else if (setFlag == 1) //按键设置标志

            {

                LCD_DispOneChar(5, 1, '>');

                LCD_DispOneChar(11, 1, ' '); //更新显示标志

            }

            else if (setFlag == 2) //按键设置标志

            {

                LCD_DispOneChar(5, 1, ' ');

                LCD_DispOneChar(11, 1, '>'); //更新显示标志

            }

        }

        CheckKey();            //检测按键

    }

}


void CheckKey(void)

{

    // static unsigned char rekey = 0;

    // if ((KEY_SET == 0) || (KEY_SUB == 0) || (KEY_ADD == 0)) //检测到按键按下

    // {

    //     DelayMs(10); //小抖动

    //     if (rekey == 0)

    //     {

    //         if (KEY_SET == 0) //检测是否按下

    //         {

    //             rekey = 1;

    //             setFlag++; //设置标志

    //             if (setFlag >= 3)

    //                 setFlag = 0;

    //         }

    //         else if (KEY_SUB == 0) //减值键

    //         {

    //             rekey = 1;

    //             if (setFlag == 1) //处于设置1

    //             {

    //                 if (setLow > 0)

    //                 {

    //                     setLow = setLow - 1;

    //                 }

    //             }

    //             else if (setFlag == 2) //处于设置2

    //             {

    //                 if (setHigh > setLow + 1)

    //                 {

    //                     setHigh = setHigh - 1;

    //                 }

    //             }

    //         }

    //         else if (KEY_ADD == 0) //加值键

    //         {

    //             rekey = 1;

    //             if (setFlag == 1) //处于设置1

    //             {

    //                 if (setLow < setHigh - 1)

    //                 {

    //                     setLow = setLow + 1;

    //                 }

    //             }

    //             else if (setFlag == 2) //处于设置2

    //             {

    //                 if (setHigh < 99)

    //                 {

    //                     setHigh = setHigh + 1;

    //                 }

    //             }

    //         }

    //     }

    // }

    // else

    // {

    //     rekey = 0; //防止重复检测到按键

    // }


    if (KEY_SET == 0) //检测是否按下

    {

        DelayMs(20);

        if (KEY_SET == 0) //检测是否按下

        {

            setFlag++; //设置标志

            if (setFlag >= 3)

                setFlag = 0;

        }

        while (KEY_SET == 0); //等待释放

    }


    if (KEY_SUB == 0) //检测是否按下,可实现连减

    {

        DelayMs(180);

        if (KEY_SUB == 0) //检测是否按下

        {

            if (setFlag == 1) //处于设置1

            {

                if (setLow > 0)

                {

                    setLow = setLow - 1;

                }

            }

            else if (setFlag == 2) //处于设置2

            {

                if (setHigh > setLow + 1)

                {

                    setHigh = setHigh - 1;

                }

            }

        }

    }


    if (KEY_ADD == 0) //检测是否按下,可实现连加

    {

        DelayMs(180);

        if (KEY_ADD == 0) //检测是否按下

        {

            if (setFlag == 1) //处于设置1

            {

                if (setLow < setHigh - 1)

                {

                    setLow = setLow + 1;

                }

            }

            else if (setFlag == 2) //处于设置2

            {

                if (setHigh < 99)

                {

                    setHigh = setHigh + 1;

                }

            }

        }

    }



}


/*------------------------------------------------

                    定时器初始化子程序

------------------------------------------------*/

void Timer0_Init(void)

{

    TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响

    TH0 = (65536 - 18432) / 256; //重新赋值 20ms

    TL0 = (65536 - 18432) % 256;

    EA = 1;  //总中断打开

    ET0 = 1; //定时器中断打开

    TR0 = 1; //定时器开关打开

}

/*------------------------------------------------

                定时器中断子程序

------------------------------------------------*/

void Timer0_Interrupt(void) interrupt 1

{

    static unsigned char time20ms  = 0;

    TH0 = (65536 - 18432) / 256; //重新赋值 20ms

    TL0 = (65536 - 18432) % 256;

    time20ms++;


    if (time20ms > 50)

    {

        time20ms = 0;

        readTempFlag = 1; //读标志位置1

        if (buzzerLater < 200)

            buzzerLater++;

    }


    if (time20ms % 10 == 0)

    {

        dispFlag = 1;

    }


}


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

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


进入单片机查看更多内容>>
相关视频
  • 【TI MSPM0 应用实战】智能小车+工业角度编码器+血氧仪+烟雾探测器!硬核参考设计详解!

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

  • 直播回放: Microchip Timberwolf™ 音频处理器在线研讨会

  • 基于灵动MM32W0系列MCU的指夹血氧仪控制及OTA升级应用方案分享

精选电路图
  • 1瓦线性调频增强器

  • 家用电器遥控器

  • 12V 转 28V DC-DC 变换器(基于 LM2585)

  • 红外开关

  • DS1669数字电位器

  • HA1377 桥式放大器 BCL 电容 17W(汽车音频)

    相关电子头条文章