基于51单片机的温控系统
基于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单片机的温控系统相关推荐
- S0011基于51单片机DS18B20温控风扇仿真设计
基于51单片机DS18B20温控风扇仿真设计 (仿真+原理图+源码+设计报告) 原理图:Altium Designer 仿真原版本:proteus 7.8 程序编译器:keil 4/keil 5 编程 ...
- 51单片机计算机实物焊接,基于51单片机的最小系统焊接图 浅谈单片机最小系统...
本文主要是关于51单片机的相关介绍,并对基于51单片机的最小系统焊接进行了详尽的阐述. 单片机最小系统 单片机最小系统主要由电源.复位.振荡电路以及扩展部分等部分组成. 对于一个完整的电子设计来讲,首 ...
- 基于51单片机的时钟系统
这一次带来的项目是课程设计级别的基于51单片机的时钟系统,本次的项目共有两种,一种是基础功能时钟,上电后自动从00-00-00开始计时,另一种加上了调时功能,上电后自动从00-00-00开始,当需要 ...
- pt100+51单片机的温控系统程序+仿真图 还带压力显示的
pt100+51单片机的温控系统程序+仿真图 还带压力显示的 使用pt100测温度,经过放大器放大后的电压值乘以236就是实际的温度值0.42V对应100度,0V对应0度,经过ad运算显示出来,其他滤 ...
- 基于51单片机篮球计分系统
目录 一.项目功能概述 二.仿真 三.程序 四.论文 五.资料清单 资料下载地址:基于51单片机篮球计分系统 一.项目功能概述 液晶显示比赛时间.甲队和乙队的得分: 甲 甲队和乙队的得分分别有加1分 ...
- 【课设分享】基于51单片机的恒温控制器系统
文章目录 恒温控制器系统概述 仿真软件 系统设计 电路设计 软件代码编写 代码下载 恒温控制器系统概述 该恒温控制器系统包含以下几个功能: 可按键设定温度 可显示当前温度和用户设定温度 有升温.降温模 ...
- 基于51单片机的电子温度计系统的设计与实现
设计一个基于51单片机的电子温度计系统,其采用STC12C5A60S2芯片作为控制中心,DS18B20温度传感器为测温元件,LCD为显示器件.硬件设计部分包括温度传感电路设计.温度控制电路设计及显示电 ...
- 基于51单片机的病房呼叫系统
基于51单片机的病房呼叫系统 声明:本系统仅仅是模拟基础功能,包括矩阵按键模块,数码管模块,蜂鸣器模块,独立按键模块,仅供学习使用.首先,考虑到51单片机开发板的矩阵按键只有4*4=16个,数码管显示 ...
- 基于51单片机的倒计时系统
具体实现功能 系统由STC89C52单片机+按键电路+复位电路+晶振电路+LCD1602显示模块构成. 具体功能: (1)六位LED显示,从59分59秒99开始倒计时: (2)倒计时精度为0.01秒, ...
最新文章
- Zookeeper内部的简单细节(一)
- (四)建筑物多边形化简系统——“去尾巴”和分割复杂多边形
- IOS - 快速入门
- SAP CRM right dimension attribute后台存储
- Learning XNA 3.0翻译连载--序言
- 全志R40 串口485 控制操作
- 派生类从基类继承的过程
- 【渝粤教育】国家开放大学2018年春季 8038-21T实用管理基础 参考试题
- python+selenium环境配置(windows7环境)
- kafka与mysql持久化_漫游Kafka设计篇之数据持久化
- SWMM代码移植到64位平台
- “鬼影”浅析 - 反病毒,信息安全,网络安全,反木马,病毒资讯平台,安全解决方案,电脑使用技巧,杀毒软件交流,anti-virus,民间反病毒联盟
- 如何解决ueditor乱码问题
- css实用技巧之制作优惠券凹槽
- c35是什么意思_混凝土标号怎么来的?C30_C25_C35_都是什么意思
- 数据分析师岗位热招!你也有希望进大厂~
- 期货投资交易为什么要分批建仓?
- 第二周 新星杯的收获和感触
- 程序员该考虑什么时候辞职?
- 解决react脚手架运行后多出来很多webpack的日志