前言
主控板STM32F302R8+驱动板X-NUCLEO-IHM07M1+直流无刷电机WR36BL61,采用六步换相法实现电机的正反转驱动。 关于X-NUCLEO-IHM07M1驱动板的介绍,请阅读: 直流有刷电机驱动基于STM32F302R8+X-NUCLEO-IHM07M1(一) 直流无刷电机的驱动原理请阅读: 直流无刷电机及Matlab/Simulink驱动仿真
一、STM32F302R8+X-NUCLEO-IHM07M1驱动直流无刷电机
1.1.功能需求
驱动直流无刷电机转动,并实现直流无刷电机的换向控制;按下一次按键电机正转;再按一次按键电机停止;再按一次按键电机反转;再按一次按键电机停止,以此循环。
1.2.硬件设计
控制板:STM32F302R8 驱动板:X-NUCLEO-IHM07M1 直流无刷电机:WR36BL61,额定功率10W,额定电压24V,额定电流0.5A,转速2000RMP,极对数2。
1.3.软件设计
1.3.1.STM32CubeMX底层配置
为了更直观简单的实现直流无刷电机的六步换相控制,将所用引脚均设置为普通I/O口模式。 1、RCC设置为外接时钟,72MHz 2、PA8、PA9、PA10、PC10、PC11、PC12设置为推挽输出、无上下拉电阻、高速,初始化状态设为0;PA15、PB3、PB10设置为输入,无上下拉电阻;PB13设置为推挽输出,下拉电阻、高速,初始化状态为0;PC13设置为输入,无上下拉电阻。 3、使能USART2,异步模式,波特率115200,8位数据位,1位停止位,无奇偶校验位 3、IDE设置为MDK-RAM,在Keil环境中编写应用层程序
1.3.2.应用层开发
在Keil环境中编写应用层程序,实现功能需求。
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART2_UART_Init();
while (1)
{
if(Key_Scany(KEY_GPIO_Port,KEY_Pin)==1)
{
Mode++;
if(Mode>3)
Mode=0;
}
switch(Mode)
{
case 0:
BLDC_Stop();
LED_Stop();
break;
case 1:
BLDC_Driver(1);
LED_Driver();
break;
case 2:
BLDC_Stop();
LED_Stop();
break;
case 3:
BLDC_Driver(0);
LED_Driver();
break;
}
}
}
按键扫描函数Key_Scany()
uint8_t Key_Scany(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
{
if(HAL_GPIO_ReadPin(GPIOx, GPIO_Pin)==0)
{
while(HAL_GPIO_ReadPin(GPIOx, GPIO_Pin)==0);
return 1;
}
else
return 0;
}
电机驱动函数BLDC_Driver()
void BLDC_Driver(uint8_t Direction)
{
static uint8_t Pre_HallState=0;
uint8_t HallState;
HallState=Get_HallState();
if(Pre_HallState!=HallState)
{
HAL_GPIO_WritePin(GPIOC, EN1_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC, EN2_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOC, EN3_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_RESET);
if(Direction==1)
{
switch(HallState)
{
case 1:
HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_SET);
break;
case 5:
HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_RESET);
break;
case 4:
HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_RESET);
break;
case 6:
HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_RESET);
break;
case 2:
HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_SET);
break;
case 3:
HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_SET);
break;
default:
break;
}
}
else
{
switch(HallState)
{
case 1:
HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_RESET);
break;
case 5:
HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_SET);
break;
case 4:
HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_SET);
break;
case 6:
HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_SET);
break;
case 2:
HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_RESET);
break;
case 3:
HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_RESET);
break;
default:
break;
}
}
Pre_HallState=HallState;
}
}
霍尔状态函数Get_HallState()
uint8_t Get_HallState(void)
{
uint8_t HallState;
HallState=HAL_GPIO_ReadPin(H1_GPIO_Port, H1_Pin);
HallState<<=1;
HallState|=HAL_GPIO_ReadPin(GPIOB, H2_Pin);
HallState<<=1;
HallState|=HAL_GPIO_ReadPin(GPIOB, H3_Pin);
return HallState;
}
电机停止函数BLDC_Stop()
void BLDC_Stop(void)
{
HAL_GPIO_WritePin(GPIOC, EN1_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOC, EN2_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOC, EN3_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, IN1_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, IN2_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOA, IN3_Pin, GPIO_PIN_RESET);
}
1.4.编译下载观察试验现象
总结
主控板STM32F302R8+驱动板X-NUCLEO-IHM07M1+直流无刷电机WR36BL61,采用六步换相法实现电机的正反转驱动,为后续章节的分析奠定基础。
|