基于51单片机的温度控制器.docx
《基于51单片机的温度控制器.docx》由会员分享,可在线阅读,更多相关《基于51单片机的温度控制器.docx(20页珍藏版)》请在冰豆网上搜索。
基于51单片机的温度控制器
温度控制器
本设计要求温度控制器实现以下基本功能:
(1).数码管准确显示温度值,测量精度为
0.5
;
(2).五个按键操作(设置温度,加键、复位);
(3).可以温度设置,超过设定温度,继电器吸合(且蜂鸣器发出报警声)。
Proteus仿真图
程序清单
仅供学习参考
Main.c
/*==========================================================
说明:
基于DS18b20的温度控制报警程序
作者:
kks
创建时间:
2013-03-18
修改时间:
============================================================*/
#include"config.h"
#include"type.h"
#include"DS18B20.h"
/*===================全局定义===============================*/
staticuint8uKeyValue=0;//键值
staticuint16unTemp=0;//读取的温度值
staticuint8uCnt=0;//定时器计数值
bitb2msflag=0;//2ms时间标志位
bitb2mskeyflag=0;//2ms标志,用于按键扫描
bitb50msflag=0;
uint8uKeyCnt=0;//按键延时计数
uint8codeSegTable[]={0XC0,0XF9,0XA4,0XB0,0X99,
0X92,0X82,0XF8,0X80,0X90,/*不带小数点的断码表*/
0x40,0x79,0x24,0x30,0x19,
0x12,0x02,0x78,0x00,0x10,/*带小数点的断码表*/
0xbf,0xff,0x86,0x88};//-,不显示,E,R
uint8codeBitTable[]={0xfe,0xfd,0xfb,0xf7};//位码
uint8DisBuff[]={0,0,0,0};//显示缓存区
/*************************************************************
*函数名:
Delay250us
*输入:
无
*输出:
*功能:
蜂鸣器延时函数
**************************************************************/
voidDelay250us(void)
{
uint8j;
for(j=28;j>0;j--)//250us基准延时程序
;
}
*函数名:
Init
程序初始化
voidInit(void)
P0=P1=P2=P3=0XFF;//IO口初始化
TMOD=0x01;//定时器0方式1
TH0=0xf8;//定时2ms
TL0=0x30;
ET0=1;
EX0=1;
EA=1;
TR0=1;
KeyHandle
tem
返回温度上下限设置值,上限最大值为90,下限为0
按键处理程序
uint8KeyHandle(uint8tem)
if(KEYUP==0)
uKeyCnt++;
if(uKeyCnt>=2)//消抖
uKeyCnt=0;
tem++;
if(tem>99)
tem=0;
while(!
KEYUP);
if(KEYDOWN==0)
if(uKeyCnt>=2)
tem--;
if(tem==-1)
tem=99;
KEYDOWN);
if(KEYWRITE==0)
CopyToEEPROM();//将上下限拷贝到E2PROM
KEYWRITE);
returntem;
Buzz
蜂鸣器报警函数
voidBuzz(void)
uint8i;
for(i=10;i>0;i--)
BEEP=0;
Delay250us();
BEEP=1;
TemAlarm
温度报警检测
voidTemAlarm(void)
if((unTemp>uTHigh*10)||(unTemp{RELAY=0;//继电器动作Buzz();//蜂鸣器报警}else{RELAY=1;//继电器复位BEEP=1;//关闭蜂鸣器}}/**************************************************************函数名:DispTem*输入:无*输出:无*功能:温度数码管显示**************************************************************/voidDisTem(void){uint8i,j;for(i=30;i>0;i--){for(j=0;j<4;){P0=SegTable[DisBuff[j]];P2=BitTable[j];if(b2msflag){b2msflag=0;P2=0xff;j++;}}}}/**************************************************************函数名:CopyToDisBuff*输入:tem*输出:无*功能:将温度数据写入显示缓存区**************************************************************/voidCopyToDisBuff(uint16tem){DisBuff[0]=sign;DisBuff[1]=tem/100;DisBuff[2]=tem%100/10+10;DisBuff[3]=tem%10;}/**************************************************************函数名:Error*输入:无*输出:无*功能:若无DS18b20或其故障,显示ERR**************************************************************/voidError(void){DisBuff[0]=21;//不显示DisBuff[1]=22;//EDisBuff[2]=23;//RDisBuff[3]=23;//R}/**************************************************************函数名:SoftReset*输入:无*输出:无*功能:单片机软件复位**************************************************************/voidSoftReset(void){((void(code*)(void))0x0000)();//函数指针reset指向地址0}/**************************************************************函数名:main*输入:无*输出:无*功能:主函数,程序入口**************************************************************/voidmain(void){Init();if(Reset18b20()){GetFromEEPROM();//读取温度上下限值unTemp=ReadTem();//读取温度uTHigh=uTemHigh;//将上下限值复制到临时存储区uTLow=uTemLow;}else{Error();while(Reset18b20()==0){DisTem();}SoftReset();//软件复位}while(1){DisTem();//调用显示switch(uKeyValue){case0:if(b50msflag){b50msflag=0;unTemp=ReadTem();//读取温度CopyToDisBuff(unTemp);//更新显示缓存区TemAlarm();//温度报警检测}break;case1:if(b2mskeyflag){b2mskeyflag=0;uTHigh=KeyHandle(uTHigh);//设置温度上限CopyToDisBuff(uTHigh*10);//更新显示缓存区}break;case2:if(b2mskeyflag){b2mskeyflag=0;uTLow=KeyHandle(uTLow);//设置温度下限CopyToDisBuff(uTLow*10);//更新显示缓存区}break;default:uKeyValue=0;break;}}}/**************************************************************函数名:Timer0ISR*输入:无*输出:无*功能:T0中断服务函数**************************************************************/voidTimer0ISR(void)interrupt1using1{TH0=0xf8;//重赋初值TL0=0x30;b2msflag=1;//2ms时间标志b2mskeyflag=1;uCnt++;if(uCnt>=25){uCnt=0;b50msflag=1;}}/**************************************************************函数名:INT0ISR*输入:无*输出:无*功能:INT0中断服务函数**************************************************************/voidINT0ISR(void)interrupt0using0{uKeyValue++;if(uKeyValue>=3){uKeyValue=0;}}Config.H/*==========================================================说明:硬件配置信息作者:kks创建时间:2012-09-03修改时间:2013-03-18============================================================*/#ifndef_CONFIG_H_#define_CONFIG_H_#include/*******独立按键********/sbitKEYUP=P1^4;//加sbitKEYDOWN=P1^5;//减sbitKEYWRITE=P1^6;//写入/*******蜂鸣器********/sbitBEEP=P3^6;/*******继电器********/sbitRELAY=P3^7;/*******DS18B20信号线********/sbitQS=P3^3;#endifType.h/*==========================================================说明:数据类型定义作者:kks创建时间:2012-09-03修改时间:2013-03-18============================================================*/#ifndef__TYPE_H__#define__TYPE_H__/*================================================整型数据类型================================================*/typedefunsignedcharuint8;typedefunsignedintuint16;typedefunsignedlonguint32;typedefcharint8;typedefintint16;typedeflongint32;typedefunsignedcharWPARAM;typedefunsignedcharLPARAM;/*================================================枚举数据类型================================================*/typedefenum{FALSE,TRUE}BOOL;#endifDS18b20.h#ifndef_DS18B20_H_#define_DS18B20_H_#ifndef_DS18B20_C_#define_EXTERN#endif/*===================全局定义===============================*//*===================全局变量===============================*/#ifdef_EXTERNexternuint8uTemHigh;//温度上限externuint8uTemLow;//温度下限externuint8uTHigh;externuint8uTLow;externuint8sign;//符号位#undef_EXTERN#endif/*===================全局函数===============================*/bitReset18b20(void);uint8Rbyte18b20(void);voidWbyte18b20(uint8dat);uint16ReadTem(void);voidCopyToEEPROM(void);voidGetFromEEPROM(void);#endifDS18B20.c/*==========================================================说明:DS18B20驱动程序作者:kks创建时间:2012-03-19优化时间:2013-03-20============================================================*/#define_DS18B20_C_#include#include"config.h"#include"type.h"#include"DS18B20.h"uint8uTemHigh=0;//温度上限uint8uTemLow=0;//温度下限uint8uTHigh=0;//温度上限临时存储uint8uTLow=0;//温度下限临时存储uint8sign=0xff;//用来判断暂存器的高5位是否为负floatf_temp=0;//定义浮点型的温度数据/**************************************************************函数名:Delay15us*输入:uint16t*输出:无*功能:单位为15us延时函数,延时时间=15(1+t)us**************************************************************/voidDelay15us(uint16t){uint16i;for(i=t;i>0;i--){_nop_();_nop_();_nop_();_nop_();}_nop_();_nop_();}/**************************************************************函数名:Reset18b20*输入:无*输出:1-复位成功,0-复位失败*功能:复位DS18b20,检测DS18b20工作是否正常**************************************************************/bitReset18b20(void){bitrest=1;QS=1;//QS复位Delay15us(1);//延时30usQS=0;//拉低总线Delay15us(32);//延时495usQS=1;//释放总线Delay15us(4);//延时15-60us,rest=QS;//记录DS返回的状态Delay15us(15);//延时240us后,释放总线QS=1;return(~rest);//返回复位结果}/**************************************************************函数名:Wbyte18b20*输入:dat-待写字节数据*输出:无*功能:DS18b20写一字节数据**************************************************************/voidWbyte18b20(uint8dat){uint8i;for(i=8;i>0;i--){QS=0;//拉低总线,产生写时序_nop_();_nop_();//至少延时1usQS=dat&0x01;//从最低位写起Delay15us(3);//延时60usQS=1;//释放总线dat>>=1;//数据右移一位,准备写下一位}}/**************************************************************函数名:Rbyte18b20*输入:无*输出:dat-读出数据*功能:DS18b20读一字节数据**************************************************************/uint8Rbyte18b20(void){uint8i,dat=0;for(i=8;i>0;i--){dat>>=1;QS=0;//产生读时序_nop_();_nop_();//至少延时1usQS=1;//释放总线_nop_();_nop_();_nop_();_nop_();//延时4us后读数据if(QS)dat|=0x80;Delay15us(3);//延时60us}returndat;}/******************************
RELAY=0;//继电器动作
Buzz();//蜂鸣器报警
else
RELAY=1;//继电器复位
BEEP=1;//关闭蜂鸣器
DispTem
温度数码管显示
voidDisTem(void)
uint8i,j;
for(i=30;i>0;i--)
for(j=0;j<4;)
P0=SegTable[DisBuff[j]];
P2=BitTable[j];
if(b2msflag)
b2msflag=0;
P2=0xff;
j++;
CopyToDisBuff
将温度数据写入显示缓存区
voidCopyToDisBuff(uint16tem)
DisBuff[0]=sign;
DisBuff[1]=tem/100;
DisBuff[2]=tem%100/10+10;
DisBuff[3]=tem%10;
Error
若无DS18b20或其故障,显示ERR
voidError(void)
DisBuff[0]=21;//不显示
DisBuff[1]=22;//E
DisBuff[2]=23;//R
DisBuff[3]=23;//R
SoftReset
单片机软件复位
voidSoftReset(void)
((void(code*)(void))0x0000)();//函数指针reset指向地址0
main
主函数,程序入口
voidmain(void)
Init();
if(Reset18b20())
GetFromEEPROM();//读取温度上下限值
unTemp=ReadTem();//读取温度
uTHigh=uTemHigh;//将上下限值复制到临时存储区
uTLow=uTemLow;
Error();
while(Reset18b20()==0)
DisTem();
SoftReset();//软件复位
while
(1)
DisTem();//调用显示
switch(uKeyValue)
case0:
if(b50msflag)
b50msflag=0;
CopyToDisBuff(unTemp);//更新显示缓存区
TemAlarm();//温度报警检测
break;
case1:
if(b2mskeyflag)
b2mskeyflag=0;
uTHigh=KeyHandle(uTHigh);//设置温度上限
CopyToDisBuff(uTHigh*10);//更新显示缓存区
case2:
uTLow=KeyHandle(uTLow);//设置温度下限
CopyToDisBuff(uTLow*10);//更新显示缓存区
default:
uKeyValue=0;
Timer0ISR
T0中断服务函数
voidTimer0ISR(void)interrupt1using1
TH0=0xf8;//重赋初值
b2msflag=1;//2ms时间标志
b2mskeyflag=1;
uCnt++;
if(uCnt>=25)
uCnt=0;
b50msflag=1;
INT0ISR
INT0中断服务函数
voidINT0ISR(void)interrupt0using0
uKeyValue++;
if(uKeyValue>=3)
Config.H
硬件配置信息
2012-09-03
#ifndef_CONFIG_H_
#define_CONFIG_H_
#include
/*******独立按键********/
sbitKEYUP=P1^4;//加
sbitKEYDOWN=P1^5;//减
sbitKEYWRITE=P1^6;//写入
/*******蜂鸣器********/
sbitBEEP=P3^6;
/*******继电器********/
sbitRELAY=P3^7;
/*******DS18B20信号线********/
sbitQS=P3^3;
#endif
Type.h
数据类型定义
#ifndef__TYPE_H__
#define__TYPE_H__
/*
================================================
整型数据类型
*/
typedefunsignedcharuint8;
typedefunsignedintuint16;
typedefunsignedlonguint32;
typedefcharint8;
typedefintint16;
typedeflongint32;
typedefunsignedcharWPARAM;
typedefunsignedcharLPARAM;
枚举数据类型
typedefenum
FALSE,TRUE
}BOOL;
DS18b20.h
#ifndef_DS18B20_H_
#define_DS18B20_H_
#ifndef_DS18B20_C_
#define_EXTERN
/*===================全局变量===============================*/
#ifdef_EXTERN
externuint8uTemHigh;//温度上限
externuint8uTemLow;//温度下限
externuint8uTHigh;
externuint8uTLow;
externuint8sign;//符号位
#undef_EXTERN
/*===================全局函数===============================*/
bitReset18b20(void);
uint8Rbyte18b20(void);
voidWbyte18b20(uint8dat);
uint16ReadTem(void);
voidCopyToEEPROM(void);
voidGetFromEEPROM(void);
DS18B20.c
DS18B20驱动程序
2012-03-19
优化时间:
2013-03-20
#define_DS18B20_C_
uint8uTemHigh=0;//温度上限
uint8uTemLow=0;//温度下限
uint8uTHigh=0;//温度上限临时存储
uint8uTLow=0;//温度下限临时存储
uint8sign=0xff;//用来判断暂存器的高5位是否为负
floatf_temp=0;//定义浮点型的温度数据
Delay15us
uint16t
单位为15us延时函数,延时时间=15(1+t)us
voidDelay15us(uint16t)
uint16i;
for(i=t;i>0;i--)
_nop_();_nop_();_nop_();_nop_();
_nop_();_nop_();
Reset18b20
1-复位成功,0-复位失败
复位DS18b20,检测DS18b20工作是否正常
bitReset18b20(void)
bitrest=1;
QS=1;//QS复位
(1);//延时30us
QS=0;//拉低总线
Delay15us(32);//延时495us
QS=1;//释放总线
Delay15us(4);//延时15-60us,
rest=QS;//记录DS返回的状态
Delay15us(15);//延时240us后,释放总线
QS=1;
return(~rest);//返回复位结果
Wbyte18b20
dat-待写字节数据
DS18b20写一字节数据
voidWbyte18b20(uint8dat)
for(i=8;i>0;i--)
QS=0;//拉低总线,产生写时序
_nop_();_nop_();//至少延时1us
QS=dat&0x01;//从最低位写起
Delay15us(3);//延时60us
dat>>=1;//数据右移一位,准备写下一位
Rbyte18b20
dat-读出数据
DS18b20读一字节数据
uint8Rbyte18b20(void)
uint8i,dat=0;
dat>>=1;
QS=0;//产生读时序
_nop_();_nop_();//延时4us后读数据
if(QS)
dat|=0x80;
returndat;
/******************************
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1