[STM32CubeMX Learning] Timer input capture reads infrared NEC code

1. Introduction to NEC coding

NEC Protocol is the code of infrared remote control widely used at present. Its carrier frequency is 38khz, that is, it can generate 38000 pulses per second, and each pulse period is: 1000000us/38000=26.3us.

The NEC protocol uses pulse intervals to encode each bit of data, and uses the time intervals of different data bits to represent different logical bits.

The high-order bit of the sent data comes first.

Note: The remote control receiver is at low level when it receives a pulse, and at high level when it is idle .

Logic "0": 562.5µs active pulse + 562.5µs idle interval, for a total duration of 1.125ms.

Logic "1": 562.5µs active pulse + 1.6875ms idle interval, for a total duration of 2.25ms.

Start bit: valid pulse of 9ms + idle interval of 4.5ms, the total duration is 13.5ms.

 Based on this, NEC sends a frame of data: start bit + address code + address code inverse + command code + command code inverse

 Repeat code: When you keep pressing a button, after sending a frame of data, a repeat code will be sent every 110ms.

9ms active pulse + 2.25ms idle interval, the total duration is 11.25ms.

 2. STM32CubeMX configuration

The schematic diagram is as follows:

The STM32CubeMX configuration is as follows:

The frequency division factor is 71, and the main frequency is 72mhz, so the timer frequency is 72mhz/(71+1)=1mhz, that is, it counts once every 1µs.

The counting method is counting up.

The autoload value is the maximum value of 65535, which will overflow in 65.535µs, which is greater than all logic bits, so don't worry about overflow.

Enable autoloading.

Falling edge trigger.

 

 Enable interrupt, pin set pull-up.

3. Code analysis NEC code

Start input capture after TIM3 initialization

  /* USER CODE BEGIN TIM3_Init 2 */
  
  HAL_TIM_IC_Start_IT(&htim3, TIM_CHANNEL_3); //启动输入捕获

  /* USER CODE END TIM3_Init 2 */

 define global variables

uint16_t IRTimer_Data = 0;//存放计数值
uint32_t IRCode = 0;//存放红外码
uint8_t IR_Flag = 0;//IR解析完成标志位
uint8_t IR_LeaderCode = 0;

Interrupt processing function and analysis function

/* USER CODE BEGIN 4 */
void Paser_IRCode(uint16_t PData)
{  
  if((PData>12000)&&(PData<15000))//获得引导码,理论值13500
    IR_LeaderCode = 1;

  if(IR_LeaderCode==1)
  {
    if((PData>1000)&&(PData<1300))//0,理论值1125
    {
      IRCode=(IRCode<<1);
      i++;
    }
    else if((PData>2000)&&(PData<2500))//1,理论值2250
    {
      IRCode = (IRCode<<1)|0x01;
      i++;
    }
    if(i==32)
    {
      i = 0;
      IR_LeaderCode = 0;
      IR_Flag = 1;
    }
  }
}

void TIM_IRQHandler(void)
{	
    IRTimer_Data = HAL_TIM_ReadCapturedValue(&htim3,TIM_CHANNEL_3);//获取当前的捕获值. 
    __HAL_TIM_SET_COUNTER(&htim3,0);   //设置计数寄存器的值变为0
    Paser_IRCode(IRTimer_Data);
}

Remember to put the function into the interrupt function

void TIM3_IRQHandler(void)
{
  /* USER CODE BEGIN TIM3_IRQn 0 */
  
  /* USER CODE END TIM3_IRQn 0 */
  TIM_IRQHandler();
  /* USER CODE BEGIN TIM3_IRQn 1 */
  
  /* USER CODE END TIM3_IRQn 1 */
}

Print the NEC code in the main function

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
    
    if(IR_Flag ==1) 
    {
      printf("%08x\r\n",IRCode);
      IR_Flag = 0;
    }

  }
  /* USER CODE END 3 */

The result of pressing button 1 on the remote control is as follows. It can be seen that the address code is 0x00, the inverse of the address is 0xff, the command code is 0x68, and the inverse of the command is 0x97.

Guess you like

Origin blog.csdn.net/weixin_46183891/article/details/123455852