本节虽然使用电机模块, 但是主要使用到的就是定时器的 PWM 来驱动.
像舵机一样, 有刷电机同样需要 PWM 来驱动, 只不过不想舵机一样有硬性要求, 需要达到多少频率, 多少占空比才能够进行工作.
有刷电机是一种更加灵活的, 可以控制的电机类型.
前置介绍
实验目的与模块介绍

实验引脚

TB6612FNG 驱动模块


AO1 和 AO2 就可以连接一个直流电机 进行控制
BO1 和 BO2 也可以连接一个直流电机 进行控制
VM 电机驱动电压输入引脚, 即该电源是给电机的.
PWMA / B: A / B 通道 PWM 输入引脚, 即需通过 STM32 输入 PWM 到引脚中, 才能够驱动电机. (电机转速则由 PWM 占空比决定)
AIN1 和 AIN2 即逻辑输入引脚, 输入不同的电平来控制电机的正反转.
BIN1 和 BIN2 同理, 输入不同的电平来控制电机的正反转.
首先 AO1 和 AO2 是电源, 电机的输出引脚, 不需要配置
GND 需要进行接地.
还有连接芯片的 VCC 和 GND. 用来供给驱动芯片工作.
而 电机的驱动电源 VM 需要连接 5V 的供电引脚.
STM32 要使用的引脚用 PWM 引脚连接 PWMA,
然后再用两个 GPIO 连接 AIN2 和 AIN1 来控制电机的方向.
同时, 还可以用一个 GPIO 引脚来连接 STBY (待机引脚), 控制芯片的工作.
即总共需要用到 STM32 的 4 个引脚


|----|--------|--------|-------|------|
| 状态 | 导通的开关 | 截止的开关 | 电流方向 | 电机动作 |
| 正转 | Q1, Q4 | Q2, Q3 | 左 → 右 | 正向旋转 |
| 反转 | Q2, Q3 | Q1, Q4 | 右 → 左 | 反向旋转 |
关键提示:
- 严禁直通(Shoot-through): 在同一个侧臂(例如Q1和Q2,或者Q3和Q4)不能同时导通。如果Q1和Q2同时导通,电源VM会直接短路到地,导致电路烧毁。



PWM 配置的极性是高电平, 占空比越大, 电机转速越高, 反之, 极性是低电平, 占空比越大, 电机转速越低.
项目配置
TIM3

先点击 PB0, 选择 TIM3_CH3, 然后在 TIM3 中, 将 Channel3 改为 PWM Generation CH3
PSC : 72-1
ARR : 100-1
auto-reload preload : Enabel
其余默认即可
GPIO
(GPIO_Output) AIN1 , AIN2 控制方向的引脚 : PA4, PA5
(GPIO_Output) STBY 控制工作模式 : PA7
(GPIO_Input) 按键引脚 : PA0, PA13

按照图中红框处, 将两个按键输入引脚的标签改为 KEY1 和 KEY2, 并设置 下拉模式 (pull-down)
其他引脚的标签改为图中对应的引脚功能名称
代码部分
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
// 建议使用 20% 到 80% 的占空比, 如果过高或者过低, 可能会出现其他问题.
#define SPEED_LOW 20 // 低速, 占空比 20%
#define SPEED_HIGH 80 // 高速, 占空比 80%
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
uint8_t speed_mode = 0; // 0=慢速, 1=快速
uint8_t direction_mode = 0; // 0=正转, 1=反转
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/**
* @brief 设置电机的转向和转速
* @param direction: 方向控制: 0 为正转, 1 为反转
* @param speed: PWM 占空比 (范围 0~100), 值越大转速越快 (PWM极性为High的情况下)
* @retval 无
* @note 使用 TIM3 通道 3 输出 PWM 控制转速, AIN1 / AIN2 控制方向
*/
void Motor_Set(uint8_t direction, uint16_t speed)
{
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_3, speed); // 设置占空比
if (direction == 0) // 正转
{
HAL_GPIO_WritePin(AIN1_GPIO_Port, AIN1_Pin, GPIO_PIN_SET); // AIN1 高电平
HAL_GPIO_WritePin(AIN2_GPIO_Port, AIN2_Pin, GPIO_PIN_RESET); // AIN2 低电平
}
else // 反转
{
HAL_GPIO_WritePin(AIN1_GPIO_Port, AIN1_Pin, GPIO_PIN_RESET); // AIN1 低电平
HAL_GPIO_WritePin(AIN2_GPIO_Port, AIN2_Pin, GPIO_PIN_SET); // AIN2 高电平
}
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_TIM3_Init();
/* USER CODE BEGIN 2 */
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_3); // 开启 PWM 输出 (PB0-TIM3-CH3)
HAL_GPIO_WritePin(STBY_GPIO_Port, STBY_Pin, GPIO_PIN_SET); // STBY 拉高使能电机驱动芯片
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
// 初始情况 PWM 为 0, AIN1 和 AIN2 也为 0 , 电机是停止状态
// 只有当按下按键(KEY1 或者 KEY2), 才能够设置电机的转速和方向, 电机才会被驱动.
if (HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == GPIO_PIN_SET) // KEY1 切换速度模式
{
// 切换速度模式 (0: 低速, 1: 高速)
speed_mode = !speed_mode;
// 根据当前速度模式选择对应占空比
uint16_t speed = (speed_mode == 0) ? SPEED_LOW : SPEED_HIGH;
// 设置电机转向和速度
Motor_Set(direction_mode, speed);
while(HAL_GPIO_ReadPin(KEY1_GPIO_Port, KEY1_Pin) == GPIO_PIN_SET); // 等待松手
}
if (HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == GPIO_PIN_SET) // KEY2 切换方向模式
{
// 切换方向模式 (0: 正转, 1: 反转)
direction_mode = !direction_mode;
// 根据当前速度模式选择对应占空比
uint16_t speed = (speed_mode == 0) ? SPEED_LOW : SPEED_HIGH;
// 设置电机转向和速度
Motor_Set(direction_mode, speed);
while(HAL_GPIO_ReadPin(KEY2_GPIO_Port, KEY2_Pin) == GPIO_PIN_SET); // 等待松手
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
程序现象
参考接线:

通过按键 KEY1 切换速度, 按键 KEY2 切换旋转方向.



分别对应
正转-慢速
正转-快速
反转-慢速