利用MSP430 TimerA的CCR1捕获模式对红外遥控芯片M50560-008P进行红外解码的实例。注:定义的测量时间都是经过实际调试后调整得到,可能与芯片手册会有出入。
//红外遥控芯片M50560-008P,其编码格式和M50560-001P一致,可参阅数据手册。
#define UserCode 0xC2
#define LeadCodeOrSeprateTime 4000 //4ms,对应1MHz的计数时钟
#define Bit0Time1 600 //0.600ms,对应1MHz的计数时钟
#define Bit0Time2 520 //0.520ms,对应1MHz的计数时钟
#define Bit1Time1 600 //0.600ms,对应1MHz的计数时钟
#define Bit1Time2 1600 //1.600ms,对应1MHz的计数时钟
#define DataCount 8 //8位的用户码或数据码
void ParaSet(uchar DataCode)//红外遥控输入处理
{
//处理代码
}
void SysInit(void)
{
//系统参数初始化代码
}
void main(void)//主函数
{
SysInit();//系统参数初始化
P1DIR=0xFB;//初始化P1.2(红外接收头)为输入
P1IE=0x04;//使能P1.2的中断
P1IES=0x04;//下降沿触发P1.2中断(红外接收头反相输出)
}
#pragma vector=PORT1_VECTOR
__interrupt void PORT1()//红外遥控输入中断处理
{
uint LeadBitTime[2],BitTime[3],LastBitTime;
uchar i,j,k,Data[2];
P1IE=0x00;//关闭P1.2中断
_EINT();//进入中断后,系统自动关总中断允许,因此需再开总中断允许
if((P1IFG&0x04)==BIT2)//红外遥控输入
{
P1IFG&=0xFB;//中断标志位复位
P1SEL|=0x04;//P1.2第二功能选择,进入TimerA的CCR1捕获模式
TACTL|=MC_2+TACLR;//启动TA计数器的连续计数模式
TACCTL1&=~CCIFG;//复位捕获标志
for(k=0;k<2;k++)
{
while((TACCTL1&BIT0)!=CCIFG);//等待上升沿
LeadBitTime[0]=CCR1;
TACCTL1&=~CCIFG;
while((TACCTL1&BIT0)!=CCIFG);//等待下降沿
LeadBitTime[1]=CCR1;
TACCTL1&=~CCIFG;
if(LeadBitTime[1]-LeadBitTime[0]>LeadCodeOrSeprateTime+500||LeadBitTime[1]-LeadBitTime[0]<LeadCodeOrSeprateTime-500)
{
TACTL|=MC_0+TACLR; //停止TA计数
P1SEL&=0xFB;//P1.2恢复选择第一功能即为I/O口
return;
}//如果引导码不符则退出
LastBitTime=LeadBitTime[1];
for(i=0;i<DataCount;i++)//用户码和数据码解码
{
BitTime[0]=LastBitTime;//位码开始时刻赋初值
for(j=1;j<3;j++)
{
while((TACCTL1&BIT0)!=CCIFG);//等待上升沿或下降沿跳变
BitTime[j]=CCR1;//读取捕获计时值
TACCTL1&=~CCIFG;//复位捕获标志
}
LastBitTime=BitTime[2];//为下一个位码保存开始时刻初值
Data[k]>>=1;//得到的用户码和数据码右移1位,高位填0,准备接收码位码值
if(BitTime[2]-BitTime[1]>Bit0Time2-200&&BitTime[2]-BitTime[1]<Bit0Time2+200){Data[k]&=0x7F;}
if(BitTime[2]-BitTime[1]>Bit1Time2-200&&BitTime[2]-BitTime[1]<Bit1Time2+200) {Data[k]|=0x80;}//0、1判别。如果满足判据则为1
}
}
if(Data[0]!=UserCode)
{//如果用户码不为0xC2则退出
TACTL|=MC_0+TACLR; //停止TA计数
P1SEL&=0xFB;//P1.2恢复选择第一功能即为I/O口
return;
}
TACTL|=MC_0+TACLR; //停止TA计数
ParaSet(Data[1]);//参数设置
TACTL|=MC_0+TACLR; //停止TA计数
P1SEL&=0xFB;//P1.2恢复选择第一功能即为I/O口
}
P1IE=0x04;//使能P1.2的中断
}