/*此程序為紅外遙控電子鐘,晶振為12M,MCU型號為51系列,電路很簡單四位共陽數碼管,紅外接收管sm0038接在P3.2*/
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
#define c(x) (x*120000/120000)
sbit IR=P3^2;
sbit ge=P2^3;//數碼管四位選控制端
sbit shi=P2^2;
sbit bai=P2^1;
sbit qian=P2^0;
char miao,fen=59,shij=23;//時分秒3個變量
uchar num,ding; //兩定時器計數變量
uint temp;//遙控解碼變量
uchar i;
uchar j;
bit flag;//控制小數點亮與滅變量
bit power;//控制數碼管亮與滅變量
bit flash;//進入時間調整標志位變量
uchar IRBUF[4]; //用于保存解碼結果
uchar code table[]={
0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90,
0x88,0x83,0xc6,0xa1,0x86,
0x8e
};
uint Low()
{
TL0=0;
TH0=0;
TR0=1;
while(!IR&&(TH0&0x80)==0);
TR0=0;
return TH0*256+TL0;
}
//=============================================================
uint High()
{
TL0=0;
TH0=0;
TR0=1;
while(IR&&(TH0&0x80)==0);
TR0=0;
return TH0*256+TL0;
}
void xian(uchar shik,uchar fen)
{
P0=table[shik/10];
if(power==0)
qian=0;
else
qian=1;
// delay(2);
qian=1;
if(flag==0)
P0=table[shik%10]&0x7f;
else
P0=table[shik%10]|0x80;
if(power==0)
bai=0;
else
bai=1;
//delay(2);
bai=1;
P0=table[fen/10];
if(power==0)
shi=0;
else
shi=1;
//delay(2);
shi=1;
P0=table[fen%10];
if(power==0)
ge=0;
else
ge=1;
//delay(2);
ge=1;
}
void yin()
{
while(1)
{
restart:
while(IR)
{
xian(shij,fen);
if(flash==1)
{
if(ding>5)
{
ding=0;
power=~power;
//xian(shij,fen);
}
}
}
temp=Low();
if(temp<c(8500) || temp>c(9500)) continue;//引導脈沖低電平9000
temp=High();
if(temp<c(4000) || temp>c(5000)) continue;//引導脈沖高電平4500
for(i=0;i<4;i++) //4個字節(jié)
{
for(j=0;j<8;j++) //每個字節(jié)8位
{
temp=Low();
if(temp<c(200) || temp>c(800)) goto restart;
temp=High();
if(temp<c(200) || temp>c(2000)) goto restart;
IRBUF[i]>>=1;
if(temp>c(1120)) IRBUF[i]|=0x80;
}
}
return;
}
}
//==============================================================
main()
{
TMOD=0x11;
EA=1;
TR0=1;
ET0=1;
TL0=0;
TH0=0;
TR1=1;
ET1=1;
TH1=(65536-100)/256; //定時器0設定約1000us中斷一次,用于數碼管掃描
TL1=(65536-100)%256;
while(1)
{
yin();
switch(IRBUF[2])
{
case 0x58:flash=~flash;if(flash==0)power=0;//進入調整時間狀態(tài)
break;
case 0x1b:if(flash==1){shij++;if(shij>23)shij=0;}//如果數碼管在閃爍則可以進入小時"+"調整
break;
case 0x1f:if(flash==1){shij--;if(shij<=(0-1))shij=23;}//如果數碼管在閃爍則可以進入小時"-"調整
break;
case 0x0f:if(flash==1){fen++;if(fen>59)fen=0;}//如果數碼管在閃爍則可以進入分"+"調整
break;
case 0x1a:if(flash==1){fen--;if(fen<=(0-1))fen=59;}//如果數碼管在閃爍則可以進入分"-"調整
break;
}
}
}
void zhong3() interrupt 3
{
TH1=(65536-50000)/256;
TL1=(65536-50000)%256;
num++;
ding++;
if(num>=10)
{
num=0;
miao++;//數碼管閃爍變量
if(flash==0)
flag=~flag;
else
flag=0;
if(miao>119)
{
miao=0;
fen++;
if(fen>59)
{
fen=0;
shij++;
if(shij>23)
shij=0;
}
}
}
}
void zhong1() interrupt 1
{
TL0=0;
TH0=0;
}