空间规划科 发表于 2022-6-30 09:46

定时器:霍尔传感器接口与六步算法

实现结果本文的目的是 实现下图所示。
(文档这个图是错的,霍尔信号和CCR2的位置不对,先将就着)
声明由于实验室缺少电机,所以咱用另一块板子timer3模拟霍尔信号TIH1、TIH2、TIH3出来。

空间规划科 发表于 2022-6-30 09:50

* 模拟霍尔信号
代码如下:
/*******************************************************************************
* @name : initTIM3
* @brief : init TIM3
* @param : u16 arr, u16 arr
* @retval : void
*******************************************************************************/
void initTIM3(u16 psc, u16 arr)
{
    TIM_TimeBaseInitTypeDef TIM_StructInit;
    GPIO_InitTypeDef GPIO_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
   
    TIM_DeInit(TIM3);
   
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;                      // TIM3 CH1/2
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                                                   
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;                                 // TIM3 CH3
    GPIO_Init(GPIOB, &GPIO_InitStructure);
   
    TIM_StructInit.TIM_Prescaler = psc;                                       // set Prescaler: psc + 1
    TIM_StructInit.TIM_Period = arr;                                          // set Period: arr + 1
    TIM_StructInit.TIM_ClockDivision = TIM_CKD_DIV1;                            // set ClockDivision :0                        
    TIM_StructInit.TIM_CounterMode = TIM_CounterMode_Up;                                             
    TIM_TimeBaseInit(TIM3, &TIM_StructInit);   
   
    TIM_CCPreloadControl(TIM3, ENABLE);                                       // Enable ARR preload
    TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);                                  // Enable update interrupt
   
    NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_InitStructure);

        TIM_Cmd(TIM3, ENABLE);
}

空间规划科 发表于 2022-6-30 09:53

配置好定时器3后,模拟信号:

空间规划科 发表于 2022-6-30 09:55

/*******************************************************************************
* @name : simMotorPrepareCommutation
* @brief :simulate hall Input
* @param : void
* @retval : void
*******************************************************************************/
void simMotorPrepareCommutation(void)
{
    if (gSimStep == 1){
      // Step 1 Configuration
      CH1ON;
      CH2OFF;
      CH3OFF;
      gSimStep++;
    }
    else if (gSimStep == 2){
      // Step 2 Configuration
      CH1ON;
      CH2ON;
      CH3OFF;
      gSimStep++;
    }
    else if (gSimStep == 3){
      // Step 3 Configuration
      CH1ON;
      CH2ON;
      CH3ON;
      gSimStep++;
    }
    else if (gSimStep == 4){
      // Step 4 Configuration
      CH1OFF;
      CH2ON;
      CH3ON;
      gSimStep++;
    }
    else if (gSimStep == 5){
      // Step 5 Configuration
      CH1OFF;
      CH2OFF;
      CH3ON;
      gSimStep++;
    }
    else{
      // Step 6 Configuration      
      CH1OFF;
      CH2OFF;
      CH3OFF;
      gSimStep = 1;
    }   
}

空间规划科 发表于 2022-6-30 10:31

通过中断调度

空间规划科 发表于 2022-6-30 10:35

/*******************************************************************************
* @name : TIM3_IRQHandler
* @brief :
* @param : void
* @retval : void
*******************************************************************************/
void TIM3_IRQHandler(void)
{      
    if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) {
      TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
      simMotorPrepareCommutation();
    }
}

空间规划科 发表于 2022-6-30 10:36

/*
--------------------------------------------------------------------------------
      TIM2 (hall timer)            |    TIM3 (Simulate the hall output)
--------------------------------------------------------------------------------
   PA_0: hall input channel1   |   PA_6 (TIM3_CH1)
--------------------------------------------------------------------------------
   PA_1: hall input channel2   |   PA_7 (TIM3_CH2)
--------------------------------------------------------------------------------
   PA_2: hall input channel3   |   PB_0 (TIM3_CH3)
--------------------------------------------------------------------------------
NOTE: if use TIM3 simulate, In order to achieve better results, please use anot-
her board to output and the main function just only init TIM3 and its parameter.
*/


int main(void)
{
        //....
    initTIM3(0x0, 0xFFFF);
   
    //.....
}

空间规划科 发表于 2022-6-30 10:38

MB024引脚图

空间规划科 发表于 2022-6-30 10:38

空间规划科 发表于 2022-6-30 10:40

好吧,接上逻辑分析仪看看:

空间规划科 发表于 2022-6-30 10:40

结果:

空间规划科 发表于 2022-6-30 10:43

没问题就可以进入正文。

正文
配置霍尔输入定时器配置:

空间规划科 发表于 2022-6-30 10:44


void initHallTimer2()
{
    TIM_TimeBaseInitTypeDef pBase;
    TIM_OCInitTypeDef       pOC;
    TIM_ICInitTypeDef       pIC;
   
    COMMON_EnableIpClock(emCLOCK_TIM2);
    COMMON_NVIC_Configure(TIM2_IRQn, 1, 1);
    GPIO_TIMER2_HALL_INPUT_Configure();
   
    TIM_DeInit(TIM2);
    TIM_TimeBaseStructInit(&pBase);
    pBase.TIM_Period      = 0xFFFF;
    pBase.TIM_Prescaler   = 0;
    pBase.TIM_CounterMode   = TIM_CounterMode_Up;
    pBase.TIM_ClockDivision = TIM_CKD_DIV1;
    pBase.TIM_RepetitionCounter = 0;
    TIM_TimeBaseInit(TIM2, &pBase);
   
    TIM_OCStructInit(&pOC);
    pOC.TIM_Pulse         = 0x1;
    pOC.TIM_OCMode          = TIM_OCMode_PWM2;
    pOC.TIM_OutputState   = TIM_OutputState_Enable;
    pOC.TIM_OCPolarity      = TIM_OCPolarity_High;
    TIM_OC2Init(TIM2, &pOC);
    TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE); // Add OC2 handle to reduce delay
   
    TIM_SelectHallSensor(TIM2, ENABLE);
    pIC.TIM_Channel   = TIM_Channel_1;
    pIC.TIM_ICPolarity= TIM_ICPolarity_Rising;
    pIC.TIM_ICSelection = TIM_ICSelection_TRC;
    pIC.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    pIC.TIM_ICFilter    = 0x0;
    TIM_ICInit(TIM2, &pIC);
    TIM_SelectInputTrigger(TIM2, TIM_TS_TI1F_ED);
    TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);
    TIM_SelectOutputTrigger(TIM2, TIM_TRIGSource_OC2Ref);
   
    TIM_Cmd(TIM2, ENABLE);
}

空间规划科 发表于 2022-6-30 10:47

调度:
/* /
|---------|--------------------------------------------------------------------|
| PA_0    |   _|- - -|_ _ _|- - -| _ _ _                                       |
|         |                                                                  |
| PA_1    |   _ _|- - -|_ _ _|- - -| _ _                                       |
|         |                                                                  |
| PA_2    |   _ _ _|- - -|_ _ _|- - -| _                                       |
|---------+--------------------------------------------------------------------|
|pos value||0 1 3 7 6 4|0 1 3 7 6 4|..                                       |
|------------------------------------------------------------------------------|
*///
void TIM2_IRQHandler(void)
{      
    if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET) {
      TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
      /* Calculate motor speed or else with CCR1 values */
      HallCCR1 = TIM_GetCapture1(TIM2);
      
      /* get step position by PA_0 / PA_1 / PA_2 */
      HallPos = (GPIO_ReadInputData(GPIOA)) & 0x0007;
      
      /* Step Motor commutation*/
      BLDCMotorPrepareCommutation(HallPos, TIM_OCMode_PWM1, TIM_OCMode_PWM1);
    }
}

空间规划科 发表于 2022-6-30 10:53


/// @briefMain function, program entry.
/// @paramNone.
/// @retval None.

int main(void)
{
        MCUID = SetSystemClock(emSYSTICK_On, AppTaskTick);
   
    initHallTimer2();
    initMotorTimer1(0, 999);
   
    while(1){
      
    }
}

空间规划科 发表于 2022-6-30 10:54


/// @briefMain function, program entry.
/// @paramNone.
/// @retval None.

int main(void)
{
        MCUID = SetSystemClock(emSYSTICK_On, AppTaskTick);
   
    initHallTimer2();
    initMotorTimer1(0, 999);
   
    while(1){
      
    }
}

空间规划科 发表于 2022-6-30 12:29


/// @briefMain function, program entry.
/// @paramNone.
/// @retval None.

int main(void)
{
        MCUID = SetSystemClock(emSYSTICK_On, AppTaskTick);
   
    initHallTimer2();
    initMotorTimer1(0, 999);
   
    while(1){
      
    }
}

空间规划科 发表于 2022-6-30 12:29

出来这个玩意?这肯定是前面步进值没算好。继续修改

空间规划科 发表于 2022-6-30 12:31

空间规划科 发表于 2022-6-30 12:32


void BLDCMotorPrepareCommutation(u8 pos, TIMOCMODE_Typedef TIM_CHxMode, TIMOCMODE_Typedef TIM_CHxNMode)
{
    if (pos == 0){
      /* Channel1 configuration: CH1 output: PWM */
      TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_CHxMode);
      TIM_CCxCmd      (TIM1, TIM_Channel_1, TIM_CCx_Enable);
      TIM_CCxNCmd   (TIM1, TIM_Channel_1, TIM_CCxN_Disable);
      
      /* Channel2 configuration: CH2N output: PWM */
      TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_CHxNMode);
      TIM_CCxCmd      (TIM1, TIM_Channel_2, TIM_CCx_Disable);
      TIM_CCxNCmd   (TIM1, TIM_Channel_2, TIM_CCxN_Enable);
      
      /* Channel3 configuration: CH3 None */
      TIM_CCxCmd      (TIM1, TIM_Channel_3, TIM_CCx_Disable);
      TIM_CCxNCmd   (TIM1, TIM_Channel_3, TIM_CCxN_Disable);
    }
    else if (pos == 1){
      /*Channel1 configuration: CH1 output: PWM */
      TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_CHxMode);
      TIM_CCxCmd      (TIM1, TIM_Channel_1, TIM_CCx_Enable);
      TIM_CCxNCmd   (TIM1, TIM_Channel_1, TIM_CCxN_Disable);
      
      /*Channel2 configuration: CH2 None */
      TIM_CCxCmd      (TIM1, TIM_Channel_2, TIM_CCx_Disable);
      TIM_CCxNCmd   (TIM1, TIM_Channel_2, TIM_CCxN_Disable);
      
      /*Channel3 configuration: CH3N output: PWM */
      TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_CHxNMode);
      TIM_CCxCmd      (TIM1, TIM_Channel_3, TIM_CCx_Disable);
      TIM_CCxNCmd   (TIM1, TIM_Channel_3, TIM_CCxN_Enable);
    }
    else if (pos == 3){
      /* Channel1 configuration: CH1 None */
      TIM_CCxCmd      (TIM1, TIM_Channel_1, TIM_CCx_Disable);
      TIM_CCxNCmd   (TIM1, TIM_Channel_1, TIM_CCxN_Disable);
      
      /* Channel2 configuration: CH2 output: PWM */
      TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_CHxMode);
      TIM_CCxCmd      (TIM1, TIM_Channel_2, TIM_CCx_Enable);
      TIM_CCxNCmd   (TIM1, TIM_Channel_2, TIM_CCxN_Disable);
      
      /* Channel3 configuration: CH3N output: PWM */
      TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_CHxNMode);
      TIM_CCxCmd (TIM1, TIM_Channel_3, TIM_CCx_Disable);
      TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Enable);
    }
    else if (pos == 7){
      /* Channel1 configuration: CH1N output: PWM */
      TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_CHxNMode);
      TIM_CCxCmd (TIM1, TIM_Channel_1, TIM_CCx_Disable);
      TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Enable);
      
      /* Channel2 configuration: CH2 output: PWM */
      TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_CHxMode);
      TIM_CCxCmd (TIM1, TIM_Channel_2, TIM_CCx_Enable);
      TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Disable);
      
      /* Channel3 configuration: CH3 None */
      TIM_CCxCmd (TIM1, TIM_Channel_3, TIM_CCx_Disable);
      TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Disable);
    }
    else if (pos == 6){
      /* Channel1 configuration: CH1N output: PWM */
      TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_CHxNMode);
      TIM_CCxCmd (TIM1, TIM_Channel_1, TIM_CCx_Disable);
      TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Enable);
      
      /* Channel2 configuration: CH2 None */
      TIM_CCxCmd (TIM1, TIM_Channel_2, TIM_CCx_Disable);
      TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Disable);
      
      /* Channel3 configuration: CH3 output: PWM */
      TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_CHxMode);
      TIM_CCxCmd (TIM1, TIM_Channel_3, TIM_CCx_Enable);
      TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Disable);
    }
    else if (pos == 4){   
      /* Channel1 configuration: CH1 None */
      TIM_CCxCmd (TIM1, TIM_Channel_1, TIM_CCx_Disable);
      TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Disable);
      
      /* Channel2 configuration: CH2N output: PWM */
      TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_CHxNMode);
      TIM_CCxCmd (TIM1, TIM_Channel_2, TIM_CCx_Disable);
      TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Enable);
      
      /* Channel3 configuration: CH3 output: PWM */
      TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_CHxMode);
      TIM_CCxCmd (TIM1, TIM_Channel_3, TIM_CCx_Enable);
      TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Disable);
    }
}
页: [1] 2
查看完整版本: 定时器:霍尔传感器接口与六步算法