当前位置: 首页 > news >正文

利用STM32的定时器输出PWM方波

        脉冲宽度调制 (PWM) ,是英文“ Pulse Width Modulation ”的缩写,简称脉宽调制,是利用
微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽
度的控制。
       
        图中,我们假定定时器工作在向上计数 PWM 模式,且当 CNT<CCRx 时,输出 0 ,当 CNT>=CCRx 时输出 1 。那么就可以得到如上的 PWM 示意图:当 CNT 值小于 CCRx 的时候, IO 输出低电平 (0) ,当 CNT 值大于等于 CCRx 的时候,IO 输出高电平 (1) ,当 CNT 达到 ARR 值的时候,重新归零,然后重新向上计数,依次循环。 改变 CCRx 的值,就可以改变 PWM 输出的占空比,改变 ARR 的值,就可以改变 PWM 输出的频率,这就是 PWM 输出的原理。(PS:操作寄存器请大家自行查阅手册,我这里还是只演示CubeMX+HAL库函数)。
      下面来操作CubeMX输出PWM,首先还是选择外部晶振开启总线调试接口;接下来有个关键点,配置挂载tim的时钟总线频率,我这里统一用了72M;
然后是第二个关键点,选择时钟模式,时钟源选择Internal Clock,然后开启对应的通道并选择PWM生成模式。
       最后一个配置要点参数设置,首先明确一点,一组高低电平组成的PWM波形的周期计算公式如下:T=\frac{(Prescaler+1)*(Counter Period+1)}{Ftim},其中Prescaler是预分频系数,Counter Period是自动重装载寄存器里存储的计数周期,Ftim是挂载TIM的时钟总线上的时钟信号频率。计数模式一般习惯性选择向上计数(Count Mode选择UP),内部时钟预分频不用,影子寄存器可以使能一下。

       触发输出参数选择中触发事件选择复位Reset,主从模式选择disable。

       最后的PWM生成参数,PWM模式选择模式1,两者的区别是

  1. PWM mode 1
    • 在向上计数中,当计数值小于CCR(捕获/比较寄存器)值时,PWM输出高电平;当计数值大于CCR值时,PWM输出低电平。
    • 在向下计数中(如果存在中心对齐模式),当计数值小于CCR值时,PWM输出低电平;当计数值大于CCR值时,PWM输出高电平。
    • 这种模式下,PWM信号的输出逻辑在低电平和高电平之间切换,以控制PWM的占空比。
  2. PWM mode 2
    • 在向上计数中,当计数值小于CCR值时,PWM输出低电平;当计数值大于CCR值时,PWM输出高电平。
    • 在向下计数中(如果存在中心对齐模式),当计数值小于CCR值时,PWM输出高电平;当计数值大于CCR值时,PWM输出低电平。
    • 与PWM mode 1相反,这种模式下PWM信号的输出逻辑在高电平和低电平之间切换,以控制PWM的占空比。
我们可以先试着用CubeMX配置固定占空比的PWM方波,这种需求只需要一行hal库代码就能实现。主要精力放在填写参数上,首先将预分频系数设置为7199,计数周期为4999,挂载在一个72Mhz的时钟线上,所以理论上一对高低电平组成的周期为0.5s。然后将PWM Generation Channel4中的Pulse设置为2000(理论占空比为2000/5000=0.4),极性设置为低(我的开发板上的LED灯低电平点亮),随后生成代码。
在TIM初始化函数中直接开启PWM。
  /* USER CODE BEGIN TIM3_Init 2 */HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_4);/* USER CODE END TIM3_Init 2 */

观察示波器波形,可以看到高低电平周期为500ms,其中300ms输出高电平,200ms输出低电平,和理论值相符合。LED灯只是不停地闪烁,并没有实现呼吸灯效果。

当然更多时候占空比需要可调,我来演示一下pluse占空比选择0,输出比较预装载寄存器需要使能,快速模式可以关闭,极性选择高。

生成代码至IDE开始调参。
①命名一个占空比变量
  /* USER CODE BEGIN 1 */uint16_t pwm=0;      //调控占空比/* USER CODE END 1 */

②主循环里写逻辑功能

    /* USER CODE BEGIN 3 */while(pwm<499){pwm++;__HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_4, pwm);    //通过修改比较值来改变占空比}while(pwm){pwm--;__HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_4, pwm);    //通过修改比较值来改变占空比HAL_Delay(1);}HAL_Delay(200);}/* USER CODE END 3 */

观察示波器波形论证结果

宏观来讲,每个循环最后延时200ms已经实现。

每个高低电平组成的周期实测500us,理论值(71+1)*(499+1)/72000000=0.0005s基本符合。

占空比大致为80%,输出400us低电平之后输出100us高电平,也符合理论范围。占空比调制成功实现了呼吸灯效果。

相关文章:

  • 10分钟完成微信JSAPI支付对接过程-JAVA后端接口
  • JVM专题九:JVM分代知识点梳理
  • mysql8 锁表与解锁
  • java:aocache:基于aspectJ实现的方法缓存工具
  • 等保2.0对云计算有哪些特定的安全要求?
  • AI Agent项目实战(03)-利用TTS技术让你的AI Agent发声
  • jenkins在使用pipeline时,为何没有方块形视图
  • CSF视频文件格式转换WMV格式(2024年可用)
  • k8s架构设计思想
  • python Flask methods
  • 【linux】网络基础(2)——udp协议
  • RabbitMQ 之 延迟队列
  • 【开发环境】MacBook M2安装git并拉取gitlab项目,解决gitlab出现Access Token使用无效的方法
  • ElementUI搭建
  • 百日筑基第八天-看看mybatis
  • 【mysql】环境安装、服务启动、密码设置
  • 【翻译】babel对TC39装饰器草案的实现
  • css属性的继承、初识值、计算值、当前值、应用值
  • Js基础知识(一) - 变量
  • Laravel 实践之路: 数据库迁移与数据填充
  • Laravel5.4 Queues队列学习
  • npx命令介绍
  • Python打包系统简单入门
  • ViewService——一种保证客户端与服务端同步的方法
  • Vue.js 移动端适配之 vw 解决方案
  • 程序员最讨厌的9句话,你可有补充?
  • 目录与文件属性:编写ls
  • 浅谈JavaScript的面向对象和它的封装、继承、多态
  • scrapy中间件源码分析及常用中间件大全
  • !!Dom4j 学习笔记
  • #Linux(权限管理)
  • #QT(串口助手-界面)
  • $nextTick的使用场景介绍
  • (02)Hive SQL编译成MapReduce任务的过程
  • (delphi11最新学习资料) Object Pascal 学习笔记---第2章第五节(日期和时间)
  • (二)丶RabbitMQ的六大核心
  • (附源码)流浪动物保护平台的设计与实现 毕业设计 161154
  • (力扣记录)235. 二叉搜索树的最近公共祖先
  • (利用IDEA+Maven)定制属于自己的jar包
  • (实战篇)如何缓存数据
  • (转)树状数组
  • .NET gRPC 和RESTful简单对比
  • .Net调用Java编写的WebServices返回值为Null的解决方法(SoapUI工具测试有返回值)
  • .sh 的运行
  • /*在DataTable中更新、删除数据*/
  • ?php echo ?,?php echo Hello world!;?
  • @for /l %i in (1,1,10) do md %i 批处理自动建立目录
  • [ vulhub漏洞复现篇 ] JBOSS AS 5.x/6.x反序列化远程代码执行漏洞CVE-2017-12149
  • []error LNK2001: unresolved external symbol _m
  • [<MySQL优化总结>]
  • [120_移动开发Android]008_android开发之Pull操作xml文件
  • [145] 二叉树的后序遍历 js
  • [2023-年度总结]凡是过往,皆为序章
  • [8481302]博弈论 斯坦福game theory stanford week 1
  • [BIZ] - 1.金融交易系统特点