首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

BLDC控制实验:方波、霍尔、开环、定速、正转

  • 23-09-22 01:23
  • 4757
  • 5421
blog.csdn.net

本文记录博主学习BLDC控制软件的过程。

文章目录

  • 1 概述
  • 2 软件架构及工具链
    • 2.1 软件架构
    • 2.2 工具链
  • 3 底层代码生成
    • 3.1 时钟配置
    • 3.2 按键输入配置
    • 3.3 串口通信配置
    • 3.4 霍尔信号外部中断配置
    • 3.5 MOS管导通开关配置
  • 4 接口及配置代码
    • 4.1 系统定时器重装载值
    • 4.2 按键输入接口函数
    • 4.3 重定向printf函数
    • 4.4 霍尔信号状态函数
    • 4.5 MOS管导通控制函数
    • 4.6 电机启停函数
  • 5 应用层模型及代码生成
    • 5.1 基于模型设计(MBD)方案
    • 5.2 低频任务子系统
    • 5.3 霍尔中断子系统
    • 5.4 代码生成及调用
  • 6 总结

1 概述

本文是博主第一次做BLDC控制实验,内容只是写代码让BLDC转起来,而暂时不考虑其他复杂的需求。

控制的方法是比较简单的六步换相法。利用电机内部的霍尔传感器,通过参考电机厂家给出的二二导通换相表,生成方波来控制电机。第一次实验为了简化需求,只考虑开环、定速、正转的情况:

  • 开环:不考虑速度反馈,直接给PWM让电机转起来;
  • 定速:不考虑速度调节,换相的时候给的PWM都是相同的值;
  • 正转:只参考换相表中正转的部分,不考虑反转;

所以,实验目标为,通过按下开发板上的Key1按键使BLDC低速运转,按下Key2按键使BLDC停止运转。

本实验需要BLDC六步换相的理论作为知识储备。

2 软件架构及工具链

2.1 软件架构

博主根据自己的工作习惯和经验,制订出实验的软件架构如下:
在这里插入图片描述
其中,各个板块的含义如下:

  • ASW:应用层软件,包含电机控制策略和算法;
  • BSW:底层软件,包含驱动Stm32的寄存器配置;
  • Interface:接口层软件,为底层和应用层之间的接口函数;
  • UI:调试开发板所用的代码;

2.2 工具链

对于架构中不同的板块,博主也根据经验选择合适的工具链进行开发。

  • Matlab/Simulink:基于模型开发的利器,非常适用于应用层软件开发。首先在Simulink中创建控制策略的模型,再用Embedded Coder组件生成C代码;
  • CubeMX:ST公司开发的用于配置STM32的工具,通过配置时钟和外设引脚,可以生成标准的HAL库,可用于BSW代码的生成;
  • MDK:STM32的编译环境,用于编译、调试软件并下载到控制器中,Interface的手写代码也在其中完成;
  • 串口调试助手:用于监测程序运行过程中的一些变量值;

3 底层代码生成

本章节会结合原理图,研究配置CubeMX生成底层代码。

3.1 时钟配置

博主用的开发板是STM32F405RGT6,在CubeMX中将时钟源设置为外部晶振。
在这里插入图片描述
时钟数配置如下图。
在这里插入图片描述
由于后续的低频任务会运行在系统定时器中断里,所以这里需要留意一下系统定时器的频率为168MHz,也就是1秒钟计数168000000次。

3.2 按键输入配置

在本实验中,开发板上的按键是用于告诉单片机启动或停止电机的请求。开发板上焊接了5个按键模块,如下图。本实验只需要用SW1和SW2两个。
在这里插入图片描述
以SW1为例,它的左端接地,右端连接到单片机的PC13引脚,如下图。
在这里插入图片描述
所以在CubeMX中配置PC13引脚的模式为输入模式,并配置为上拉。
在这里插入图片描述
这样的配置表示,PC13引脚接收到低电平时,按键SW1被按下,接收到高电平时,按键SW1没有被按下。SW2的按键引脚配置类似。

3.3 串口通信配置

串口通信可以将单片机运行过程中的全局变量发送到PC上,然后通过串口调试助手读取信息,是一种验证问题的常规方式。

从原理图可以看出,PB10和PB11引脚是串口3发送和接收的引脚。
在这里插入图片描述
首先将串口模式设置为Asynchronous,也就是异步通信。
在这里插入图片描述
然后是一些参数设置,包括波特率、字长度等。这里的设置将和PC上的串口调试助手相对应。
在这里插入图片描述
最后是NVIC中断优先级设置,这里暂时设置为如下图。
在这里插入图片描述

3.4 霍尔信号外部中断配置

六步换相法控制BLDC需要根据霍尔传感器信号输入来判断导通哪些MOS管,因此需要配置3个引脚来分别接收A相,B相,C相三个霍尔信号。
在这里插入图片描述
从原理图中可以看出,PB6,PB7,PB8这三个引脚分别对应着A相,B相,C相,所以接下来需要在CubeMX中配置这三个引脚。以PB6为例,在CubeMX中如下。
在这里插入图片描述
在这里插入图片描述
首先,GPIO_EXTI表示用于GPIO的外部中断。GPIO mode配置成了上升或下降沿触发的外部中断,也就是说,当电机转动导致了霍尔信号变化的时候,会触发外部中断。这一点很重要,因为在该中断回调函数里,会执行换相逻辑。

3.5 MOS管导通开关配置

STM32通过控制引脚输出PWM或GPIO电平,来导通MOS管,从而实现了BLDC的换相控制。由于采用了H PWM-L ON的控制方式,上桥由PWM驱动,下桥由高低电平驱动。

以A相为例,原理图如下。左边的TIM1_CH是PWM,TIM1_CHN是高低电平。
在这里插入图片描述
然后顺藤摸瓜找到对应的引脚,TIM1_CH对应PA8,TIM1_CHN对应PB13。
在这里插入图片描述
接着就可以在CubeMX分别配置PWM输出和GPIO输出。
在这里插入图片描述
这里博主将上桥PWM配置为Up向上计数,重装载值为12000。也就是说后面进行输出比较的时候,范围是0~12000。
在这里插入图片描述
下桥的GPIO配置为推挽输出,初始为低电平。

以上配置完成后,就可以生成Keil工程了。

4 接口及配置代码

本章节会在Keil中手写一些代码,作为两方面用处。一方面是为应用层软件配置好输入输出接口函数,另一方面是调用Hal库函数对底层进一步配置。

4.1 系统定时器重装载值

在main文件的初始化代码段加上如下函数:

HAL_SYSTICK_Config(168000U);
  • 1

该函数用于配置系统定时器重装载值为168000。结合前文将系统时钟配置为168MHz,重装载值配置为168000就意味着通过系统定时器产生1ms中断。在中断函数SysTick_Handler中将执行低频任务。

4.2 按键输入接口函数

在main文件中配置如下按键输入接口函数,调用该函数可以返回按键状态(1或0)。

// Get Key State
uint8_t Get_Key1State(void)
{
	return((uint8_t)(!HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13)));
}

uint8_t Get_Key2State(void)
{
	return((uint8_t)(!HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_0)));
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

博主习惯于将输入的接口函数以Get_开头,其实相当于封装了一层统一的命名,并简化传参。这里的Get函数中调用了Hal库的读取GPIO pin脚的函数,并对返回值取反,使得返回1代表按键按下,0代表按键没有按下。

4.3 重定向printf函数

在main文件中重新定义fputc 函数:

int fputc(int ch, FILE *f)
{
	HAL_UART_Transmit(&huart3, (uint8_t *)&ch, 1, 0xFFFF);
	return (ch);
}
  • 1
  • 2
  • 3
  • 4
  • 5

通过这种方式,就可以用printf函数将全局变量打印到PC上。本文的实验比较简单,没有做UI上位机,就用串口调试助手查看电机运行的实时数据了。

4.4 霍尔信号状态函数

在main文件中配置霍尔信号状态接收函数,调用该函数可以返回霍尔传感器状态(1或0)。

// Get Hall State
uint8_t Get_HallAState(void)
{
	return HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_6);
}

uint8_t Get_HallBState(void)
{
	return HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7);
}

uint8_t Get_HallCState(void)
{
	return HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_8);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

应用层调用霍尔信号状态函数可以获取当前的A,B,C三相的霍尔传感器状态,然后查阅换相表得到导通的MOS管。

4.5 MOS管导通控制函数

在main文件中配置MOS管导通控制函数,调用该函数可以设置MOS管的开关或者PWM。

// Mos
void Set_T1PWM(uint32_t PWMValue)
{
	__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_1,PWMValue);
}

void Set_T3PWM(uint32_t PWMValue)
{
	__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_2,PWMValue);
}

void Set_T5PWM(uint32_t PWMValue)
{
	__HAL_TIM_SET_COMPARE(&htim1,TIM_CHANNEL_3,PWMValue);
}

void Set_T2Status(uint8_t State)
{
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13,(GPIO_PinState)State);
}

void Set_T4Status(uint8_t State)
{
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14,(GPIO_PinState)State);
}

void Set_T6Status(uint8_t State)
{
	HAL_GPIO_WritePin(GPIOB, GPIO_PIN_15,(GPIO_PinState)State);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

其中,T1,T3,T5是上桥,在CubeMX配置为定时器PWM,因此传入的是输出比较值;T2,T4,T6是下桥,配置为GPIO输出,因此传入0或1的状态,来控制导通与断开。这里传入的PWMValue是0~12000,因为CubeMX中配置重装载值为12000。

4.6 电机启停函数

在main文件中配置电机启停函数,调用该函数可以启动或停止定时器通道,从而达到启停电机的效果。

// Set_StartStopMotor
void Set_StartStopMotor(uint8_t State)
{
	if(State == 0) //Stop Motor
	{
		HAL_TIM_PWM_Stop(&htim1,TIM_CHANNEL_1);
		HAL_TIM_PWM_Stop(&htim1,TIM_CHANNEL_2);
		HAL_TIM_PWM_Stop(&htim1,TIM_CHANNEL_3);
	}
	else
	{
		HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);
		HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_2);
		HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_3);
	}
	
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

Set函数会根据传入的State参数来判断调用Stop或是Start的Hal库函数。

5 应用层模型及代码生成

本实验的电机控制应用层软件采用Simulink建模并生成代码。

5.1 基于模型设计(MBD)方案

Matlab/Simulink软件的灵活性很强,可以定制化生成各式各样的代码。博主按照自己的建模习惯,制定了本小节的MBD方案,但不是Matlab/Simulink的唯一用法。

首先,将所有控制策略做在一个模型文件和数据字典中,命名为MotorControl,如下图所示。
在这里插入图片描述
数据字典中定义了枚举量、Signal对象等,并根据需要设定Storage Class和头文件。
在这里插入图片描述
模型的顶层调用了两个function-call子系统,分别对应系统定时器中断中运行的低频任务,和霍尔传感器外部中断中运行的换相任务。在代码生成的时候会生成SystickTask和HallExitTask两个函数。

在这里插入图片描述
下面博主会叙述自己设计的BLDC控制策略,如有不当之处,希望能够交流探讨。

5.2 低频任务子系统

本实验中的低频任务只做两件事,电机状态机建模、启动停止控制。输入为按键状态、霍尔传感器状态,输出为电机状态。

1)首先是按键输入监测,调用了Get_Key1State()接口函数,并通过延时两个周期判断产生了上升沿。
在这里插入图片描述
这部分做了两个延时,也就是,第一个周期Key1State为0,然后连续两个周期为1的情况时,视为一次启动电机的请求(StartMotorReq置为1)。

2)电机状态机,Stateflow中共有4个状态:Init,Start,Run,Stop。
在这里插入图片描述

电机状态机的输入为启动或停止电机的请求。默认进入Init初始化状态,如果产生了启动电机请求(StartMotorReq)则跳转到Start状态。如果在Start状态停留了10个周期(StartCount == 10),则进入Run状态。当产生了停止电机请求(StopMotorReq),无论当前为Start状态还是Run状态都会跳入Stop状态。

进入Start或是Stop状态的时候,会产生一个事件(Event)用于触发外面的子系统。

每个状态进入时,都会输出MotorState,作为状态机外面的逻辑判断的依据。

3)电机启动的时候还未进入霍尔传感器引起的中断,在该状态中也需要进行启动时的换相函数。首先通过Get_HallXState函数获取三个霍尔传感器的状态,再通过移位进行组装合成。
在这里插入图片描述
A相左移2位,B相左移1位,C相不移位。例如A,B,C三相分别是1,0,1时,

HallState = (A << 2) + (B << 1) + C = 4 + 0 + 1 = 5
  • 1

后面的模型会通过HallState 输入到查表模块(1D Lookup Table)中来判断哪些MOS管需要导通。然后通过调用Set函数导通Mos管。
在这里插入图片描述
PWMValue的值在数据字典中定义为2000。这是因为本实验做开环定速旋转,设的过高会引起启动时的抖动。

5.3 霍尔中断子系统

霍尔中断子系统中的模型中没有电机状态机的部分,其余的和5.2 低频任务子系统相似,也是根据霍尔传感器的状态判断导通MOS管。但是有一点区别在于该子系统需要输出HallExtiFlag,也就是霍尔激活标志位。
在这里插入图片描述

5.4 代码生成及调用

将模型MotorControl.slx配置好Embedded Coder后,Ctrl + B生成代码。
在这里插入图片描述
顶层的两个子系统分别生成了HallExtiTask.c和SystickTask.c两个c文件,并且其中包含了同名的函数。这两个函数就是上文两个子系统对应的代码。
在这里插入图片描述
MotorControl.c中生成了一个初始化函数MotorControl_initialize(),用于将模型中定义的全局变量初始化为0。

将所有的C文件和头文件拷贝到Keil工程中,然后在三个地方分别调用。
1)在main函数中调用初始化函数MotorControl_initialize();
在这里插入图片描述
2)在系统定时器中断函数中调用SystickTask();
在这里插入图片描述
3)在霍尔传感器中断回调函数中调用HallExtiTask();
在这里插入图片描述
另外,调用函数需要加上对应的头文件,否则编译无法通过。

最后在Keil中编译软件,并通过ST-Link下载到单片机中。尝试按下按键1和按键2,验证是否可以启动和停止。

6 总结

博主第一次做电机控制实验,感觉还是很有意思的。后面会按照本文的方法论去继续研究BLDC的控制。

>>返回个人博客总目录

注:本文转载自blog.csdn.net的chhttty的文章"https://blog.csdn.net/u013288925/article/details/118855066"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2024 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top