//智能遥控电风扇控制器源程序
#include "AT89x051.H"
#define uchar unsigned char
#define uint unsigned int
#define b1 0xe200
#define b2 0xe210
#define b3 0xe208
#define b4 0xe218
#define b5 0xe204
#define b6 0xe214
#define b7 0xe20c //阵风
#define b8 0xe21c //自然风
#define b9 0xe280 //自动档
#define on_off 0xe240 //电源开关
#define ch_a 0xe250 //加档
#define ch_s oxe248 //减档
#define time 0xe2e8 //定时
#define louver 0xe24c //转页
#define count_num 500 //显示次数
#define time1_num 18000
#define time2_num 100
#define bell P3_4
#define c_f 0xd4 //"F"
#define c_h 0xce //"H"
#define c_g 0x81 //"="
uint time1=time1_num; //18000*100*2ms=1h
uchar time2=time2_num;
uint count=count_num; //显示次数
uchar sort=3; //显示off
uchar dis_bit=0; //显示的位
uchar code_length=16;
uchar data dis[4]={0x02,0x02,0x00,0xff}; //显示数据区
uchar temperature;
uint code_t=0;
uchar code1=0;
uchar code2=0;
bit bdata code_start=0; //代码起始标志
bit bdata button=0; //无键按下
bit bdata i_flag=0; // 有无中断标志
bit bdata t_flag=0;//测温标志
bit bdata bt=0; //判断是否是定时键
bit bdata off=0; //为0无定时
uchar code TAB[11]={0x5f,0x0a,0x9d,0x9b,0xca,0xd3,0xd7,0x5a,0xdf,0xdb,0x75};
void timer_0(void);
void dis_t(void); //温度显示
void dis_s(void); //档位显示
void dis_h(void); //时间
void dis_off(void); //关机显示
void delay(uint t); //延时
uchar d_code(uint t); //解码
uchar begin=0; //开始补偿
void c_code(void); //键号转换
void off_time(void); //定时关
void measure_temperature(void);
void key_time(void); //定时按钮
void sort_key(void); //风类按钮
void mov_p1(uchar t0,t1,t2); //显示
void button_process(void); //按键处理
//********定时关机*********
void off_time(void)
{
if(off==1)
{
if(time1--==0)
{
time2--;
time1=time1_num;
}
if(time2==0)
{
dis[3]=dis[3]-1;
time2=time2_num;
}
if(dis[3]==0)
{
code_t=on_off; //关机
c_code();
}
}
}
//********定时器0中断*********
void timer0() interrupt 1 using 2
{
off_time();
if(dis_bit==0&&t_flag==0)
{
key_time();
sort_key();
}
switch(sort)
{
case 0:
if(count!=0)
{
mov_p1(dis[0],dis[1],TAB[10]); //显示温度
count--;
}
break;
case 1:
if(count!=0)
{
mov_p1(c_f,c_g,TAB[dis[2]]); //显示档位
count--;
}
break;
case 2:
if(count!=0)
{
dis_h(); //显示时间
count--;
}
break;
case 3:
mov_p1(0x5f,c_f,c_f);//显示关机
default:
break;
}
timer_0();
if(count==0) //轮流显示
{
P3_0=P3_1=P3_5=1;
if(i_flag==0&&t_flag==0)
measure_temperature();
count=count_num;
sort=(sort&0x03)+1;
if(sort>=3)
sort=0; //完成一轮显示
}
}
//***********定时按钮************
void key_time(void)
{
bit i=P1_2;
P1_2=1;
if(P1_2==0)
{
delay(50);
if(P1_2==0) //确认有按键
{
bell=0;
delay(100);
bell=1;
while(P1_2==0)
{;}
if(dis[3]==0xff)
{
dis[3]=1;
off=0; //取反后为1,定时
}
else
{
if(dis[3]<9)
{
dis[3]=dis[3]+1;
off=0; //取反后为1,定时
}
else
off=1; //取反后为0,取消定时
}
sort=2;
code_t=time; //显示时间
c_code();
//bt=0; //恢复
}
}
P1_2=i;
i_flag=0; //恢复执行其它任务
}
//***********换档按钮************
void sort_key(void)
{
bit i=P1_1;
P1_1=1;
if(P1_1==0)
{
delay(50);
if(P1_1==0)
{
button=1;
bell=0;
delay(200);
bell=1;
while(P1_1==0)
{;}
if(dis[2]<9)
{
dis[2]=dis[2]+1;
code2=dis[2];
}
else
{
dis[2]=0;
code2=10; //power off
}
delay(100);
sort=1;
count=5000;
//TF0=1;
}
}
P1_1=i;
i_flag=0; //恢复执行其它任务
}
//********定时器1中断测温************
void timer1() interrupt 3 using 3
{
uint temp;
TR0=0; //计数停
TR1=0; //定时停
temp=TH0*256+TL0; //取温度值
temperature=(7000-temp)/11; //计算温度
//if(dis[2]!=0)
// temperature--; //工作时补偿1度
/*if(F0==0&&begin<=10) //开始温度加3度
temperature+=3;
if(F0==0&&begin<=60&&begin>10)
temperature+=2;
if(F0==0&&begin<=150&&begin>60)
temperature+=1;
*/
dis[0]=TAB[temperature/10];
dis[1]=TAB[temperature%10];
IE0=0;
t_flag=0;
timer_0();
EX0=1;
}
//***********键号转换************
void c_code(void)
{
bit bdata i=0;
switch(code_t)
{
case b1:
code1=1;
break;
case b2:
code1=2;
break;
case b3:
code1=3;
break;
case b4:
code1=4;
break;
case b5:
code1=5;
break;
case b6:
code1=6;
break;
case b7:
code1=7;
break;
case b8:
code1=8;
break;
case b9:
code1=9;
break;
case on_off:
code1=10; //关机
dis[3]=0xff;
//#####标志复位############
button=0; //无键按下
i_flag=0; // 无中断标志
bt=0; //无定时键按下
off=0; //无定时
time1=time1_num; //定时初值复位
time2=time2_num;
count=count_num; //显示次数
break;
case time:
off=~off;
if(off==0)
dis[3]=0xff; //取消定时
i=1;
bt=1;
count=5000; //延长显示
sort=2; //显示时间
TF0=1;
break;
case louver:
P3_3=~P3_3;
code1=code2;
break;
default:
code1=0;
break;
}
if(bt==1&&i==0) //装载代码
{
if(code1<9) //定时最大9h
{
dis[3]=code1;
bt=0;
}
}
else
if(i==0)
{
code2=code1;
count=5000; //延长显示
if(code1==10)
{
dis[2]=0; //F=0
sort=3; //显示关机
}
else
{
dis[2]=code1;
sort=1; //显示风类
}
TF0=1;
}
}
//**********判断代码************
uchar d_code(uint t)
{
if(t<=0x220&&t>=0x190)
return 0;
else
{
if(t<=0x430&&t>=0x390)
return 1;
else
return 0xff;
}
}
//*********** 接收代码中断 ************
void receive_code() interrupt 0 using 1
{
uint temp,i;
ET0=0;
i_flag=1; //暂停其它任务
if(TR1==0)
{
TR1=0;
TMOD=0x11;
TH1=TL1=0;
TR1=code_start=1;
}
else
{
TR1=code_start=0;
temp=TH1*256+TL1;
if((d_code(temp)==0||d_code(temp)==1)&&code_length!=0)
{
TH1=TL1=0;
TR1=code_start=1;
code_t=(code_t<<1)+d_code(temp);
code_length--;
}
else
{
if(code_length==0&&((code_t&0xff00)==0xe200)) //除掉误码
{
code_length=16;
bell=0; //正确收到,响声提示
c_code(); //转换代码
for(i=0;i<6000;i++)
{
EX0=0;
P3_0=P3_1=P3_5=1;
if(i>800)
bell=1;
IE0=0;
if(P3_2==0)
i--;
button=1; //有按键需要处理
}
i_flag=0; //恢复执行其它任务
}
else //误码
{
code_length=16;
for(i=0;i<6000;i++)
{
EX0=0;
IE0=0;
if(P3_2==0)
i--;
i_flag=0; //恢复执行其它任务
}
}
timer_0();
EX0=1;
}
}
}
//***********显示代码送P1口************
void mov_p1(uchar t0,t1,t2)
{
switch(dis_bit)
{
case 0:
P1=t0;
P3_1=P3_5=1;
P3_0=0;
dis_bit=1;
break;