原创 DMA输入捕获红外线解码

2020-5-10 15:09 4106 63 4 分类: MCU/ 嵌入式

DMA 方式,TIM输入捕获,红外线解码

当前系统时钟为48MHz 将预分频到0.1mS 也就是除4800

DMA 打开,设置为存储器增加。模式可以用线性模式,更加方便。

定义一个结构体,用于存储采集的数据。

typedef union{

  uint32_t data32b[32];

  uint16_t data16b[64];

}unICData;

 

unICData ICData;

 

HAL_TIM_IC_Start_DMA(&htim5,TIM_CHANNEL_4,ICData.data32b,260);

采集到的数据可以从live watch看到

可以将数据导出存成文本文件。并导入matlabexcel

将数据前后相减,就知道脉冲间距了。

  Columns 1 through 18

 

    51    12    22    23    22    11    12    11    11    12    22    23    22    11    12    11    11    12

 

  Columns 19 through 33

 

    11    22    23    11    11    12    11    23    22    12    11    22    23    22    23

 

明显: 最长的是先导码,第一个51 11/12 长的为0码,22/23长的为1码。所以上述指令解码为:

01110000 01110000  00110000 11001111  32位数据 707030CF

 

一种可能的解码方法。将TIM 通道设置为输入捕获中断。在第一个中断时启动DMA采集。在最后一个中断发生时,分析DMA采集的数据。判断头部,获取数据码。
解码程序如下:
void IREncoder(void){
  static uint16_t CurCnt,PreCnt;
  static uint8_t stt=0;
  uint8_t temp;
  static uint32_t RsvCode; 
  CurCnt = __HAL_TIM_GET_COMPARE(&htim5,TIM_CHANNEL_4);
  if(CurCnt > PreCnt)
      temp = CurCnt - PreCnt;
    else
      temp = 65525 - PreCnt + CurCnt;
  if(stt = 0){       
    if((temp >= 48)&&(temp <= 53)){
      stt = 1;   // 找到头
      RsvCode = 0;
    }
    }
  else{
    stt ++;
    RsvCode <<= 1;
    if((temp >= 10)&&(temp <= 13)){
      RsvCode += 0;
    }
    else
      RsvCode += 1;
    if(stt >= 32){
      stt = 0;        
    }      
  }
}

作者: southcreek, 来源:面包板社区

链接: https://mbb.eet-china.com/blog/uid-me-408807.html

版权声明:本文为博主原创,未经本人允许,禁止转载!

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
63
关闭 站长推荐上一条 /3 下一条