
本帖最后由 hpdell 于 2015-12-17 21:21 编辑 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("\r\nTIM 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("\r\nTIM 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("\r\nTIM 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("\r\nIR User Code: 0x%02X%02X ", g_tIR.RxBuf[0],g_tIR.RxBuf[1]); printf("\r\nIR 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(); } } |