单片机驱动BLDC带hall六步法

发布时间:2026/7/8 1:23:57
单片机驱动BLDC带hall六步法 单片机 STM32F407开发板DMF407电机开发板平台keil V5.31HSE 为8MHZHSI为16MHZ主函数int main(void) { uint8_t key,t; char buf[32]; int16_t pwm_duty_temp 0; HAL_Init(); /* 初始化HAL库 */ sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */ delay_init(168); /* 延时初始化 */ usart_init(115200); /* 串口初始化为115200 */ led_init(); /* 初始化LED */ key_init(); /* 初始化按键 */ lcd_init(); /* 初始化LCD */ bldc_init(100000-1,0); bldc_ctrl(MOTOR_1,CCW,0); /* 初始无刷电机接口1速度 */ HAL_TIM_Base_Start_IT(g_atimx_handle); /* 启动高级定时器1 */ /* 显示提示信息 */ g_point_color WHITE; g_back_color BLACK; lcd_show_string(10, 10, 200, 16, 16, BLDC Motor Test,g_point_color); lcd_show_string(10, 30, 200, 16, 16, KEY0:Start forward, g_point_color); lcd_show_string(10, 50, 200, 16, 16, KEY1:Start backward, g_point_color); lcd_show_string(10, 70, 200, 16, 16, KEY2:Stop, g_point_color); printf(按下KEY0 开始正转加速\r\n); printf(按下KEY1 开始反转加速\r\n); printf(按下KEY2 停止电机\r\n); while (1) { t; if(t % 20 0) { sprintf(buf,PWM_Duty:%.1f%%,(float)((g_bldc_motor1.pwm_duty/MAX_PWM_DUTY)*100));/* 显示控制PWM占空比 */ lcd_show_string(10,110,200,16,16,buf,g_point_color); LED0_TOGGLE(); /* LED0(红灯) 翻转 */ } key key_scan(0); if(key KEY0_PRES) /* 按下KEY0设置比较值500 */ { pwm_duty_temp 500; if(pwm_duty_temp MAX_PWM_DUTY/2) /* 限速 */ pwm_duty_temp MAX_PWM_DUTY/2; if(pwm_duty_temp 0) /* 通过判断正负号设置旋转方向 */ { g_bldc_motor1.pwm_duty pwm_duty_temp; g_bldc_motor1.dir CW; } else { g_bldc_motor1.pwm_duty -pwm_duty_temp; g_bldc_motor1.dir CCW; } g_bldc_motor1.run_flag RUN; /* 开启运行 */ start_motor1(); /* 开启运行 */ } else if(key KEY1_PRES) /* 按下KEY1设置比较值-500 */ { pwm_duty_temp - 500; if(pwm_duty_temp -MAX_PWM_DUTY/2) pwm_duty_temp -MAX_PWM_DUTY/2; if(pwm_duty_temp 0) /* 通过判断正负号设置旋转方向 */ { g_bldc_motor1.pwm_duty -pwm_duty_temp; g_bldc_motor1.dir CCW; } else { g_bldc_motor1.pwm_duty pwm_duty_temp; g_bldc_motor1.dir CW; } g_bldc_motor1.run_flag RUN; /* 开启运行 */ start_motor1(); /* 运行电机 */ } else if(key KEY2_PRES) /* 按下KEY2关闭电机 */ { stop_motor1(); /* 停机 */ g_bldc_motor1.run_flag STOP; /* 标记停机 */ pwm_duty_temp 0; /* 数据清0 */ g_bldc_motor1.pwm_duty 0; } delay_ms(10); } }hall配置void hall_gpio_init(void) { GPIO_InitTypeDef gpio_init_struct; HALL1_U_GPIO_CLK_ENABLE(); HALL1_V_GPIO_CLK_ENABLE(); HALL1_W_GPIO_CLK_ENABLE(); /* 霍尔通道 1 引脚初始化 */ gpio_init_struct.Pin HALL1_TIM_CH1_PIN; gpio_init_struct.Mode GPIO_MODE_INPUT; gpio_init_struct.Pull GPIO_PULLUP; HAL_GPIO_Init(HALL1_TIM_CH1_GPIO, gpio_init_struct); /* 霍尔通道 2 引脚初始化 */ gpio_init_struct.Pin HALL1_TIM_CH2_PIN; HAL_GPIO_Init(HALL1_TIM_CH2_GPIO, gpio_init_struct); /* 霍尔通道 3 引脚初始化 */ gpio_init_struct.Pin HALL1_TIM_CH3_PIN; HAL_GPIO_Init(HALL1_TIM_CH3_GPIO, gpio_init_struct); }读取halluint32_t hallsensor_get_state(uint8_t motor_id) { __IO static uint32_t state ; state 0; if(motor_id MOTOR_1) { if(HAL_GPIO_ReadPin(HALL1_TIM_CH1_GPIO,HALL1_TIM_CH1_PIN) ! GPIO_PIN_RESET) /* 霍尔传感器状态获取 */ { state | 0x01U; } if(HAL_GPIO_ReadPin(HALL1_TIM_CH2_GPIO,HALL1_TIM_CH2_PIN) ! GPIO_PIN_RESET) /* 霍尔传感器状态获取 */ { state | 0x02U; } if(HAL_GPIO_ReadPin(HALL1_TIM_CH3_GPIO,HALL1_TIM_CH3_PIN) ! GPIO_PIN_RESET) /* 霍尔传感器状态获取 */ { state | 0x04U; } } return state; }定时器配置void atim_timx_oc_chy_init(uint16_t arr, uint16_t psc) { ATIM_TIMX_PWM_CHY_CLK_ENABLE(); /* TIMX 时钟使能 */ g_atimx_handle.Instance ATIM_TIMX_PWM; /* 定时器x */ g_atimx_handle.Init.Prescaler psc; /* 定时器分频 */ g_atimx_handle.Init.CounterMode TIM_COUNTERMODE_UP; /* 向上计数模式 */ g_atimx_handle.Init.Period arr; /* 自动重装载值 */ g_atimx_handle.Init.ClockDivisionTIM_CLOCKDIVISION_DIV1; /* 分频因子 */ g_atimx_handle.Init.AutoReloadPreload TIM_AUTORELOAD_PRELOAD_DISABLE; /*使能TIMx_ARR进行缓冲*/ g_atimx_handle.Init.RepetitionCounter 0; /* 开始时不计数*/ HAL_TIM_PWM_Init(g_atimx_handle); /* 初始化PWM */ g_atimx_oc_chy_handle.OCMode TIM_OCMODE_PWM1; /* 模式选择PWM1 */ g_atimx_oc_chy_handle.Pulse 0; g_atimx_oc_chy_handle.OCPolarity TIM_OCPOLARITY_HIGH; /* 输出比较极性为高 */ g_atimx_oc_chy_handle.OCNPolarity TIM_OCNPOLARITY_HIGH; g_atimx_oc_chy_handle.OCFastMode TIM_OCFAST_DISABLE; g_atimx_oc_chy_handle.OCIdleState TIM_OCIDLESTATE_RESET; g_atimx_oc_chy_handle.OCNIdleState TIM_OCNIDLESTATE_RESET; HAL_TIM_PWM_ConfigChannel(g_atimx_handle, g_atimx_oc_chy_handle, ATIM_TIMX_PWM_CH1); /* 配置TIMx通道y */ HAL_TIM_PWM_ConfigChannel(g_atimx_handle, g_atimx_oc_chy_handle, ATIM_TIMX_PWM_CH2); /* 配置TIMx通道y */ HAL_TIM_PWM_ConfigChannel(g_atimx_handle, g_atimx_oc_chy_handle, ATIM_TIMX_PWM_CH3); /* 配置TIMx通道y */ /* 开启定时器通道1输出PWM */ HAL_TIM_PWM_Start(g_atimx_handle,TIM_CHANNEL_1); /* 开启定时器通道2输出PWM */ HAL_TIM_PWM_Start(g_atimx_handle,TIM_CHANNEL_2); /* 开启定时器通道3输出PWM */ HAL_TIM_PWM_Start(g_atimx_handle,TIM_CHANNEL_3); }启动电机void start_motor1(void) { SHUTDOWN_EN; /* 使能PWM输出 */ HAL_TIM_PWM_Start(g_atimx_handle,TIM_CHANNEL_1); HAL_TIM_PWM_Start(g_atimx_handle,TIM_CHANNEL_2); HAL_TIM_PWM_Start(g_atimx_handle,TIM_CHANNEL_3); }六步法/* 六步换向函数指针数组 */ pctr pfunclist_m1[6] { m1_uhwl, m1_vhul, m1_vhwl, m1_whvl, m1_uhvl, m1_whul }; /** * brief U相上桥臂导通V相下桥臂导通 * param 无 * retval 无 */ void m1_uhvl(void) { g_atimx_handle.Instance-CCR1 g_bldc_motor1.pwm_duty; /* U相上桥臂PWM */ g_atimx_handle.Instance-CCR2 0; g_atimx_handle.Instance-CCR3 0; HAL_GPIO_WritePin(M1_LOW_SIDE_V_PORT,M1_LOW_SIDE_V_PIN,GPIO_PIN_SET); /* V相下桥臂导通 */ HAL_GPIO_WritePin(M1_LOW_SIDE_U_PORT,M1_LOW_SIDE_U_PIN,GPIO_PIN_RESET); /* U相下桥臂关闭 */ HAL_GPIO_WritePin(M1_LOW_SIDE_W_PORT,M1_LOW_SIDE_W_PIN,GPIO_PIN_RESET); /* W相下桥臂关闭 */ } /** * brief U相上桥臂导通W相下桥臂导通 * param 无 * retval 无 */ void m1_uhwl(void) { g_atimx_handle.Instance-CCR1 g_bldc_motor1.pwm_duty; g_atimx_handle.Instance-CCR2 0; g_atimx_handle.Instance-CCR3 0; HAL_GPIO_WritePin(M1_LOW_SIDE_W_PORT,M1_LOW_SIDE_W_PIN,GPIO_PIN_SET); HAL_GPIO_WritePin(M1_LOW_SIDE_U_PORT,M1_LOW_SIDE_U_PIN,GPIO_PIN_RESET); HAL_GPIO_WritePin(M1_LOW_SIDE_V_PORT,M1_LOW_SIDE_V_PIN,GPIO_PIN_RESET); } /** * brief V相上桥臂导通W相下桥臂导通 * param 无 * retval 无 */ void m1_vhwl(void) { g_atimx_handle.Instance-CCR10; g_atimx_handle.Instance-CCR2 g_bldc_motor1.pwm_duty; g_atimx_handle.Instance-CCR30; HAL_GPIO_WritePin(M1_LOW_SIDE_W_PORT,M1_LOW_SIDE_W_PIN,GPIO_PIN_SET); HAL_GPIO_WritePin(M1_LOW_SIDE_U_PORT,M1_LOW_SIDE_U_PIN,GPIO_PIN_RESET); HAL_GPIO_WritePin(M1_LOW_SIDE_V_PORT,M1_LOW_SIDE_V_PIN,GPIO_PIN_RESET); } /** * brief V相上桥臂导通U相下桥臂导通 * param 无 * retval 无 */ void m1_vhul(void) { g_atimx_handle.Instance-CCR1 0; g_atimx_handle.Instance-CCR2 g_bldc_motor1.pwm_duty; g_atimx_handle.Instance-CCR3 0; HAL_GPIO_WritePin(M1_LOW_SIDE_U_PORT,M1_LOW_SIDE_U_PIN,GPIO_PIN_SET); HAL_GPIO_WritePin(M1_LOW_SIDE_V_PORT,M1_LOW_SIDE_V_PIN,GPIO_PIN_RESET); HAL_GPIO_WritePin(M1_LOW_SIDE_W_PORT,M1_LOW_SIDE_W_PIN,GPIO_PIN_RESET); } /** * brief W相上桥臂导通U相下桥臂导通 * param 无 * retval 无 */ void m1_whul(void) { g_atimx_handle.Instance-CCR1 0; g_atimx_handle.Instance-CCR2 0; g_atimx_handle.Instance-CCR3 g_bldc_motor1.pwm_duty; HAL_GPIO_WritePin(M1_LOW_SIDE_U_PORT,M1_LOW_SIDE_U_PIN,GPIO_PIN_SET); HAL_GPIO_WritePin(M1_LOW_SIDE_V_PORT,M1_LOW_SIDE_V_PIN,GPIO_PIN_RESET); HAL_GPIO_WritePin(M1_LOW_SIDE_W_PORT,M1_LOW_SIDE_W_PIN,GPIO_PIN_RESET); } /** * brief W相上桥臂导通V相下桥臂导通 * param 无 * retval 无 */ void m1_whvl(void) { g_atimx_handle.Instance-CCR1 0; g_atimx_handle.Instance-CCR2 0; g_atimx_handle.Instance-CCR3 g_bldc_motor1.pwm_duty; HAL_GPIO_WritePin(M1_LOW_SIDE_V_PORT,M1_LOW_SIDE_V_PIN,GPIO_PIN_SET); HAL_GPIO_WritePin(M1_LOW_SIDE_U_PORT,M1_LOW_SIDE_U_PIN,GPIO_PIN_RESET); HAL_GPIO_WritePin(M1_LOW_SIDE_W_PORT,M1_LOW_SIDE_W_PIN,GPIO_PIN_RESET); }调用int watchtemp0; void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if(htim-Instance ATIM_TIMX_PWM) /* 55us */ { #ifdef H_PWM_L_ON if(g_bldc_motor1.run_flag RUN) { watchtemp; if(g_bldc_motor1.dir CW) /* 正转 */ { g_bldc_motor1.step_sta hallsensor_get_state(MOTOR_1); /* 顺序6,2,3,1,5,4 */ } else /* 反转 */ { g_bldc_motor1.step_sta 7 - hallsensor_get_state(MOTOR_1); /* 顺序5,1,3,2,6,4 。使用7减完后可与数组pfunclist_m1对应上顺序 实际霍尔值为2,6,4,5,1,3*/ } if((g_bldc_motor1.step_sta 6)(g_bldc_motor1.step_sta 1))/* 判断霍尔组合值是否正常 */ { pfunclist_m1[g_bldc_motor1.step_sta-1](); /* 通过数组成员查找对应的函数指针 */ } else /* 霍尔传感器错误、接触不良、断开等情况 */ { stop_motor1(); g_bldc_motor1.run_flag STOP; } } #endif } }实验结果定时器中断时间加大需要更大的占空比才能启动。