BLDC无刷电机六步换向驱动
1.霍尔传感器读数
三路霍尔传感器表示旋转位置,根据霍尔传感器控制电机UVW相;
使用通用定时器TIM5的霍尔传感器模式读取三路霍尔信号跳变:TIM配置为HallSensor模式
TIM_HandleTypeDef h_HALL_TIM = {0};
void HALL_Init(void)
{
h_HALL_TIM.Instance = TIM5;//APB1,90Mhz 90 000 000
h_HALL_TIM.Init.Prescaler = 90;
h_HALL_TIM.Init.CounterMode = TIM_COUNTERMODE_UP;
h_HALL_TIM.Init.Period = 0xFFFF;
h_HALL_TIM.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
h_HALL_TIM.Init.RepetitionCounter = 0;
h_HALL_TIM.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
TIM_HallSensor_InitTypeDef HALL_sConfig = {0};
HALL_sConfig.IC1Polarity = TIM_ICPOLARITY_BOTHEDGE;
HALL_sConfig.IC1Prescaler = TIM_ICPSC_DIV1;
HALL_sConfig.IC1Filter = 0x1;
HALL_sConfig.Commutation_Delay = 0x0000;//霍尔传感器变化后,隔一段时间触发COM事件给TIM8
HAL_TIMEx_HallSensor_Init(&h_HALL_TIM,&HALL_sConfig);
HAL_TIMEx_HallSensor_Start_IT(&h_HALL_TIM);//捕获中断
__HAL_TIM_ENABLE_IT(&h_HALL_TIM,TIM_IT_UPDATE);//使能更新中断
__HAL_TIM_ENABLE_IT(&h_HALL_TIM,TIM_IT_TRIGGER);//触发中断
}
void HAL_TIMEx_HallSensor_MspInit(TIM_HandleTypeDef *htim)
{
if(htim->Instance == TIM5)
{
__HAL_RCC_TIM5_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
GPIO_InitTypeDef HALL_GPIO_Init = {0};
HALL_GPIO_Init.Pin = GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12;
HALL_GPIO_Init.Mode = GPIO_MODE_AF_PP;
HALL_GPIO_Init.Pull = GPIO_NOPULL;
HALL_GPIO_Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HALL_GPIO_Init.Alternate = GPIO_AF2_TIM5;
HAL_GPIO_Init(GPIOH,&HALL_GPIO_Init);
HAL_NVIC_SetPriority(TIM5_IRQn,0,0);
HAL_NVIC_EnableIRQ(TIM5_IRQn);
}
}
/*霍尔值读取函数*/
uint8_t HALL_Read(void)
{
uint8_t Hall_Num = 0;
Hall_Num |= (HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_10)<<2);
Hall_Num |= (HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_11)<<1);
Hall_Num |= (HAL_GPIO_ReadPin(GPIOH,GPIO_PIN_12)<<0);
return Hall_Num;
}
2.高级定时器生成PWM波控制电机转速
高级定时器初始化PWM模式:
TIM_HandleTypeDef h_BLDC_PWM_Tim = {0};
void BLDC_TIM_Init(void)
{
h_BLDC_PWM_Tim.Instance = TIM8;
h_BLDC_PWM_Tim.Init.Prescaler = 2-1;
h_BLDC_PWM_Tim.Init.CounterMode = TIM_COUNTERMODE_UP;
h_BLDC_PWM_Tim.Init.Period = 6000-1;
h_BLDC_PWM_Tim.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
h_BLDC_PWM_Tim.Init.RepetitionCounter = 0;
h_BLDC_PWM_Tim.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
HAL_TIM_PWM_Init(&h_BLDC_PWM_Tim);
TIM_OC_InitTypeDef BLDC_sConfig = {0};
BLDC_sConfig.OCMode = TIM_OCMODE_PWM1;
BLDC_sConfig.Pulse = 0;
BLDC_sConfig.OCPolarity = TIM_OCPOLARITY_HIGH;
BLDC_sConfig.OCNPolarity = TIM_OCNPOLARITY_HIGH;
BLDC_sConfig.OCFastMode = TIM_OCFAST_DISABLE;
BLDC_sConfig.OCIdleState = TIM_OCIDLESTATE_RESET;
BLDC_sConfig.OCNIdleState = TIM_OCIDLESTATE_RESET;
HAL_TIM_OC_ConfigChannel(&h_BLDC_PWM_Tim,&BLDC_sConfig,TIM_CHANNEL_1);
HAL_TIM_OC_ConfigChannel(&h_BLDC_PWM_Tim,&BLDC_sConfig,TIM_CHANNEL_2);
HAL_TIM_OC_ConfigChannel(&h_BLDC_PWM_Tim,&BLDC_sConfig,TIM_CHANNEL_3);
//HAL_TIM_PWM_Start_IT(&h_BLDC_PWM_Tim, uint32_t Channel);
/*统一控制三个通道输出,TIM5TRGO触发COM*/
//HAL_TIMEx_ConfigCommutEvent(&h_BLDC_PWM_Tim,TIM_TS_ITR3,TIM_COMMUTATION_TRGI);
}
void HAL_TIM_PWM_MspInit(TIM_HandleTypeDef *htim)
{
__HAL_RCC_TIM8_CLK_ENABLE();
__HAL_RCC_GPIOI_CLK_ENABLE();
__HAL_RCC_GPIOH_CLK_ENABLE();
GPIO_InitTypeDef PWM_GPIO_Init;
PWM_GPIO_Init = (GPIO_InitTypeDef){0};
PWM_GPIO_Init.Pin = GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
PWM_GPIO_Init.Mode = GPIO_MODE_AF_PP;
PWM_GPIO_Init.Pull = GPIO_NOPULL;
PWM_GPIO_Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
PWM_GPIO_Init.Alternate = GPIO_AF3_TIM8;
HAL_GPIO_Init(GPIOI,&PWM_GPIO_Init);
PWM_GPIO_Init = (GPIO_InitTypeDef){0};
PWM_GPIO_Init.Pin = GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
PWM_GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
PWM_GPIO_Init.Pull = GPIO_NOPULL;
PWM_GPIO_Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOH,&PWM_GPIO_Init);
}
电机驱动板使能信号:
void BLDC_SHDN(void)
{
__HAL_RCC_GPIOE_CLK_ENABLE();
GPIO_InitTypeDef SHDN_GPIO_Init;
SHDN_GPIO_Init = (GPIO_InitTypeDef){0};
SHDN_GPIO_Init.Pin = GPIO_PIN_6;
SHDN_GPIO_Init.Mode = GPIO_MODE_OUTPUT_PP;
SHDN_GPIO_Init.Pull = GPIO_NOPULL;
SHDN_GPIO_Init.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(GPIOE,&SHDN_GPIO_Init);
HAL_GPIO_WritePin(GPIOE,GPIO_PIN_6,GPIO_PIN_SET);//电机驱动板使能信号
}
六步换向函数:
void BLDC_Turn(uint8_t Hall_Num)
{
if(BLDC_NO1.Turn_Dir)
{
/*顺时针*/
if(Hall_Num == 5){BLDC_UV();}
if(Hall_Num == 1){BLDC_WV();}
if(Hall_Num == 3){BLDC_WU();}
if(Hall_Num == 2){BLDC_VU();}
if(Hall_Num == 6){BLDC_VW();}
if(Hall_Num == 4){BLDC_UW();}
}
else
{
/*逆时针*/
if(Hall_Num == 5){BLDC_VU();}
if(Hall_Num == 1){BLDC_VW();}
if(Hall_Num == 3){BLDC_UW();}
if(Hall_Num == 2){BLDC_UV();}
if(Hall_Num == 6){BLDC_WV();}
if(Hall_Num == 4){BLDC_WU();}
}
}
void BLDC_UV(void)
{
__HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_1, BLDC_NO1.PWM_Compare);
__HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_2, 0);
__HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_3, 0);
// HAL_TIM_PWM_Start(&h_BLDC_PWM_Tim,TIM_CHANNEL_1);
// HAL_TIM_PWM_Stop(&h_BLDC_PWM_Tim,TIM_CHANNEL_2);
// HAL_TIM_PWM_Stop(&h_BLDC_PWM_Tim,TIM_CHANNEL_3);
HAL_GPIO_WritePin(GPIOH,GPIO_PIN_13,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOH,GPIO_PIN_14,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOH,GPIO_PIN_15,GPIO_PIN_RESET);
}
void BLDC_UW(void)
{
__HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_1, BLDC_NO1.PWM_Compare);
__HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_2, 0);
__HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_3, 0);
// HAL_TIM_PWM_Start(&h_BLDC_PWM_Tim,TIM_CHANNEL_1);
// HAL_TIM_PWM_Stop(&h_BLDC_PWM_Tim,TIM_CHANNEL_2);
// HAL_TIM_PWM_Stop(&h_BLDC_PWM_Tim,TIM_CHANNEL_3);
HAL_GPIO_WritePin(GPIOH,GPIO_PIN_13,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOH,GPIO_PIN_14,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOH,GPIO_PIN_15,GPIO_PIN_SET);
}
void BLDC_VW(void)
{
__HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_2, BLDC_NO1.PWM_Compare);
__HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_1, 0);
__HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_3, 0);
// HAL_TIM_PWM_Stop(&h_BLDC_PWM_Tim,TIM_CHANNEL_1);
// HAL_TIM_PWM_Start(&h_BLDC_PWM_Tim,TIM_CHANNEL_2);
// HAL_TIM_PWM_Stop(&h_BLDC_PWM_Tim,TIM_CHANNEL_3);
HAL_GPIO_WritePin(GPIOH,GPIO_PIN_13,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOH,GPIO_PIN_14,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOH,GPIO_PIN_15,GPIO_PIN_SET);
}
void BLDC_VU(void)
{
__HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_2, BLDC_NO1.PWM_Compare);
__HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_1, 0);
__HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_3, 0);
// HAL_TIM_PWM_Stop(&h_BLDC_PWM_Tim,TIM_CHANNEL_1);
// HAL_TIM_PWM_Start(&h_BLDC_PWM_Tim,TIM_CHANNEL_2);
// HAL_TIM_PWM_Stop(&h_BLDC_PWM_Tim,TIM_CHANNEL_3);
HAL_GPIO_WritePin(GPIOH,GPIO_PIN_13,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOH,GPIO_PIN_14,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOH,GPIO_PIN_15,GPIO_PIN_RESET);
}
void BLDC_WU(void)
{
__HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_3, BLDC_NO1.PWM_Compare);
__HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_1, 0);
__HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_2, 0);
// HAL_TIM_PWM_Stop(&h_BLDC_PWM_Tim,TIM_CHANNEL_1);
// HAL_TIM_PWM_Stop(&h_BLDC_PWM_Tim,TIM_CHANNEL_2);
// HAL_TIM_PWM_Start(&h_BLDC_PWM_Tim,TIM_CHANNEL_3);
HAL_GPIO_WritePin(GPIOH,GPIO_PIN_13,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOH,GPIO_PIN_14,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOH,GPIO_PIN_15,GPIO_PIN_RESET);
}
void BLDC_WV(void)
{
__HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_3, BLDC_NO1.PWM_Compare);
__HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_1, 0);
__HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_2, 0);
// HAL_TIM_PWM_Stop(&h_BLDC_PWM_Tim,TIM_CHANNEL_1);
// HAL_TIM_PWM_Stop(&h_BLDC_PWM_Tim,TIM_CHANNEL_2);
// HAL_TIM_PWM_Start(&h_BLDC_PWM_Tim,TIM_CHANNEL_3);
HAL_GPIO_WritePin(GPIOH,GPIO_PIN_13,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOH,GPIO_PIN_14,GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOH,GPIO_PIN_15,GPIO_PIN_RESET);
}
电机启动函数:
void BLDC_Start(void)
{
__HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_1, 0);
__HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_2, 0);
__HAL_TIM_SET_COMPARE(&h_BLDC_PWM_Tim, TIM_CHANNEL_3, 0);
HAL_TIM_PWM_Start(&h_BLDC_PWM_Tim,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&h_BLDC_PWM_Tim,TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&h_BLDC_PWM_Tim,TIM_CHANNEL_3);
HAL_GPIO_WritePin(GPIOH,GPIO_PIN_13,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOH,GPIO_PIN_14,GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOH,GPIO_PIN_15,GPIO_PIN_RESET);
HAL_TIM_GenerateEvent(&h_BLDC_PWM_Tim, TIM_EVENTSOURCE_COM);//软件生成COM事件
__HAL_TIM_CLEAR_FLAG(&h_BLDC_PWM_Tim,TIM_FLAG_COM);
HAL_Delay(10);//自举电容充电
BLDC_Turn(HALL_Read());
HAL_TIM_GenerateEvent(&h_BLDC_PWM_Tim, TIM_EVENTSOURCE_COM);//软件生成COM事件
__HAL_TIM_CLEAR_FLAG(&h_BLDC_PWM_Tim,TIM_FLAG_COM);
}
3.通用定时器输入捕获函数中调用六步换向函数:
void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)//输入捕获函数
{
if(htim->Instance == h_HALL_TIM.Instance)
{
//printf("\n Hall_Num=%d,",HALL_Read());
BLDC_Turn(HALL_Read());
}
}
4.主函数中检测案件控制电机加减速
while (1)
{
if(Key_Scan(GPIOA,GPIO_PIN_0)==1)
{
BLDC_NO1.Turn_Dir_PWM += 100;
if(BLDC_NO1.Turn_Dir_PWM>=6000){BLDC_NO1.Turn_Dir_PWM = 6000;}
if(BLDC_NO1.Turn_Dir_PWM<=-6000){BLDC_NO1.Turn_Dir_PWM = -6000;}
if(BLDC_NO1.Turn_Dir_PWM >= 0)
{
BLDC_NO1.Turn_Dir = 1;
BLDC_NO1.PWM_Compare = BLDC_NO1.Turn_Dir_PWM;
}
else
{
BLDC_NO1.Turn_Dir = 0;
BLDC_NO1.PWM_Compare = -BLDC_NO1.Turn_Dir_PWM;
}
BLDC_Start();
printf("\n PWM=%d,",BLDC_NO1.PWM_Compare);
}
if(Key_Scan(GPIOC,GPIO_PIN_13)==1)
{
BLDC_NO1.Turn_Dir_PWM -= 100;
if(BLDC_NO1.Turn_Dir_PWM>=6000){BLDC_NO1.Turn_Dir_PWM = 6000;}
if(BLDC_NO1.Turn_Dir_PWM<=-6000){BLDC_NO1.Turn_Dir_PWM = -6000;}
if(BLDC_NO1.Turn_Dir_PWM >= 0)
{
BLDC_NO1.Turn_Dir = 1;
BLDC_NO1.PWM_Compare = BLDC_NO1.Turn_Dir_PWM;
}
else
{
BLDC_NO1.Turn_Dir = 0;
BLDC_NO1.PWM_Compare = -BLDC_NO1.Turn_Dir_PWM;
}
BLDC_Start();
printf("\n PWM=%d,",BLDC_NO1.PWM_Compare);
}
}