恒温控制器系统概述
该恒温控制器系统包含以下几个功能:
- 可按键设定温度
- 可显示当前温度和用户设定温度
- 有升温、降温模块
- 可最终达到恒温
仿真软件
系统设计
电路设计
恒温控制系统一共有6个模块,分别是主控芯片模块、按键输入模块、设定温度显示模块、当前温度显示模块、温度采集模块和升温、降温模块。
- 按键输入模块:该模块由4*3的矩阵键盘和1个确认按钮构成。系统刚开始启动后,用户通过矩阵键盘输入想要设定的温度(0°~99°),输入完毕后按下确认键,然后将该温度数据传送给主控芯片AT89C51;
- 设定温度显示模块:该模块由一个2位8段LED数码管构成,主控芯片AT89C51使用P3口控制该数码管的段选,使用P2.4和P2.5两个端口来控制该数码管的位选。主控芯片AT89C51将从矩阵键盘得到的设定温度信息,通过2位8段LED数码管显示出来;
- 温度采集模块;该模块由一个DS18B20温度传感器构成。使用DS18B20温度传感器采集当前的温度,并将该温度信息传送给主控芯片AT89C51;
- 当前温度显示模块:该模块由两个74HC573锁存器和一个4位8段LED数码管构成,主控芯片AT89C51使用P2.6和P2.7控制两个74HC573锁存器的片选,两个锁存器的输入口均与主控芯片的P0口相连,并使用一个100欧的排阻作为P0口的上拉电阻,两个锁存器的输出口分别与4位8段LED数码管的段选口与位选口相连;
- 升温、降温模块:该模块由一个绿色LED和一个红色LED构成,绿色LED负责降温,每闪烁一次温度下降0.5°,红色LED负责升温,每闪烁一次温度上升0.5°。主控芯片AT89C51根据当前温度和用户设定温度之间的差值,来控制升温还是降温,以达到恒温的目的。
软件代码编写
程序的具体流程如下:
- 硬件初始化,关闭所有的数码管;
- 进行两次按键扫描循环,分别获取用户设定温度的十位和个位,获取完毕后,判断确认键是否被按下,如果用户按下确认键则进入到主程序循环中;
while(ok)
{
while(key1 == 15)
{
key1 = keyscan();
delay(50);
}
while(key2 == 15)
{
key2 = keyscan();
delay(50);
}
delay(100);
}
uchar keyscan()
{
uchar temp,key;
key = 15;
P1 = 0xfe;
temp = P1;
temp = temp & 0xf0;
if(temp!=0xf0)
{
delay(10);
temp = P1;
temp = temp & 0xf0;
if(temp!=0xf0)
{
temp = P1;
switch(temp)
{
case 0xee:
key = 1;
break;
case 0xde:
key = 2;
break;
case 0xbe:
key = 3;
break;
}
while(temp!=0xf0)
{
temp = P1;
temp = temp & 0xf0;
}
}
}
P1 = 0xfd;
temp = P1;
temp = temp & 0xf0;
if(temp!=0xf0)
{
delay(10);
temp = P1;
temp = temp & 0xf0;
if(temp!=0xf0)
{
temp = P1;
switch(temp)
{
case 0xed:
key = 4;
break;
case 0xdd:
key = 5;
break;
case 0xbd:
key = 6;
break;
}
while(temp!=0xf0)
{
temp = P1;
temp = temp & 0xf0;
}
}
}
P1 = 0xfb;
temp = P1;
temp = temp & 0xf0;
if(temp!=0xf0)
{
delay(10);
temp = P1;
temp = temp & 0xf0;
if(temp!=0xf0)
{
temp = P1;
switch(temp)
{
case 0xeb:
key = 7;
break;
case 0xdb:
key = 8;
break;
case 0xbb:
key = 9;
break;
}
while(temp!=0xf0)
{
temp = P1;
temp = temp & 0xf0;
}
}
}
P1 = 0xf7;
temp = P1;
temp = temp & 0xf0;
if(temp!=0xf0)
{
delay(10);
temp = P1;
temp = temp & 0xf0;
if(temp!=0xf0)
{
temp = P1;
switch(temp)
{
case 0xe7:
key = 0;
break;
case 0xd7:
key = 0;
break;
case 0xb7:
key = 0;
break;
}
while(temp!=0xf0)
{
temp = P1;
temp = temp & 0xf0;
}
}
}
return key;
}
- 在主程序循环中,首先调用dis_set()函数显示用户设定温度;
for(i=20;i>0;i--)
dis_set(key1, key2);
void dis_set(uchar k1, uchar k2)
{
display2(1, k1);
display2(2, k2);
display2(0, k1);
}
void display2(uchar num, uchar tem_data)
{
if(num==0)
{
S1 = 1;
S2 = 1;
delay(5);
}
if(num==1)
{
S1 = 0;
S2 = 1;
P3 = table[tem_data];
delay(5);
}
else if(num==2)
{
S1 = 1;
S2 = 0;
P3 = table[tem_data];
delay(5);
}
}
然后再从温度传感器获取当前温度,获取当前温度的流程如下图所示,先调用DSreset()函数进行温度传感器的初始化,再调用temwrite()函数,对传感器写入温度转换的指令,进行温度获取和转换,然后调用get_tem()函数对传感器写入读取寄存器指令,从寄存器中读取存储的温度数据,并对该数据进行精度转换处理,最后获得一个保留了1位小数的当前温度数据;
temchange();
void temchange(void)
{
DSreset();
delay(1);
temwrite(0xcc);
temwrite(0x44);
}
uint get_tem(void)
{
uchar l8,h8;
DSreset();
delay(1);
temwrite(0xcc);
temwrite(0xbe);
l8 = temread();
h8 = temread();
tem = h8;
tem = tem<<8;
tem = tem|l8;
f_tem = tem*0.0625;
tem = f_tem*10+0.5;
return (tem);
}
DS18B20温度传感器的基本操作代码如下,各项操作要严格遵守DS18B20温度传感器的时序图,延时时间要足够,可以根据使用的主控芯片适当地修改循环的次数来调整延时。
初始化
uint DSreset(void)
{
uint i;
DS = 0;
i = 73;
while(i>0)
i--;
DS = 1;
i = 0;
while(DS)
{
delay(1);
i++;
if(i>10)
{
return 0;
}
}
DS = 1;
return 1;
}
读1位数据
bit temreadbit(void)
{
uint i;
bit tem_bitdata;
DS = 0;
i++;
DS = 1;
i++;
i++;
tem_bitdata = DS;
i = 10;
while(i>0)
i--;
return(tem_bitdata);
}
读1字节数据
uchar temread(void)
{
uint i;
uchar j,tem_data;
for(i=1;i<=8;i++)
{
j = temreadbit();
tem_data = (j<<7)|(tem_data>>1);
}
return (tem_data);
}
写1字节数据
void temwrite(uchar tem_data)
{
uint i;
uchar j;
bit send_bitdata;
for(j=1;j<=8;j++)
{
send_bitdata = tem_data&0x01;
tem_data = tem_data>>1;
if(send_bitdata)
{
DS = 0;
i++;
i++;
DS = 1;
i = 10;
while(i>0)
i--;
}
else
{
DS = 0;
i = 10;
while(i>0)
i--;
DS = 1;
i++;
i++;
}
}
}
- 获取完当前温度,调用dis_tem()函数显示当前温度;
for(i=20;i>0;i--)
dis_tem(get_tem());
void dis_tem(uint t)
{
uchar i;
i = t/100;
display1(1,i);
i = t%100/10;
display1(2,i+10);
i = t%10;
display1(3,i);
}
void display1(uchar num, uchar tem_data)
{
WE = 1;
P0 = ~((0x01)<<(num));
WE = 0;
DU = 1;
P0 = table[tem_data];
DU = 0;
delay(10);
}
- 将当前温度和用户设定温度传入deal()函数,进行恒温控制,在恒温控制函数deal()中,根据判断当前温度和用户设定温度之间的差值进行不同的处理,如果当前温度小于用户设定温度,就进行升温处理,即红灯闪烁一次,每闪烁一次温度上升0.5°,如果当前温度大于用户设定温度,就进行降温处理,即绿灯闪烁一次,每闪烁一次温度下降0.5°,如果当前温度与用户设定温度想等,则不做处理,只显示温度;
void deal(uint t, uint t_set)
{
uchar i;
if(t<t_set)
{
work(15, 0x20);
}
else if(t>t_set)
{
work(15, 0x40);
}
else
{
i = 15;
while(i--)
{
dis_tem(tem_set);
dis_set(key1, key2);
}
}
}
void work(uint s, uchar led)
{
uchar i;
if(led==0x20)
{
i = s;
led0 = ~(led0);
tem = tem+5;
while(i--)
{
dis_tem(tem);
dis_set(key1, key2);
}
led0 = ~(led0);
i = s;
while(i--)
{
dis_tem(tem);
dis_set(key1, key2);
}
}
else
{
i = s;
led1 = ~(led1);
tem = tem-5;
while(i--)
{
dis_tem(tem);
dis_set(key1, key2);
}
led1 = ~(led1);
i = s;
while(i--)
{
dis_tem(tem);
dis_set(key1, key2);
}
}
}
- 进行一次恒温控制后,系统又回到主程序循环的起始点,不断重复上述3-5步骤,使温度保持在用户设定的温度,达到恒温的效果。
代码下载
完整仿真代码下载:基于51单片机的恒温控制器系统
|