快热式家用电热水器.docx
《快热式家用电热水器.docx》由会员分享,可在线阅读,更多相关《快热式家用电热水器.docx(23页珍藏版)》请在冰豆网上搜索。
![快热式家用电热水器.docx](https://file1.bdocx.com/fileroot1/2023-1/6/e6c2c66f-2a2a-4dfa-9e78-e24a6131cc66/e6c2c66f-2a2a-4dfa-9e78-e24a6131cc661.gif)
快热式家用电热水器
单片机课程设计成绩评定表
课题名称
快热式家用电热水器
设计任务要求
1、能够用液晶显示当前水温,能显示设定功率档位;
2、温度检测显示范围为00~99,精确度为±1;
3、设置3个功率档位指示灯,1~4档一个灯亮,5~8档2个灯亮,9档3个灯全亮。
0档无功率输出,档位灯不亮;
4、设置3个轻触按钮,分别为电源开关,“+”键,“-”键。
加热功率分0~9档,按“+”键依次递增至9档,按“-”键依次减至0档;
5、出水温度超过65度时停止加热,并蜂鸣报警,温度降到45度以下时恢复;
学生自评成绩
功能实现:
自评成绩:
学生互评成绩
互评成绩:
指导教师评定成绩
评定成绩:
1、方案论证:
方案一:
采用2为数码管显示出水温度,并能显示功率档位,用热敏电阻组成电桥来采集信号,再经放大,A/D转换后送单片机。
采用不同功率的电热丝组合得到多种加热功率,本方案采用数码管显示虽然低廉,但需要同时显示温度和功率档位,显示不直观。
测温系统,采用了热敏电阻,A/D转换,实现起来较为麻烦。
且硬件连接较为复杂,精度和效率方面有待提高;
方案二:
采用1602液晶显示出水温度,既方便又直观,采用目前较为先进的集成测温传感器DS18B20,该温度传感器能直接将温度转换成数字信号供单片机直接处理,且硬件连接极为简单,效率和精度相比方案一更高;采用目前较为流行的双向可控硅,通过控制双向可控硅的导通角可实现功率的任意控制,相比多种加热丝,价格更为低廉,功率控制更为灵活。
通过对比我们最终选定方案二。
2、系统硬件电路的设计:
1、系统硬件电路简介:
系统硬件电路由7个模块组成,即:
单片系统及外围电路、电源电路、按键输入电路、液晶显示及指示灯电路、报警电路、功率控制电路和温度检测电路。
本系统所有电路均集成与一块电路板上,既可作为快热式家用电热水器系统使用,又可作为一个单片机最小系统用于其它系统开发;同时支持系统升级!
2、系统框图如下:
3、系统各模块原理图:
(1)单片机及外围电路:
设计之初,经过我们的精心考虑,我们最终决定完善单片机的最小系统,这样该系统一方面可以作为一个家用电热水器系统使用,另一方面,还可以作为一个单片机最小系统所使用,便于二次开发。
(2)电源电路:
左边电路将220v的市电转化为5v的直流电,为整个系统供电,右边电路为过零检测电路,用于检测市电的过零点,为功率控制电路提供触发依据;
(3)按键输入电路:
按键按下后,产生一个低电平,通过判断相应管脚的低电平,可以识别当前是哪个按键被按下。
此处三个按键用于控制加热功率;
(4)液晶显示及指示灯电路:
本液晶显示及指示灯电路,由3个LED灯及1602液晶组成。
其中3个LED灯用于指示当前的加热档位,1602液晶不仅用于显示当前的水温,还可用于显示当前加热档位,显示更为直观;
(5)功率控制及报警电路:
左边蜂鸣器用于超温报警,右边双向可控硅用于控制加热功率,可控硅的导通角可由光电耦合器任意控制,D11用于指示当前加热电路正处于工作状态。
4、整机系统PCB图:
3、系统实物图:
4、系统程序的设计:
(1)快热式热水器必须实现温度检测,温度显示,功率控制3大功能,51单片机实现多任务处理的一个方法就是分时复用,在程序设计时要分配好各任务所占CPU的时间。
分时复用规则:
对于实时性要求较高的任务,应放在最里层的循环中,而对实时性要求不是很高的任务,则可放在外层,以达到最
佳状态。
本系统的温度及功率档位显示、按键扫描、加热控制任务相对实时性较高,而温度检测则对实时性的要求较低,可将其放在循环外层。
(2)程序流程图:
N
5、
性能测试:
测试数据一览表
功率档位
加热丝电压
超调量
0
0
0
1
60
0.7%
2
92
1%
3
115
1.4%
4
133
1.8%
5
147
2.3%
6
162
2.9%
7
185
3.8%
8
211
4.5%
9
223
5.1%
本次测试数据,基本上满足了要求。
4、心得体会:
本次课程设计在我们组员的密切配合下,历时一周完成,当中学习到了不少知识。
硬件电路方面,本次课程设计我们将所有系统集于一体,从原理图的绘制,PCB的布局布线,到电路板的制成,电路的调试,当中遇到了不少问题,通过组员的互相讨论,分析,最终我们成功的解决了这些问题,这既增强了我们的团队合作能力,又增强了我们的实际动手能力;双向可控硅的使用加深了我们对于“弱电控制强电”重要思想的理解。
软件方面,本次软件设计,一是增强了自已模块化编程的能力;二是软件调试能力上了一个台阶;三是进一步理解了实时系统与非实时系统的区别以及在程序中CPU的时间分配问题。
5、分工情况:
(1)硬件电路设计:
刘海龙,许琪
(2)系统软件设计:
吴春风
(3)硬件电路调试:
许琪,吴春风,刘海龙
(4)设计报告书写:
吴春风
六、程序清单:
1)主函数main.c:
#include
#include"lcd1602.h"
#include"ds18b20.h"
#include"jiank.h"
#include"delay.h"
voidmain(void)
{
unsignedintj;
Sys_Init();//系统初始化
lcd1602_init();
ds18b20_init();
show_decp();//辅助显示
EA=1;//开总中断
while
(1)
{
for(j=300;j>0;j--)
{
Key_Scan();
Heater_Control();
}
show_temp();//显示温度值
}
}
2)显示子函数lcd1602.c:
/**********功能:
显示当前水温值,显示辅助字符,超温报警控制***********/
#include
#include"ds18b20.h"
#include"jiank.h"
#include"delay.h"
#defineucharunsignedchar
#defineuintunsignedint
#defineulongunsignedlong
#definelcd1602_command0
#definelcd1602_data1
#definedata_portP0
sbitrs=P1^5;//数据命令选择,0为命令,1为数据
sbitrw=P1^6;//读写选择,0为写,1为读;
sbiten=P1^7;//使能lcd
ucharcodeDS18B20Buffer1[]={"PowerStall:
"};//辅助显示字符1
ucharcodeDS18B20Buffer2[]={"Value:
"};//辅助显示字符2
ucharTempBuffer[8];//温度缓冲区
/**********************LCD1602写函数*****************************/
voidlcd1602_write(bitstyle,ucharinput)
{
EA=0;//读取温度值时,不允许中断
en=0;
rs=style;//选择写入数据还是命令
rw=0;//选择写
data_port=input;
delay_100us(10);//1ms
en=1;
delay_100us(10);//1ms
en=0;//数据传完;
EA=1;//读取温度值时,不允许中断
}
/***************************************************************/
/**********************LCD1602初始化函数************************/
voidlcd1602_init(void)
{
delay_100us(20);
lcd1602_write(lcd1602_command,0x38);
delay_100us(20);
lcd1602_write(lcd1602_command,0x38);
delay_100us(20);
lcd1602_write(lcd1602_command,0x38);
lcd1602_write(lcd1602_command,0x38);//设置8位格式,2行,5x7
lcd1602_write(lcd1602_command,0x0c);//整体显示,关光标,不闪烁
lcd1602_write(lcd1602_command,0x06);//设定输入方式,增量不移位
lcd1602_write(lcd1602_command,0x01);//清除屏幕显示
}
/******************************************************************/
/*********************液晶字符定位函数*****************************/
voidlocation(unsignedcharrow,unsignedcharcolumn)//行:
row,列:
column
{
if(row==0)
lcd1602_write(lcd1602_command,0x80|column);
if(row==1)
lcd1602_write(lcd1602_command,0x80|(column-0x40));
}
/********************************************************************/
/****************将字符输出到液晶显示(写入液晶即可显示)***********/
voidprint(uchar*str)
{
while(*str!
='\0')
{
lcd1602_write(lcd1602_data,*str);
str++;
}
}
/********************************************************************/
/*******************温度数据转换成液晶字符***********************/
/*******************超温报警提醒*************************************/
voidtemp_to_str(void)//温度数据转换成液晶字符显示
{
ulongtt=0;
tt=read_temperature();
if(tt>650000){beep=0;swpst=0;}//超温报警,断开继电器
if(tt<450000){beep=1;swpst=1;}//回温消除警报,接通继电器
TempBuffer[0]=tt/100000+'0';//十位
TempBuffer[1]=tt/10000%10+'0';//个位
TempBuffer[2]=46;//小数点
TempBuffer[3]=tt/1000%10+'0';//小数点后一位
TempBuffer[4]=tt/100%10+'0';//小数点后两位
TempBuffer[5]=0xdf;//温度符号
TempBuffer[6]='C';
TempBuffer[7]='\0';
}
/*******************************************************************/
/*************************辅助显示*********************************/
voidshow_decp(void)
{
location(0,0);
print(DS18B20Buffer1);
location(1,0);
print(DS18B20Buffer2);
}
/********************************************************************/
/**********************液晶字符显示**********************************/
voidshow_temp(void)//液晶显示程序
{
temp_to_str();//温度数据转换成液晶字符
location(1,7);//液晶字符显示位置
print(TempBuffer);//显示温度
}
/*******************************************************************/
3)测温子函数ds18b20.c:
/************功能:
采集当前水温,送至1602液晶显示******************/
#include
#include"jiank.h"
#include"delay.h"
sbitDB=P1^4;//ds18b20数据线(单总线)
/*************DS18B20初始化*******************************/
voidds18b20_init(void)
{
unsignedcharsuccess_flag=0;
EA=0;//读取温度值时,不允许中断
DB=1;
delay_100us(5);
DB=0;
delay_100us(14);
DB=1;
delay_100us
(1);
if(DB&0X01)
{
success_flag=0;
beep=0;
}
else
{
success_flag=1;
DB=1;
}
delay_100us(100);
EA=1;//读取温度值时,不允许中断
}
/*****************************************************************/
*******功能:
向ds18b20写一个字节的数据***************************/
/************(从低位写起)*****************************************/
voidwrite_byte(unsignedchardat)
{
unsignedchari,p;
EA=0;//读取温度值时,不允许中断
for(i=8;i>0;i--)
{
p=dat&0x01;
if(p==0)
{
DB=0;
delay_100us
(1);
DB=1;
}
if(p==0x01)
{
DB=0;
delay_5us();
DB=1;
delay_100us
(2);
}
dat>>=1;
}
EA=1;//读取温度值时,不允许中断
}
/*******************************************************************/
/*********功能:
从ds18b20读取一个字节的数据************************/
unsignedcharread_byte(void)
{
unsignedchari,value;
EA=0;//读取温度值时,不允许中断
for(i=0;i<8;i++)
{
DB=1;
delay_5us();
value>>=1;
DB=0;
delay_5us();
DB=1;
if(DB&0x01)
value|=0x80;
delay_100us
(1);
DB=1;
}
EA=1;//读取温度值时,不允许中断
returnvalue;
}
/******************************************************************/
/*************功能:
将读出的数据转化为温度值************************/
unsignedlongread_temperature(void)
{
unsignedcharaa,bb,cc=0;
unsignedlongsum=0;
floattemp;
unsignedinti;
ds18b20_init();
write_byte(0xCC);
write_byte(0x44);
//delay_50ms(5);
for(i=180;i>0;i--)//提高响应速度
{Key_Scan();Heater_Control();}
ds18b20_init();
//delay_5us();
write_byte(0xCC);
write_byte(0xBE);
aa=read_byte();//提取低字节数据
bb=read_byte();//提取高字节数据
cc=aa;
aa&=0x0f;//屏蔽高4位获取小数部分数据
bb<<=4;
bb+=(cc&0xf0)>>4;//获取整数部分数据
temp=(float)(aa*0.0625+bb);
sum=(long)(temp*10000);
returnsum;
}
4)键盘扫描及温控函数jiank.c:
/********功能:
控制加热功率,控制加热与否,指示当前档位*******/
#include
#include"lcd1602.h"
#include"delay.h"
sbitkey1=P3^5;//按键"+"
sbitkey2=P3^6;//按键"-"
sbitkey3=P3^7;//加热开关按键
sbitbeep=P2^2;//蜂鸣器
sbitled0=P1^0;//功率指示
sbitled1=P1^1;//功率指示
sbitled2=P1^2;//功率指示
sbittrigger=P2^3;//光耦激励信号
sbitswpst=P2^4;//加热开关(继电器)
unsignedcharPower_Flag=2;//功率控制标志
unsignedcharPowerBuffer[2];//功率显示缓冲区
/**************系统初始化***********************/
voidSys_Init(void)
{
swpst=1;
trigger=1;//光耦触发禁止
EX0=1;//外部中断0使能
IT0=1;//下降沿触发
TMOD=0X10;//选择定时器1,并设置其工作方式为1;
}
/***********************************************/
/********************蜂鸣函数******************/
voidBeep(void)
{
beep=0;
delay_50ms
(1);
beep=1;
}
/***********************************************/
/****************键盘扫描函数*****************/
voidKey_Scan(void)
{
//功率“+”
if(key1==0)
{
delay_100us(200);//20ms
if(key1==0)
{
if(Power_Flag>=0&&Power_Flag<9)
{
Power_Flag++;
Beep();
}
while(!
key1);//等待按键释放
}
}
//功率“-”
elseif(key2==0)
{
delay_100us(400);//20ms
if(key2==0)
{
if(Power_Flag<=9&&Power_Flag>0)
{
Power_Flag--;
Beep();
}
while(!
key2);//等待按键释放
}
}
//加热开关
elseif(key3==0)
{
delay_100us(400);//20ms
if(key3==0)
{
Beep();
EX0=0;
ET1=0;
led0=1;
led1=1;
led2=1;
while(!
key3);//等待按键释放
while
(1)
{
if(key3==0)
{
delay_100us(400);//20ms
if(key3==0)
{
Beep();
EX0=1;
ET1=1;
while(!
key3);//等待按键释放
break;
}
}
}
}
}
else;
PowerBuffer[0]=Power_Flag+'0';
PowerBuffer[1]='\0';
location(0,13);
print(PowerBuffer);
}
/******************************************************/
/*******************加热功率控制函数******************/
voidHeater_Control(void)
{
switch(Power_Flag)
{
case0:
{EX0=0;ET1=0;trigger=1;led0=1;led1=1;led2=1;break;}
case1:
case2:
case3:
case4:
{led0=0;led1=1;led2=1;EX0=1;break;}
case5:
case6:
case7:
case8:
{led0=0;led1=0;led2=1;EX0=1;break;}
case9:
{/*EX0=0;ET1=0;trigger=0;*/EX0=1;led0=0