news 2026/4/23 9:16:07

STM32定时器进阶应用:PWM输出与电机控制实战(基于STM32F103C8T6标准库开发)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM32定时器进阶应用:PWM输出与电机控制实战(基于STM32F103C8T6标准库开发)

1. PWM基础与电机控制原理

PWM(脉冲宽度调制)是控制电机速度最常用的方法之一。简单来说,PWM就是通过快速开关电源来控制平均电压。想象一下水龙头,如果快速开关水龙头,就能控制水流的大小。PWM也是类似的原理,只不过控制的是电流。

在STM32中,定时器可以生成精确的PWM信号。以STM32F103C8T6为例,它有4个通用定时器(TIM2-TIM5),每个定时器有4个独立的通道,都可以输出PWM信号。PWM信号有三个关键参数:

  • 频率:决定PWM信号开关的快慢
  • 占空比:决定高电平所占的比例
  • 分辨率:决定占空比调节的精细程度

对于电机控制来说,PWM频率通常在1kHz-20kHz之间。频率太低会导致电机发出噪音,太高则可能超出驱动电路的响应能力。占空比直接决定了电机的转速,0%占空比电机停止,100%占空比全速运转。

2. 定时器PWM输出配置

2.1 硬件准备与时钟配置

首先需要开启定时器的时钟。STM32F103C8T6的定时器2-4挂在APB1总线上,时钟频率为72MHz(系统时钟经过分频后)。配置步骤如下:

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

接下来配置时基单元,这决定了PWM的基本频率:

TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructure.TIM_Period = 999; // 自动重装载值 TIM_TimeBaseStructure.TIM_Prescaler = 71; // 预分频值 TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

这个配置会产生一个1kHz的PWM信号(72MHz/(71+1)/(999+1)=1kHz)。

2.2 PWM通道配置

配置PWM输出模式,以通道1为例:

TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 500; // 初始占空比50% TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM3, &TIM_OCInitStructure);

最后别忘了使能定时器和PWM输出:

TIM_Cmd(TIM3, ENABLE); TIM_CtrlPWMOutputs(TIM3, ENABLE);

3. 电机驱动电路设计

3.1 H桥驱动原理

要控制直流电机的方向和速度,通常使用H桥电路。H桥由四个开关管组成,可以控制电流方向。常见的H桥驱动芯片有L298N、TB6612等。

以L298N为例,它的基本连接方式:

  • 两个PWM输入控制速度
  • 两个方向控制引脚控制转向
  • 需要外接电源(注意与逻辑电源隔离)

3.2 保护电路设计

电机是感性负载,会产生反向电动势,必须设计保护电路:

  1. 续流二极管:在每个MOSFET上并联快速恢复二极管
  2. 滤波电容:在电源端加装大容量电解电容(100uF以上)
  3. 光耦隔离:防止电机干扰MCU

实际接线时,PWM信号线要尽量短,避免干扰。如果驱动大功率电机,建议使用独立的电源为电机供电。

4. 完整代码实现与调试

4.1 初始化代码整合

将前面的配置整合成一个初始化函数:

void PWM_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; // 开启时钟 RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 配置GPIO GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; // TIM3_CH1 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 定时器基础配置 TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_TimeBaseStructure.TIM_Period = 999; TIM_TimeBaseStructure.TIM_Prescaler = 71; TIM_TimeBaseStructure.TIM_ClockDivision = 0; TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); // PWM通道配置 TIM_OCInitTypeDef TIM_OCInitStructure; TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; TIM_OCInitStructure.TIM_Pulse = 0; // 初始占空比0% TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; TIM_OC1Init(TIM3, &TIM_OCInitStructure); // 使能 TIM_Cmd(TIM3, ENABLE); TIM_CtrlPWMOutputs(TIM3, ENABLE); }

4.2 速度控制函数

添加一个设置占空比的函数:

void Set_Motor_Speed(uint16_t speed) { // 限制速度范围 if(speed > 999) speed = 999; TIM_SetCompare1(TIM3, speed); }

4.3 实际调试技巧

调试时常见问题及解决方法:

  1. 电机不转:检查电源是否接通,PWM信号是否输出
  2. 电机抖动:可能是PWM频率不合适,尝试调整频率
  3. 干扰MCU:检查地线连接,增加滤波电容
  4. 发热严重:检查H桥是否短路,PWM频率是否过高

建议调试步骤:

  1. 先用示波器确认PWM信号正常
  2. 接上电机前先测量输出电压
  3. 从小占空比开始逐步增加
  4. 监测电流防止过载

5. 进阶应用与优化

5.1 闭环速度控制

开环控制容易受负载影响,可以加入编码器实现闭环控制。常见方案:

  1. 光电编码器:通过中断测量脉冲数
  2. 霍尔传感器:成本低但精度较差
  3. 电流检测:通过采样电阻检测电机电流

以编码器为例,STM32的定时器可以直接读取编码器信号:

void Encoder_Init(void) { // 编码器接口模式配置 TIM_EncoderInterfaceConfig(TIM2, TIM_EncoderMode_TI12, TIM_ICPolarity_Rising, TIM_ICPolarity_Rising); TIM_SetCounter(TIM2, 0); TIM_Cmd(TIM2, ENABLE); }

5.2 PID算法实现

PID控制器可以显著改善电机控制性能。简单PID实现:

typedef struct { float Kp, Ki, Kd; float error, lastError, integral; } PID_Controller; float PID_Update(PID_Controller* pid, float setpoint, float measurement) { pid->error = setpoint - measurement; pid->integral += pid->error; float derivative = pid->error - pid->lastError; pid->lastError = pid->error; return pid->Kp * pid->error + pid->Ki * pid->integral + pid->Kd * derivative; }

使用时需要根据实际电机特性调整PID参数,这是一个需要耐心调试的过程。

5.3 多电机同步控制

对于需要协调控制的场合(如机器人),可以使用多个定时器同步触发:

// 配置主从定时器 TIM_SelectInputTrigger(TIM2, TIM_TS_ITR0); // TIM2作为从定时器 TIM_SelectSlaveMode(TIM2, TIM_SlaveMode_Trigger); // 触发模式 TIM_SelectMasterSlaveMode(TIM3, TIM_MasterSlaveMode_Enable); // TIM3作为主定时器 TIM_SelectOutputTrigger(TIM3, TIM_TRGOSource_Update); // 更新事件触发

这样TIM3的更新事件会同步触发TIM2,确保多个电机的PWM信号同步。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/18 16:28:50

PyCharm 终端显示优化

PyCharm 终端美化方案针对PyCharm终端无行号及输出不清晰问题,推荐三种美化方案:1)使用Rich库实现彩色打印;2)用PrettyTable/Tabulate优化表格输出;3)安装GrepConsole插件进行界面美化。特别推荐…

作者头像 李华
网站建设 2026/4/18 15:32:25

如何轻松备份微信聊天记录:WeChatMsg完整使用指南

如何轻松备份微信聊天记录:WeChatMsg完整使用指南 【免费下载链接】WeChatMsg 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 项目地址: https://gitcode.com/GitHub_Trending/we/WeChatMsg…

作者头像 李华
网站建设 2026/4/18 0:27:26

算法是什么

1. 从“做事步骤”到“计算过程” 这一节先回答一个最基本的问题:什么叫算法。 算法是一种定义良好的计算过程。它接收一个或一组输入,经过有限个明确步骤,在有限时间内产生一个或一组输出。也可以说,算法就是把输入转换成输出的一…

作者头像 李华
网站建设 2026/4/18 22:37:17

如何快速免费获取Axure RP中文语言包?5分钟解决界面语言障碍

如何快速免费获取Axure RP中文语言包?5分钟解决界面语言障碍 【免费下载链接】axure-cn Chinese language file for Axure RP. Axure RP 简体中文语言包。支持 Axure 11、10、9。不定期更新。 项目地址: https://gitcode.com/gh_mirrors/ax/axure-cn 如果您正…

作者头像 李华
网站建设 2026/4/18 2:00:02

**Pytest实战进阶:用插件化设计重构测试架构,让自动化测试更优雅高效**在现代软件开发中,**单元测试与集成测试**早已不是可有

Pytest实战进阶:用插件化设计重构测试架构,让自动化测试更优雅高效 在现代软件开发中,单元测试与集成测试早已不是可有可无的环节,而是构建高质量代码的核心保障。而 Pytest 作为 Python 生态中最主流的测试框架之一,凭…

作者头像 李华