各位高人好:
我是在用 STC89c516RD+, DS1302, 红外发射器TC9012 红外接收头1838T
写一个
电子时钟,时钟正常运行,在数码管上也正确显示,只是当进行红外控制时,当扫描的频率很低时,能够较好的按照预期效果执行;但当扫描的频率高时,程序根本接收不到我发送的正确信息,现象只是数码管在很短的时间内乱闪,然后恢复正常,没有起到红外的控制作用。不管是延时扫描还是定时扫描都不行,求大家帮忙啊,我改了好长时间都没有成功,都快崩溃了!
下面是程序
#include<reg52.h>
#define uc unsigned char
#define ui unsigned int
sbit led=P1^2; //流水灯控制位
sbit zhh=P1^3; //8*8点阵的行控制位
sbit wei=P1^1; //数码管位选控制
sbit duan=P1^0; //数码管段选控制
sbit dio=P3^2; //ds1302数据位
sbit sclk=P3^3; //ds1302时钟位
sbit rst=P3^4; //ds1302控制位
sbit en=P1^7; //1602控制位
uc dm[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//段码0-9
uc wm[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//位码
uc hc[]={0,0,0x40,0,0,0x40,0,0};//缓存显示的时钟数据,时,分,秒
uc hc1[33]={0}; //用于接收解码后红外信号
uc shuju[4]={0}; //接收到红外信号,整理为四个字节
uc hour,minute,second,jishi,done,ready,con,j;
/***************************************************
延时
***************************************************/
void delay(ui n)
{
ui x,y;
for(x=25;x>0;x--) //扫描频率高时x定为25,低时定为4000
for(y=n;y>0;y--);
}
/***************************************************
显示函数
***************************************************/
void display()
{
uc i;
for(i=0;i<8;i++)
{
duan=1;
P0=0x00;
duan=0;
P0=0xff;//用于消隐
wei=1;
P0=wm[i];
wei=0;
P0=0x00;//用于消隐
duan=1;
if(i==2||i==5) //在时分秒中间加一杠
P0=hc[i];
else
P0=dm[hc[i]];
duan=0;
delay(1);
// TR1=1; //这是用定时来扫描
// while(!j);
// j=0;
// TR1=0;
}
}
/***************************************************
初始化
***************************************************/
void init()
{
P0=0xff; //关闭流水灯
led=0;
P0=0x00; //关闭点阵
zhh=0;
wei=0; //关闭数码管,在显示程序中再打开
duan=0;
rst=0; //关闭ds1302
en=0; //关闭1602液晶
}
/***************************************************
1302设置 读写都按照1302的时序要求完成
***************************************************/
void write(uc dat)
{
uc i;
for(i=0;i<8;i++)
{
if(dat&0x01)
dio=1;
else
dio=0;
sclk=0;
sclk=1;
dat>>=1;
}
}
void write1302(uc add,uc dat)
{
rst=0;
sclk=0;
rst=1;
write(add);
write(dat);
rst=0;
sclk=1;
}
uc read()
{
uc i,dat;
for(i=0;i<8;i++)
{
if(dio)
dat|=0x80;
sclk=1;
sclk=0;
dat>>=1;
}
return(dat);
}
uc read1302(uc add)
{
uc dat;
rst=0;
sclk=0;
rst=1;
write(add);
dat=read();
rst=0;
sclk=1;
return(dat);
}
void init1302() //1302初始化,时分秒的设置
{
write1302(0x8e,0x00);
write1302(0x80,(0/10*16+0%10));
write1302(0x82,(46/10*16+46%10));
write1302(0x84,(20/10*16+20%10));
write1302(0x8e,0x80);
}
void change1302() //1302更改,改变时分秒,在红外控制时用
{
write1302(0x8e,0x00);
write1302(0x80,(second/10*16+second%10));
write1302(0x82,(minute/10*16+minute%10));
write1302(0x84,(hour/10*16+hour%10));
write1302(0x8e,0x80);
}
/***************************************************
DTB转换
***************************************************/
void convert()
{
hour=read1302(0x85); //从1302中读取数据
minute=read1302(0x83);
second=read1302(0x81);
hour=hour/16*10+hour%16; //将读取的BCD码转换为十进制
minute=minute/16*10+minute%16;
second=second/16*10+second%16;
hc[0]=hour/10; //将时分秒的各位放入缓存
hc[1]=hour%10;
hc[3]=minute/10;
hc[4]=minute%10;
hc[6]=second/10;
hc[7]=second%10;
}
/***************************************************
定时器初始化
***************************************************/
void
tinit()
{
TMOD=0x12;
TH0=0x00;
TL0=0x00;
TH1=(65536-4000)/256;
TL1=(65536-4000)%256;
EA=1;
ET0=1;
ET1=1;
TR0=1;
}
/***************************************************
外部中断0初始化
***************************************************/
void einit()
{
EX0=1;
IT0=1;
}
/***************************************************
红外信号接收
***************************************************/
void rec()
{
uc i,j,k=1,dat;
for(i=0;i<4;i++) //将接收到的红外信号进行整理
{
for(j=0;j<8;j++)
{
dat>>=1;
if(hc1[k]>7) //晶振为11.0592MHz
dat|=0x80;
k++;
}
shuju[i]=dat;
dat=0;
}
ready=1;
}
/***************************************************
红外信号解码
***************************************************/
void jiema() //信号的散转
{
switch(shuju[2])
{
case 0x47:
{
con=1; //开启红外控制
}
break;
case 0x15:
{
hour++;
if(hour==24)
hour=0;
}
break;
case 0x07:
{
hour--;
if(hour>=24)
hour=23;
}
break;
case 0x40:
{
minute++;
if(minute==60)
minute=0;
}
break;
case 0x44:
{
minute--;
if(minute>=60)
minute=59;
}
break;
case 0x46:
{
second++;
if(second==60)
second=0;
}
break;
case 0x45:
{
second--;
if(second>=60)
second=59;
}
break;
case 0x43:
{
con=0; //关闭红外控制
}
break;
}
}
/***************************************************
红外处理
***************************************************/
void redcon() //红外信号综合处理
{
if(done)
{
rec();
done=0;
}
if(ready)
{
jiema();
ready=0;
}
}
/***************************************************
主函数
***************************************************/
void main()
{
init(); //初始化
init1302();
tinit();
einit();
while(1)
{
while(con==1)
{
change1302(); //将时分秒重新写入1302
convert(); //将数据读出并转换为十进制
display(); //显示
}
while(con==0)
{
convert(); //将数据读出并转换为十进制
display(); //显示
}
}
}
void timer0() interrupt 1
{
jishi++; //记录两个下降沿间的时间
}
void timer1() interrupt 3 //用于定时扫描时
{
TH1=(65536-4000)/256;
TL1=(65536-4000)%256;
j=1;
}
void exter0() interrupt 0 //红外中断控制
{
static uc i;
uc flag;
if(flag)
{
if(jishi<55&&jishi>30) //辨别头码
i=0;
hc1[i]=jishi; //存后32位信号
jishi=0;
i++;
if(i==33)
{
i=0;
done=1;
}
}
else
{
jishi=0;
flag=1;
}
redcon(); //接收完后进行红外信号综合处理
}
一周热门 更多>