您现在的位置是:首页 >学无止境 >通用定时器电机控制程序网站首页学无止境
通用定时器电机控制程序
硬件连接:电源:为电机提供合适的电源电压。
GPIO 引脚:
选择一个定时器的 PWM 输出通道连接到电机驱动模块的 PWM 输入引脚,用于控制电机的转速。
另外选择两个 GPIO 引脚连接到电机驱动模块的方向控制引脚,用于控制电机的正反转。
电机驱动模块:常用的电机驱动模块有 L298N 等,它可以将单片机输出的信号放大,以驱动电机
L298N 电机驱动模块
L298N 的电源输入:
逻辑电源(VSS):通常接 5V,可直接连接到 STM32F4 开发板的 5V 输出引脚,为 L298N 内部的逻辑电路供电。
电机电源(VS):根据所驱动电机的额定电压来选择合适的电源,一般在 5V - 46V 之间。例如,如果电机额定电压是 12V,就接入 12V 电源。同时,为了减少电源噪声的影响,在 VS 和 GND 之间并联一个大容量的电解电容(如 100μF)和一个小容量的陶瓷电容(如 0.1μF)进行滤波。
接地(GND):L298N 的 GND 要和 STM32F4 开发板的 GND 以及电机电源的 GND 连接在一起,形成共地。
控制信号部分
使能引脚:
ENA:用于控制通道 A 的电机使能,连接到 STM32F4 的一个 GPIO 引脚,通过该引脚输出 PWM 信号来控制电机的转速。
ENB:用于控制通道 B 的电机使能,同样连接到 STM32F4 的一个 GPIO 引脚,输出 PWM 信号。
L298N 是一款常用的双全桥步进电机和直流电机驱动芯片,它有两个独立的 H 桥驱动电路,每个 H 桥可以驱动一个直流电机。具体的引脚对应关系如下:
通道 A:IN1 和 IN2 用于控制通道 A 的电机正反转,OUT1 和 OUT2 是连接通道 A 的电机的两个引脚该通道电机的输出引脚,连接电机的两端。
通道 B:IN3 和 IN4 用于控制通道 B 的电机正反转,OUT3 和 OUT4 是接通道 B 的电机的两个引脚该通道电机的输出引脚,连接另一个电机的两端。
散热处理
L298N 在驱动大功率电机时会产生较多热量,因此需要安装合适的散热片,以保证芯片在正常的温度范围内工作,避免因过热导致芯片损坏。
#include "stm32xxxx_hal.h"
TIM_HandleTypeDef htim3;
// 错误处理函数
void Error_Handler(void)
{
while (1)
{
}
}
// 控制电机正转
void Motor_Forward()
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);
}
// 控制电机反转
void Motor_Reverse()
{
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_SET);
}
// 控制电机转速
void Motor_SetSpeed(uint32_t speed)
{
if (speed > htim3.Init.Period)
{
speed = htim3.Init.Period;
}
//主要作用是设置指定定时器的指定通道的比较寄存器(CCR)的值
__HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, speed);
}
// TIM3初始化函数
void TIM3_Init(void)
{
__HAL_RCC_TIM3_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
// 配置PWM输出引脚(PA6连接TIM3_CH1)
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM3;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// 配置电机方向控制引脚(PB0和PB1)
GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
htim3.Instance = TIM3;
htim3.Init.Prescaler = 84 - 1;// 假设系统时钟为84MHz,分频后得到1MHz的计数时钟
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 1000 - 1; // 自动重载值,决定PWM信号的周期,这里周期为1ms
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
{
Error_Handler();
}
//typedef struct
{
uint32_t OCMode; /*!< 指定输出比较模式,如 PWM 模式、翻转模式等 */
uint32_t Pulse; /*!< 指定脉冲值,即比较寄存器的值,影响 PWM 占空比等 */
uint32_t OCPolarity; /*!< 指定输出通道的极性,高电平有效或低电平有效 */
uint32_t OCNPolarity; /*!< 指定互补输出通道的极性,高电平有效或低电平有效 */
uint32_t OCFastMode; /*!< 指定快速模式是否使能 */
uint32_t OCIdleState; /*!< 指定输出通道在空闲状态下的电平 */
uint32_t OCNIdleState; /*!< 指定互补输出通道在空闲状态下的电平 */
} TIM_OC_InitTypeDef;
TIM_OC_InitTypeDef sConfigOC = {0};
sConfigOC.OCMode = TIM_OCMODE_PWM1;
sConfigOC.Pulse = 500;// 初始占空比为50%
sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
if (HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1) != HAL_OK)
{
Error_Handler();
}
}
int main(void)
{
HAL_Init();
TIM3_Init();
while (1)
{
// 电机正转,转速为80%
Motor_Forward();
Motor_SetSpeed(800);
HAL_Delay(2000);
// 电机反转,转速为30%
Motor_Reverse();
Motor_SetSpeed(300);
HAL_Delay(2000);
}
}
注意事项
电源和驱动模块:确保电机的电源和驱动模块能够提供足够的功率,避免电机因功率不足而无法正常工作。
PWM 频率:PWM 频率的选择会影响电机的运行效果,过高或过低的频率可能会导致电机产生噪声、发热等问题,需要根据电机的特性进行调整。
保护电路:在电机控制电路中,建议添加适当的保护电路,如二极管、电容等,以防止电机产生的反电动势损坏单片机和驱动模块