带温度测量LCD显示的红外遥控数字钟
扫描二维码
随时随地手机看文章
主要功能为:DS1302,DS18B20,液晶1602驱动
万能电视遥控器(000)的解码。
用遥控器控制DS1302的各种功能
DS18B20的精度为0.06摄氏度
DS1302有蜂鸣器定时报警,继电器控制高电家器,蜂鸣器整点报时
接口:蜂鸣器P2.2
继电器 K1:P2.1 K2:P2.0
每秒闪灯 P3.1
红外接收头 P3.2外部中断零T0
按键:KEY1:P3.3(调整时间及切换)P3.4(调蜂鸣器定时) P3.5(调继电器定时)
DS18B20:数据传送DQ P3.7
DS1302 :CEP2.7 CK=P2.5 IO=P2.6
液晶1602:RS P1.0 RW P1.1 EN P1.2 数据传输接口 P0
注:程序中青色显示部分为可扩展部分
/**************************************************************************************/
//所用到的文件库
#include
#include "1602LCDDriver.h"
#include "DS18B20Driver.h"
#include "DS1302Driver.h"
#include
//1302的数据表示结构体
struct TimerStruct
{
unsigned char Year;
unsigned char Month;
unsigned char Day;
unsigned char Week;
unsigned char Hour;
unsigned char Minute;
unsigned char Second;
};
struct TimerStruct RealClock;
//标志常量定义
const unsigned char DATECODE1[]={"TS"};
const unsigned char DATECODE2[]={"DF"};
const unsigned char DATECODE3[]={"DJ"};
//重要常数定义
#define distinguish_y 0x80 //引导码
#define distinguish_a 0x7e //地址码
//各个接口定义
sbit key1=P3^3;
sbit key2=P3^4;
sbit key3=P3^5;
sbit sound=P2^2;
sbit k1=P2^1;
sbit k2=P2^0;
sbit led=P3^1;
//有关液晶显示的变量
unsigned char idata mins,hours,days,months,weeks,years; //超128个变量扩展变量空间
unsignedchar a,k,endf_flag;
bit keychange_flag,biaof_flag,biaoj_flag,fmq_flag,key_flag;
unsigned char idata Minute1,Hour1,Day1,Month1,Week1,Year1;//超128个变量扩展变量空间
unsigned char idata Minute2,Hour2,Day2,Month2,Week2,Year2;//超128个变量扩展变量空间
unsigned char DATECODE22[1]={' '};
unsigned char DATECODE33[1]={' '};
//红外参量
bit receiv_en,bootable,rled_flag,end_flag,change_flag,led_flag,bell_flag,click,data_flag;
unsigned char receiv_data[4];
unsigned char receiv_times,led_count,led_a,bell_time,Irq_times;
//液晶显示数据
unsigned char DateBuffer1[]={"2006/08/18/5"};
unsigned char TimeBuffer1[]= {"23:50:00"};
//1302内部数据
unsigned char DateBuffer[]={"2005/01/01/5"};
unsigned char TimeBuffer[]= {"00:00:00"};
unsigned char LCDDisplayBuffer[]={" "};
//函数声明
void tiaoshi(struct TimerStruct *Real);
void dingshif(void);
void dingshij(void);
void tiao_delay(void);
void quxiaofmq(void);
void quxiaojdq(void);
void show_quxiaofmq(void);
//有关延时的中断
void times1() interrupt 3 using 2
{
TH1=0X3C;
TL1=0XA8;
if(bell_flag&&bell_time<2) //蜂鸣器提示
{
sound=0;
bell_time++;
}
else
{
sound=1;
bell_time=0;
bell_flag=0;
}
if(++Irq_times==10) //没秒闪灯指示
{
click=~click;
}
else if(Irq_times==20)
{
Irq_times=0;
click=~click;
}
}
//蜂鸣器测试
void fmq_delay(unsigned char delaytimef)
{
unsigned char j,h,k;
sound=0;TR1=0; //蜂鸣器由此函数控制时,关中断
for(j=delaytimef;j>0;j--)
//for(e=10;e>0;e--) //延时1S
for(k=20;k>0;k--) //延时1MS
for(h=248;h>0;h--);
sound=1; //返回由中断控制蜂鸣器
TR1=1;
}
//遥控器编码测试
//编码接收处理
unsigned int difference(unsigned int val1,val2) //误差处理函数
{
if(val1>val2)
{
return(val1-val2);
}
else
{
return(val2-val1);
}
}
void receiv_ray(void) interrupt 0 using 1 //红外接收
{
unsigned int pulse_width;
if(receiv_en)
{
pulse_width=TH0*256+TL0;
TH0=0;
TL0=0;
if(difference(pulse_width,13400)<300) //接收到引导码
{
bootable=1;
}
if(bootable)
{
receiv_data[receiv_times/8]>>=1;
if(difference(pulse_width,1100)<200) //接收到零
{
receiv_data[receiv_times/8]&=0x7f;
}
else if(difference(pulse_width,2100)<200) //接收到一
{
receiv_data[receiv_times/8]|=0x80;
}
if(++receiv_times>31)
{
receiv_times=0;
bootable=0;
rled_flag=1;
bell_flag=1;
EX0=1;
}
}
}
}
//接收到遥控器按键处理
voidrled_deal(void)
{
switch(receiv_data[2])
{
case 0x03 : k1=1; break;//继电器一工作 “1”
case 0x05 : k2=1; break;//继电器二工作 “2”
case 0x25 : k1=0; break;//继电器一关闭 “电源”
case 0x1d : k2=0; break;//继电器二关闭 “静音”
case 0x2d : endf_flag=0; break;//切断蜂鸣器叫 “屏显”键
case 0x3b : show_quxiaofmq(); break;//取消蜂鸣器 “伴音”键
case 0x27 : quxiaojdq(); break;//取消继电器 “丽音”键
case 0xb1 : tiaoshi(&RealClock);led_flag=1;break;//调整时间 “制式”键
case 0xa3 : dingshif();led_flag=1; break;//调整蜂鸣器定时时间 “画中画”键
case 0xa9 : dingshij();led_flag=1; break;//调整继电器定时时间 “正常 ” 键
default : break;
}
}
//红外控制调整数据
voidled_tiao (void)
{
led_count=0;
end_flag=0;
while(!end_flag)
{
if(receiv_data[2]==0x2d) end_flag=1; //“OK完成”键
if(receiv_data[2]==0x35||receiv_data[2]==0x37)
{
led_count++,receiv_data[2]=0x00; //“音量+”或“频道”上键
}
if(receiv_data[2]==0x3d||receiv_data[2]==0x3f)
{
led_count--,receiv_data[2]=0x00; //“音量-”或“频道”下键
}
data_flag=0;
switch(receiv_data[2])
{
case 0x01 : led_a=0;data_flag=1; //“0”
break;
case 0x03 : led_a=1;data_flag=1; //“1”
break;
case 0x05 : led_a=2;data_flag=1; //“2”
break;
case 0x07 : led_a=3;data_flag=1; //“3”
break;
case 0x09 : led_a=4;data_flag=1; //“4”
break;
case 0x0b : led_a=5;data_flag=1; //“5”
break;
case 0x0d : led_a=6;data_flag=1; //“6”
break;
case 0x0f : led_a=7;data_flag=1; //“7”
break;
case 0x11 : led_a=8;data_flag=1; //“8”
break;
case 0x13 : led_a=9;data_flag=1; //“9”
break;
default:break;
}
//光标移动方向控制
led_count=led_count%11;
switch(led_count)
{
case 0:write_lcd_command(0x80+0x45);
if(data_flag==1) TimeBuffer1[4]=led_a+0x30; break; //分个修改对应位置的字符
case 1:write_lcd_command(0x80+0x44);
if(data_flag==1) TimeBuffer1[3]=led_a+0x30; break; //分十
case 2:write_lcd_command(0x80+0x42);
if(data_flag==1) TimeBuffer1[1]=led_a+0x30;break; //时个
case 3:write_lcd_command(0x80+0x41);
if(data_flag==1) TimeBuffer1[0]=led_a+0x30;break; //时十
case 4:write_lcd_command(0x80+0x0c);
if(data_flag==1) DateBuffer1[11]=led_a+0x30;break; //星期不闪
case 5:write_lcd_command(0x80+0x0a);
if(data_flag==1) DateBuffer1[9]=led_a+0x30;break; //日个 不闪
case 6:write_lcd_command(0x80+0x9);
if(data_flag==1) DateBuffer1[8]=led_a+0x30; break; //日十
case 7:write_lcd_command(0x80+0x7);
if(data_flag==1) DateBuffer1[6]=led_a+0x30;break; //月个
case 8:write_lcd_command(0x80+0x6);
if(data_flag==1) DateBuffer1[5]=led_a+0x30;break; //月十
case 9:write_lcd_command(0x80+0x4);
if(data_flag==1) DateBuffer1[3]=led_a+0x30;break; //年个
case 10: write_lcd_command(0x80+0x3);
if(data_flag==1) DateBuffer1[2]=led_a+0x30;break; //年十
default: break;
//case 11: write_lcd_command(0x80+0x2);break; //年百
//case 12: write_lcd_command(0x80+0x1);break; //年千
}
tiao_delay();
tiao_delay();
//write_lcd_command(0X0C); //全部字符显示,光标消失
lcd_displaystr_ram(0,1,DateBuffer1); //实时显示修改的数据
lcd_displaystr_ram(1,1,TimeBuffer1); //实时显示修改的数据
write_lcd_command(0x0f); //符号显示,光标显示,光标闪烁
}
//数值记录
mins=TimeBuffer1[4]-0x30+(TimeBuffer1[3]-0x30)*10; //分
hours=TimeBuffer1[1]-0x30+(TimeBuffer1[0]-0x30)*10;//时
days=DateBuffer1[9]-0x30+(DateBuffer1[8]-0x30)*10; //日
months=DateBuffer1[6]-0x30+(DateBuffer1[5]-0x30)*10; //月
weeks=DateBuffer1[11]-0x30; //星期
years=DateBuffer1[3]-0x30+(DateBuffer1[2]-0x30)*10;//年
}
//时间调整
void tiao_delay(void)
{
unsigned char i,j;
for(i=100;i>0;i--)
for(j=248;j>0;j--);
}
//机械按键调整数据
void key_change( void )
{
while(keychange_flag)
{
if(key2==0) tiao_delay();
if(key2==0) a++;
if(key3==0) tiao_delay();
if(key3==0) a--;
switch(k)
{
case 1:
//write_lcd_command(0x80+0x45);
write_lcd_command(0x80+0x44); //修改对应位置的字符
mins=a%60;
break;
case 2:
//write_lcd_command(0x80+0x42);
write_lcd_command(0x80+0x41); //修改对应位置的字符
hours=a%24;
break;
case 3:
//write_lcd_command(0x80+0x0a);
write_lcd_command(0x80+0x9); //修改对应位置的字符
days=a%32;
break;
case 4:
write_lcd_command(0x80+0x0c); //修改对应位置的字符
weeks=a%7;
break;
case 5:
//write_lcd_command(0x80+0x7);
write_lcd_command(0x80+0x6); //修改对应位置的字符
months=a%13;
break;
case 6:
//write_lcd_command(0x80+0x4);
write_lcd_command(0x80+0x3); //修改对应位置的字符
years=a;
break;
}
if(key1==0) tiao_delay();
if(key1==0) keychange_flag=0;
TimeBuffer1[4]=mins%10+0x30; //分个位
TimeBuffer1[3]=mins/10+0x30;
TimeBuffer1[1]=hours%10+0x30; //时
TimeBuffer1[0]=hours/10+0x30;
DateBuffer1[9]=days%10+0x30;//日
DateBuffer1[8]=days/10+0x30;
DateBuffer1[6]=months%10+0x30;//月
DateBuffer1[5]=months/10+0x30;
DateBuffer1[11]=weeks%10+0x30;//星期
DateBuffer1[3]=years%10+0x30; //年
DateBuffer1[2]=years/10+0x30;
tiao_delay();
tiao_delay();
write_lcd_command(0x0f); //符号显示,光标显示,光标闪烁
//write_lcd_command(0x0C); //全部字符显示,光标消失
lcd_displaystr_ram(0,1,DateBuffer1); //实时显示修改的数据
lcd_displaystr_ram(1,1,TimeBuffer1); //实时显示修改的数据
}
}
//调整时初值显示
void show(void) //显示调整时的初始值
{ //解决1302和1602的进制不一样的问题
mins=mins-mins/16*6;
hours=hours-hours/16*6;
days=days-days/16*6;
months=months-months/16*6;
years=years-years/16*6;
TimeBuffer1[4]=mins%10+0x30; //分个位
TimeBuffer1[3]=mins/10+0x30; //分十位
TimeBuffer1[1]=hours%10+0x30; //时个位
TimeBuffer1[0]=hours/10+0x30; //时十位
DateBuffer1[9]=days%10+0x30; //日个位
DateBuffer1[8]=days/10+0x30; //日十位
DateBuffer1[6]=months%10+0x30; //月个位
DateBuffer1[5]=months/10+0x30; //月十位
DateBuffer1[11]=weeks%10+0x30; //星期
DateBuffer1[3]=years%10+0x30; //年个位
DateBuffer1[2]=years/10+0x30; //年十位
//DateBuffer1[1]=years/100+0x30; //年百位
//DateBuffer1[0]=years/1000+0x30;//年千未
lcd_displaystr_ram(0,1,DateBuffer1);
lcd_displaystr_ram(1,1,TimeBuffer1);
}
//为方便定时设时,分成一,二两部分
//机械按键时间调整一
void key_tiao1(void)
{
tiao_delay();
k=1,a=mins,keychange_flag=1;
key_change(); //分
tiao_delay();
k++,a=hours,keychange_flag=1;
key_change(); //时
tiao_delay();
k++,a=years,keychange_flag=1;
key_change(); //星期
}
//机械按键时间调整二
voidkey_tiao2(void)
{
tiao_delay();
k++,a=days,keychange_flag=1;
key_change(); //日
tiao_delay();
k++,a=months,keychange_flag=1;
key_change(); //月
tiao_delay();
k++,a=years,keychange_flag=1;
key_change(); //年
}
//调整1302时间
void tiaoshi(struct TimerStruct *Real)
{
lcd_displaystr(0,14,DATECODE1);
mins=Real->Minute;
hours=Real->Hour;
days=Real->Day;
months=Real->Month;
weeks=Real->Week;
years=Real->Year;
show();
if(key_flag==1)
{
fmq_delay(300);
key_flag=0;
key_tiao1();
key_tiao2();
fmq_delay(300);
}
if(led_flag==1)
{
led_flag=0,
led_tiao();
}
mins=mins+mins/10*6;
hours=hours+hours/10*6;
days=days+days/10*6;
months=months+months/10*6;
years=years+years/10*6;
write_lcd_command(0x01); //清屏
Write_DS1302_RTC(0x8e,0x00); //写控制
Write_DS1302_RTC(0x80,0x00); //写秒
Write_DS1302_RTC(0x82,mins); //写分
Write_DS1302_RTC(0x84,hours);//写时
Write_DS1302_RTC(0x86,days); //写日
Write_DS1302_RTC(0x88,months); //写月
Write_DS1302_RTC(0x8a,weeks);//写星期
Write_DS1302_RTC(0x8c,years);//写年
Write_DS1302_RTC(0x8e,0x80); //控制
initize_lcd();
Init_DS1302_RTC();
}
//调整蜂鸣器定时
void dingshif(void)
{
biaof_flag=1;
lcd_displaystr(0,14,DATECODE2);
mins=Minute1;
hours=Hour1;
days=Day1;
//months=Month1;
//weeks=Week1;
//years=Year1;
show();
if(key_flag==1)
{
fmq_delay(300);
key_flag=0,
key_tiao1();
fmq_delay(300);
}
if(led_flag==1)
{
led_flag=0,
led_tiao();
}
mins=mins+mins/10*6; //解决LCD和1302的进制不同
hours=hours+hours/10*6;
days=days+days/10*6;
Minute1=mins;
Hour1=hours;
Day1=days;
//Month1=months;
//Week1=weeks;
//Year1=years;
write_lcd_command(0x01); //清屏
DATECODE22[0]='&';
if(biaoj_flag==1) DATECODE33[0]='!';
tiao_delay();
lcd_displaystr(0,14,DATECODE22);//蜂鸣器定时加入标志
lcd_displaystr(0,15,DATECODE33);
}
//调整继电器定时
voiddingshij(void)
{
biaoj_flag=1;
lcd_displaystr(0,14,DATECODE3);
mins=Minute2;
hours=Hour2;
days=Day2;
//months=Month2;
//weeks=Week2;
//years=Year2;
show();
if(key_flag==1)
{
fmq_delay(300);
key_flag=0;
key_tiao1();
fmq_delay(300);
}
if(led_flag==1)
{
led_flag=0,
led_tiao();
}
mins=mins+mins/10*6; //解决LCD和1302的进制不同
hours=hours+hours/10*6;
days=days+days/10*6;
Minute2=mins;
Hour2=hours;
Day2=days;
//Month2=months;
//Week2=weeks;
//Year2=years;
k1=k2=1;
write_lcd_command(0x01); //清屏
DATECODE33[0]='!';
if(biaof_flag==1) DATECODE22[0]='&';
tiao_delay();
lcd_displaystr(0,14,DATECODE22);//继电器定时加入标志
lcd_displaystr(0,15,DATECODE33);
}
//蜂鸣器报警及取消
void show_quxiaofmq(void)
{
biaof_flag=0;
DATECODE22[0]=' ';
if(biaoj_flag==0) DATECODE33[0]=' ';
lcd_displaystr(0,14,DATECODE22); //蜂鸣器报警取消标志
lcd_displaystr(0,15,DATECODE33);
write_lcd_command(0x01); //清屏
}
void quxiaofmq(void)
{
endf_flag=60; //蜂鸣器响1分钟
biaof_flag=0;
if(RealClock.Hour=Hour1)
if(RealClock.Day=Day1)
//if(RealClock.Month=Month1)
// if(RealClock.Year=Year1)
{
while(endf_flag)
{
TR1=1;
TR1=1;
TR1=1;
TR1=1;
TR1=1;
TR1=1;
fmq_delay(100);
endf_flag--;
if(key1==0) tiao_delay();
if(key1==0) endf_flag=0;
if(key1==0) tiao_delay();
if(key1==0) endf_flag=0;
if(key1==0) tiao_delay();
if(key1==0) endf_flag=0;
if(key1==0) tiao_delay();
if(key1==0) endf_flag=0;
}
Minute1=Minute1-2;
write_lcd_command(0x01); //清屏
DATECODE22[0]=' ';
if(biaoj_flag==0) DATECODE33[0]=' ';
lcd_displaystr(0,14,DATECODE22); //蜂鸣器报警取消标志
lcd_displaystr(0,15,DATECODE33);
}
}
//继电器取消
void quxiaojdq(void)
{
biaoj_flag=0;
if(RealClock.Hour=Hour2)
if(RealClock.Day=Day2)
// if(RealClock.Month=Month2)
// if(RealClock.Year=Year2)
k1=0,k2=0;
fmq_delay(50);
write_lcd_command(0x01); //清屏
DATECODE33[0]=' ';
if(biaof_flag==0) DATECODE22[0]=' ';
lcd_displaystr(0,14,DATECODE22);//继电器取消标志
lcd_displaystr(0,15,DATECODE33);
Minute2=Minute2-1;
}
//控制主函数
void main(void)
{
TMOD=0x11; //均为方式一
EA=1;
ET1=1;
EX0=1; //开外中断
IT0=1; //边沿触发
TR0=1;
//TH1=(65536-50000)/256; //定时50MS
//TL1=(65536-50000)%256;
TR1=1;
k1=k2=0;
fmq_flag=1;
receiv_en=1; //红外开关
rled_flag=0; //红外是否接收到数据
led_flag=0; //红外调整标志
key_flag=0; //按键调整标志
end_flag=0;
change_flag=1;
bell_flag=0;
fmq_delay(50);
initize_lcd();
Init_DS1302_RTC();
while(1)
{
unsigned intTemp,Temperature; //16位数据
unsigned char TemperatureH;
unsigned char TemperatureL;
bell_flag=0;
while(DS18B20_Reset());
DS18B20_Write(0xCC);
DS18B20_Write(0xBE);
TemperatureL=DS18B20_Read(); //低位
TemperatureH=DS18B20_Read(); //高位
while(DS18B20_Reset());
DS18B20_Write(0xCC);
DS18B20_Write(0x44);
Temp=TemperatureH*256+TemperatureL;//左移8位
if(Temp & 0xf800) //去除低11位后判断
{
LCDDisplayBuffer[0]=' ';
Temp=(~Temp)+1;
TemperatureL=Temp%256;
TemperatureH=Temp/256;
}
Temp>>=4;
Temperature=Temp; //右移四位
LCDDisplayBuffer[1]=Temp/10+0x30;
LCDDisplayBuffer[2]=Temp%10+0x30;
Temp=TemperatureL;
Temp&=0x000F; //保留低四位
Temp*=625; //化小数
Temp/=100;
LCDDisplayBuffer[3]='.';
LCDDisplayBuffer[4]=Temp/10+0x30;
LCDDisplayBuffer[5]=Temp%10+0x30;
LCDDisplayBuffer[6]='C';
Write_DS1302_RTC(0x90, 0xa5); //打开充电二极管
Temp=Read_DS1302_RTC(0x81); //秒
RealClock.Second=Temp;
TimeBuffer[7]=Temp%16+0x30;
TimeBuffer[6]=Temp/16+0x30;
Temp=Read_DS1302_RTC(0x83); //分
RealClock.Minute=Temp;
TimeBuffer[4]=Temp%16+0x30;
TimeBuffer[3]=Temp/16+0x30; //时
Temp=Read_DS1302_RTC(0x85);
RealClock.Hour=Temp;
TimeBuffer[1]=Temp%16+0x30;
TimeBuffer[0]=Temp/16+0x30;
Temp=Read_DS1302_RTC(0x87); //日
RealClock.Day=Temp;
DateBuffer[9]=Temp%16+0x30;
DateBuffer[8]=Temp/16+0x30;
Temp=Read_DS1302_RTC(0x89); //月
RealClock.Month=Temp;
DateBuffer[6]=Temp%16+0x30;
DateBuffer[5]=Temp/16+0x30;
Temp=Read_DS1302_RTC(0x8b); //星期
RealClock.Week=Temp;
DateBuffer[11]=Temp%16+0x30;
Temp=Read_DS1302_RTC(0x8d); //年
RealClock.Year=Temp;
DateBuffer[3]=Temp%16+0x30;
DateBuffer[2]=Temp/16+0x30;
lcd_displaystr_ram(0,1,DateBuffer);
lcd_displaystr_ram(1,1,TimeBuffer);
lcd_displaystr_ram(1,sizeof(TimeBuffer),LCDDisplayBuffer);
//机械按键控制
if(key1==0) tiao_delay();
if(key1==0) tiaoshi(&RealClock),key_flag=1;
if(key2==0) tiao_delay();
if(key2==0) dingshif(),key_flag=1;
if(key3==0) tiao_delay();
if(key3==0) dingshij(),key_flag=1;
//红外接收控制
if(rled_flag)
{
if(receiv_data[0]==distinguish_y&&receiv_data[1]==distinguish_a)//遥控器是否正确
{
if((receiv_data[2]+receiv_data[3])==0xff) //红外是否接收到正确的数据
{
rled_deal();
EX0=1;
}
else
EX0=1;
}
else
EX0=1;
}
//报警及取消
if(RealClock.Minute==Minute1&&biaof_flag==1) quxiaofmq();//蜂鸣器报警及取消
if(RealClock.Minute==Minute2&&biaoj_flag==1) quxiaojdq();//继电器取消
if(RealClock.Minute==0x00&&fmq_flag==1) //整点报时
{
fmq_delay(80),fmq_flag=0;
}
if(RealClock.Minute==0x02) fmq_flag=1;
led=click;
//温度处理
// if(Temperature>=0x3500) fmq_delay(1);
// if(Temperature<=0x2500) fmq_delay(2);
}
}