基于51单片机的温控系统
本文是基于STC89C52单片机的温度控制系统,主要由主控模块、显示模块及外围电路几个部分组成。 通过DS18B20检测外部温度,通过LCD1602显示,按键可调节上下限。当温度超过上限或低于下限,蜂鸣器均会报警。当温度超过上限时,电机会开始工作,模拟风扇,起到降温作用。LED灯电路模拟家用电灯,由两个开关对其进行控制。 删除线格式 该温控系统可以模拟简易智能家居系统。
系统硬件设计
整体电路原理图设计 该系统由51单片机作为主控模块,通过DS18B20检测温度,由LCD1602显示,并加外围电路组成。 测温显示模块 蜂鸣器报警及电机模块
系统软件设计
单片机IO口定义
sbit beep = P1^7;
sbit LED1 = P1^0;
sbit LED2 = P1^1;
sbit k1 = P1^2;
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;
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)
{
RS = 0;
RW = 0;
P0 = date;
EN = 1;
delay(100);
EN = 0;
}
void lcd_data(uint8 date)
{
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;
else
return 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;
else
DQ = 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;
delay(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++;
write_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 char
typedef unsigned char uint8;
typedef unsigned int uint16;
sbit beep = P1^7;
sbit LED1 = P1^0;
sbit LED2 = P1^1;
sbit k1 = P1^2;
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;
void motor_run();
void motor_stop();
void LED1_SWITCH();
void LED2_SWITCH();
void init();
void delay(uint16 time);
void lcd_init();
void lcd_order(uint8 date);
void lcd_data(uint8 date);
void write_1602(uint8 add,uint8 daa);
void display();
uint8 DS18B20_init();
void DS18B20_write(uint8 date);
uint8 DS18B20_read();
void DS18B20_check();
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();
DS18B20_init();
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();
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++;
write_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(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)
{
RS = 0;
RW = 0;
P0 = date;
EN = 1;
delay(100);
EN = 0;
}
void lcd_data(uint8 date)
{
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;
else
return 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;
else
DQ = 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;
delay(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()
{
if(k1==0)
LED1 = 0;
else if(k1==1)
LED1 = 1;
}
void LED2_SWITCH()
{
if(k2==0)
LED2 = 0;
else if(k2==1)
LED2 = 1;
}
使用Proteus仿真
整体电路PCB设计 51单片机温控系统程序(电机模拟风扇 可调上下限)Proteus仿真 DS18B20+LCD1602显示 原理图+程序+仿真图 HappyFrankie的公众号
|