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的相关宏定义-方便后续更换成其它高级定时器- #define BLDC_TIMx TIM1
- #define BLDC_TIM_CLK RCC_APB2Periph_TIM1
- #define BLDC_TIM_GPIO_CLK (RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB)
- #define BLDC_TIM_CH1_PORT GPIOA
- #define BLDC_TIM_CH1_PIN GPIO_Pin_8 //通道1
- #define BLDC_TIM_CH2_PORT GPIOA
- #define BLDC_TIM_CH2_PIN GPIO_Pin_9 //通道2
- #define BLDC_TIM_CH3_PORT GPIOA
- #define BLDC_TIM_CH3_PIN GPIO_Pin_10 //通道3
- #define BLDC_TIM_CH1N_PORT GPIOB
- #define BLDC_TIM_CH1N_PIN GPIO_Pin_13 //互补通道1
- #define BLDC_TIM_CH2N_PORT GPIOB
- #define BLDC_TIM_CH2N_PIN GPIO_Pin_14 //互补通道2
- #define BLDC_TIM_CH3N_PORT GPIOB
- #define BLDC_TIM_CH3N_PIN GPIO_Pin_15 //互补通道3
- #define BLDC_TIM_BKIN_PORT GPIOB
- #define BLDC_TIM_BKIN_PIN GPIO_Pin_12 //刹车输入
复制代码 TIM1高级定时器所使用的6路PWM引脚以及刹车引脚初始化- void TIMx_GPIO_Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure = {0};
- RCC_APB2PeriphClockCmd(BLDC_TIM_GPIO_CLK|RCC_APB2Periph_AFIO,ENABLE);
- /* TIMx_CH1 */
- GPIO_InitStructure.GPIO_Pin = BLDC_TIM_CH1_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(BLDC_TIM_CH1_PORT, &GPIO_InitStructure);
- /* TIMx_CH2 */
- GPIO_InitStructure.GPIO_Pin = BLDC_TIM_CH2_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(BLDC_TIM_CH2_PORT, &GPIO_InitStructure);
- /* TIMx_CH3 */
- GPIO_InitStructure.GPIO_Pin = BLDC_TIM_CH3_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(BLDC_TIM_CH3_PORT, &GPIO_InitStructure);
- /* TIMx_CH1N */
- GPIO_InitStructure.GPIO_Pin = BLDC_TIM_CH1N_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(BLDC_TIM_CH1N_PORT, &GPIO_InitStructure);
- /* TIMx_CH2N */
- GPIO_InitStructure.GPIO_Pin = BLDC_TIM_CH2N_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(BLDC_TIM_CH2N_PORT, &GPIO_InitStructure);
- /* TIMx_CH3N */
- GPIO_InitStructure.GPIO_Pin = BLDC_TIM_CH3N_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(BLDC_TIM_CH3N_PORT, &GPIO_InitStructure);
- /* TIMx_BKIN */
- GPIO_InitStructure.GPIO_Pin = BLDC_TIM_BKIN_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_Init(BLDC_TIM_BKIN_PORT, &GPIO_InitStructure);
- }
- TIM1高级定时器的参数的初始化
- //PWM频率-20KHz
- #define BLDC_TIM_PWM_FREQ 20000
- // 定时器预分频系数-(2-1)
- #define BLDC_TIM_PRESCALER 1
- //定时器计数周期-(144000000/2=72000000/20000=3600)
- #define BLDC_TIM_PERIOD (uint16_t)(SystemCoreClock/(BLDC_TIM_PRESCALER+1)/BLDC_TIM_PWM_FREQ)
- //定时器重复寄存器数值
- #define BLDC_TIM_REPETITIONCOUNTER 0 //PWM占空比
- void TIMx_Mode_Init(void)//开关频率20K
- {
- TIM_OCInitTypeDef TIM_OCInitStructure = {0};
- TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure = {0};
- TIM_BDTRInitTypeDef TIM_BDTRInitStructure = {0};
- RCC_APB2PeriphClockCmd(BLDC_TIM_CLK, ENABLE);
- TIM_TimeBaseInitStructure.TIM_Period = BLDC_TIM_PERIOD;
- TIM_TimeBaseInitStructure.TIM_Prescaler = BLDC_TIM_PRESCALER;
- TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
- TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseInitStructure.TIM_RepetitionCounter = BLDC_TIM_REPETITIONCOUNTER;
- TIM_TimeBaseInit(BLDC_TIMx, &TIM_TimeBaseInitStructure);
- TIM_ARRPreloadConfig(BLDC_TIMx, ENABLE);
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
- TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
- TIM_OCInitStructure.TIM_Pulse = 0;
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
- TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High;
- TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
- TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCNIdleState_Reset;
- TIM_OC1Init(BLDC_TIMx, &TIM_OCInitStructure);// 初始化通道 1 输出 PWM
- TIM_OC2Init(BLDC_TIMx, &TIM_OCInitStructure);// 初始化通道 2 输出 PWM
- TIM_OC3Init(BLDC_TIMx, &TIM_OCInitStructure);// 初始化通道 3 输出 PWM
- TIM_OC1PreloadConfig(BLDC_TIMx, TIM_OCPreload_Enable);
- TIM_OC2PreloadConfig(BLDC_TIMx, TIM_OCPreload_Enable);
- TIM_OC3PreloadConfig(BLDC_TIMx, TIM_OCPreload_Enable);
- TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
- TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
- TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
- TIM_BDTRInitStructure.TIM_DeadTime = 10; //死区时间=138.9ns
- TIM_BDTRInitStructure.TIM_Break = TIM_Break_Enable;
- TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
- TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Disable;
- TIM_BDTRConfig(BLDC_TIMx, &TIM_BDTRInitStructure);
- //死区以及刹车参数初始化
- TIM_SelectInputTrigger( BLDC_TIMx, TIM_TS_ITR3 );
- TIM_SelectCOM(BLDC_TIMx,ENABLE);
- TIM_CCPreloadControl(BLDC_TIMx,ENABLE);
- //设置触发源为TIM4霍尔定时器,并使能COM事件以达到换相时的同步功能
- TIM_CtrlPWMOutputs(BLDC_TIMx, ENABLE);
- TIM_Cmd(BLDC_TIMx, ENABLE);
- TIM_CCxCmd(BLDC_TIMx,TIM_Channel_1,TIM_CCx_Disable);
- TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_1,TIM_CCxN_Disable);
- TIM_CCxCmd(BLDC_TIMx,TIM_Channel_2,TIM_CCx_Disable);
- TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_2,TIM_CCxN_Disable);
- TIM_CCxCmd(BLDC_TIMx,TIM_Channel_3,TIM_CCx_Disable);
- TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_3,TIM_CCxN_Disable);
- }
复制代码 3、与霍尔传感器接口-霍尔定时器的配置
霍尔定时器TIM4的相关宏定义-方便后续更换成其它霍尔定时器- #define HALL_TIMx TIM4
- #define HALL_TIM_CLK RCC_APB1Periph_TIM4
- #define HALL_TIM_PERIOD 0xFFFF //ARR,计数周期,配置为最大65535
- #define HALL_TIM_PRESCALER (144-1) //预分频系数为144
- #define HALL_TIM_Channel_x TIM_Channel_1 //通道1
- #define HALL_TIM_GPIO_CLK RCC_APB2Periph_GPIOB
- #define HALL_TIM_CH1_PIN GPIO_Pin_6
- #define HALL_TIM_CH1_GPIO GPIOB
- #define HALL_TIM_CH2_PIN GPIO_Pin_7
- #define HALL_TIM_CH2_GPIO GPIOB
- #define HALL_TIM_CH3_PIN GPIO_Pin_8
- #define HALL_TIM_CH3_GPIO GPIOB
- TIM4霍尔定时器所使用的3路捕获引脚的初始化
- void TIMx_HALL_GPIO_Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure = {0};
- RCC_APB2PeriphClockCmd(HALL_TIM_GPIO_CLK,ENABLE);
- /* TIM4_CH1 */
- GPIO_InitStructure.GPIO_Pin = HALL_TIM_CH1_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
- GPIO_Init(HALL_TIM_CH1_GPIO, &GPIO_InitStructure);
- /* TIM4_CH2 */
- GPIO_InitStructure.GPIO_Pin = HALL_TIM_CH2_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
- GPIO_Init(HALL_TIM_CH2_GPIO, &GPIO_InitStructure);
- /* TIM4_CH3 */
- GPIO_InitStructure.GPIO_Pin = HALL_TIM_CH3_PIN;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
- GPIO_Init(HALL_TIM_CH3_GPIO, &GPIO_InitStructure);
- }
- void TIMx_HALL_Mode_Init(void)
- {
- TIM_ICInitTypeDef TIM_ICInitStructure = {0};
- TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure = {0};
- NVIC_InitTypeDef NVIC_InitStructure={0};
- RCC_APB1PeriphClockCmd(HALL_TIM_CLK, ENABLE);
- TIM_TimeBaseInitStructure.TIM_Period = HALL_TIM_PERIOD;
- TIM_TimeBaseInitStructure.TIM_Prescaler = HALL_TIM_PRESCALER;
- TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1;
- TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;
- TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0;
- TIM_TimeBaseInit(HALL_TIMx, &TIM_TimeBaseInitStructure);
- NVIC_InitStructure.NVIC_IRQChannel = HALL_TIM_IRQn;
- NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
- NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
- NVIC_Init(&NVIC_InitStructure);
- TIM_ITConfig( HALL_TIMx, TIM_IT_Trigger, ENABLE );
- TIM_ITConfig( HALL_TIMx, TIM_IT_CC1, ENABLE );
- TIM_ICInitStructure.TIM_Channel = HALL_TIM_Channel_x;
- TIM_ICInitStructure.TIM_ICFilter = 0x00;
- TIM_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_BothEdge;
- TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;
- TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_TRC;
- TIM_ICInit(HALL_TIMx,&TIM_ICInitStructure);
- //使能霍尔传感器的接口,将三个通道的信号异或输入。
- TIM_SelectHallSensor(HALL_TIMx,ENABLE);
- //输入触发源选择,选择TI1F_ED
- TIM_SelectInputTrigger( HALL_TIMx, TIM_TS_TI1F_ED );
- //从模式选择,复位模式
- TIM_SelectSlaveMode( HALL_TIMx, TIM_SlaveMode_Reset );
- //主从模式使能
- TIM_SelectMasterSlaveMode( HALL_TIMx, TIM_MasterSlaveMode_Enable );
- //使能霍尔定时器
- TIM_Cmd( HALL_TIMx, ENABLE );
- //清除中断标志位,防止直接第一次进入中断
- TIM_ClearITPendingBit (HALL_TIMx,TIM_IT_Trigger);
- }
复制代码 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信号,通过此处的更新可以捕获到两个换相之前的延时,从而推算出马达的速度信息。
触发换相:
获取霍尔定时器三个通道的霍尔信号- uint8_t get_hall_state(void)
- {
- uint8_t state = 0;
- if((HALL_TIM_CH1_GPIO->INDR & HALL_TIM_CH1_PIN) != (uint32_t)Bit_RESET)
- //CH1状态获取
- {
- state |= 0x01U << 0;
- }
- if((HALL_TIM_CH2_GPIO->INDR & HALL_TIM_CH2_PIN) != (uint32_t)Bit_RESET)
- //CH2状态获取
- {
- state |= 0x01U << 1;
- }
- if((HALL_TIM_CH3_GPIO->INDR & HALL_TIM_CH3_PIN) != (uint32_t)Bit_RESET)
- //CH3状态获取
- {
- state |= 0x01U << 2;
- }
- return state; // 返回传感器状态
- }
复制代码 霍尔定时器中断换相- void TIM4_IRQHandler(void)
- {
- if( TIM_GetITStatus( TIM4, TIM_IT_Trigger|TIM_IT_CC1 ) != RESET )
- {
- uint8_t step = 0;
- step = get_hall_state();
- switch(step)
- {
- case 3: //V+ W-
- //输出比较通道1配置
- TIM_CCxCmd(BLDC_TIMx,TIM_Channel_1,TIM_CCx_Disable);
- TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_1,TIM_CCxN_Disable);
- //输出比较通道2配置
- TIM_SetCompare2(BLDC_TIMx,BLDC_TIM_PERIOD*speed_duty/100);
- TIM_CCxCmd(BLDC_TIMx,TIM_Channel_2,TIM_CCx_Enable);
- //输出比较通道3配置
- TIM_SetCompare3(BLDC_TIMx,BLDC_TIM_PERIOD);
- TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_3,TIM_CCxN_Enable);
- break;
- case 2: //V+ U-
- //输出比较通道3配置
- TIM_CCxCmd(BLDC_TIMx,TIM_Channel_3,TIM_CCx_Disable);
- TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_3,TIM_CCxN_Disable);
- //输出比较通道1配置
- TIM_SetCompare1(BLDC_TIMx,BLDC_TIM_PERIOD);
- TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_1,TIM_CCxN_Enable);
- //输出比较通道2配置
- TIM_SetCompare2(BLDC_TIMx,BLDC_TIM_PERIOD*speed_duty/100);
- TIM_CCxCmd(BLDC_TIMx,TIM_Channel_2,TIM_CCx_Enable);
- break;
- case 6: //W+ U-
- //输出比较通道2配置
- TIM_CCxCmd(BLDC_TIMx,TIM_Channel_2,TIM_CCx_Disable);
- TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_2,TIM_CCxN_Disable);
- //输出比较通道1配置
- TIM_SetCompare1(BLDC_TIMx,BLDC_TIM_PERIOD);
- TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_1,TIM_CCxN_Enable);
- //输出比较通道3配置
- TIM_SetCompare3(BLDC_TIMx,BLDC_TIM_PERIOD*speed_duty/100);
- TIM_CCxCmd(BLDC_TIMx,TIM_Channel_3,TIM_CCx_Enable);
- break;
- case 4: //W+ V-
- //输出比较通道1配置
- TIM_CCxCmd(BLDC_TIMx,TIM_Channel_1,TIM_CCx_Disable);
- TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_1,TIM_CCxN_Disable);
- //输出比较通道2配置
- TIM_SetCompare2(BLDC_TIMx,BLDC_TIM_PERIOD);
- TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_2,TIM_CCxN_Enable);
- //输出比较通道3配置
- TIM_SetCompare3(BLDC_TIMx,BLDC_TIM_PERIOD*speed_duty/100);
- TIM_CCxCmd(BLDC_TIMx,TIM_Channel_3,TIM_CCx_Enable);
- break;
- case 5: //U+ V-
- //输出比较通道3配置
- TIM_CCxCmd(BLDC_TIMx,TIM_Channel_3,TIM_CCx_Disable);
- TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_3,TIM_CCxN_Disable);
- //输出比较通道1配置
- TIM_SetCompare1(BLDC_TIMx,BLDC_TIM_PERIOD*speed_duty/100);
- TIM_CCxCmd(BLDC_TIMx,TIM_Channel_1,TIM_CCx_Enable);
- //输出比较通道2配置
- TIM_SetCompare2(BLDC_TIMx,BLDC_TIM_PERIOD);
- TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_2,TIM_CCxN_Enable);
- break;
- case 1: //U+ W-
- //输出比较通道2配置
- TIM_CCxCmd(BLDC_TIMx,TIM_Channel_2,TIM_CCx_Disable);
- TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_2,TIM_CCxN_Disable);
- //输出比较通道1配置
- TIM_SetCompare1(BLDC_TIMx,BLDC_TIM_PERIOD*speed_duty/100);
- TIM_CCxCmd(BLDC_TIMx,TIM_Channel_1,TIM_CCx_Enable);
- //输出比较通道3配置
- TIM_SetCompare3(BLDC_TIMx,BLDC_TIM_PERIOD);
- TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_3,TIM_CCxN_Enable);
- break;
- default: //关闭输出
- TIM_CCxCmd(BLDC_TIMx,TIM_Channel_1,TIM_CCx_Disable);
- TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_1,TIM_CCxN_Disable);
- TIM_CCxCmd(BLDC_TIMx,TIM_Channel_2,TIM_CCx_Disable);
- TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_2,TIM_CCxN_Disable);
- TIM_CCxCmd(BLDC_TIMx,TIM_Channel_3,TIM_CCx_Disable);
- TIM_CCxNCmd(BLDC_TIMx,TIM_Channel_3,TIM_CCxN_Disable);
- break;
- }
- TIM_GenerateEvent(TIM1,TIM_EventSource_COM);//软件产生COM事件将配置写入
- }
- TIM_ClearITPendingBit( TIM4, TIM_IT_Trigger );
- TIM_ClearITPendingBit( TIM4, TIM_IT_CC1 );
- }
复制代码
文章来源:cnblogs
|