[MM32硬件] 定时器:霍尔传感器接口与六步算法

[复制链接]
2026|31
 楼主| 空间规划科 发表于 2022-6-30 09:46 | 显示全部楼层 |阅读模式
实现结果

本文的目的是 实现下图所示。
watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NoZW5kdTEwMw==,size_16,color_FFFFFF,t_70.jpg (文档这个图是错的,霍尔信号和CCR2的位置不对,先将就着)


声明

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


 楼主| 空间规划科 发表于 2022-6-30 09:50 | 显示全部楼层
* 模拟霍尔信号
代码如下:
  1. /*******************************************************************************
  2. * [url=home.php?mod=space&uid=139335]@name[/url] : initTIM3
  3. * [url=home.php?mod=space&uid=247401]@brief[/url] : init TIM3
  4. * @param : u16 arr, u16 arr
  5. * @retval : void
  6. *******************************************************************************/
  7. void initTIM3(u16 psc, u16 arr)
  8. {
  9.     TIM_TimeBaseInitTypeDef TIM_StructInit;
  10.     GPIO_InitTypeDef GPIO_InitStructure;
  11.     NVIC_InitTypeDef NVIC_InitStructure;
  12.    
  13.     TIM_DeInit(TIM3);
  14.    
  15.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;                      // TIM3 CH1/2
  16.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;                                                   
  17.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  18.     GPIO_Init(GPIOA, &GPIO_InitStructure);
  19.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;                                   // TIM3 CH3
  20.     GPIO_Init(GPIOB, &GPIO_InitStructure);
  21.    
  22.     TIM_StructInit.TIM_Prescaler = psc;                                         // set Prescaler: psc + 1
  23.     TIM_StructInit.TIM_Period = arr;                                            // set Period: arr + 1
  24.     TIM_StructInit.TIM_ClockDivision = TIM_CKD_DIV1;                            // set ClockDivision :0                        
  25.     TIM_StructInit.TIM_CounterMode = TIM_CounterMode_Up;                                             
  26.     TIM_TimeBaseInit(TIM3, &TIM_StructInit);   
  27.    
  28.     TIM_CCPreloadControl(TIM3, ENABLE);                                         // Enable ARR preload
  29.     TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);                                  // Enable update interrupt
  30.    
  31.     NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
  32.     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  33.     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  34.     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  35.     NVIC_Init(&NVIC_InitStructure);

  36.         TIM_Cmd(TIM3, ENABLE);
  37. }
 楼主| 空间规划科 发表于 2022-6-30 09:53 | 显示全部楼层
配置好定时器3后,模拟信号:
 楼主| 空间规划科 发表于 2022-6-30 09:55 | 显示全部楼层
  1. /*******************************************************************************
  2. * @name : simMotorPrepareCommutation
  3. * @brief :  simulate hall Input
  4. * @param : void
  5. * @retval : void
  6. *******************************************************************************/
  7. void simMotorPrepareCommutation(void)
  8. {
  9.     if (gSimStep == 1){
  10.         // Step 1 Configuration
  11.         CH1ON;
  12.         CH2OFF;
  13.         CH3OFF;
  14.         gSimStep++;
  15.     }
  16.     else if (gSimStep == 2){
  17.         // Step 2 Configuration
  18.         CH1ON;
  19.         CH2ON;
  20.         CH3OFF;
  21.         gSimStep++;
  22.     }
  23.     else if (gSimStep == 3){
  24.         // Step 3 Configuration
  25.         CH1ON;
  26.         CH2ON;
  27.         CH3ON;
  28.         gSimStep++;
  29.     }
  30.     else if (gSimStep == 4){
  31.         // Step 4 Configuration
  32.         CH1OFF;
  33.         CH2ON;
  34.         CH3ON;
  35.         gSimStep++;
  36.     }
  37.     else if (gSimStep == 5){
  38.         // Step 5 Configuration
  39.         CH1OFF;
  40.         CH2OFF;
  41.         CH3ON;
  42.         gSimStep++;
  43.     }
  44.     else{
  45.         // Step 6 Configuration      
  46.         CH1OFF;
  47.         CH2OFF;
  48.         CH3OFF;  
  49.         gSimStep = 1;
  50.     }   
  51. }
 楼主| 空间规划科 发表于 2022-6-30 10:31 | 显示全部楼层
通过中断调度
 楼主| 空间规划科 发表于 2022-6-30 10:35 | 显示全部楼层
  1. /*******************************************************************************
  2. * @name : TIM3_IRQHandler
  3. * @brief :  
  4. * @param : void
  5. * @retval : void
  6. *******************************************************************************/
  7. void TIM3_IRQHandler(void)
  8. {      
  9.     if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) {
  10.         TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
  11.         simMotorPrepareCommutation();
  12.     }
  13. }
 楼主| 空间规划科 发表于 2022-6-30 10:36 | 显示全部楼层
  1. /*
  2. --------------------------------------------------------------------------------
  3.       TIM2 (hall timer)            |    TIM3 (Simulate the hall output)
  4. --------------------------------------------------------------------------------
  5.      PA_0  : hall input channel1   |     PA_6 (TIM3_CH1)
  6. --------------------------------------------------------------------------------
  7.      PA_1  : hall input channel2   |     PA_7 (TIM3_CH2)
  8. --------------------------------------------------------------------------------
  9.      PA_2  : hall input channel3   |     PB_0 (TIM3_CH3)
  10. --------------------------------------------------------------------------------
  11. NOTE: if use TIM3 simulate, In order to achieve better results, please use anot-
  12. her board to output and the main function just only init TIM3 and its parameter.
  13. */


  14. int main(void)
  15. {
  16.         //....
  17.     initTIM3(0x0, 0xFFFF);
  18.    
  19.     //.....
  20. }
 楼主| 空间规划科 发表于 2022-6-30 10:38 | 显示全部楼层
MB024引脚图
5382162bd0c9b959bf.png
 楼主| 空间规划科 发表于 2022-6-30 10:38 | 显示全部楼层
 楼主| 空间规划科 发表于 2022-6-30 10:40 | 显示全部楼层
好吧,接上逻辑分析仪看看:

6869262bd0ced801ba.png
 楼主| 空间规划科 发表于 2022-6-30 10:40 | 显示全部楼层
结果:
9435962bd0d303b250.png
 楼主| 空间规划科 发表于 2022-6-30 10:43 | 显示全部楼层
没问题就可以进入正文。

正文
配置霍尔输入定时器配置:
 楼主| 空间规划科 发表于 2022-6-30 10:44 | 显示全部楼层

  1. void initHallTimer2()
  2. {
  3.     TIM_TimeBaseInitTypeDef pBase;
  4.     TIM_OCInitTypeDef       pOC;
  5.     TIM_ICInitTypeDef       pIC;
  6.    
  7.     COMMON_EnableIpClock(emCLOCK_TIM2);
  8.     COMMON_NVIC_Configure(TIM2_IRQn, 1, 1);
  9.     GPIO_TIMER2_HALL_INPUT_Configure();
  10.    
  11.     TIM_DeInit(TIM2);
  12.     TIM_TimeBaseStructInit(&pBase);
  13.     pBase.TIM_Period        = 0xFFFF;
  14.     pBase.TIM_Prescaler     = 0;
  15.     pBase.TIM_CounterMode   = TIM_CounterMode_Up;
  16.     pBase.TIM_ClockDivision = TIM_CKD_DIV1;
  17.     pBase.TIM_RepetitionCounter = 0;
  18.     TIM_TimeBaseInit(TIM2, &pBase);
  19.    
  20.     TIM_OCStructInit(&pOC);
  21.     pOC.TIM_Pulse           = 0x1;
  22.     pOC.TIM_OCMode          = TIM_OCMode_PWM2;
  23.     pOC.TIM_OutputState     = TIM_OutputState_Enable;
  24.     pOC.TIM_OCPolarity      = TIM_OCPolarity_High;
  25.     TIM_OC2Init(TIM2, &pOC);
  26.     TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE); // Add OC2 handle to reduce delay
  27.    
  28.     TIM_SelectHallSensor(TIM2, ENABLE);
  29.     pIC.TIM_Channel     = TIM_Channel_1;
  30.     pIC.TIM_ICPolarity  = TIM_ICPolarity_Rising;
  31.     pIC.TIM_ICSelection = TIM_ICSelection_TRC;
  32.     pIC.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  33.     pIC.TIM_ICFilter    = 0x0;
  34.     TIM_ICInit(TIM2, &pIC);  
  35.     TIM_SelectInputTrigger(TIM2, TIM_TS_TI1F_ED);
  36.     TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Reset);
  37.     TIM_SelectOutputTrigger(TIM2, TIM_TRIGSource_OC2Ref);
  38.    
  39.     TIM_Cmd(TIM2, ENABLE);
  40. }

 楼主| 空间规划科 发表于 2022-6-30 10:47 | 显示全部楼层
调度:
  1. /* /
  2. |---------|--------------------------------------------------------------------|
  3. | PA_0    |   _|- - -|_ _ _|- - -| _ _ _                                       |
  4. |         |                                                                    |
  5. | PA_1    |   _ _|- - -|_ _ _|- - -| _ _                                       |
  6. |         |                                                                    |
  7. | PA_2    |   _ _ _|- - -|_ _ _|- - -| _                                       |
  8. |---------+--------------------------------------------------------------------|
  9. |pos value|  |0 1 3 7 6 4|0 1 3 7 6 4|..                                       |
  10. |------------------------------------------------------------------------------|
  11. *///
  12. void TIM2_IRQHandler(void)
  13. {      
  14.     if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET) {
  15.         TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
  16.         /* Calculate motor speed or else with CCR1 values */
  17.         HallCCR1 = TIM_GetCapture1(TIM2);
  18.         
  19.         /* get step position by PA_0 / PA_1 / PA_2 */
  20.         HallPos = (GPIO_ReadInputData(GPIOA)) & 0x0007;
  21.         
  22.         /* Step Motor commutation*/
  23.         BLDCMotorPrepareCommutation(HallPos, TIM_OCMode_PWM1, TIM_OCMode_PWM1);
  24.     }
  25. }
 楼主| 空间规划科 发表于 2022-6-30 10:53 | 显示全部楼层

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

  4. int main(void)
  5. {
  6.         MCUID = SetSystemClock(emSYSTICK_On, AppTaskTick);
  7.    
  8.     initHallTimer2();
  9.     initMotorTimer1(0, 999);
  10.    
  11.     while(1){
  12.         
  13.     }
  14. }
 楼主| 空间规划科 发表于 2022-6-30 10:54 | 显示全部楼层

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

  4. int main(void)
  5. {
  6.         MCUID = SetSystemClock(emSYSTICK_On, AppTaskTick);
  7.    
  8.     initHallTimer2();
  9.     initMotorTimer1(0, 999);
  10.    
  11.     while(1){
  12.         
  13.     }
  14. }
 楼主| 空间规划科 发表于 2022-6-30 12:29 | 显示全部楼层

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

  4. int main(void)
  5. {
  6.         MCUID = SetSystemClock(emSYSTICK_On, AppTaskTick);
  7.    
  8.     initHallTimer2();
  9.     initMotorTimer1(0, 999);
  10.    
  11.     while(1){
  12.         
  13.     }
  14. }
 楼主| 空间规划科 发表于 2022-6-30 12:29 | 显示全部楼层
出来这个玩意?这肯定是前面步进值没算好。继续修改
 楼主| 空间规划科 发表于 2022-6-30 12:31 | 显示全部楼层
 楼主| 空间规划科 发表于 2022-6-30 12:32 | 显示全部楼层

  1. void BLDCMotorPrepareCommutation(u8 pos, TIMOCMODE_Typedef TIM_CHxMode, TIMOCMODE_Typedef TIM_CHxNMode)
  2. {
  3.     if (pos == 0){
  4.         /* Channel1 configuration: CH1 output: PWM */
  5.         TIM_SelectOCxM  (TIM1, TIM_Channel_1, TIM_CHxMode);
  6.         TIM_CCxCmd      (TIM1, TIM_Channel_1, TIM_CCx_Enable);
  7.         TIM_CCxNCmd     (TIM1, TIM_Channel_1, TIM_CCxN_Disable);
  8.         
  9.         /* Channel2 configuration: CH2N output: PWM */
  10.         TIM_SelectOCxM  (TIM1, TIM_Channel_2, TIM_CHxNMode);
  11.         TIM_CCxCmd      (TIM1, TIM_Channel_2, TIM_CCx_Disable);
  12.         TIM_CCxNCmd     (TIM1, TIM_Channel_2, TIM_CCxN_Enable);
  13.         
  14.         /* Channel3 configuration: CH3 None */
  15.         TIM_CCxCmd      (TIM1, TIM_Channel_3, TIM_CCx_Disable);
  16.         TIM_CCxNCmd     (TIM1, TIM_Channel_3, TIM_CCxN_Disable);
  17.     }
  18.     else if (pos == 1){
  19.         /*  Channel1 configuration: CH1 output: PWM */
  20.         TIM_SelectOCxM  (TIM1, TIM_Channel_1, TIM_CHxMode);
  21.         TIM_CCxCmd      (TIM1, TIM_Channel_1, TIM_CCx_Enable);
  22.         TIM_CCxNCmd     (TIM1, TIM_Channel_1, TIM_CCxN_Disable);
  23.         
  24.         /*  Channel2 configuration: CH2 None */
  25.         TIM_CCxCmd      (TIM1, TIM_Channel_2, TIM_CCx_Disable);
  26.         TIM_CCxNCmd     (TIM1, TIM_Channel_2, TIM_CCxN_Disable);
  27.         
  28.         /*  Channel3 configuration: CH3N output: PWM */
  29.         TIM_SelectOCxM  (TIM1, TIM_Channel_3, TIM_CHxNMode);
  30.         TIM_CCxCmd      (TIM1, TIM_Channel_3, TIM_CCx_Disable);
  31.         TIM_CCxNCmd     (TIM1, TIM_Channel_3, TIM_CCxN_Enable);
  32.     }
  33.     else if (pos == 3){
  34.         /* Channel1 configuration: CH1 None */
  35.         TIM_CCxCmd      (TIM1, TIM_Channel_1, TIM_CCx_Disable);
  36.         TIM_CCxNCmd     (TIM1, TIM_Channel_1, TIM_CCxN_Disable);
  37.         
  38.         /* Channel2 configuration: CH2 output: PWM */
  39.         TIM_SelectOCxM  (TIM1, TIM_Channel_2, TIM_CHxMode);
  40.         TIM_CCxCmd      (TIM1, TIM_Channel_2, TIM_CCx_Enable);
  41.         TIM_CCxNCmd     (TIM1, TIM_Channel_2, TIM_CCxN_Disable);
  42.         
  43.         /* Channel3 configuration: CH3N output: PWM */
  44.         TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_CHxNMode);
  45.         TIM_CCxCmd (TIM1, TIM_Channel_3, TIM_CCx_Disable);
  46.         TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Enable);
  47.     }
  48.     else if (pos == 7){
  49.         /* Channel1 configuration: CH1N output: PWM */
  50.         TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_CHxNMode);
  51.         TIM_CCxCmd (TIM1, TIM_Channel_1, TIM_CCx_Disable);
  52.         TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Enable);
  53.         
  54.         /* Channel2 configuration: CH2 output: PWM */
  55.         TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_CHxMode);
  56.         TIM_CCxCmd (TIM1, TIM_Channel_2, TIM_CCx_Enable);
  57.         TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Disable);
  58.         
  59.         /* Channel3 configuration: CH3 None */
  60.         TIM_CCxCmd (TIM1, TIM_Channel_3, TIM_CCx_Disable);
  61.         TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Disable);
  62.     }
  63.     else if (pos == 6){
  64.         /* Channel1 configuration: CH1N output: PWM */
  65.         TIM_SelectOCxM(TIM1, TIM_Channel_1, TIM_CHxNMode);
  66.         TIM_CCxCmd (TIM1, TIM_Channel_1, TIM_CCx_Disable);
  67.         TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Enable);
  68.         
  69.         /* Channel2 configuration: CH2 None */
  70.         TIM_CCxCmd (TIM1, TIM_Channel_2, TIM_CCx_Disable);
  71.         TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Disable);
  72.         
  73.         /* Channel3 configuration: CH3 output: PWM */
  74.         TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_CHxMode);
  75.         TIM_CCxCmd (TIM1, TIM_Channel_3, TIM_CCx_Enable);
  76.         TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Disable);
  77.     }
  78.     else if (pos == 4){     
  79.         /* Channel1 configuration: CH1 None */
  80.         TIM_CCxCmd (TIM1, TIM_Channel_1, TIM_CCx_Disable);
  81.         TIM_CCxNCmd(TIM1, TIM_Channel_1, TIM_CCxN_Disable);
  82.         
  83.         /* Channel2 configuration: CH2N output: PWM */
  84.         TIM_SelectOCxM(TIM1, TIM_Channel_2, TIM_CHxNMode);
  85.         TIM_CCxCmd (TIM1, TIM_Channel_2, TIM_CCx_Disable);
  86.         TIM_CCxNCmd(TIM1, TIM_Channel_2, TIM_CCxN_Enable);
  87.         
  88.         /* Channel3 configuration: CH3 output: PWM */
  89.         TIM_SelectOCxM(TIM1, TIM_Channel_3, TIM_CHxMode);
  90.         TIM_CCxCmd (TIM1, TIM_Channel_3, TIM_CCx_Enable);
  91.         TIM_CCxNCmd(TIM1, TIM_Channel_3, TIM_CCxN_Disable);
  92.     }
  93. }
您需要登录后才可以回帖 登录 | 注册

本版积分规则

34

主题

150

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部