目录
一、驱动方式选择
1.编码器识别序号
2.PWM控制方案
3.驱动板与单片机接线
驱动板接口 | I/O |
5V_IN | +5V |
GND | GND |
W+ | PA8 |
V+ | PA9 |
U+ | PA10 |
W- | PA7 |
V- | PB0 |
U- | PB1 |
HW | PB8 |
HV | PB7 |
HU | PB6 |
SD | PA0 |
key_add | PB12 |
key_down | PB13 |
key_sotp | PB14 |
二、使用cubemx配置基本工程
1.先选用外部时钟
2.配置时钟树
3.选择调试模式
4.配置TIM1的3路pwm,频率10KHz
5.配置TIM4的霍尔编码器,采样频率为10KHz
6.配置SD、pwm互补通道、以及按键
7.如需串口通信,自行配置usart2
三、移植部分野火驱动无刷电机代码
1.先开启pwm,在while(1)前
HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);
HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_2);
HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_3);
2.motor.c
/**
* @brief 使能霍尔传感器
* @param 无
* @retval 无
*/
void hall_enable(void)
{
/* 使能霍尔传感器接口 */
__HAL_TIM_ENABLE_IT(&htim4, TIM_IT_TRIGGER);
__HAL_TIM_ENABLE_IT(&htim4, TIM_IT_UPDATE);
HAL_TIMEx_HallSensor_Start(&htim4);
HAL_TIM_TriggerCallback(&htim4); // 执行一次换相
}
/**
* @brief 禁用霍尔传感器
* @param 无
* @retval 无
*/
void hall_disable(void)
{
/* 禁用霍尔传感器接口 */
__HAL_TIM_DISABLE_IT(&htim4, TIM_IT_TRIGGER);
__HAL_TIM_DISABLE_IT(&htim4, TIM_IT_UPDATE);
HAL_TIMEx_HallSensor_Stop(&htim4);
}
/**
* @brief 停止pwm输出
* @param 无
* @retval 无
*/
void stop_pwm_output(void)
{
__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_3,0); //U+
__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_2,0); //V+
__HAL_TIM_SetCompare(&htim1,TIM_CHANNEL_1,0); //W+
//普通IO初始化,驱动3个下桥臂
HAL_GPIO_WritePin(PWM_U__GPIO_Port,PWM_U__Pin,GPIO_PIN_RESET);//UL//GPIO_PIN_SET GPIO_PIN_RESET
HAL_GPIO_WritePin(PWM_V__GPIO_Port,PWM_V__Pin,GPIO_PIN_RESET);//VL
HAL_GPIO_WritePin(PWM_W__GPIO_Port,PWM_W__Pin,GPIO_PIN_RESET);//WL
}
/**
* @brief 使能电机
* @param 无
* @retval 无
*/
void set_bldcm_enable(void)
{
BLDCM_ENABLE_SD();
HAL_Delay(1);
hall_enable();
}
/**
* @brief 禁用电机
* @param 无
* @retval 无
*/
void set_bldcm_disable(void)
{
/* 禁用霍尔传感器接口 */
hall_disable();
/* 停止 PWM 输出 */
stop_pwm_output();
/* 关闭 MOS 管 */
BLDCM_DISABLE_SD();
}
//获取霍尔传感器值
uint8_t get_hall_state(void)
{
uint8_t state = 0;
#if 1
/* 读取霍尔传感器 U 的状态 */
if(HAL_GPIO_ReadPin(HU_GPIO_Port, HU_Pin) != GPIO_PIN_RESET)
{
state|= 0x01U << 0;
}
/* 读取霍尔传感器 V 的状态 */
if(HAL_GPIO_ReadPin(HV_GPIO_Port, HV_Pin) != GPIO_PIN_RESET)
{
state |= 0x01U << 1;
}
/* 读取霍尔传感器 W 的状态 */
if(HAL_GPIO_ReadPin(HW_GPIO_Port, HW_Pin) != GPIO_PIN_RESET)
{
state |= 0x01U << 2;
}
#else
state = (GPIOH->IDR >> 10) & 7; // 读 3 个霍尔传感器的状态
#endif
if(state==1)
hall_count++;
//printf("stateL:%d\n",state);
return state; // 返回传感器状态
}
/******以下自己添加的********************/
uint32_t get_motor_speed(void)
{
uint32_t dat;
dat = hall_count / 2;
hall_count = 0;
return dat;
}
uint16_t set_motor_speed(void)
{
static uint16_t speed = 40;
uint8_t key_num;
static uint8_t key1_tem = 0;
key_num = KEY_Scan(0);
if (key_num == 1)
{
key1_tem++;
}
else if (key_num == 2)
speed -= 5;
else if (key_num == 3)
speed += 5;
if (key1_tem % 2 == 1)
{
set_bldcm_enable();
}
if (speed < 6)
speed = 6;
if (speed > 80)
speed = 80;
return speed;
}
3. 霍尔传感器中断回调函数
void HAL_TIM_TriggerCallback(TIM_HandleTypeDef *htim)
{
uint8_t state = 0;
state = get_hall_state();
switch (state)
{
case 1: /* U+ W- */
__HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_3, pwm_pulse); // U+
__HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_2, 0); // V+
__HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_1, 0); // W+
HAL_GPIO_WritePin(PWM_U__GPIO_Port, PWM_U__Pin, GPIO_PIN_RESET); // U- //GPIO_PIN_SET GPIO_PIN_RESET
HAL_GPIO_WritePin(PWM_V__GPIO_Port, PWM_V__Pin, GPIO_PIN_RESET); // V-
HAL_GPIO_WritePin(PWM_W__GPIO_Port, PWM_W__Pin, GPIO_PIN_SET); // W-
break;
case 2: /* V+ U- */
__HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_3, 0); // U+
__HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_2, pwm_pulse); // V+
__HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_1, 0); // W+
HAL_GPIO_WritePin(PWM_U__GPIO_Port, PWM_U__Pin, GPIO_PIN_SET); // U- //GPIO_PIN_SET GPIO_PIN_RESET
HAL_GPIO_WritePin(PWM_V__GPIO_Port, PWM_V__Pin, GPIO_PIN_RESET); // V-
HAL_GPIO_WritePin(PWM_W__GPIO_Port, PWM_W__Pin, GPIO_PIN_RESET); // W-
break;
case 3: /* V+ W- */
__HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_3, 0); // U+
__HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_2, pwm_pulse); // V+
__HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_1, 0); // W+
HAL_GPIO_WritePin(PWM_U__GPIO_Port, PWM_U__Pin, GPIO_PIN_RESET); // U- //GPIO_PIN_SET GPIO_PIN_RESET
HAL_GPIO_WritePin(PWM_V__GPIO_Port, PWM_V__Pin, GPIO_PIN_RESET); // V-
HAL_GPIO_WritePin(PWM_W__GPIO_Port, PWM_W__Pin, GPIO_PIN_SET); // W-
break;
case 4: /* W+ V- */
__HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_3, 0); // U+
__HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_2, 0); // V+
__HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_1, pwm_pulse); // W+
HAL_GPIO_WritePin(PWM_U__GPIO_Port, PWM_U__Pin, GPIO_PIN_RESET); // U- //GPIO_PIN_SET GPIO_PIN_RESET
HAL_GPIO_WritePin(PWM_V__GPIO_Port, PWM_V__Pin, GPIO_PIN_SET); // V-
HAL_GPIO_WritePin(PWM_W__GPIO_Port, PWM_W__Pin, GPIO_PIN_RESET); // W-
break;
case 5: /* U+ V -*/
__HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_3, pwm_pulse); // U+
__HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_2, 0); // V+
__HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_1, 0); // W+
HAL_GPIO_WritePin(PWM_U__GPIO_Port, PWM_U__Pin, GPIO_PIN_RESET); // U- //GPIO_PIN_SET GPIO_PIN_RESET
HAL_GPIO_WritePin(PWM_V__GPIO_Port, PWM_V__Pin, GPIO_PIN_SET); // V-
HAL_GPIO_WritePin(PWM_W__GPIO_Port, PWM_W__Pin, GPIO_PIN_RESET); // W-
break;
case 6: /* W+ U- */
__HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_3, 0); // U+
__HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_2, 0); // V+
__HAL_TIM_SetCompare(&htim1, TIM_CHANNEL_1, pwm_pulse); // W+
HAL_GPIO_WritePin(PWM_U__GPIO_Port, PWM_U__Pin, GPIO_PIN_SET); // U- //GPIO_PIN_SET GPIO_PIN_RESET
HAL_GPIO_WritePin(PWM_V__GPIO_Port, PWM_V__Pin, GPIO_PIN_RESET); // V-
HAL_GPIO_WritePin(PWM_W__GPIO_Port, PWM_W__Pin, GPIO_PIN_RESET); // W-
break;
}
}
4.while(1)里 ,使用printf前先重定义
/* USER CODE BEGIN WHILE */
uint16_t t;
while (1)
{
t++;
pwm_pulse=set_motor_speed();
if(t>60000)
{
t=0;
HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
printf("pwm_pulse:%4d\tspeed:%6d\r\n",pwm_pulse,get_motor_speed());
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
5.工程下载
链接:https://pan.baidu.com/s/1TuqtS7-SCrIyJOy_Fb_XuQ
提取码:1234
6.注意事项
1)确认接线正确;
2)使用驱动板为野火系列无刷驱动板,其有隔离与防上下桥导通逻辑电路,在其它驱动板上必须确保你的这个换相逻辑和你的板子是对应起来的;
3)若刚开始不转,可以手动转动电机转轴,以触发中断回调;
4)pwm控制方案不唯一,可自行调整
四、测试视频
VID_20230420_203226