项目场景:
无刷电机FOC控制,配置通用定时器TIM4为霍尔输入检测。
控制平台,国民N32G435CBL7。
问题描述
端口配置:
/* Hall port configuration. */GPIO_InitStructure.Pin = GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8;GPIO_InitStructure.GPIO_Current = GPIO_DC_2mA;GPIO_InitStructure.GPIO_Slew_Rate = GPIO_Slew_Rate_High;//Default HighGPIO_InitStructure.GPIO_Pull = GPIO_Pull_Up;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Input;GPIO_InitStructure.GPIO_Alternate = GPIO_AF2_TIM4;GPIO_InitPeripheral(GPIOB, &GPIO_InitStructure);
TIM4配置:
/* Check RCC_Configuration()Enable TIM4 Clock, GPIO, AFIORCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_TIM4, ENABLE);RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_GPIOB | RCC_APB2_PERIPH_AFIO, ENABLE);
*//* TIM4 Configuration */TIM_DeInit(TIM4);/* Time Base configuration */TIM_InitTimBaseStruct(&TIM_TimeBaseStructure);TIM_TimeBaseStructure.Prescaler = 0;TIM_TimeBaseStructure.CntMode = TIM_CNT_MODE_UP;TIM_TimeBaseStructure.Period = APB1_CLK_FREQ / 1000000 * 2000;//Notice calculation procedure to avoid overflow.TIM_TimeBaseStructure.ClkDiv = 0;TIM_TimeBaseStructure.RepetCnt = 0;TIM_InitTimeBase(TIM4, &TIM_TimeBaseStructure);TIM_ICInitType TIM_ICInitStructure; TIM_InitIcStruct(&TIM_ICInitStructure);TIM_ICInitStructure.Channel = TIM_CH_1;TIM_ICInitStructure.IcPolarity = TIM_IC_POLARITY_RISING;TIM_ICInitStructure.IcSelection = TIM_IC_SELECTION_TRC;TIM_ICInitStructure.IcPrescaler = TIM_IC_PSC_DIV1;TIM_ICInitStructure.IcFilter = 0x0;TIM_ICInit(TIM4, &TIM_ICInitStructure);
//Adjust to TIM_IC_POLARITY_BOTHEDGE
// TIM4->CCEN &= (uint32_t) ~((uint32_t)TIM_CCEN_CC1EN);
// TIM4->CCMOD1 |= 0x0003;
// TIM4->CCEN |= 0x000A;
// TIM4->CCEN |= ((uint32_t)TIM_CCEN_CC1EN);/* TIM4 Input Capture configuration */TIM_SelectHallSensor(TIM4, ENABLE);//XOR(CC1,CC2,CC3)->TI1F_EDTIM_SelectInputTrig(TIM4, TIM_TRIG_SEL_TI1F_ED);TIM_SelectSlaveMode(TIM4, TIM_SLAVE_MODE_RESET);TIM_SelectMasterSlaveMode(TIM4, TIM_MASTER_SLAVE_MODE_ENABLE);/* Clear Timer Interrupt Pending Bit */TIM_ClrIntPendingBit(TIM4,TIM_INT_TRIG);/* Enable Timer Interrupt */TIM_ConfigInt(TIM4,TIM_INT_TRIG,ENABLE);TIM_ConfigInt(TIM4,TIM_INT_UPDATE,ENABLE);/* Enable TIM4 */TIM_Enable(TIM4,ENABLE);
初版代码
TIM_ICInitStructure.IcPolarity = TIM_IC_POLARITY_BOTHEDGE;
双边沿检测,编译可以通过,但代码会卡死,进入TIM_ICInit,发现初始化函数只支持TIM4进行单边沿检测。
/**
* @brief Initializes the TIM peripheral according to the specified
* parameters in the TIM_ICInitStruct.
* @param TIMx where x can be 1 to 8 except 6 and 7 to select the TIM peripheral.
* @param TIM_ICInitStruct pointer to a TIM_ICInitType structure
* that contains the configuration information for the specified TIM peripheral.
*/
void TIM_ICInit(TIM_Module* TIMx, TIM_ICInitType* TIM_ICInitStruct)
{/* Check the parameters */assert_param(IsTimCh(TIM_ICInitStruct->Channel));assert_param(IsTimIcSelection(TIM_ICInitStruct->IcSelection));assert_param(IsTimIcPrescaler(TIM_ICInitStruct->IcPrescaler));assert_param(IsTimInCapFilter(TIM_ICInitStruct->IcFilter));if ((TIMx == TIM1) || (TIMx == TIM8) || (TIMx == TIM2) || (TIMx == TIM3) || (TIMx == TIM4) || (TIMx == TIM5) || (TIMx == TIM9)){assert_param(IsTimIcPalaritySingleEdge(TIM_ICInitStruct->IcPolarity));}else{assert_param(IsTimIcPolarityAnyEdge(TIM_ICInitStruct->IcPolarity));}if (TIM_ICInitStruct->Channel == TIM_CH_1){assert_param(IsTimList8Module(TIMx));/* TI1 Configuration */ConfigTI1(TIMx, TIM_ICInitStruct->IcPolarity, TIM_ICInitStruct->IcSelection, TIM_ICInitStruct->IcFilter);/* Set the Input Capture Prescaler value */TIM_SetInCap1Prescaler(TIMx, TIM_ICInitStruct->IcPrescaler);}else if (TIM_ICInitStruct->Channel == TIM_CH_2){assert_param(IsTimList6Module(TIMx));/* TI2 Configuration */ConfigTI2(TIMx, TIM_ICInitStruct->IcPolarity, TIM_ICInitStruct->IcSelection, TIM_ICInitStruct->IcFilter);/* Set the Input Capture Prescaler value */TIM_SetInCap2Prescaler(TIMx, TIM_ICInitStruct->IcPrescaler);}else if (TIM_ICInitStruct->Channel == TIM_CH_3){assert_param(IsTimList3Module(TIMx));/* TI3 Configuration */ConfigTI3(TIMx, TIM_ICInitStruct->IcPolarity, TIM_ICInitStruct->IcSelection, TIM_ICInitStruct->IcFilter);/* Set the Input Capture Prescaler value */TIM_SetInCap3Prescaler(TIMx, TIM_ICInitStruct->IcPrescaler);}else{assert_param(IsTimList3Module(TIMx));/* TI4 Configuration */ConfigTI4(TIMx, TIM_ICInitStruct->IcPolarity, TIM_ICInitStruct->IcSelection, TIM_ICInitStruct->IcFilter);/* Set the Input Capture Prescaler value */TIM_SetInCap4Prescaler(TIMx, TIM_ICInitStruct->IcPrescaler);}
}
实测配置为上升沿检测霍尔状态也能正常检测。
或者尝试通过寄存器直接配置为双边沿,上面代码中在
TIM_ICInit(TIM4, &TIM_ICInitStructure);之后有如下被注释代码颗进行双边沿配置。
//Adjust to TIM_IC_POLARITY_BOTHEDGE
// TIM4->CCEN &= (uint32_t) ~((uint32_t)TIM_CCEN_CC1EN);
// TIM4->CCMOD1 |= 0x0003;
// TIM4->CCEN |= 0x000A;
// TIM4->CCEN |= ((uint32_t)TIM_CCEN_CC1EN);
具体参考用户手册。
论坛发现STM32双边沿检测也有类似的问题,需要在硬件设计中注意,且在代码中进行必要调整。
解决方案:
如上代码。