以下是我的红外解码程序。但一直有个问题弄不清出:文中红色标记的语句如果注释,就无**确解码。此程序是参考 天狼星 教程的。
#include"STC52.h" //晶振12MHz
#include"intrins.h"
typedef unsigned char BYTE; //Bits 8; value range 0-255
typedef unsigned int WORD; //Bits 16;value range 0- 65536
#define NOP _nop_()
#define SegPort P0 //数码管段位输出口
#define DigitPort P1 //数码管位
#define TimerHighInitValue 0xEC //定时器初值 高位
#define TimerLowInitValue 0x78 //定时器初值 低位
BYTE CurDigit = 0; //当前点亮的数码管
//共阳型数码管 0-9 字码数组,存储在代码区
code BYTE SegCode[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83, 0xc6,0xa1,0x86,0x8e};
//位选,第一位为最右边位,
code BYTE DigitSelect[] = {0xf7,0xfb,0xfd,0xfe};
//数码管显示缓冲区数组
BYTE SegBuf[4] = {0};
bit IRDecode;
bit IRDataFrame;
bit Timer1IRQEvent;
bit StartReceive;
BYTE IRTime = 0;
/*STC89C51/52RC/RD 禁止ALE,扩展RAM。内部扩展RAM(1024字节),
*物理上是内部,逻辑上是外部,C语言用 xdata 声明存储类型即可
*于此相关的特殊功能寄存器为 AUXR(0X8E),0:ALEOFF,1:EXTRAM;
*Reset value xxxx,xx00;
*/
BYTE xdata IRData[33] = {0};
WORD IRCode[4] = {0};
void Timer0Init();
void Timer1Init();
void INT1Init();
void SegRefreshDisplayBuf();
void SegDisplay();
void display();
void delay();
void IRDataDecode();
void main()
{
Timer0Init();
Timer1Init();
INT1Init();
SegRefreshDisplayBuf();
EA = 1;
while(1)
{
if(IRDataFrame)
{
IRDataFrame = 0;
IRDataDecode();
}
if(IRDecode)
{
IRDecode = 0;
SegRefreshDisplayBuf();
}
if(Timer1IRQEvent)
{
Timer1IRQEvent = 0;
SegDisplay();
}
}
}
void Timer0Init()
{
TMOD = 0X02;
TH0 = 0X9C;//0;
TL0 = 0X9C;//0;
ET0 = 1;
TR0 = 1;
}
void Timer1Init()
{
TMOD |= 0X10; //工作方式1
TH1 = TimerHighInitValue;
TL1 = TimerLowInitValue; //定时 5ms
ET1 = 1;
TR1 = 1;
}
void INT1Init()
{
IT1 = 1;
EX1 = 1;
}
void Timer0_ISR() interrupt 1
{
IRTime++;
}
void Timer1IRQ() interrupt 3
{
TH1 = TimerHighInitValue;
TL1 = TimerLowInitValue+6; //重装初值
Timer1IRQEvent = 1; //T1 中断标志位
}
void INT1_ISR() interrupt 2
{
static BYTE bitnum =0;
if(StartReceive)
{
if((120 < IRTime) && (IRTime < 140))//47 55//检测引导码
{
bitnum = 0; //为什么将这行注释,就只能一次解码正确
}
IRData[bitnum++] = IRTime;
IRTime = 0;
if(bitnum == 33)
{
bitnum = 0;
IRDataFrame = 1;
}
}
else
{
StartReceive = 1;
IRTime = 0;
}
}
void IRDataDecode()
{
BYTE k = 1;
BYTE j;
BYTE i;
BYTE Temp;
for(j=0; j<4; j++)
{
for(i=0; i<8; i++)
{
Temp = Temp >> 1;
if(IRData[k++] >16 ) //6 //是数据“1”
{
Temp = Temp | 0x80;
}
}
IRCode[j] = Temp;
}
IRDecode = 1;
StartReceive = 0;
}
void SegRefreshDisplayBuf()
{
SegBuf[0] = IRCode[1] %16; //个位
SegBuf[1] = IRCode[1] /16; //十位
SegBuf[2] = IRCode[2] %16; //百位
SegBuf[3] = IRCode[2] /16; //千位
}
void SegDisplay()
{
SegPort = 0xff; //关闭所有数码管,否则会有拖影
if(CurDigit<4)
{
DigitPort = DigitSelect[CurDigit]; //确定当前字型码
SegPort = SegCode[SegBuf[CurDigit]]; //点亮一个数码管
CurDigit++; //位数小于4,位数加一,准备下一位
}
else
CurDigit = 0;
}