TIM-有感BLDC实现解析-基于CH32V203 - RISC-V MCU技术社区 - 电子技术论坛 - 广受欢迎的专业电子论坛
分享 收藏 返回

[文章]

TIM-有感BLDC实现解析-基于CH32V203


1、BLDC运行基本原理简要介绍
在图1-20(a)中,AB相通电,电流处于转子产生的磁场内,根据左手定则,我们判断线圈AA’中的上半部导线A受到一个顺时针方向的电磁力,而AA’的下半部导线A’也受到一个顺时针方向的电磁力。由于线圈绕组在定子上,定子是固定不动的,故根据作用力与反作用力,定子绕组AA’会施加给转子一个逆时针方向的反作用力,转子在这个力的作用下,就转起来了。同理,与AA’的情况类似,BB’也会对转子产生一个逆时针的反作用力。当转子逆时针转过60°后,到达图1-20(b)的位置,这时线圈BB’已经到达转子磁极的边缘位置了,再转下去就要产生反方向的力了,所以这时就要换相,换成AC相通电,见图1-20(c)。这样,每过60°换相通电,转子就可以一直转下去了。


2、6路PWM互补波形的输出
高级定时器tiM1的相关宏定义-方便后续更换成其它高级定时器
  1. #define BLDC_TIMx TIM1
  2. #define BLDC_TIM_CLK RCC_APB2Periph_TIM1
  3. #define BLDC_TIM_GPIO_CLK (RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB)
  4. #define BLDC_TIM_CH1_PORT GPIOA
  5. #define BLDC_TIM_CH1_PIN GPIO_Pin_8 //通道1
  6. #define BLDC_TIM_CH2_PORT GPIOA
  7. #define BLDC_TIM_CH2_PIN GPIO_Pin_9 //通道2
  8. #define BLDC_TIM_CH3_PORT GPIOA
  9. #define BLDC_TIM_CH3_PIN GPIO_Pin_10 //通道3
  10. #define BLDC_TIM_CH1N_PORT GPIOB
  11. #define BLDC_TIM_CH1N_PIN GPIO_Pin_13 //互补通道1
  12. #define BLDC_TIM_CH2N_PORT GPIOB
  13. #define BLDC_TIM_CH2N_PIN GPIO_Pin_14 //互补通道2
  14. #define BLDC_TIM_CH3N_PORT GPIOB
  15. #define BLDC_TIM_CH3N_PIN GPIO_Pin_15 //互补通道3
  16. #define BLDC_TIM_BKIN_PORT GPIOB
  17. #define BLDC_TIM_BKIN_PIN GPIO_Pin_12 //刹车输入
TIM1高级定时器所使用的6路PWM引脚以及刹车引脚初始化
  1. void TIMx_GPIO_Init(void)
  2. {
  3. GPIO_InitTypeDef GPIO_InitStructure = {0};
  4. RCC_APB2PeriphClockCmd(BLDC_TIM_GPIO_CLK|RCC_APB2Periph_AFIO,ENABLE);
  5. /* TIMx_CH1 */
  6. GPIO_InitStructure.GPIO_Pin = BLDC_TIM_CH1_PIN;
  7. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  8. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  9. GPIO_Init(BLDC_TIM_CH1_PORT, &GPIO_InitStructure);
  10. /* TIMx_CH2 */
  11. GPIO_InitStructure.GPIO_Pin = BLDC_TIM_CH2_PIN;
  12. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  13. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  14. GPIO_Init(BLDC_TIM_CH2_PORT, &GPIO_InitStructure);
  15. /* TIMx_CH3 */
  16. GPIO_InitStructure.GPIO_Pin = BLDC_TIM_CH3_PIN;
  17. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  18. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  19. GPIO_Init(BLDC_TIM_CH3_PORT, &GPIO_InitStructure);
  20. /* TIMx_CH1N */
  21. GPIO_InitStructure.GPIO_Pin = BLDC_TIM_CH1N_PIN;
  22. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  23. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  24. GPIO_Init(BLDC_TIM_CH1N_PORT, &GPIO_InitStructure);
  25. /* TIMx_CH2N */
  26. GPIO_InitStructure.GPIO_Pin = BLDC_TIM_CH2N_PIN;
  27. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  28. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  29. GPIO_Init(BLDC_TIM_CH2N_PORT, &GPIO_InitStructure);
  30. /* TIMx_CH3N */
  31. GPIO_InitStructure.GPIO_Pin = BLDC_TIM_CH3N_PIN;
  32. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  33. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  34. GPIO_Init(BLDC_TIM_CH3N_PORT, &GPIO_InitStructure);
  35. /* TIMx_BKIN */
  36. GPIO_InitStructure.GPIO_Pin = BLDC_TIM_BKIN_PIN;
  37. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  38. GPIO_Init(BLDC_TIM_BKIN_PORT, &GPIO_InitStructure);
  39. }
  40. TIM1高级定时器的参数的初始化
  41. //PWM频率-20KHz
  42. #define BLDC_TIM_PWM_FREQ 20000
  43. // 定时器预分频系数-(2-1)
  44. #define BLDC_TIM_PRESCALER 1
  45. //定时器计数周期-(144000000/2=72000000/20000=3600)
  46. #define BLDC_TIM_PERIOD (uint16_t)(SystemCoreClock/(BLDC_TIM_PRESCALER+1)/BLDC_TIM_PWM_FREQ)
  47. //定时器重复寄存器数值
  48. #define BLDC_TIM_REPETITIONCOUNTER 0 //PWM占空比
  49. void TIMx_Mode_Init(void)//开关频率20K
  50. {
  51. TIM_OCInitTypeDef TIM_OCInitStructure = {0};
  52. TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure = {0};
  53. TIM_BDTRInitTypeDef TIM_BDTRInitStructure = {0};
  54. RCC_APB2PeriphClockCmd(BLDC_TIM_CLK, ENABLE);
  55. TIM_TimeBaseInitStructure.TIM_Period = BLDC_TIM_PERIOD;
  56. TIM_TimeBaseInitStructure.TIM_Prescaler = BLDC_TIM_PRESCALER;
  57. TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  58. TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
  59. TIM_TimeBaseInitStructure.TIM_RepetitionCounter = BLDC_TIM_REPETITIONCOUNTER;
  60. TIM_TimeBaseInit(BLDC_TIMx, &TIM_TimeBaseInitStructure);
  61. TIM_ARRPreloadConfig(BLDC_TIMx, ENABLE);
  62. TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
  63. TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
  64. TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
  65. TIM_OCInitStructure.TIM_Pulse = 0;
  66. TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
  67. TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
  68. TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
  69. TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
  70. TIM_OC1Init(BLDC_TIMx, &TIM_OCInitStructure);// 初始化通道 1 输出 PWM
  71. TIM_OC2Init(BLDC_TIMx, &TIM_OCInitStructure);// 初始化通道 2 输出 PWM
  72. TIM_OC3Init(BLDC_TIMx, &TIM_OCInitStructure);// 初始化通道 3 输出 PWM
  73. TIM_OC1PreloadConfig(BLDC_TIMx, TIM_OCPreload_Enable);
  74. TIM_OC2PreloadConfig(BLDC_TIMx, TIM_OCPreload_Enable);
  75. TIM_OC3PreloadConfig(BLDC_TIMx, TIM_OCPreload_Enable);
  76. TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
  77. TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
  78. TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
  79. TIM_BDTRInitStructure.TIM_DeadTime = 10; //死区时间=138.9ns
  80. TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable;
  81. TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
  82. TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;
  83. TIM_BDTRConfig(BLDC_TIMx, &TIM_BDTRInitStructure);
  84. //死区以及刹车参数初始化
  85. TIM_SelectInputTrigger( BLDC_TIMx, TIM_TS_ITR3 );
  86. TIM_SelectCOM(BLDC_TIMx,ENABLE);
  87. TIM_CCPreloadControl(BLDC_TIMx,ENABLE);
  88. //设置触发源为TIM4霍尔定时器,并使能COM事件以达到换相时的同步功能
  89. TIM_CtrlPWMOutputs(BLDC_TIMx, ENABLE);
  90. TIM_Cmd(BLDC_TIMx, ENABLE);
  91. TIM_CCxCmd(BLDC_TIMx,TIM_Channel_1,TIM_CCx_Disable);
  92. TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_1,TIM_CCxN_Disable);
  93. TIM_CCxCmd(BLDC_TIMx,TIM_Channel_2,TIM_CCx_Disable);
  94. TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_2,TIM_CCxN_Disable);
  95. TIM_CCxCmd(BLDC_TIMx,TIM_Channel_3,TIM_CCx_Disable);
  96. TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_3,TIM_CCxN_Disable);
  97. }
3、与霍尔传感器接口-霍尔定时器的配置

霍尔定时器TIM4的相关宏定义-方便后续更换成其它霍尔定时器
  1. #define HALL_TIMx TIM4
  2. #define HALL_TIM_CLK RCC_APB1Periph_TIM4
  3. #define HALL_TIM_PERIOD 0xFFFF //ARR,计数周期,配置为最大65535
  4. #define HALL_TIM_PRESCALER (144-1) //预分频系数为144
  5. #define HALL_TIM_Channel_x TIM_Channel_1 //通道1
  6. #define HALL_TIM_GPIO_CLK RCC_APB2Periph_GPIOB
  7. #define HALL_TIM_CH1_PIN GPIO_Pin_6
  8. #define HALL_TIM_CH1_GPIO GPIOB
  9. #define HALL_TIM_CH2_PIN GPIO_Pin_7
  10. #define HALL_TIM_CH2_GPIO GPIOB
  11. #define HALL_TIM_CH3_PIN GPIO_Pin_8
  12. #define HALL_TIM_CH3_GPIO GPIOB
  13. TIM4霍尔定时器所使用的3路捕获引脚的初始化
  14. void TIMx_HALL_GPIO_Init(void)
  15. {
  16. GPIO_InitTypeDef GPIO_InitStructure = {0};
  17. RCC_APB2PeriphClockCmd(HALL_TIM_GPIO_CLK,ENABLE);
  18. /* TIM4_CH1 */
  19. GPIO_InitStructure.GPIO_Pin = HALL_TIM_CH1_PIN;
  20. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  21. GPIO_Init(HALL_TIM_CH1_GPIO, &GPIO_InitStructure);
  22. /* TIM4_CH2 */
  23. GPIO_InitStructure.GPIO_Pin = HALL_TIM_CH2_PIN;
  24. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  25. GPIO_Init(HALL_TIM_CH2_GPIO, &GPIO_InitStructure);
  26. /* TIM4_CH3 */
  27. GPIO_InitStructure.GPIO_Pin = HALL_TIM_CH3_PIN;
  28. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  29. GPIO_Init(HALL_TIM_CH3_GPIO, &GPIO_InitStructure);
  30. }
  31. void TIMx_HALL_Mode_Init(void)
  32. {
  33. TIM_ICInitTypeDef TIM_ICInitStructure = {0};
  34. TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure = {0};
  35. NVIC_InitTypeDef NVIC_InitStructure={0};
  36. RCC_APB1PeriphClockCmd(HALL_TIM_CLK, ENABLE);
  37. TIM_TimeBaseInitStructure.TIM_Period = HALL_TIM_PERIOD;
  38. TIM_TimeBaseInitStructure.TIM_Prescaler = HALL_TIM_PRESCALER;
  39. TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
  40. TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
  41. TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
  42. TIM_TimeBaseInit(HALL_TIMx, &TIM_TimeBaseInitStructure);
  43. NVIC_InitStructure.NVIC_IRQChannel = HALL_TIM_IRQn;
  44. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  45. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  46. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  47. NVIC_Init(&NVIC_InitStructure);
  48. TIM_ITConfig( HALL_TIMx, TIM_IT_Trigger, ENABLE );
  49. TIM_ITConfig( HALL_TIMx, TIM_IT_CC1, ENABLE );
  50. TIM_ICInitStructure.TIM_Channel = HALL_TIM_Channel_x;
  51. TIM_ICInitStructure.TIM_ICFilter = 0x00;
  52. TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_BothEdge;
  53. TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
  54. TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_TRC;
  55. TIM_ICInit(HALL_TIMx,&TIM_ICInitStructure);
  56. //使能霍尔传感器的接口,将三个通道的信号异或输入。
  57. TIM_SelectHallSensor(HALL_TIMx,ENABLE);
  58. //输入触发源选择,选择TI1F_ED
  59. TIM_SelectInputTrigger( HALL_TIMx, TIM_TS_TI1F_ED );
  60. //从模式选择,复位模式
  61. TIM_SelectSlaveMode( HALL_TIMx, TIM_SlaveMode_Reset );
  62. //主从模式使能
  63. TIM_SelectMasterSlaveMode( HALL_TIMx, TIM_MasterSlaveMode_Enable );
  64. //使能霍尔定时器
  65. TIM_Cmd( HALL_TIMx, ENABLE );
  66. //清除中断标志位,防止直接第一次进入中断
  67. TIM_ClearITPendingBit (HALL_TIMx,TIM_IT_Trigger);
  68. }
4、定时器的联动与触发换相
定时器联动概述:
1、高级定时器TIM1设定TIM4为主定时器,即利用TIM4触发TIM1
2、霍尔定时器配置了TIM4_CH1、TIM4_CH2、TIM4_CH3三个通道捕获的电平在经过异或后形成TI1信号,并经过双边沿检测器,形成TI1F_ED的脉冲波形信号。
3、设置定时器内部TRC触发,IC1配置为输入捕获(无论配置为上升沿还是下降沿均可捕获到TI1F_ED的脉冲波形信号),IC1输入源配置为TRC。一旦捕获到此信号即开始换相操作。
4、同时TRC信号生成TRGI信号触发复位更新TIM4的CNT计数值,使得CNT=0,产生一个UPDATE信号,通过此处的更新可以捕获到两个换相之前的延时,从而推算出马达的速度信息。
触发换相:

获取霍尔定时器三个通道的霍尔信号
  1. uint8_t get_hall_state(void)
  2. {
  3. uint8_t state = 0;
  4. if((HALL_TIM_CH1_GPIO->INDR & HALL_TIM_CH1_PIN) != (uint32_t)Bit_RESET)
  5. //CH1状态获取
  6. {
  7. state |= 0x01U << 0;
  8. }
  9. if((HALL_TIM_CH2_GPIO->INDR & HALL_TIM_CH2_PIN) != (uint32_t)Bit_RESET)
  10. //CH2状态获取
  11. {
  12. state |= 0x01U << 1;
  13. }
  14. if((HALL_TIM_CH3_GPIO->INDR & HALL_TIM_CH3_PIN) != (uint32_t)Bit_RESET)
  15. //CH3状态获取
  16. {
  17. state |= 0x01U << 2;
  18. }
  19. return state; // 返回传感器状态
  20. }
霍尔定时器中断换相
  1. void TIM4_IRQHandler(void)
  2. {
  3. if( TIM_GetITStatus( TIM4, TIM_IT_Trigger|TIM_IT_CC1 ) != RESET )
  4. {
  5. uint8_t step = 0;
  6. step = get_hall_state();
  7. switch(step)
  8. {
  9. case 3: //V+ W-
  10. //输出比较通道1配置
  11. TIM_CCxCmd(BLDC_TIMx,TIM_Channel_1,TIM_CCx_Disable);
  12. TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_1,TIM_CCxN_Disable);
  13. //输出比较通道2配置
  14. TIM_SetCompare2(BLDC_TIMx,BLDC_TIM_PERIOD*speed_duty/100);
  15. TIM_CCxCmd(BLDC_TIMx,TIM_Channel_2,TIM_CCx_Enable);
  16. //输出比较通道3配置
  17. TIM_SetCompare3(BLDC_TIMx,BLDC_TIM_PERIOD);
  18. TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_3,TIM_CCxN_Enable);
  19. break;
  20. case 2: //V+ U-
  21. //输出比较通道3配置
  22. TIM_CCxCmd(BLDC_TIMx,TIM_Channel_3,TIM_CCx_Disable);
  23. TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_3,TIM_CCxN_Disable);
  24. //输出比较通道1配置
  25. TIM_SetCompare1(BLDC_TIMx,BLDC_TIM_PERIOD);
  26. TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_1,TIM_CCxN_Enable);
  27. //输出比较通道2配置
  28. TIM_SetCompare2(BLDC_TIMx,BLDC_TIM_PERIOD*speed_duty/100);
  29. TIM_CCxCmd(BLDC_TIMx,TIM_Channel_2,TIM_CCx_Enable);
  30. break;
  31. case 6: //W+ U-
  32. //输出比较通道2配置
  33. TIM_CCxCmd(BLDC_TIMx,TIM_Channel_2,TIM_CCx_Disable);
  34. TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_2,TIM_CCxN_Disable);
  35. //输出比较通道1配置
  36. TIM_SetCompare1(BLDC_TIMx,BLDC_TIM_PERIOD);
  37. TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_1,TIM_CCxN_Enable);
  38. //输出比较通道3配置
  39. TIM_SetCompare3(BLDC_TIMx,BLDC_TIM_PERIOD*speed_duty/100);
  40. TIM_CCxCmd(BLDC_TIMx,TIM_Channel_3,TIM_CCx_Enable);
  41. break;
  42. case 4: //W+ V-
  43. //输出比较通道1配置
  44. TIM_CCxCmd(BLDC_TIMx,TIM_Channel_1,TIM_CCx_Disable);
  45. TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_1,TIM_CCxN_Disable);
  46. //输出比较通道2配置
  47. TIM_SetCompare2(BLDC_TIMx,BLDC_TIM_PERIOD);
  48. TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_2,TIM_CCxN_Enable);
  49. //输出比较通道3配置
  50. TIM_SetCompare3(BLDC_TIMx,BLDC_TIM_PERIOD*speed_duty/100);
  51. TIM_CCxCmd(BLDC_TIMx,TIM_Channel_3,TIM_CCx_Enable);
  52. break;
  53. case 5: //U+ V-
  54. //输出比较通道3配置
  55. TIM_CCxCmd(BLDC_TIMx,TIM_Channel_3,TIM_CCx_Disable);
  56. TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_3,TIM_CCxN_Disable);
  57. //输出比较通道1配置
  58. TIM_SetCompare1(BLDC_TIMx,BLDC_TIM_PERIOD*speed_duty/100);
  59. TIM_CCxCmd(BLDC_TIMx,TIM_Channel_1,TIM_CCx_Enable);
  60. //输出比较通道2配置
  61. TIM_SetCompare2(BLDC_TIMx,BLDC_TIM_PERIOD);
  62. TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_2,TIM_CCxN_Enable);
  63. break;
  64. case 1: //U+ W-
  65. //输出比较通道2配置
  66. TIM_CCxCmd(BLDC_TIMx,TIM_Channel_2,TIM_CCx_Disable);
  67. TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_2,TIM_CCxN_Disable);
  68. //输出比较通道1配置
  69. TIM_SetCompare1(BLDC_TIMx,BLDC_TIM_PERIOD*speed_duty/100);
  70. TIM_CCxCmd(BLDC_TIMx,TIM_Channel_1,TIM_CCx_Enable);
  71. //输出比较通道3配置
  72. TIM_SetCompare3(BLDC_TIMx,BLDC_TIM_PERIOD);
  73. TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_3,TIM_CCxN_Enable);
  74. break;
  75. default: //关闭输出
  76. TIM_CCxCmd(BLDC_TIMx,TIM_Channel_1,TIM_CCx_Disable);
  77. TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_1,TIM_CCxN_Disable);
  78. TIM_CCxCmd(BLDC_TIMx,TIM_Channel_2,TIM_CCx_Disable);
  79. TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_2,TIM_CCxN_Disable);
  80. TIM_CCxCmd(BLDC_TIMx,TIM_Channel_3,TIM_CCx_Disable);
  81. TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_3,TIM_CCxN_Disable);
  82. break;
  83. }
  84. TIM_GenerateEvent(TIM1,TIM_EventSource_COM);//软件产生COM事件将配置写入
  85. }
  86. TIM_ClearITPendingBit( TIM4, TIM_IT_Trigger );
  87. TIM_ClearITPendingBit( TIM4, TIM_IT_CC1 );
  88. }

文章来源:cnblogs


更多回帖

×
发帖