cube MX IR 遥控器解码程序 请教 ?

2019-07-21 00:39发布

cube MX 遥控器解码程序 请教 ??

中断程序可以进入到 HAL_TIM_IC_CaptureCallback  这个函数里面,只是获取到数据不对,

望高人指点指点看看是哪里设置不对 ???

硬件连接 PB0

单片机频率:168MHz

程序如下 :

#define IR_REPEAT_SEND_EN  1 /* 连发使能 */
#define IR_REPEAT_FILTER  10 /* 遥控器108ms 发持续按下脉冲, 连续按下1秒后启动重发 */
TIM_HandleTypeDef      TimHandle3_Ir;
/* Timer Input Capture Configuration Structure declaration */
TIM_IC_InitTypeDef     sICConfig_Ir;
IRD_T g_tIR;
/* Capture index */
uint16_t               uhCaptureIndex = 0;


void HAL_TIM_IC_MspInit(TIM_HandleTypeDef *htim)
{
  GPIO_InitTypeDef   GPIO_InitStruct;

  /*##-1- Enable peripherals and GPIO Clocks #################################*/
  /* TIMx Peripheral clock enable */
  __HAL_RCC_TIM3_CLK_ENABLE();
    
  /* Enable GPIO channels Clock */
  __GPIOB_CLK_ENABLE();
  
  /* Configure  (TIMx_Channel) in Alternate function, push-pull and 100MHz speed */
  GPIO_InitStruct.Pin = GPIO_PIN_0;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;    /* 上下拉电阻不使能 外接5V 上啦电阻 */
  GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
  GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  /*##-2- Configure the NVIC for TIMx ########################################*/
  /* Set the TIMx priority */
  HAL_NVIC_SetPriority(TIM3_IRQn, 0, 1);
  
  /* Enable the TIMx global Interrupt */
  HAL_NVIC_EnableIRQ(TIM3_IRQn);
}


void IRD_TIM_IC_MspInit(void)
{
  uint16_t uwPrescalerValue = 0;
  __IO uint32_t freq = HAL_RCC_GetSysClockFreq();
  
  /*##-1- Configure the TIM peripheral #######################################*/ 
  /* Set TIMx instance */
  TimHandle3_Ir.Instance = TIM3;
  /* //预分频数,定时器主频=系统频率/2/分频系数-1,即一个时钟脉冲为1us */
  uwPrescalerValue = (uint32_t) ((freq / 2) / 1000000) - 1;  
  
  TimHandle3_Ir.Init.Period            = 10;      // 10us 中断一次
  TimHandle3_Ir.Init.Prescaler         = uwPrescalerValue;    // 遥控器解码与分频系数设置,1us
  TimHandle3_Ir.Init.ClockDivision     = 0;
  TimHandle3_Ir.Init.CounterMode       = TIM_COUNTERMODE_UP;
  TimHandle3_Ir.Init.RepetitionCounter = 0;
    
  if(HAL_TIM_IC_Init(&TimHandle3_Ir) != HAL_OK)
  {
    printf(" TIM IC IR Init Error ...");
  }
  
  /*##-2- Configure the Input Capture channel ################################*/ 
  /* Configure the Input Capture of channel 2 */
  sICConfig_Ir.ICPolarity  = TIM_ICPOLARITY_BOTHEDGE;
  sICConfig_Ir.ICSelection = TIM_ICSELECTION_DIRECTTI;
  sICConfig_Ir.ICPrescaler = TIM_ICPSC_DIV1;
  sICConfig_Ir.ICFilter    = 0;   
  if(HAL_TIM_IC_ConfigChannel(&TimHandle3_Ir, &sICConfig_Ir, TIM_CHANNEL_3) != HAL_OK)
  {
    /* Configuration Error */
    printf(" TIM IC IR Init Error ...");
  }  
  
  /*##-3- Start the Input Capture in interrupt mode ##########################*/
  if(HAL_TIM_IC_Start_IT(&TimHandle3_Ir, TIM_CHANNEL_3) != HAL_OK)
  {
    /* Starting Error */
    printf(" TIM IC IR Init Error ...");
  }  
  
g_tIR.LastCapture = 0; 
g_tIR.FinishFlag = 0;
g_tIR.RepeatFlag = 0;
g_tIR.Status = 0;
}


void IRD_DispValume(void)
{
  if(g_tIR.FinishFlag == TRUE)
  {
      printf(" IR User Code: 0x%02X%02X ", g_tIR.RxBuf[0],g_tIR.RxBuf[1]);
      printf(" IR Data Code: 0x%02X%02X ", g_tIR.RxBuf[2],g_tIR.RxBuf[3]);
      
   g_tIR.FinishFlag = FALSE;
  } 
}

/*
*********************************************************************************************************
* 函 数 名: IRD_DecodeNec
* 功能说明: 按照NEC编码格式实时解码
* 形    参: _width 脉冲宽度,单位 10us
* 返 回 值: 无
*********************************************************************************************************
*/
void IRD_DecodeNec(uint16_t _width)
{
static uint16_t s_LowWidth;
static uint8_t s_Byte;
static uint8_t s_Bit;
uint16_t TotalWitdh;

/* NEC 格式 (5段)
  1、引导码  9ms低 + 4.5ms高
  2、低8位地址码  0=1.125ms  1=2.25ms    bit0先传
  3、高8位地址码  0=1.125ms  1=2.25ms
  4、8位数据      0=1.125ms  1=2.25ms
  5、8为数码反码  0=1.125ms  1=2.25ms
*/
loop1: 
switch (g_tIR.Status)
{
  case 0:   /* 929 等待引导码低信号  7ms - 11ms */
   if ((_width > 700) && (_width < 1100))
   {
    g_tIR.Status = 1;
    s_Byte = 0;
    s_Bit = 0;
   }
   break;
  case 1:   /* 413 判断引导码高信号  3ms - 6ms */
   if ((_width > 313) && (_width < 600)) /* 引导码 4.5ms */
   {
    g_tIR.Status = 2;
   }
   else if ((_width > 150) && (_width < 250)) /* 2.25ms */
   {
    
    #if   (IR_REPEAT_SEND_EN  > 0)    // 连发功能开启  
     if (g_tIR.RepeatCount >= IR_REPEAT_FILTER)
     {
      g_tIR.RepeatFlag = TRUE;   //重复标志码置位
     }
     else
     {
      g_tIR.RepeatCount++;
     }
    #endif
     
    g_tIR.Status = 0; /* 复位解码状态 */
   }
   else
   {
    /* 异常脉宽 */
    g_tIR.Status = 0; /* 复位解码状态 */
   }
   break;
  
  case 2:   /* 低电平期间 0.56ms */
   if ((_width > 10) && (_width < 100))
   {  
    g_tIR.Status = 3;
    s_LowWidth = _width; /* 保存低电平宽度 */
   }
   else /* 异常脉宽 */
   {
    /* 异常脉宽 */
    g_tIR.Status = 0; /* 复位解码器状态 */ 
    goto loop1;  /* 继续判断同步信号 */
   }
   break;
  case 3:   /* 85+25, 64+157 开始连续解码32bit */      
   TotalWitdh = s_LowWidth + _width;
   /* 0的宽度为1.125ms,1的宽度为2.25ms */    
   s_Byte >>= 1;
   if ((TotalWitdh > 92) && (TotalWitdh < 132))
   {
    ;     /* bit = 0 */
   }
   else if ((TotalWitdh > 205) && (TotalWitdh < 245))
   {
    s_Byte += 0x80;  /* bit = 1 */
   } 
   else
   {
    /* 异常脉宽 */
    g_tIR.Status = 0; /* 复位解码器状态 */ 
    goto loop1;  /* 继续判断同步信号 */
   }
   
   s_Bit++;
   if (s_Bit == 8) /* 收齐8位 */
   {
    g_tIR.RxBuf[0] = s_Byte;
    s_Byte = 0;
   }
   else if (s_Bit == 16) /* 收齐16位 */
   {
    g_tIR.RxBuf[1] = s_Byte;
    s_Byte = 0;
   }
   else if (s_Bit == 24) /* 收齐24位 */
   {
    g_tIR.RxBuf[2] = s_Byte;
    s_Byte = 0;
   }
   else if (s_Bit == 32) /* 收齐32位 */
   {
    g_tIR.RxBuf[3] = s_Byte;
        
    if (g_tIR.RxBuf[2] + g_tIR.RxBuf[3] == 255) /* 检查校验 */
    {
     g_tIR.RepeatCount = 0; /* 重发计数器 */ 
      g_tIR.FinishFlag = TRUE;
    }
    
    g_tIR.Status = 0; /* 等待下一组编码 */
    break;
   }
   g_tIR.Status = 2; /* 继续下一个bit */
   break;      
}
}



void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
{
uint16_t NowCapture;
uint16_t Width;
  
  if (htim->Channel == HAL_TIM_ACTIVE_CHANNEL_3 )   // 中断程序可以进来,只是获取到数据不对,
  {
    /* Get the 1st Input Capture value */
    NowCapture = HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_3);
  

  if (NowCapture >= g_tIR.LastCapture)
  {
   Width = NowCapture - g_tIR.LastCapture;
  }
  else if (NowCapture < g_tIR.LastCapture) /* 计数器抵达最大并翻转 */
  {
   Width = ((0xFFFF - g_tIR.LastCapture) + NowCapture);
  }
    
  if ((g_tIR.Status == 0) && (g_tIR.LastCapture == 0))
  {
   g_tIR.LastCapture = NowCapture;
   return;
  }
    
  g_tIR.LastCapture = NowCapture; /* 保存当前计数器,用于下次计算差值 */
  
  IRD_DecodeNec(Width);  /* 解码 */

  }
}

void TIM3_IRQHandler(void)
{
  HAL_TIM_IRQHandler(&TimHandle3_Ir);
}




void main()

{

........
IRD_TIM_IC_MspInit();

  while (1)
  {

  IRD_DispValume();


  }

}

友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。