news 2026/2/27 10:38:49

基于STM32的平衡车开发计划-1-PWM设置

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于STM32的平衡车开发计划-1-PWM设置

我们使用的是STM32F103C8T6进行编程和实现。

一.配置一下PWM输出

1.PWM设置

HAL_TIM_PWM_Start(&htim1,TIM_CHANNEL_1);启动PWM

使用的是TIM1的ch1通道,也就是PA8端口,cubemx会自动帮我们配置好。预分频为72,自从重装值1000,采用向上计数模式,占空比为500,那么我们实测的话应该会产生一个占空比500的PWM波形,我们连接到逻辑分析仪,观测波形

2.波形观察

然后逻辑分析仪查看结果。

可以看到确实产生了一个占空比50的PWM波形。

3.动态改变占空比

因为单纯的占空比设置肯定不能满足我们对于平衡车的要求。所一我们测试一下动态改变占空比,再主循环接入一下代码

HAL_Delay(10);

a += 300;

if(a > 900){

a = 100;

}

//通过这个宏改变占空比

__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, a);

我们发现还是可以改变占空比的。

可以看到我们的占空比是在不断地变化的,之后就完成我们的PWM了。

二 使用定时器编码器接口对电机进行测速

先找到逻辑分析仪对应的软件,之后我们来配置定时器编码器接口,使用的是TIM3的ch1和ch2

之后就是不分频然后启动预加载值。之后把定时器设置为编码器模式。之后生成文件用于试验测速是否可行,记得勾选生成.c和.h文件。

使用cubemx配置完成之后,我们就可以观测波形了。

先来了解一下函数

  1. 硬件中断发生:定时器溢出。

  2. 固定入口:CPU跳到固定地址TIM3_IRQHandler这是谁都不能改的)。

  3. HAL库接管:TIM3_IRQHandler里直接调用了HAL_TIM_IRQHandler(&htim3)。这个HAL函数会做所有标准杂活:检查是哪种中断、清除中断标志等。

  4. 关键一步:当HAL_TIM_IRQHandler判断出这次是“更新中断”(即溢出)后,它就会去寻找并调用一个名为HAL_TIM_PeriodElapsedCallbac函数。

  5. 你的舞台:HAL_TIM_PeriodElapsedCallback就是留给你的“插槽”。HAL库提供了一个默认的空函数,但如果你自己写了一个,程序就会执行你的版本。你在这个函数里写if(htim->Instance == TIM3)和记录溢出方向的代码,这才是你的定制化处理逻辑。

所以,“回调”的意思是:HAL库的通用处理函数“回过头来调用”你提供的函数。这样,你无需关心复杂的中断标志位清除等底层细节,只需关注核心业务逻辑

TIM_HandleTypeDef *htim这个函数里面的参数是什么意思

也有可能你写完程序的注释,再次生成就会变成乱码,需要在这里加一个系统的环境变量,可以搜索一下。

之后我们可以用串口看一下是否会溢出。使用我们的串口发送函数。

接下来我们据需要进行溢出判断也就是速度,看看到底是正向溢出还是反向溢出

假设定时器是16位,最大值65535

编码器计数:... 65533, 65534, 65535, 0, 1, 2, ...

如果没有溢出记录,我们会以为从65535到2是转少了

实际上:65535 → 溢出 → 0 → 1 → 2 = 实际增加了4

// 全局变量

int32_t overflow_count = 0; // 溢出次数,正数表示正转溢出,负数表示反转溢出

uint32_t last_counter = 0; // 上一次读取的计数值

之后我们需要启动定时器2定一个基准时间用来给编码器测速。

第一步先要配置好管脚和串口,然后启动我们得定时器3配置为编码器模式。

第一步先要配置好管脚和串口,然后启动我们得定时器3配置为编码器模式。

这样子就可以实现编码器测速以及中断溢出检测了

我们可以看到CNT得值以及溢出后得中断。接下来我们规定速度。因为我们规定的是达到30之后产生溢出,我们先用编码器测试,之后对接到测速。

测速得话,我们还需要一个定时器用来产生时间间隔,然后我们得脉冲数,和这个时间间隔计算就可以可到我们得速度:转速 = (单位时间内的脉冲数) / (编码器每转脉冲数 × 时间间隔)
  • TIM3的CNT值 = 脉冲数
  • TIM2的溢出周期 = 时间间隔
int n = 0; // 记录溢出数量先定义一个带符号得变量用于判断方向。记录TIM3在测量周期内的计数器溢出次数。
  • TIM3的CNT寄存器只有16位(最大值65535)
  • 当电机转得很快时,CNT可能会溢出多次
  • n 记录的是完整的65535循环次数
编码器正向旋转 → TIM3向上计数(0,1,2,...)
编码器反向旋转 → TIM3向下计数(65535,65534,...)但是我们这里设置9方便观察结果
TIM2每100ms中断一次,进行转速计算
第一步:读取当前CNT值
uint16_t x = TIM3->CNT; // 读取当前计数值(0-65535)
第二步:计算总脉冲数
这是最复杂的部分,也是测速得核心
情况1:正向旋转(n ≥ 0)
total = x + n * 10;10是因为从0开始计数记到9一共是10个数
  • n = 溢出次数
  • n * 10= 溢出部分的总脉冲数
  • x = 当前未溢出的脉冲数
  • 总脉冲数= 溢出部分 + 当前部分
情况2:反向旋转(n < 0)
total = (10 - x) - (n + 1) * 10;
  • 当反向旋转时,n是负数(如-1、-2...)
  • 10-x:因为反向旋转时,CNT从10开始递减
  • - (n + 1) * 10:计算溢出的负脉冲数
第三步:计算转速并输出
printf("speed%d = %lf\r\n", n>=0?1:-1, total*1.0/0.1);
  • n>=0?1:-1:输出旋转方向(1正向,-1反向)
  • total*1.0/0.1:计算脉冲频率(脉冲数/秒)
    • total:100ms内的脉冲数
    • total*1.0/0.1:换算成1秒内的脉冲数
第四步:复位
TIM3->CNT = 0; // 编码器计数器清零
n = 0; // 溢出计数器清零
需要记住得是
因为反向旋转时,CNT是倒着数的:
  • 从9开始:9(表示刚开始)
  • 到8:走了1步
  • 到7:走了2步
  • ...
  • 到0:走了9步
假设我们x是7正传得话就是走了七步,7个脉冲,因为是正向计数,但是反转不是如果反转x=7的话因为是反向计数,需要用ARR-x才是你记录多少步。x是当前未溢出得计数值。
还有反向得话从0-9已经发生了一次溢出,在进行溢出时候n会变为-2,但是实际上只发生了一次完整的循环计数。
  • n = -1:已经发生了1次溢出(刚开始第一个循环)
  • n = -2:已经发生了2次溢出(完成第一个循环 + 刚开始第二个循环)
  • n = -3:已经发生了3次溢出(完成两个循环 + 刚开始第三个循环)
这是由定时器的硬件机制决定的:
  1. 硬件标志位:UIF(更新中断标志)在CNT从ARR→0(正向)或从0→ARR(反向)时置位
  2. 对称性:硬件设计要保持正反向的对称性
  3. 中断触发:无论是正向还是反向,当CNT"翻越"边界时都触发中断
现在应该明白了:
  • n 记录的是溢出事件次数(负数)
  • n+1 得到的是负数,如:-1→0, -2→-1, -3→-2
  • -(n+1) 才是完整循环数:0, 1, 2...
  • -(n+1*10 就是完整循环的脉冲数
total = 当前循环已走步数 + 完整循环脉冲数
= (10-x) + [-(n+1)]×10
把反向旋转想象成倒着爬楼梯
  • 楼梯编号:0(地面), 1, 2, ..., 9(楼顶)
  • 正向:从0开始向上爬,到9再回到0(循环结束)
  • 反向:从0开始向下?不对,0是地面,没法向下!
    • 实际上:先瞬移到楼顶(9),然后向下爬
    • 每次从地面瞬移到楼顶时,记一次"溢出"
    • 从楼顶爬回地面时,完成一个循环,但没有"溢出"事件
这就是为什么反向时n的含义不同
我们先进行编程
先开启中断
主循环打印值测试一下
之后是我们的中断函数,到这里我们就测试完成了
之后我们在cube中配置完成后就可以使用电机的编码器进行测速了
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/21 12:04:18

在STM32函数指针是什么,怎么使用还有典型应用场景。

函数指针听起来复杂&#xff0c;但其实你可以把它理解成一个“遥控器”。它本身不干活&#xff0c;但按一下&#xff08;调用它&#xff09;&#xff0c;就能遥控执行另一个函数。在STM32开发里&#xff0c;这个“遥控”的特性&#xff0c;正好能解决硬件和应用之间灵活联动的问…

作者头像 李华
网站建设 2026/2/16 5:49:25

进销存最新推荐 | 哪个进销存软件性价比最好?- 象过河软件

在数字化管理工具选型中&#xff0c;进销存软件的 “性价比” 从来不是单纯看价格&#xff0c;而是 “功能实用性 投入成本” 的综合考量。市面上有的软件低价但功能残缺&#xff0c;有的功能齐全却年费高昂&#xff0c;还有的隐藏插件收费&#xff0c;让企业陷入 “两难”。2…

作者头像 李华
网站建设 2026/2/25 13:09:37

5个关键技巧:高效使用baseimage-docker构建企业级容器环境

5个关键技巧&#xff1a;高效使用baseimage-docker构建企业级容器环境 【免费下载链接】baseimage-docker A minimal Ubuntu base image modified for Docker-friendliness 项目地址: https://gitcode.com/gh_mirrors/ba/baseimage-docker 在容器化技术日益普及的今天&a…

作者头像 李华
网站建设 2026/2/27 4:12:24

LabVIEW信号时频加权分析

实现模拟动态信号的时域、频域加权处理&#xff0c;支持多类加权滤波器&#xff08;如 A/C/ITU-R 468-4&#xff09;&#xff0c;可对比原始信号与加权信号的时域波形、功率谱&#xff0c;直观展示加权对信号的影响&#xff0c;适用于声学、振动信号的加权分析场景。说明时频加…

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

VMware ESXi 8.0U3h 发布 - 领先的裸机 Hypervisor

VMware ESXi 8.0U3h 发布 - 领先的裸机 Hypervisor 同步发布 Dell (戴尔)、HPE (慧与)、Lenovo (联想)、Inspur/IEIT SYSTEMS (浪潮)、H3C (新华三)、Cisco (思科)、Fujitsu (富士通)、Hitachi (日立)、NEC (日电)、Huawei (华为)、xFusion (超聚变) OEM 定制版 请访问原文链…

作者头像 李华
网站建设 2026/2/22 0:08:48

基于Spring+MySQL的奖学金管理系统的设计与实现--59044(免费领源码)原创的定制程序,java、PHP、python、C#小程序、文案全套、毕设成品等等.

感兴趣的可以先收藏起来&#xff0c;还有大家在毕设选题&#xff0c;项目以及论文编写等相关问题都可以关注一下&#xff0c;希望帮助更多的人顺利毕业~ 基于SpringMySQL的奖学金管理系统 的设计与实现 摘 要 随着信息技术的快速发展&#xff0c;奖学金管理的需求日益增长。传…

作者头像 李华