嵌入式系统开发13——STM32输出PWM实现呼吸灯

这篇具有很好参考价值的文章主要介绍了嵌入式系统开发13——STM32输出PWM实现呼吸灯。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文主要介绍在STM32F103C8T6上,利用定时器输出PWM波形,进而驱动LED实现呼吸灯。

一、任务要求

使用TIM3和TIM4,分别输出一个PWM波形,PWM的占空比随时间变化,去驱动你外接的一个LED以及最小开发板上已焊接的LED(固定接在 PC13 GPIO端口),实现2个 LED呼吸灯的效果。

二、PWM简介

1、什么是PWM

脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换的许多领域中。

通俗讲,PWM是一种 对模拟信号电平进行数字编码 的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码

PWM信号仍然是数字的 ,因为在给定的任何时刻,满幅值的直流供电要么完全有(ON),要么完全无(OFF)。电压或电流源是以一种通(ON)或断(OFF)的重复脉冲序列被加到模拟负载上去的。通的时候即是直流供电被加到负载上的时候,断的时候即是供电被断开的时候。只要带宽足够,任何模拟值都可以使用PWM进行编码。

嵌入式系统开发13——STM32输出PWM实现呼吸灯

2、相关概念

  • pwm的频率:
    是指1秒钟内信号从高电平到低电平再回到高电平的次数(一个周期);也就是说一秒钟PWM有多少个周期
    单位: Hz
    表示方式: 50Hz 100Hz

  • pwm的周期:
    周期: 一个脉冲信号的时间
    1s内测周期次数等于频率:T=1/f
    如:50Hz = 20ms 一个周期,频率为50Hz ,也就是说一个周期是20ms 那么一秒钟就有 50次PWM周期

  • 占空比:
    是一个脉冲周期内,高电平的时间与整个周期时间的比例
    单位: % (0%-100%)
    表示方式:20%
    嵌入式系统开发13——STM32输出PWM实现呼吸灯

  • 脉宽时间: 高电平时间
    脉宽时间占总周期时间的比例,就是占空比

3、PWM的产生

通过STM32控制板,有两种方式能产生PWM,第一是利用 普通IO口 输出PWM,第二种是利用 定时器的PWM的IO口复用IO口

(1)PWM端口
STM32 的定时器除了 TIM6TIM7。其他的定时器都可以用来产生 PWM 输出。其中高级定时器 TIM1 和 TIM8 可以同时产生多达 7 路的 PWM 输出。而通用定时器也能同时产生多达 4路的 PWM 输出,这样,STM32 最多可以同时产生 30 路 PWM 输出。

(2)普通IO口
一般能够输出PWM的端口都会在主要功能那一栏出现CHx的标志,而普通定时器没有出现这种标志。如图所示,上面的红框就是普通的定时器,不是专用的PWM端口。
嵌入式系统开发13——STM32输出PWM实现呼吸灯

STM32F103C8T6的PWM口
由于本人的实验环境是在stm32最小系统上实现的,因此在此给出 STM32F103C8T6 的PWM口配置。不是所有的芯片都有重映像功能的STM32F103C8T6 的四个定时器就不需要重映像。

TIM1_CH1->PA8;
TIM1_CH2->PA9;
TIM1_CH3->PA10;
TIM1_CH4->PA11;
嵌入式系统开发13——STM32输出PWM实现呼吸灯

TIM2_CH1->PA0;
TIM2_CH2->PA1;
TIM2_CH3->PA2;
TIM2_CH4->PA3;
嵌入式系统开发13——STM32输出PWM实现呼吸灯

TIM3_CH1->PA6;
TIM3_CH2->PA7;
TIM3_CH3->PB0;
TIM3_CH4->PB1;
嵌入式系统开发13——STM32输出PWM实现呼吸灯

TIM4_CH1->PB6;
TIM4_CH1->PB7;
TIM4_CH1->PB8;
TIM4_CH1->PB9;
嵌入式系统开发13——STM32输出PWM实现呼吸灯

普通IO口产生PWM
普通IO口产生一个pwm其实就是通过一个高低电平周期性的变化。确定频率就可以确定周期(T=1/f)也就是在一个周期内产生pwm的时间。
改变占空比: 确定了时间,高电平的时间不就是想要的占空比么,比如要产生一个频率1khz,占空比为70%的pwm,根据频率我们知道了周期为1ms,产生一个占空比为70%的不就是0.7ms的时间给高电平么。我们用定时器中断的方式,使0.1ms产生一次中断,计数中断次数,中断处理函数前七次中断都给高电平就可以产生对应的波形了。

区别
1)一般而言,尽量选用PWM口进行PWM输出,因为普通IO口模拟PWM的输出频率越高,进入定时器中断的次数就越快,中断间隔的时间越短,如果再有其他类型的中断也要处理时,会因为中断的优先级嵌套等待响应,影响控制精度,PWM输出误差增大,也会影响其他如ADC等中断处理,甚至会较出现单片机逻辑出错,死机或者跑飞的情况。

2)普通IO也可以输出PWM,只是产生PWM一般用转用芯片(开关电源上用的较多)或者单片机的PWM内置模块如定时器,很小直接用MCU的IO口线直接输出因为那样太耗MCU资源了。

4、PWM的通道

每一个捕获/比较通道都是围绕着一个捕获/比较寄存器(包含影子寄存器),包括捕获的输入部分(数字滤波、多路复用和预分频器),和输出部分(比较器和输出控制)

捕获/比较模块由一个预装载寄存器和一个影子寄存器组成。读写过程仅操作预装载寄存器

在捕获模式下,捕获发生在影子寄存器上,然后再复制到预装载寄存器中

在比较模式下,预装载寄存器的内容被复制到影子寄存器中,然后影子寄存器的内容和计数器进行比较

嵌入式系统开发13——STM32输出PWM实现呼吸灯

5、PWM工作过程

嵌入式系统开发13——STM32输出PWM实现呼吸灯
每个定时器有四个通道,每一个通道都有一个捕获比较寄存器,将寄存器值和计数器值比较,通过比较结果输出高低电平,实现输出PWM信号
嵌入式系统开发13——STM32输出PWM实现呼吸灯

如图为向上计数:
定时器重装载值为ARR,比较值CCRx
t时刻对计数器值和比较值进行比较
如果计数器值小于CCRx值,输出低电平
如果计数器值大于CCRx值,输出高电平

PWM的一个周期
定时器从0开始向上计数
当0-t1段,定时器计数器TIMx_CNT值小于CCRx值,输出低电平
t1-t2段,定时器计数器TIMx_CNT值大于CCRx值,输出高电平
当TIMx_CNT值达到ARR时,定时器溢出,重新向上计数…循环此过程
至此一个PWM周期完成

影响因素
ARR : 决定PWM周期(在时钟频率一定的情况下,当前为默认内部时钟CK_INT)
CCRx : 决定PWM占空比(高低电平所占整个周期比例)

PWM工作过程(以通道1为例)
嵌入式系统开发13——STM32输出PWM实现呼吸灯

  • TIMx_CCMR1 寄存器的 OC1M[2:0] 位,设置输出模式控制器
    110: PWM模式1
    111: PWM模式2

  • 计数器值 TIMx_CNT 与通道1捕获比较寄存器 CCR1 进行比较,通过比较结果输出有效电平和无效电平
    OC1REF =0 无效电平
    OC1REF =1 无效电平

  • 通过输出模式控制器产生的信号
    TIMx_CCER 寄存器的 CC1P 位,设置输入/捕获通道1输出极性
    0: 高电平有效
    1: 低电平有效

  • TIMx_CCER:CC1E 位控制输出使能电路,信号由此输出到对应引脚
    0: 关闭
    1: 开启

6、PWM输出高低电平

计数器值 TIMx_CNT 与捕获比较寄存器值 CCRx 比较后,最终输出高电平还是低电平, 由TIMx_CCMR1:OC1M 位和 TIMx_CCER:CC1P 位共同决定

(1)TIMx_CCMR1 寄存器的 OC1M[2:0] 位,设置PWM 模式1模式2
嵌入式系统开发13——STM32输出PWM实现呼吸灯
通过设置模式1或模式2,决定了比较结果输出有效或无效电平

(2)TIMx_CCER 寄存器的 CC1P 位,设置输入/捕获通道1输出极性
嵌入式系统开发13——STM32输出PWM实现呼吸灯
通过设置输出极性,确定有效或无效电平为最终输出的高电平或低电平

总结:
模式1:
CNT<CCR 为有效电平 //(OC1REF = 1)
CNT>CCR 为无效电平 //(OC1REF = 0)
模式2:
CNT<CCR 为无效电平 //(OC1REF = 0)
CNT>CCR 为有效电平 //(OC1REF = 1)
CC1P:
0:高电平有效
1:低电平有效

7、PWM的计数模式

向上计数模式:
下面是一个PWM模式1的例子。当 TIMx_CNT<TIMx_CCRx 时PWM信号参考 OCxREF 为高,否则为低。如果 TIMx_CCRx 中的比较值大于自动重装载值 (TIMx_ARR) ,则 OCxREF 保持为’1’。如果比较值为0,则 OCxREF 保持为’0’:
嵌入式系统开发13——STM32输出PWM实现呼吸灯

向下计数模式:
在PWM模式1,当 TIMx_CNT>TIMx_CCRx 时参考信号 OCxREF 为低,否则为高。如果 TIMx_CCRx 中的比较值大于 TIMx_ARR 中的自动重装载值,则 OCxREF 保持为’1’。该模式下不能产生0%的PWM波形

中央对齐模式:
TIMx_CR1 寄存器中的 CMS 位不为’00’时,为中央对齐模式(所有其他的配置对 OCxREF/OCx 信号都有相同的作用)。根据不同的 CMS 位设置,比较标志可以在计数器向上计数时被置’1’、在计数器向下计数时被置’1’、或在计数器向上和向下计数时被置’1’。TIMx_CR1 寄存器中的计数方向位(DIR)由硬件更新,不要用软件修改它。

嵌入式系统开发13——STM32输出PWM实现呼吸灯

8、PWM相关寄存器

包含三个寄存器: 捕获/比较模式寄存器(TIMx_CCMR1/2)、捕获/比较使能寄存器(TIMx_CCER)、捕获/比较寄存器(TIMx_CCR1~4) 。设置 TIMx_CCMRx 寄存器 OCxPE 位以使能相应的预装载寄存器,最后还要设置 TIMx_CR1 寄存器的 ARPE 位,(在向上计数或中心对称模式中)使能自动重装载的预装载寄存器。其中模式设置位 OCxM 位,此位由3位组成,一共可以配置成7种模式,我们使用的是PWM模式,所以 这三位必须为110/111

捕获/比较模式寄存器总共2个,TIMx_CCMR1TIMx_CCMR2TIMx_CCMR1 控制CH1和CH2,TIMx_CCMR2 控制CH3和CH4。

下面来简单介绍一下这三种寄存器:

  • 捕获/比较模式寄存器(TIMx_CCMR1)
    作用:在PWM输出模式下,确定PWM的模式、使能相应的预装载寄存器等操作:
    嵌入式系统开发13——STM32输出PWM实现呼吸灯

  • 捕获/比较使能寄存器(TIMx_CCER)
    作用:在PWM输出模式下,确定PWM的输出极性和输出使能:
    嵌入式系统开发13——STM32输出PWM实现呼吸灯

  • 捕获/比较寄存器(TIMx_CCR1)
    作用:在PWM输出模式下,确定比较的值:
    嵌入式系统开发13——STM32输出PWM实现呼吸灯

三、创建工程

(1)打开 STM32CubeMX,点击 ACCEE TO MCU SELECTOR
嵌入式系统开发13——STM32输出PWM实现呼吸灯

(2)在搜索框输入 STM32F103C8,双击选择 STM32F103C8Tx
嵌入式系统开发13——STM32输出PWM实现呼吸灯

(3)选择调试接口,点击 System Core,选择 SYS,在右侧弹出的菜单栏中选 Serial Wire
嵌入式系统开发13——STM32输出PWM实现呼吸灯

(4)打开外部时钟,点击 System Core,选择 RCC,在右侧弹出的菜单栏中选择Crystal/Ceramic Resonator
嵌入式系统开发13——STM32输出PWM实现呼吸灯

(5)配置 TIM3,勾选 Internal Clock(内部时钟);将 Channel1 设置为 PWM Generation CH1(PWM输出通道1);
Prtscaler (定时器分频系数) 设置为71,即72分频——1MHz;Counter Mode(计数模式)设置为Up(向上计数模式);Counter Period(自动重装载值) 设置为50000,计数器从0向上计数(递增)到自动装载值,然后再次回到0开始计数,并产生一个计数溢出事件,即0.05s;CKD(时钟分频因子) 设置为No Division (不分频 )
嵌入式系统开发13——STM32输出PWM实现呼吸灯

(6)将 TIM4 设置的和 TIM3 一样
嵌入式系统开发13——STM32输出PWM实现呼吸灯

(7)配置时钟,将 HCLK 设置为 72MHz
嵌入式系统开发13——STM32输出PWM实现呼吸灯

(8)设置项目的名称、位置和编译环境,生成项目
嵌入式系统开发13——STM32输出PWM实现呼吸灯
嵌入式系统开发13——STM32输出PWM实现呼吸灯

(9)打开项目,准备代码编辑
嵌入式系统开发13——STM32输出PWM实现呼吸灯

四、代码编写

主要利用下面两个函数来控制定时器实现PWM输出

//开启 TIMx 的通道x,输出PWM
void HAL_TIM_PWM_Start(&htimx, TIM_CHANNEL_x);
/*
 * @Descript	PWM占空比更改
 * @param		htimx			相关定时器指针	
 * @param		TIM_CHANNEL_x	相关PWM通道
 * @param		Pulse			Duty_cycle = Pulse / Counter Period 
 * @return		void
*/
//修改TIMx的通道x的PWM波形的占空比
void __HAL_TIM_SET_COMPARE(&htimx, TIM_CHANNEL_x, Pulse);
/*
 * @Descript	PWM频率更改
 * @param		htimx			相关定时器指针	
 * @param		Counter_Period	PWM_fre = TIM_frq / ( Prescaler + 1 ) / ( Counter Period + 1 )
 * @return		void
*/

(1)在 main.c 文件中定义一个变量来记录 pwm 波形的占空比

uint16_t pwm=0;   //占空比

嵌入式系统开发13——STM32输出PWM实现呼吸灯

(2)打开定时器 TIM3TIM4PWM 通道1

	HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_1); 
	HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_1); 

嵌入式系统开发13——STM32输出PWM实现呼吸灯

(3)在主函数 while 循环里加入如下代码

	while (pwm< 500)                                       //在0.5s的时间内逐渐增大输出PWM的占空比,即让LED慢慢变亮
	{
		pwm++;
		__HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_1, pwm);    //修改TIM3的占空比
		__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_1, pwm);  	//修改TIM4的占空比		
		HAL_Delay(1);
	}
	while (pwm>=0)                                        //在0.5s的时间内逐渐减小输出PWM的占空比,即让LED慢慢变暗
	{
		pwm--;
		__HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_1, pwm);   //修改TIM3的占空比 
		__HAL_TIM_SetCompare(&htim4, TIM_CHANNEL_1, pwm);    //修改TIM4的占空比
		HAL_Delay(1);
	}
	HAL_Delay(100);                                         //延时0.1s

嵌入式系统开发13——STM32输出PWM实现呼吸灯

五、编译

(1)点击 Options for Target…,在 Output 下勾选 Create HEX File
嵌入式系统开发13——STM32输出PWM实现呼吸灯

(2)在 Debug 下勾选 Use Simulator,将 Dialog DLL下的输入框改为 DARMSTM.DLL,Parameter 输入框改为 -pSTM32F103C8
嵌入式系统开发13——STM32输出PWM实现呼吸灯

(3)在 Target 选择使用 V5编译器
嵌入式系统开发13——STM32输出PWM实现呼吸灯

(4)点击 Rebuild进行编译
嵌入式系统开发13——STM32输出PWM实现呼吸灯

六、烧录

1、硬件连接

USB转TTL STM32F103C8T6
GND G
3V3 3V3
RXD PA9
TXD PA10

注意将核心板上的BOOT0设置为1,BOOT1设置为0

嵌入式系统开发13——STM32输出PWM实现呼吸灯
嵌入式系统开发13——STM32输出PWM实现呼吸灯

LED模块连接方法:

输出端口 目的端口
3.3V LED阳极
PA6 LED阴极
PB6 PC13

其中的PB6->PC13是为了将TIM4_CH1的输出PWM波形接到PC13上,PC13连接着板子上的LED,从而驱动板子上的LED实现呼吸灯
嵌入式系统开发13——STM32输出PWM实现呼吸灯

2、烧录

打开 FlyMcu 烧录助手,选择刚刚生成的 HEX文件,点击 开始编程 进行烧录
嵌入式系统开发13——STM32输出PWM实现呼吸灯

3、运行效果

PWM呼吸灯

七、总结

本文主要介绍PWM相关理论知识,在学习理论知识的基础上,实现在STM32F103C8T6上,利用定时器TIM3和TIM4输出PWM波形,PWM的占空比随时间变化,去驱动你外接的一个LED以及最小开发板上已焊接的LED(固定接在 PC13 GPIO端口),实现2个 LED呼吸灯的效果。通过本次的练习,让我更加深入的理解了STM32的定时器功能以及PWM的相关知识。

学习要把理论和实践结合起来。只有在实践过程中一步一步的试错,在“发现问题——分析问题——解决问题”的过程中,逐步加深自己对理论和知识的理解。就比如在本次实践过程中,如果仅仅只阅读一些理论知识,那么对定时器和PWM的理解就会大打折扣。并且在实现呼吸灯的过程中,我也遇到了不少问题,如果没有进行实践,那将很难发现这些问题,也将不会知道如何实现PWM输出和定时器的操作。

最后就是当我们碰到解决不了的问题时,要多查阅资料,多参考他人的成功方法。这里不是指去抄别人的代码,而是去理解大佬们解决问题的思路,学习大佬们分析问题的方法以及严谨的思维方式,在理解思路的过程中提升自我。

感谢大家的阅读,欢迎大家指出本文存在的问题!


参考列表:
1.STM32CUBEMX_基于PWM的呼吸灯
2.stm32f103呼吸灯(PWM脉冲宽度调制)
3.使用STM32输出PWM波形
4.STM32 PWM基本知识及配置过程文章来源地址https://www.toymoban.com/news/detail-404399.html

到了这里,关于嵌入式系统开发13——STM32输出PWM实现呼吸灯的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 嵌入式-Stm32-江科大基于标准库的GPIO通用输入输出口

    (推荐先看文章:《 嵌入式-32单片机-GPIO推挽输出和开漏输出》) 下文图都是从参考手册借阅:STM32F10xxx(中文),大概页数是110/775左右 GPIO (General Purpose Input Output)通用输入输出口 可配置为8种输入输出模式 引脚电平:0V~3.3V,部分引脚可容忍5V(有FT标识) 输出模式 下可控

    2024年01月17日
    浏览(62)
  • [嵌入式软件][启蒙篇][仿真平台] STM32F103实现串口输出输入、ADC采集

    上一篇:[嵌入式软件][启蒙篇][仿真平台] STM32F103实现LED、按键 学C语言时,使用的printf()函数,就是通过串口打印出来的。 跟外部器件通信,比如GPS模块、蓝牙模块、wifi模块; 两个开发板之间通信,制定私有协议。 PC电脑通信,使用上位机显示数据或控制下位机。 操作:打

    2024年01月22日
    浏览(70)
  • STM32开发环境搭建&工程创建(嵌入式学习)

    简介 STM32CubeMX是STMicroelectronics公司提供的一款集成开发环境(IDE)工具,用于快速配置和初始化STM32微控制器系列的软件工程。它提供了图形化界面和交互式工具,使开发者能够轻松地生成STM32微控制器的初始化代码和配置文件。 STM32CubeMX具有以下主要功能和特点: 微控制器

    2024年02月11日
    浏览(74)
  • STM32的时钟系统(嵌入式学习)

    时钟是指用于计量和同步时间的装置或系统。时钟是嵌入式系统的脉搏,处理器内核在时钟驱动下完成指令执行,状态变换等动作,外设部件在时钟的驱动下完成各种工作,例如:串口数据的发送、AD转换、定时器计数等。因此时钟对于计算机系统是至关重要的,通常时钟系

    2024年02月16日
    浏览(50)
  • STM32的中断系统详解(嵌入式学习)

    中断是处理器中的一种机制,用于响应和处理突发事件或紧急事件。当发生中断时,当前正在执行的程序会被暂时中止,处理器会跳转到中断处理程序(也称为中断服务例程),对中断事件进行处理。处理完中断后,处理器再返回到被中断的程序继续执行。 中断可以分为内部

    2024年02月12日
    浏览(73)
  • 嵌入式物联网STM32实战开发代码例程库

    几百个例程清单,CSDN下载地址: https://download.csdn.net/download/weixin_39804904/88671879 开发例程清单(持续新增中,欢迎点赞关注): 0001基于STM32F103单片机GPIO实现控制LED灯闪烁的程序代码0001.rar 0002基于STM32F103单片机GPIO实现按键KEY的检测程序代码0002.rar 0003基于STM32F103单片机GPIO实现

    2024年02月02日
    浏览(50)
  • 嵌入式项目分享 stm32智能运动计步系统 - 物联网 嵌入式 单片机

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月20日
    浏览(76)
  • 嵌入式项目分享 stm32机器视觉的口罩佩戴检测系统 - 单片机 物联网 嵌入式

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月20日
    浏览(152)
  • 嵌入式毕设分享 基于单片机的风速测量系统 - 物联网 嵌入式 stm32 arduino

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月20日
    浏览(69)
  • 【嵌入式开发工具】STM32+Keil实现软件工程搭建与开发调试

    本篇文章介绍了使用Keil来对STM32F103C8芯片进行初始工程搭建,以及开发与工程调试的完整过程,帮助读者能够在实战中体会到Keil这个开发环境的使用方法,了解一个嵌入式工程从无到有的过程,并且具备快速搭建一个全新芯片对应最小软件工程的基本能力思路。文章首先介绍

    2024年02月05日
    浏览(66)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包