新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > uc/OS-II下ARM7定时器捕获实现红外解码

uc/OS-II下ARM7定时器捕获实现红外解码

作者:时间:2016-11-21来源:网络收藏
今天下午的时候,调试努力之下,终于把红外解码弄出来了。其实以前有次比赛的时候就已经用到了红外,只是那次用的是51单片机,用的是外部中断和延时检测脉宽来进行解码,因为51的时钟这些比较简单,所以解码很容易就正确了。但是现在换到了ARM7平台下,由于对它的不是很熟悉,怎么用普通语句实现精确延时对我来说是个难点。最后考虑用两个方案来实现红外的解码。方案一是用外部中断加定时器延时检测脉宽进行解码,但是结果并没有我想的那样美好,调试了半天也没有实现正确的解码,个人认为是任务节拍的影响,但是确实不知道该怎么修改,最后放弃方案一,改用方案二,用定时器捕获实现红外的解码,并最终实现。

LPC2103芯片带有定时器捕获,可以设置为下降沿,上升沿或双边沿捕获中断。因为结合到此款红外编码方式,所以采用下降沿进行捕获。定时器0因为用作了系统节拍定时器,所以我选择了定时器1的捕获。

本文引用地址:http://www.eepw.com.cn/article/201611/319111.htm

定时器1进行如下的初始化。

[plain]view plaincopy
print?
  1. voidSetTimer(void)
  2. {
  3. T1TCR=0x02;//关闭复位定时器1
  4. T1PR=10;//11分频,约1us计时一次(外设时钟11.0592MHZ)
  5. T1CCR=0x06;//下降沿捕获并产生中断
  6. T1IR=0x10;//清除定时器1捕获0中断
  7. T1TCR=0x01;//开启定时器1
  8. VICVectAddr1=(uint32)Timer1_Handler;//中断向量相关设置
  9. VICVectCntl1=(0x20|0x05);
  10. VICIntEnable|=(1<<5);
  11. }



然后在定时器1中断服务函数里,就算出相邻两次下降沿之间的差值。然后通过消息邮箱把消息发送到脉宽检测任务进行处理。

[plain]view plaincopy
print?
  1. voidTimer1_Exception()
  2. {
  3. staticuint32tOld;//保存旧的下降沿捕获值
  4. uint32tNew;//保存新的下降沿捕获值
  5. statici;
  6. OS_ENTER_CRITICAL();
  7. T1IR=0x10;//清除定时器1捕获0中断
  8. tNew=T1CR0;
  9. tValue=tNew-tOld;//得到两次下降沿之间的差值
  10. tOld=tNew;//以便下次中断处理
  11. OSMboxPost(Msg,(void*)tValue);//发送消息邮箱,行为同步
  12. OS_EXIT_CRITICAL();
  13. VICVectAddr=0x00;
  14. }

在检测脉宽任务里,我只需要根据测定脉宽与本来编码原有的脉宽进行比较判断,然后进行相关移位数据操作,得到数据码值。

因为我的遥控器有点不同,地址码与地址反码不互反,所以不能进行地址的判断,所以滤除掉了引导码与地址码,直接进行了数据码的处理。

只要数据码与数据反码取反相同,则调试LED闪烁一下。

当然我还没有具体知道遥控器按键对应的具体码制是多少,而且还没有检测到连发码,留待下次把码制通过串口发送到上位机进行显示。

[plain]view plaincopy
print?

[plain]view plaincopy
print?
  1. 这是检测脉宽任务的核心代码:

    while(1)
  2. {
  3. OSMboxPend(Msg,0,&err);//等待脉宽检测消息
  4. if(tValue>2145&&tValue<2345)//进行脉宽检测
  5. {
  6. ucTemp=1;//逻辑1
  7. }
  8. elseif(tValue>1025&&tValue<1225)
  9. {
  10. ucTemp=0;//逻辑0
  11. }
  12. elseif(tValue>13400&&tValue<13600)
  13. {
  14. ucCounter=0;//引导码
  15. usData0=0;
  16. usData1=0;
  17. flag=1;
  18. }
  19. else
  20. {
  21. continue;
  22. }
  23. if(flag)//数据处理过程
  24. {
  25. ucCounter++;
  26. if(ucCounter<16)
  27. {
  28. usData0|=(uint16)ucTemp;
  29. usData0<<=1;
  30. }
  31. elseif(ucCounter==16)
  32. {
  33. usData0|=(uint16)ucTemp;
  34. }
  35. elseif(ucCounter<32)
  36. {
  37. usData1|=(uint16)ucTemp;
  38. usData1<<=1;
  39. }
  40. elseif(ucCounter==32)
  41. {
  42. usData1|=(uint16)ucTemp;
  43. flag=0;
  44. OSSemPost(Sem);//发送信号量,进行码制转换任务,我的任务只是简单的实现了判断解码是否成功。
  45. }
  46. }
  47. }



评论


相关推荐

技术专区

关闭