xld0932

  • 20 主题
  • 35 帖子
  • 1472 积分
  • 身份:LV4 高级技术员
  • 论坛新秀
  • E币:1236

NUCLEO-L412KB使用外部中断和定时器解析红外数据

2019-5-22 19:21:35 显示全部楼层
1.概述

使用NUCLEO-L412开发板板载STM32L412KB的外部中断功能和定时器功能实现对红外数据的解析。通过这个项目掌握外部中断和定时器的使用,同时对红外数据、NEC协议有个大概的了解。


红外通讯的协议有很多,我们这个项目解析的是NEC遥控指令,其数据格式由同步码、地址码、地址反码、控制码、控制反码,5个部分组成。同步码由一个9ms的低电平和一个4.5ms的高电平组成。地址码、地址反码、控制码、控制反码都8位的数据格式,按照低位在前、高们在后的顺序发送。而使用反码的原因则是为了增加通讯传输的可靠性,对数据结果有一个简单的校验。红外NEC协议编码说明如下图所示:


6.png



2.硬件连接

4.jpg

说明:
将IR接收模块的数据引脚连接到NUCLEO-L412KB开发的D9引脚,即PA8;其它两根线分别连接V3.3和GND引脚。

3.STM32CubeMX设置

1.png 2.png 3.png

说明:
使用PA8引脚的外部中断复用功能,中断模式设置为下降沿触发,并使能外部触发中断。打开TIM6的定时器功能,用于对外部触发间的间隔时间采集,定时单位为0.1毫秒。

4.主要程序

  1. /* Private variables --------------------------------------------------------*/
  2. volatile uint16_t IR_CYCLE[33];
  3. volatile uint8_t  IR_RCVOK = 0;
  4. volatile uint8_t  IR_START = 0;
  5. volatile uint8_t  IR_INDEX = 0;
  6. volatile uint16_t IR_COUNT = 0;
  1. /**
  2. * @brief  : This function handles EXTI line[9:5] interrupts.
  3. * @param  :
  4. * @returns:
  5. * @details:
  6. */
  7. void EXTI9_5_IRQHandler(void)
  8. {
  9.     uint16_t IR_CycleTime;

  10.     if(IR_START)
  11.     {
  12.         IR_CycleTime = IR_COUNT;

  13.         if((IR_CycleTime < 140) && (IR_CycleTime >= 50))
  14.         {
  15.             IR_INDEX = 0;
  16.         }

  17.         IR_CYCLE[IR_INDEX++] = IR_CycleTime;

  18.         IR_COUNT = 0;

  19.         if(IR_INDEX == 33)
  20.         {
  21.             IR_START = 0;
  22.             IR_RCVOK = 1;
  23.         }
  24.     }
  25.     else
  26.     {
  27.         IR_COUNT = 0;
  28.         IR_INDEX = 0;
  29.         IR_START = 1;
  30.     }

  31.     HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8);
  32. }


  33. volatile uint32_t TIM6_Tick = 0;


  34. /**
  35. * @brief  : This function handles TIM6 global interrupt.
  36. * @param  : 0.1ms
  37. * @returns:
  38. * @details:
  39. */
  40. void TIM6_IRQHandler(void)
  41. {
  42.     IR_COUNT++;

  43.     HAL_TIM_IRQHandler(&htim6);
  44. }
  1. /**
  2. * @brief  :
  3. * @param  :
  4. * @returns:
  5. * @details:
  6. */
  7. void IR_Parsing(void)
  8. {
  9.     uint8_t i = 0, j = 0, k = 1;

  10.     if(IR_RCVOK)
  11.     {
  12.         IR_RCVOK = 0;
  13.         memset(IR_DATA, 0, sizeof(IR_DATA));

  14.         for(i = 0; i < 4; i++)
  15.         {
  16.             for(j = 0; j < 8; j++, k++)
  17.             {
  18.                 if((IR_CYCLE[k] >= 9) && (IR_CYCLE[k] < 14))
  19.                 {
  20.                     IR_DATA[i] &= ~(0x1 << j);
  21.                 }
  22.                 else if((IR_CYCLE[k] >= 20) && (IR_CYCLE[k] < 25))
  23.                 {
  24.                     IR_DATA[i] |=  (0x1 << j);
  25.                 }
  26.             }
  27.         }

  28.         printf("\r\nIR Data : 0x%02x, 0x%02x, 0x%02x, 0x%02x",
  29.                IR_DATA[0], IR_DATA[1], IR_DATA[2], IR_DATA[3]);
  30.     }
  31. }


5.运行结果

5.png

说明:
在程序上电启动后,依次按下红外遥控器的各个按键。在MCU接收到红外数据后,对接收的数据进行解析,并将解析结果通过串口打印输出。输出的数据为NEC数据格式,分别为地址码、地址反码、控制码、控制反码。

6.工程代码

IR_NEC.part03.rar (5.66 MB, 下载次数: 3)