今天下午的时候,调试努力之下,终于把红外解码弄出来了。其实之前有次比赛的时候就已经用到了红外,只是那次用的是51单片机,用的是外部中断和延时检测脉宽来进行解码,由于51的时钟这些比较简单,因此解码很容易就正确了。可是如今换到了ARM7平台下,因为对它的不是很熟悉,怎么用普通语句实现精确延时对我来讲是个难点。最后考虑用两个方案来实现红外的解码。方案一是用外部中断加定时器延时检测脉宽进行解码,可是结果并无我想的那样美好,调试了半天也没有实现正确的解码,我的认为是任务节拍的影响,可是确实不知道该怎么修改,最后放弃方案一,改用方案二,用定时器捕获实现红外的解码,并最终实现。函数
LPC2103芯片带有定时器捕获,能够设置为降低沿,上升沿或双边沿捕获中断。由于结合到此款红外编码方式,因此采用降低沿进行捕获。定时器0由于用做了系统节拍定时器,因此我选择了定时器1的捕获。ui
定时器1进行以下的初始化。编码
void SetTimer(void) { T1TCR = 0x02; //关闭复位定时器1 T1PR = 10; //11分频,约1us计时一次(外设时钟11.0592MHZ) T1CCR = 0x06; //降低沿捕获并产生中断 T1IR = 0x10; //清除定时器1捕获0中断 T1TCR = 0x01; //开启定时器1 VICVectAddr1 = (uint32)Timer1_Handler; //中断向量相关设置 VICVectCntl1 = (0x20 | 0x05); VICIntEnable |= (1 << 5); }
void Timer1_Exception() { static uint32 tOld; //保存旧的降低沿捕获值 uint32 tNew; //保存新的降低沿捕获值 static i; OS_ENTER_CRITICAL(); T1IR = 0x10; //清除定时器1捕获0中断 tNew = T1CR0; tValue = tNew - tOld; //获得两次降低沿之间的差值 tOld = tNew; //以便下次中断处理 OSMboxPost(Msg,(void*)tValue); //发送消息邮箱,行为同步 OS_EXIT_CRITICAL(); VICVectAddr = 0x00; }
在检测脉宽任务里,我只须要根据测定脉宽与原本编码原有的脉宽进行比较判断,而后进行相关移位数据操做,获得数据码值。spa
由于个人遥控器有点不一样,地址码与地址反码不互反,因此不能进行地址的判断,因此滤除掉了引导码与地址码,直接进行了数据码的处理。调试
只要数据码与数据反码取反相同,则调试LED闪烁一下。code
固然我尚未具体知道遥控器按键对应的具体码制是多少,并且尚未检测到连发码,留待下次把码制经过串口发送到上位机进行显示。同步
这是检测脉宽任务的核心代码:it
while (1) { OSMboxPend(Msg, 0, &err); //等待脉宽检测消息 if(tValue>2145 && tValue<2345) //进行脉宽检测 { ucTemp = 1; //逻辑1 } else if(tValue>1025 && tValue<1225) { ucTemp = 0; //逻辑0 } else if(tValue>13400 && tValue<13600) { ucCounter = 0; //引导码 usData0 = 0; usData1 = 0; flag = 1; } else { continue; } if(flag) //数据处理过程 { ucCounter++; if(ucCounter<16) { usData0 |= (uint16)ucTemp; usData0 <<= 1; } else if(ucCounter == 16) { usData0 |= (uint16)ucTemp; } else if(ucCounter < 32) { usData1 |= (uint16)ucTemp; usData1 <<= 1; } else if(ucCounter == 32) { usData1 |= (uint16)ucTemp; flag = 0; OSSemPost(Sem); //发送信号量,进行码制转换任务,个人任务只是简单的实现了判断解码是否成功。 } } }