基于51单片机的温控系统

本文是基于STC89C52单片机的温度控制系统,主要由主控模块、显示模块及外围电路几个部分组成。
通过DS18B20检测外部温度,通过LCD1602显示,按键可调节上下限。当温度超过上限或低于下限,蜂鸣器均会报警。当温度超过上限时,电机会开始工作,模拟风扇,起到降温作用。LED灯电路模拟家用电灯,由两个开关对其进行控制。
删除线格式 该温控系统可以模拟简易智能家居系统。

系统硬件设计

整体电路原理图设计

该系统由51单片机作为主控模块,通过DS18B20检测温度,由LCD1602显示,并加外围电路组成。
测温显示模块

蜂鸣器报警及电机模块

系统软件设计

单片机IO口定义

sbit beep = P1^7;  //定义蜂鸣器IO口sbit LED1 = P1^0;  //定义灯IO口
sbit LED2 = P1^1;
sbit k1 = P1^2;  //定义灯开关IO口
sbit k2 = P1^3;sbit MOTOR = P1^4;  //定义电机
sbit BUTTON_RUN = P1^5;  //定义电机启动按钮
sbit BUTTON_STOP = P1^6;  //定义电机关闭按钮sbit RS = P2^7;
sbit RW = P2^6;
sbit EN = P2^5;
sbit K1 = P2^0;
sbit K2 = P2^1;  //上限加
sbit K3 = P2^2;  //下限减sbit DQ = P2^3;  //DS18B20数据端

LCD1602初始化及读/写数据

void lcd_init()
{uint8 i;RW = 0;lcd_order(0x38);  //设置显示光标功能delay(100);lcd_order(0x0e);  //显示开及光标设置delay(100);lcd_order(0x06);  //显示光标移动设置delay(100);lcd_order(0x01);  //显示清屏delay(100);lcd_order(0x80);for(i=0;i<16;i++)lcd_data(hodometer[i]);
}void write_1602(uint8 add,uint8 daa)
{lcd_order(0x80+add);lcd_data(0x30+daa/10);lcd_data(0x30+daa%10);
}void lcd_order(uint8 date)  //LCD1602写指令
{RS = 0;  //选择写指令RW = 0;  //使能初始化P0 = date;  //发送指令EN = 1;  //开使能delay(100);  //延时EN = 0;  //关使能
}void lcd_data(uint8 date)  //LCD1602写数据
{RS = 1;  //选择写数据RW = 0;  //使能初始化P0 = date;  //发送指令EN = 1;  //开使能delay(100);  //延时EN = 0;  //关使能
}

DS18B20初始化及读/写数据

uint8 DS18B20_init()
{uint8 ans;DQ = 1;delay(1);DQ = 0;delay(100);DQ = 1;delay(6);ans = DQ;delay(100);if(!ans)return 1;elsereturn 0;
}void DS18B20_write(uint8 date)
{uint8 i;DQ = 1;delay(1);for(i=0;i<8;i++)  //根据时序将数据从低到高一位一位发送出来{DQ = 0;if(date&0x01)  //从低到高取出数据的每位DQ = 1;elseDQ = 0;delay(10);DQ = 1;date >>= 1;delay(1);}
}uint8 DS18B20_read()
{uint8 i,date = 0;DQ = 1;  //释放总线delay(1);for(i=0;i<8;i++)  //根据时序将数据从低到高一位一位接收{DQ = 0;date >>= 1;DQ = 1;if(DQ)date |= 0x80;  //将data的一位置1delay(8);DQ = 1;delay(1);}return date;  //返回读出的数
}void DS18B20_check()
{uint8 date1,date2;float ta;if(DS18B20_init()){DS18B20_write(0xcc);  //跳过序列号DS18B20_write(0x44);  //启动温度转换DS18B20_init();  //复位DS18B20_write(0xcc);  //跳过序列号DS18B20_write(0xbe);  //启动读取温度date1 = DS18B20_read();  //读取两个温度字节date2 = DS18B20_read();tmp = date2;tmp <<= 8;tmp = tmp|date1;ta = tmp*0.0625;tmp = ta*1000;}
}

温度上下限调节函数

void KEY()
{uint8 jj;uint8 i = 0;beep = 1;if(K1==0){while(!K1);while(1){lcd_order(0x0f);  //开启光标显示lcd_order(0x80+5);  //光标显示位置if(K2==0)  //判断加按键按下{while(K2==0);  //等待按键释放t_h++;  //温度上限加1write_1602(4,t_h);  //显示温度上限}if(K3==0)  //判断减按键按下{while(K3==0);  //等待按键释放if(t_h>t_l)  //判断温度上限大于温度下限t_h--;write_1602(4,t_h);  //显示温度上限}if(K1==0){while(K1==0);while(1){lcd_order(0x0f);lcd_order(0x80+13);if(K2==0){while(K2==0);if(t_l<t_h&&t_l>=0){lcd_order(0x80+11);lcd_data(' ');t_l++;write_1602(12,t_l);}else{t_l++;jj =~ t_l;write_1602(12,jj);}}if(K3==0){while(K3==0);if(t_l>(-50)){t_l--;if(t_l<0)jj =~ t_l;}if(t_l>=0){lcd_order(0x80+11);lcd_data(' ');write_1602(12,t_l);}if(t_l<0){write_1602(12,jj);lcd_order(0x80+11);lcd_data('-');}}if(K1==0){while(K1==0);goto loop;}}}}}loop:beep = 1;
}

完整程序展示

#include<reg52.h>
#include"stdio.h"#define uint unsigned int
#define uchar unsigned chartypedef unsigned char uint8;
typedef unsigned int uint16;sbit beep = P1^7;  //定义蜂鸣器IO口sbit LED1 = P1^0;  //定义灯IO口
sbit LED2 = P1^1;
sbit k1 = P1^2;  //定义灯开关IO口
sbit k2 = P1^3;sbit MOTOR = P1^4;  //定义电机
sbit BUTTON_RUN = P1^5;  //定义电机启动按钮
sbit BUTTON_STOP = P1^6;  //定义电机关闭按钮sbit RS = P2^7;
sbit RW = P2^6;
sbit EN = P2^5;
sbit K1 = P2^0;
sbit K2 = P2^1;  //加
sbit K3 = P2^2;  //减
sbit DQ = P2^3;  //DS18B20数据端//void delay(uint xms);
void motor_run();
void motor_stop();void LED1_SWITCH();
void LED2_SWITCH();void init();void delay(uint16 time);
void lcd_init();  //LCD1602初始化
void lcd_order(uint8 date);  //向LCD1602写一个指令
void lcd_data(uint8 date);  //向LCD1602写一个指令
void write_1602(uint8 add,uint8 daa);  //写数据void display();  //显示温度uint8 DS18B20_init();  //DS18B20初始化
void DS18B20_write(uint8 date);  //向DS18B20中写入一个数据
uint8 DS18B20_read();  //从DS18B20中读一个数据并返回
void DS18B20_check();  //启动DS18B20进行温度采集,并返回当前温度void KEY();  //修改报警范围long tmp = 0;  //存储温度值
long t_h = 37,t_l = 10;  //温度上限 温度下限bit tmp_hb = 0;  tmp_lb = 0;  //温度上下限调节指示变量void judge();  //判断报警uint8 hodometer[] = "  H:00   L:00  ";
uint8 temp[]=     "  wendu:00.00   ";
uint16 ji = 0;
uint8 ku = 0;  //标志位void main()
{init();lcd_init();  //LCD1602初始化DS18B20_init();  //DS18B20初始化DS18B20_write(0xcc);  //跳过序列号DS18B20_write(0x44);  //启动温度转换write_1602(4,t_h);write_1602(12,t_l);while(1){     LED1_SWITCH();LED2_SWITCH();motor_run();motor_stop();DS18B20_check();  //从DS18B20中读取温度display();KEY();judge();}
}void write_1602(uint8 add,uint8 daa)
{lcd_order(0x80+add);lcd_data(0x30+daa/10);lcd_data(0x30+daa%10);
}void judge()  //判断是否在报警范围
{if(tmp<(t_l*1000)||tmp>(t_h*1000)&&t_l>=0){beep = 0;delay(10);MOTOR = 1;}else if(t_l<0&&tmp>(t_h*1000)){beep = 1;MOTOR = 0;}else{beep = 1;MOTOR = 0;}
}void KEY()
{uint8 jj;uint8 i = 0;beep = 1;if(K1==0){while(!K1);while(1){lcd_order(0x0f);  //开启光标显示lcd_order(0x80+5);  //光标显示位置if(K2==0)  //判断加按键按下{while(K2==0);  //等待按键释放t_h++;  //温度上限加1write_1602(4,t_h);  //显示温度上限}if(K3==0)  //判断减按键按下{while(K3==0);  //等待按键释放if(t_h>t_l)  //判断温度上限大于温度下限t_h--;write_1602(4,t_h);  //显示温度上限}if(K1==0){while(K1==0);while(1){lcd_order(0x0f);lcd_order(0x80+13);if(K2==0){while(K2==0);if(t_l<t_h&&t_l>=0){lcd_order(0x80+11);lcd_data(' ');t_l++;write_1602(12,t_l);}else{t_l++;jj =~ t_l;write_1602(12,jj);}}if(K3==0){while(K3==0);if(t_l>(-50)){t_l--;if(t_l<0)jj =~ t_l;}if(t_l>=0){lcd_order(0x80+11);lcd_data(' ');write_1602(12,t_l);}if(t_l<0){write_1602(12,jj);lcd_order(0x80+11);lcd_data('-');}}if(K1==0){while(K1==0);goto loop;}}}}}loop:beep = 1;
}//void delay(uint xms)  //延时
//{//  uint i,j;
//  for(i=xms;i>0;i--)
//      for(j=110;j>0;j--) ;
//}void delay(uint16 time)
{while(time--);
}void lcd_init()
{uint8 i;RW = 0;lcd_order(0x38);  //设置显示光标功能delay(100);lcd_order(0x0e);  //显示开及光标设置delay(100);lcd_order(0x06);  //显示光标移动设置delay(100);lcd_order(0x01);  //显示清屏delay(100);lcd_order(0x80);for(i=0;i<16;i++)lcd_data(hodometer[i]);
}void lcd_order(uint8 date)  //LCD1602写指令
{RS = 0;  //选择写指令RW = 0;  //使能初始化P0 = date;  //发送指令EN = 1;  //开使能delay(100);  //延时EN = 0;  //关使能
}void lcd_data(uint8 date)  //LCD1602写数据
{RS = 1;  //选择写数据RW = 0;  //使能初始化P0 = date;  //发送指令EN = 1;  //开使能delay(100);  //延时EN = 0;  //关使能
}uint8 DS18B20_init()
{uint8 ans;DQ = 1;delay(1);DQ = 0;delay(100);DQ = 1;delay(6);ans = DQ;delay(100);if(!ans)return 1;elsereturn 0;
}void DS18B20_write(uint8 date)
{uint8 i;DQ = 1;delay(1);for(i=0;i<8;i++)  //根据时序将数据从低到高一位一位发送出来{DQ = 0;if(date&0x01)  //从低到高取出数据的每位DQ = 1;elseDQ = 0;delay(10);DQ = 1;date >>= 1;delay(1);}
}uint8 DS18B20_read()
{uint8 i,date = 0;DQ = 1;  //释放总线delay(1);for(i=0;i<8;i++)  //根据时序将数据从低到高一位一位接收{DQ = 0;date >>= 1;DQ = 1;if(DQ)date |= 0x80;  //将data的一位置1delay(8);DQ = 1;delay(1);}return date;  //返回读出的数
}void DS18B20_check()
{uint8 date1,date2;float ta;if(DS18B20_init()){DS18B20_write(0xcc);  //跳过序列号DS18B20_write(0x44);  //启动温度转换DS18B20_init();  //复位DS18B20_write(0xcc);  //跳过序列号DS18B20_write(0xbe);  //启动读取温度date1 = DS18B20_read();  //读取两个温度字节date2 = DS18B20_read();tmp = date2;tmp <<= 8;tmp = tmp|date1;ta = tmp*0.0625;tmp = ta*1000;}
}void display()
{uint8 i;temp[8] = 0x30+tmp/10000;temp[9] = 0x30+tmp/1000%10;temp[11] = 0x30+tmp/100%10;temp[12] = 0x30+tmp/10%10;temp[13] = 0x30+tmp%10;lcd_order(0x80+0x40);for(i=0;i<16;i++)lcd_data(temp[i]) ;
}void init()  //初始化函数
{BUTTON_RUN = 1;  BUTTON_STOP = 1;MOTOR = 0;beep = 0;delay(50);
}void motor_run()  //打开电机
{if(BUTTON_RUN==0){delay(10);if(BUTTON_RUN==0){while(1){MOTOR = 1;if(BUTTON_STOP==0){delay(5);if(BUTTON_STOP==0){break;}}}}}
}void motor_stop()  //关闭电机
{if(BUTTON_STOP==0){delay(10);if(BUTTON_STOP==0){MOTOR = 0;}}
}void LED1_SWITCH()  //LED1开关
{if(k1==0)LED1 = 0;else if(k1==1)LED1 = 1;
}void LED2_SWITCH()  //LED2开关
{if(k2==0)LED2 = 0;else if(k2==1)LED2 = 1;
}

使用Proteus仿真

整体电路PCB设计

51单片机温控系统程序(电机模拟风扇 可调上下限)Proteus仿真 DS18B20+LCD1602显示
原理图+程序+仿真图
HappyFrankie的公众号

基于51单片机的温控系统相关推荐

  1. S0011基于51单片机DS18B20温控风扇仿真设计

    基于51单片机DS18B20温控风扇仿真设计 (仿真+原理图+源码+设计报告) 原理图:Altium Designer 仿真原版本:proteus 7.8 程序编译器:keil 4/keil 5 编程 ...

  2. 51单片机计算机实物焊接,基于51单片机的最小系统焊接图 浅谈单片机最小系统...

    本文主要是关于51单片机的相关介绍,并对基于51单片机的最小系统焊接进行了详尽的阐述. 单片机最小系统 单片机最小系统主要由电源.复位.振荡电路以及扩展部分等部分组成. 对于一个完整的电子设计来讲,首 ...

  3. 基于51单片机的时钟系统

     这一次带来的项目是课程设计级别的基于51单片机的时钟系统,本次的项目共有两种,一种是基础功能时钟,上电后自动从00-00-00开始计时,另一种加上了调时功能,上电后自动从00-00-00开始,当需要 ...

  4. pt100+51单片机的温控系统程序+仿真图 还带压力显示的

    pt100+51单片机的温控系统程序+仿真图 还带压力显示的 使用pt100测温度,经过放大器放大后的电压值乘以236就是实际的温度值0.42V对应100度,0V对应0度,经过ad运算显示出来,其他滤 ...

  5. 基于51单片机篮球计分系统

    目录 一.项目功能概述 二.仿真 三.程序 四.论文 五.资料清单 资料下载地址:基于51单片机篮球计分系统 一.项目功能概述 液晶显示比赛时间.甲队和乙队的得分: 甲  甲队和乙队的得分分别有加1分 ...

  6. 【课设分享】基于51单片机的恒温控制器系统

    文章目录 恒温控制器系统概述 仿真软件 系统设计 电路设计 软件代码编写 代码下载 恒温控制器系统概述 该恒温控制器系统包含以下几个功能: 可按键设定温度 可显示当前温度和用户设定温度 有升温.降温模 ...

  7. 基于51单片机的电子温度计系统的设计与实现

    设计一个基于51单片机的电子温度计系统,其采用STC12C5A60S2芯片作为控制中心,DS18B20温度传感器为测温元件,LCD为显示器件.硬件设计部分包括温度传感电路设计.温度控制电路设计及显示电 ...

  8. 基于51单片机的病房呼叫系统

    基于51单片机的病房呼叫系统 声明:本系统仅仅是模拟基础功能,包括矩阵按键模块,数码管模块,蜂鸣器模块,独立按键模块,仅供学习使用.首先,考虑到51单片机开发板的矩阵按键只有4*4=16个,数码管显示 ...

  9. 基于51单片机的倒计时系统

    具体实现功能 系统由STC89C52单片机+按键电路+复位电路+晶振电路+LCD1602显示模块构成. 具体功能: (1)六位LED显示,从59分59秒99开始倒计时: (2)倒计时精度为0.01秒, ...

最新文章

  1. Zookeeper内部的简单细节(一)
  2. (四)建筑物多边形化简系统——“去尾巴”和分割复杂多边形
  3. IOS - 快速入门
  4. SAP CRM right dimension attribute后台存储
  5. Learning XNA 3.0翻译连载--序言
  6. 全志R40 串口485 控制操作
  7. 派生类从基类继承的过程
  8. 【渝粤教育】国家开放大学2018年春季 8038-21T实用管理基础 参考试题
  9. python+selenium环境配置(windows7环境)
  10. kafka与mysql持久化_漫游Kafka设计篇之数据持久化
  11. SWMM代码移植到64位平台
  12. “鬼影”浅析 - 反病毒,信息安全,网络安全,反木马,病毒资讯平台,安全解决方案,电脑使用技巧,杀毒软件交流,anti-virus,民间反病毒联盟
  13. 如何解决ueditor乱码问题
  14. css实用技巧之制作优惠券凹槽
  15. c35是什么意思_混凝土标号怎么来的?C30_C25_C35_都是什么意思
  16. 数据分析师岗位热招!你也有希望进大厂~
  17. 期货投资交易为什么要分批建仓?
  18. 第二周 新星杯的收获和感触
  19. 程序员该考虑什么时候辞职?
  20. 解决react脚手架运行后多出来很多webpack的日志

热门文章

  1. cookies是什么
  2. 小白也可以看懂的Numpy实操演示教程
  3. 安装双系统时进行多重引导,最好先安装Windows再装Linux
  4. 使用任务计划实现宽带pppoe断线自动连接 - Windows
  5. python中byte2array报错_python基础-bytes和bytearray的用法
  6. 企业业财一体化落地难?ERP系统推进业财融合,助力成功
  7. linux及林纳斯-托沃兹
  8. ubuntu下面高效率小工具总结
  9. python3基础知识复习 --TKinter GUI的终极选择(2)
  10. Numpy中flatten与ravel的区别