|
樓主 |
發表於 2012-10-24 00:01:34
|
顯示全部樓層
改好了!! /*------------------20121023 改寫完成 主要問題在於把第一個引導碼給算進去了,還有要先位移再|0X80 ---------*/
/*------------------20121023 改寫完成 主要問題在於把第一個引導碼給算進去了,還有要先位移再|0X80 ---------*/
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
sbit IRP=P3^2; //红外接口标志
sbit LEDirok=P1^0;
#define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换
sbit LATCH1=P2^2;//定义锁存使能端口 段锁存
sbit LATCH2=P2^3;// 位锁存
bit irpro_ok,irok,startflag;
unsigned char irtime,lcht;//放在中斷程式的計數遙控器內碼時機間累計
unsigned char IRcord[4];//紅外線遙控碼存放區
unsigned char IRBYC;//紅外線遙控碼 8位元
unsigned char Q;//紅外線遙控碼 4字
unsigned char TTemp;//紅外線遙控碼位元轉換用
unsigned char TempData[8];
unsigned char code dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};// 显示段码值0~F
unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码
/*------------------------------------------------
函数声明
------------------------------------------------*/
void Ir_work(void);
void Ircordpro(void);
void DelayUs2x(unsigned char t)
{
while(--t);
}
void DelayMs(unsigned char t)
{
while(t--)
{
DelayUs2x(245);
DelayUs2x(245);
}
}
void EX0init(void)
{
IT0=1;//外部中斷0下降緣觸發 INT0(P3^2)遙控器的脈衝時間
EX0=1;
}
void EX0_isr(void) interrupt 0 //遙控器的脈衝處理
{
if(startflag==1)//脈衝出現之後
{
if(irtime<63&&irtime>=33)//引導碼長度要在 6.5~13.5之間
{
Q=0;//把計數歸零
IRBYC=0;//位元歸零
irtime=0;
}
else
{
lcht=irtime;
TTemp>>=1;//右移一位 bit 7 =0
if(lcht>7)//假如是1 時間為2.2ms
{
TTemp|=0x80;//因為遙控脈衝從0bit先送7bit最後送出,所以時間長約2.2ms則為1,1.2ms為0
}
IRBYC++;
if(IRBYC==8)//右移8位 >=8
{
IRcord[Q]=TTemp;//把資料存入 IRcord[0~3]
IRBYC=0;
TTemp=0;
Q++;//4個字
if(Q==4)
{
irok=1;//接收完成設定旗標
Q=0;
}
}
irtime=0;//每收一個位元就把計數歸零
}
}
else
{
startflag=1;//第一次脈衝出現
irtime=0;
}
}
/*------------------------------------------------
定时器0初始化
------------------------------------------------*/
void TIM0init(void)//定时器0初始化
{
TMOD=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值
TH0=0x00; //重载值
TL0=0x00; //初始化值
EA=1; //总中断打开
ET0=1; //开中断
TR0=1;
}
/*------------------------------------------------
定时器0中断处理
------------------------------------------------*/
void tim0_isr (void) interrupt 1 using 1
{
irtime++; //用于计数2个下降沿之间的时间
}
void CH_code(void)
{
TempData[0]=dofly_DuanMa[IRcord[0]>>4];
TempData[1]=dofly_DuanMa[IRcord[0]%16];
TempData[2]=dofly_DuanMa[IRcord[1]>>4];
TempData[3]=dofly_DuanMa[IRcord[1]%16];
TempData[4]=dofly_DuanMa[IRcord[2]>>4];
TempData[5]=dofly_DuanMa[IRcord[2]%16];
TempData[6]=dofly_DuanMa[IRcord[3]>>4];
TempData[7]=dofly_DuanMa[IRcord[3]%16];
}
void Display(unsigned char FirstBit,unsigned char Num)
{
unsigned char i;
for(i=0;i<Num;i++)
{
DataPort=0; //清空数据,防止有交替重影
LATCH1=1; //段锁存
LATCH1=0;
DataPort=dofly_WeiMa[i+FirstBit]; //取位码
LATCH2=1; //位锁存
LATCH2=0;
DataPort=TempData[i]; //取显示数据,段码
LATCH1=1; //段锁存
LATCH1=0;
DelayMs(2); // 扫描间隙延时,时间太长会闪烁,太短会造成重影
}
}
/*------------------------------------------------
主函数
------------------------------------------------*/
void main(void)
{
EX0init(); //初始化外部中断
TIM0init();//初始化定时器
DataPort=0x3f; //取位码 第一位数码管选通,即二进制1111 1110
LATCH2=1; //位锁存
LATCH2=0;
while(1)//主循环
{
if(irok) //如果接收好了进行红外处理
{
LEDirok=!LEDirok;
irok=0;
CH_code();
}
Display(0,8);
}
}
|
|