打印
[MM32硬件]

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

[复制链接]
1451|31
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
实现结果

本文的目的是 实现下图所示。

(文档这个图是错的,霍尔信号和CCR2的位置不对,先将就着)


声明

由于实验室缺少电机,所以咱用另一块板子timer3模拟霍尔信号TIH1、TIH2、TIH3出来。


使用特权

评论回复
沙发
空间规划科|  楼主 | 2022-6-30 09:50 | 只看该作者
* 模拟霍尔信号
代码如下:
/*******************************************************************************
* [url=home.php?mod=space&uid=139335]@name[/url] : initTIM3
* [url=home.php?mod=space&uid=247401]@brief[/url] : 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;
    }   
}

使用特权

评论回复
5
空间规划科|  楼主 | 2022-6-30 10:31 | 只看该作者
通过中断调度

使用特权

评论回复
6
空间规划科|  楼主 | 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();
    }
}

使用特权

评论回复
7
空间规划科|  楼主 | 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);
   
    //.....
}

使用特权

评论回复
8
空间规划科|  楼主 | 2022-6-30 10:38 | 只看该作者
MB024引脚图

使用特权

评论回复
9
空间规划科|  楼主 | 2022-6-30 10:38 | 只看该作者

使用特权

评论回复
10
空间规划科|  楼主 | 2022-6-30 10:40 | 只看该作者
好吧,接上逻辑分析仪看看:

使用特权

评论回复
11
空间规划科|  楼主 | 2022-6-30 10:40 | 只看该作者
结果:

使用特权

评论回复
12
空间规划科|  楼主 | 2022-6-30 10:43 | 只看该作者
没问题就可以进入正文。

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

使用特权

评论回复
13
空间规划科|  楼主 | 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);
}

使用特权

评论回复
14
空间规划科|  楼主 | 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);
    }
}

使用特权

评论回复
15
空间规划科|  楼主 | 2022-6-30 10:53 | 只看该作者

/// @brief  Main function, program entry.
/// @param  None.
/// @retval None.

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

使用特权

评论回复
16
空间规划科|  楼主 | 2022-6-30 10:54 | 只看该作者

/// @brief  Main function, program entry.
/// @param  None.
/// @retval None.

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

使用特权

评论回复
17
空间规划科|  楼主 | 2022-6-30 12:29 | 只看该作者

/// @brief  Main function, program entry.
/// @param  None.
/// @retval None.

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

使用特权

评论回复
18
空间规划科|  楼主 | 2022-6-30 12:29 | 只看该作者
出来这个玩意?这肯定是前面步进值没算好。继续修改

使用特权

评论回复
19
空间规划科|  楼主 | 2022-6-30 12:31 | 只看该作者

使用特权

评论回复
20
空间规划科|  楼主 | 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);
    }
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

22

主题

130

帖子

0

粉丝