测温 时钟.docx
《测温 时钟.docx》由会员分享,可在线阅读,更多相关《测温 时钟.docx(11页珍藏版)》请在冰豆网上搜索。
测温时钟
#include
#defineucharunsignedchar
#defineuint unsignedint
#defineBUSY 0x80 //lcd忙检测标志
#defineDATAPORTP0 //定义P0口为LCD通讯端?
sbitP1_4=P1^4; //时钟调整
sbitP1_5=P1^5; //时钟加
sbitP1_6=P1^6; //时钟减
sbitDQ=P1^3; //定义ds18b20通信端口
sbitLCM_RS=P2^4; //数据/命令端
sbitLCM_RW=P2^5; //读/写选择端
sbitLCM_EN=P2^6; //LCD使能信号
sbitOUT=P3^7
ucharseconde=0; //定义并初始化时钟变量
ucharminite=0;
ucharhour=12;
ucharmstcnt=0;
uinttemp1,temp2,temp; //温度显示变量
uchart,set;
ucharK;
bitON_OFF=0;
bitoutflag;
ucharcodestr0[]={"--- :
:
--- "};
ucharcodestr1[]={"SET:
CSA:
.C"};
voiddelay_LCM(uint); //LCD延时子程序
voidinitLCM(void); //LCD初始化子程序
voidlcd_wait(void); //LCD检测忙子程序
voidWriteCommandLCM(ucharWCLCM,ucharBusyC); //写指令到ICM子函数
voidWriteDataLCM(ucharWDLCM); //写数据到LCM子函数
voidDisplayOneChar(ucharX,ucharY,ucharDData); //显示指定坐标的一个字符子函数
voidDisplayListChar(ucharX,ucharY,ucharcode*DData); //显示指定坐标的一串字符子函数
voidinit_timer0(void); //定时器初始化
voiddisplayfun1(void);
voiddisplayfun2(void);
voiddisplayfun3(void);
voiddisplayfun4(void);
voidkeyscan(void); //键盘扫描子程序
voidset_adj(void);
voidinc_key(void);
voiddec_key(void);
voiddelay_18B20(unsignedinti);
voidInit_DS18B20(void);
ucharReadOneChar(void);
voidWriteOneChar(unsignedchardat);
voidReadTemperature(void);
voidad0809(void);
voidplayalarm(void);
/*********延时K*1ms,12.000mhz**********/
voiddelay_LCM(uintk)
{
uinti,j;
for(i=0;i { for(j=0;j<200;j++) {;} }} /**********写指令到ICM子函数************/voidWriteCommandLCM(ucharWCLCM,ucharBusyC){ if(BusyC)lcd_wait(); DATAPORT=WCLCM; LCM_RS=0; //选中指令寄存器 LCM_RW=0; //写模式 LCM_EN=1; _nop_(); _nop_(); _nop_(); LCM_EN=0; }/**********写数据到LCM子函数************/voidWriteDataLCM(ucharWDLCM){ lcd_wait(); //检测忙信号 DATAPORT=WDLCM; LCM_RS=1; //选中数据寄存器 LCM_RW=0; //写模式 LCM_EN=1; _nop_(); _nop_(); _nop_(); LCM_EN=0;}/***********lcm内部等待函数*************/voidlcd_wait(void){ DATAPORT=0xff; LCM_EN=1; LCM_RS=0; LCM_RW=1; _nop_(); while(DATAPORT&BUSY) { LCM_EN=0; _nop_(); _nop_(); LCM_EN=1; _nop_(); _nop_(); } LCM_EN=0; }/**********LCM初始化子函数***********/voidinitLCM(){ DATAPORT=0; delay_LCM(15); WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号 delay_LCM(5); WriteCommandLCM(0x38,0); delay_LCM(5); WriteCommandLCM(0x38,0); delay_LCM(5); WriteCommandLCM(0x38,1); //8bit数据传送,2行显示,5*7字型,检测忙信号 WriteCommandLCM(0x08,1); //关闭显示,检测忙信号 WriteCommandLCM(0x01,1); //清屏,检测忙信号 WriteCommandLCM(0x06,1); //显示光标右移设置,检测忙信号 WriteCommandLCM(0x0c,1); //显示屏打开,光标不显示,不闪烁,检测忙信号}/****************显示指定坐标的一个字符子函数*************/voidDisplayOneChar(ucharX,ucharY,ucharDData){ Y&=1; X&=15; if(Y)X|=0x40; //若y为1(显示第二行),地址码+0X40 X|=0x80; //指令码为地址码+0X80 WriteCommandLCM(X,0); WriteDataLCM(DData); delay_LCM(10);}/***********显示指定坐标的一串字符子函数***********/voidDisplayListChar(ucharX,ucharY,ucharcode*DData){ ucharListLength=0; Y&=0x01; X&=0x0f; while(X<16) { DisplayOneChar(X,Y,DData[ListLength]); ListLength++; X++; }}/***********ds18b20延迟子函数(晶振12MHz)*******/voiddelay_18B20(unsignedinti){ while(i--){ _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); }}/**********ds18b20初始化函数**********************/voidInit_DS18B20(void){ unsignedcharx=0; DQ=1; //DQ复位 delay_18B20(8); //稍做延时 DQ=0; //单片机将DQ拉低 delay_18B20(80);//精确延时大于480us DQ=1; //拉高总线 delay_18B20(14); x=DQ; //稍做延时后如果x=0则初始化成功x=1则初始化失败 delay_18B20(20);}/***********ds18b20读一个字节**************/ unsignedcharReadOneChar(void){ uchari=0; uchardat=0; for(i=8;i>0;i--) { DQ=0;//给脉冲信号 dat>>=1; DQ=1;//给脉冲信号 if(DQ) dat|=0x80; delay_18B20(4); } return(dat);}/*************ds18b20写一个字节****************/ voidWriteOneChar(uchardat){ unsignedchari=0; for(i=8;i>0;i--) { DQ=0; DQ=dat&0x01; delay_18B20(5); DQ=1; dat>>=1; }}/**************读取ds18b20当前温度************/voidReadTemperature(void){ unsignedchara=0; unsignedcharb=0; unsignedchart=0; Init_DS18B20(); WriteOneChar(0xCC); //跳过读序号列号的操作 WriteOneChar(0x44); //启动温度转换 delay_18B20(100); //thismessageisweryimportant Init_DS18B20(); WriteOneChar(0xCC); //跳过读序号列号的操作 WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器)前两个就是温度 delay_18B20(100); a=ReadOneChar(); //读取温度值低位 b=ReadOneChar(); //读取温度值高位 temp1=b<<4; temp1+=(a&0xf0)>>4; temp2=a&0x0f; temp=((b*256+a)>>4); //当前采集温度值除16得实际温度值}/***************液晶显示子函数1正常显示*****************/voiddisplayfun1(void){ WriteCommandLCM(0x0c,1); //显示屏打开,光标不显示,不闪烁,检测忙信号 DisplayListChar(0,0,str0); DisplayListChar(0,1,str1); DisplayOneChar(3,0,hour/10+0x30); //液晶上显示小时 DisplayOneChar(4,0,hour%10+0x30); DisplayOneChar(6,0,minite/10+0x30); //液晶上显示分 DisplayOneChar(7,0,minite%10+0x30); DisplayOneChar(9,0,seconde/10+0x30); //液晶上显示秒 DisplayOneChar(10,0,seconde%10+0x30); DisplayOneChar(4,1,K/10+0x30); //液晶上显示设定的温度 DisplayOneChar(5,1,K%10+0x30); DisplayOneChar(11,1,temp1/10+0x30); //液晶上显示测得的温度 DisplayOneChar(12,1,temp1%10+0x30); DisplayOneChar(14,1,temp2%10+0x30); if(ON_OFF==0) //若温控标志为0 { DisplayOneChar(14,0,0x4f); //液晶上显示不控温的标志 DisplayOneChar(15,0,0x46); } else { DisplayOneChar(14,0,0x4f); //液晶上显示控温的标志 DisplayOneChar(15,0,0x4e); if(outflag==1) DisplayOneChar(0,0,0x7c); else DisplayOneChar(0,0,0xef); } }/**************键盘扫描子函数******************/voidkeyscan(void){ ucharxx; //局部变量 P1=0xff; if(P1!=0xff) { delay_LCM(50); if(P1!=0xff) { xx=P1; switch(xx) //根据按键状态,调用不同的子函数 { case0xfe:set_adj(); break; case0xfd:inc_key(); break; case0xfb:dec_key(); break; case0xf7:ON_OFF=!ON_OFF; break; default:break; } } } }/**************设定工作模式子函数****************/voidset_adj(void){ delay_LCM(100); set++; if(set>=4)set=0; }/****************按键加法子函数******************/voidinc_key(void){ delay_LCM(100); switch(set) { case0:if(P1==0xf7)ON_OFF=!ON_OFF; break; case1:hour++; if(hour>=23)hour=23; break; case2:minite++;if(minite>=59)minite=59;break; case3:K++;if(K>=99)K=99; break; default:break; } }/****************按键减法子函数*****************/voiddec_key(void){ delay_LCM(100); switch(set) { case0:if(P1==0xf7)ON_OFF=!ON_OFF; break; case1:hour--; if(hour<=0)hour=0; break; case2:minite--;if(minite<=0)minite=0;break; case3:K--;if(K<=1)K=1; break; default:break; } }/***************定时器t0初始化*******************/voidinit_timer0(void){ TMOD=0x01; //time0为定时器,方式1 TH0=0x3c; //预置计数初值 TL0=0xb0; EA=1; ET0=1; TR0=1; }/***********定时器t0中断子函数**************/voidtimer0(void)interrupt1using0 //定时器0方式1,50ms中断一次{ TH0=0x3c; TL0=0xb0; mstcnt++; if(mstcnt>=20) {seconde++;mstcnt=0;} if(seconde>=60) {minite++; seconde=0;} if(minite>=60) {hour++; minite=0;} if(hour>=24 ) {hour=0;} }/***********themainfuntion*************/ voidmain(void){ P1=0xff; //初始化p1口,全设为1 delay_LCM(500); //延时500ms启动 initLCM(); //LCD初始化 init_timer0(); //时钟定时器0初始化 Init_DS18B20(); //DS18B20初始化 DisplayListChar(0,0,str0); DisplayListChar(0,1,str1); while(1) { keyscan(); //按键扫描 ReadTemperature(); //温度采集 switch(set) //LCD根据工作模式显示 { case0:if(mstcnt>=18)displayfun1();break; //正常工作显示 //case1:displayfun2();delay_LCM(1000);break;
for(j=0;j<200;j++)
{;}
}
/**********写指令到ICM子函数************/
voidWriteCommandLCM(ucharWCLCM,ucharBusyC)
if(BusyC)lcd_wait();
DATAPORT=WCLCM;
LCM_RS=0; //选中指令寄存器
LCM_RW=0; //写模式
LCM_EN=1;
_nop_();
LCM_EN=0;
/**********写数据到LCM子函数************/
voidWriteDataLCM(ucharWDLCM)
lcd_wait(); //检测忙信号
DATAPORT=WDLCM;
LCM_RS=1; //选中数据寄存器
/***********lcm内部等待函数*************/
voidlcd_wait(void)
DATAPORT=0xff;
LCM_RS=0;
LCM_RW=1;
while(DATAPORT&BUSY)
{ LCM_EN=0;
/**********LCM初始化子函数***********/
voidinitLCM()
DATAPORT=0;
delay_LCM(15);
WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
delay_LCM(5);
WriteCommandLCM(0x38,0);
WriteCommandLCM(0x38,1); //8bit数据传送,2行显示,5*7字型,检测忙信号
WriteCommandLCM(0x08,1); //关闭显示,检测忙信号
WriteCommandLCM(0x01,1); //清屏,检测忙信号
WriteCommandLCM(0x06,1); //显示光标右移设置,检测忙信号
WriteCommandLCM(0x0c,1); //显示屏打开,光标不显示,不闪烁,检测忙信号
/****************显示指定坐标的一个字符子函数*************/
voidDisplayOneChar(ucharX,ucharY,ucharDData)
Y&=1;
X&=15;
if(Y)X|=0x40; //若y为1(显示第二行),地址码+0X40
X|=0x80; //指令码为地址码+0X80
WriteCommandLCM(X,0);
WriteDataLCM(DData);
delay_LCM(10);
/***********显示指定坐标的一串字符子函数***********/
voidDisplayListChar(ucharX,ucharY,ucharcode*DData)
ucharListLength=0;
Y&=0x01;
X&=0x0f;
while(X<16)
DisplayOneChar(X,Y,DData[ListLength]);
ListLength++;
X++;
/***********ds18b20延迟子函数(晶振12MHz)*******/
voiddelay_18B20(unsignedinti)
while(i--){
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
/**********ds18b20初始化函数**********************/
voidInit_DS18B20(void)
unsignedcharx=0;
DQ=1; //DQ复位
delay_18B20(8); //稍做延时
DQ=0; //单片机将DQ拉低
delay_18B20(80);//精确延时大于480us
DQ=1; //拉高总线
delay_18B20(14);
x=DQ; //稍做延时后如果x=0则初始化成功x=1则初始化失败
delay_18B20(20);
/***********ds18b20读一个字节**************/
unsignedcharReadOneChar(void)
uchari=0;
uchardat=0;
for(i=8;i>0;i--)
DQ=0;//给脉冲信号
dat>>=1;
DQ=1;//给脉冲信号
if(DQ)
dat|=0x80;
delay_18B20(4);
return(dat);
/*************ds18b20写一个字节****************/
voidWriteOneChar(uchardat)
unsignedchari=0;
DQ=0;
DQ=dat&0x01;
delay_18B20(5);
DQ=1;
/**************读取ds18b20当前温度************/
voidReadTemperature(void)
unsignedchara=0;
unsignedcharb=0;
unsignedchart=0;
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0x44); //启动温度转换
delay_18B20(100); //thismessageisweryimportant
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器)前两个就是温度
delay_18B20(100);
a=ReadOneChar(); //读取温度值低位
b=ReadOneChar(); //读取温度值高位
temp1=b<<4;
temp1+=(a&0xf0)>>4;
temp2=a&0x0f;
temp=((b*256+a)>>4); //当前采集温度值除16得实际温度值
/***************液晶显示子函数1正常显示*****************/
voiddisplayfun1(void)
DisplayListChar(0,0,str0);
DisplayListChar(0,1,str1);
DisplayOneChar(3,0,hour/10+0x30); //液晶上显示小时
DisplayOneChar(4,0,hour%10+0x30);
DisplayOneChar(6,0,minite/10+0x30); //液晶上显示分
DisplayOneChar(7,0,minite%10+0x30);
DisplayOneChar(9,0,seconde/10+0x30); //液晶上显示秒
DisplayOneChar(10,0,seconde%10+0x30);
DisplayOneChar(4,1,K/10+0x30); //液晶上显示设定的温度
DisplayOneChar(5,1,K%10+0x30);
DisplayOneChar(11,1,temp1/10+0x30); //液晶上显示测得的温度
DisplayOneChar(12,1,temp1%10+0x30);
DisplayOneChar(14,1,temp2%10+0x30);
if(ON_OFF==0) //若温控标志为0
DisplayOneChar(14,0,0x4f); //液晶上显示不控温的标志
DisplayOneChar(15,0,0x46);
else
DisplayOneChar(14,0,0x4f); //液晶上显示控温的标志
DisplayOneChar(15,0,0x4e);
if(outflag==1)
DisplayOneChar(0,0,0x7c);
DisplayOneChar(0,0,0xef);
/**************键盘扫描子函数******************/
voidkeyscan(void)
ucharxx; //局部变量
P1=0xff;
if(P1!
=0xff)
delay_LCM(50);
xx=P1;
switch(xx) //根据按键状态,调用不同的子函数
case0xfe:
set_adj(); break;
case0xfd:
inc_key(); break;
case0xfb:
dec_key(); break;
case0xf7:
ON_OFF=!
ON_OFF; break;
default:
break;
/**************设定工作模式子函数****************/
voidset_adj(void)
delay_LCM(100);
set++;
if(set>=4)set=0;
/****************按键加法子函数******************/
voidinc_key(void)
switch(set)
case0:
if(P1==0xf7)ON_OFF=!
case1:
hour++; if(hour>=23)hour=23; break;
case2:
minite++;if(minite>=59)minite=59;break;
case3:
K++;if(K>=99)K=99; break;
/****************按键减法子函数*****************/
voiddec_key(void)
hour--; if(hour<=0)hour=0; break;
minite--;if(minite<=0)minite=0;break;
K--;if(K<=1)K=1; break;
/***************定时器t0初始化*******************/
voidinit_timer0(void)
TMOD=0x01; //time0为定时器,方式1
TH0=0x3c; //预置计数初值
TL0=0xb0;
EA=1;
ET0=1;
TR0=1;
/***********定时器t0中断子函数**************/
voidtimer0(void)interrupt1using0 //定时器0方式1,50ms中断一次
TH0=0x3c;
mstcnt++;
if(mstcnt>=20) {seconde++;mstcnt=0;}
if(seconde>=60) {minite++; seconde=0;}
if(minite>=60) {hour++; minite=0;}
if(hour>=24 ) {hour=0;}
/***********themainfuntion*************/
voidmain(void)
P1=0xff; //初始化p1口,全设为1
delay_LCM(500); //延时500ms启动
initLCM(); //LCD初始化
init_timer0(); //时钟定时器0初始化
Init_DS18B20(); //DS18B20初始化
while
(1)
keyscan(); //按键扫描
ReadTemperature(); //温度采集
switch(set) //LCD根据工作模式显示
if(mstcnt>=18)displayfun1();break; //正常工作显示
//case1:
displayfun2();delay_LCM(1000);break;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1