【arm】国民N32G435通用定时器霍尔配置,双边沿输入捕获配置

项目场景:

无刷电机FOC控制,配置通用定时器TIM4为霍尔输入检测。

控制平台,国民N32G435CBL7。


问题描述

端口配置:

c 复制代码
    /* 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 High
    GPIO_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配置:

c 复制代码
/*  Check RCC_Configuration()
    Enable TIM4 Clock, GPIO, AFIO
        RCC_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_ED
    TIM_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进行单边沿检测。

c 复制代码
/**
* @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双边沿检测也有类似的问题,需要在硬件设计中注意,且在代码中进行必要调整。


解决方案:

如上代码。

相关推荐
小程同学>o<2 小时前
Linux 应用层开发入门(一)| ARM平台交叉编译入门:打造你的第一个Linux应用
linux·arm开发·linux应用层
切糕师学AI20 小时前
ARM 汇编指令:STM
汇编·arm开发·stm
切糕师学AI1 天前
ARM 汇编指令:LDM
汇编·arm开发
ShiMetaPi1 天前
GM-3568JHF丨ARM+FPGA异构开发板系列教程:外设教程 09 CAN
arm开发·fpga开发·fpga·rk3568
未来之窗软件服务1 天前
幽冥大陆(八十)Win7环境下ARM架构开发—东方仙盟练气期
arm开发·架构·仙盟创梦ide·东方仙盟
未来之窗软件服务2 天前
国产化系统(一)ARM轻量化系统开发与试用全指南—东方仙盟练气期
arm开发·仙盟创梦ide·东方仙盟·阿雪技术观·国产化操作系统
林政硕(Cohen0415)2 天前
ARM Linux Qt Widget 虚拟键盘输入法移植
linux·arm开发·qt·键盘·输入法
100编程朱老师3 天前
Linux 下互联网络编程的基础知识
arm开发
番茄灭世神4 天前
32位ARM单片机视频教程第一篇
arm开发·单片机·嵌入式·gd32·pn学堂
驱动探索者4 天前
[缩略语大全]之[ARM CPU]篇
arm开发