糖尿病康复,内容丰富有趣,生活中的好帮手!
糖尿病康复 > 嵌入式系统开发13——STM32输出PWM实现呼吸灯

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

时间:2020-07-31 04:25:36

相关推荐

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

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

目录

一、任务要求二、PWM简介1、什么是PWM2、相关概念3、PWM的产生4、PWM的通道5、PWM工作过程6、PWM输出高低电平7、PWM的计数模式8、PWM相关寄存器 三、创建工程四、代码编写五、编译六、烧录1、硬件连接2、烧录3、运行效果 七、总结

一、任务要求

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

二、PWM简介

1、什么是PWM

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

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

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

2、相关概念

pwm的频率:

是指1秒钟内信号从高电平到低电平再回到高电平的次数(一个周期);也就是说一秒钟PWM有多少个周期

单位: Hz

表示方式: 50Hz 100Hz

pwm的周期:

周期: 一个脉冲信号的时间

1s内测周期次数等于频率:T=1/f

如:50Hz = 20ms 一个周期,频率为50Hz ,也就是说一个周期是20ms 那么一秒钟就有 50次PWM周期

占空比:

是一个脉冲周期内,高电平的时间与整个周期时间的比例

单位: % (0%-100%)

表示方式:20%

脉宽时间: 高电平时间

脉宽时间占总周期时间的比例,就是占空比

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端口。

STM32F103C8T6的PWM口

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

TIM1_CH1->PA8;

TIM1_CH2->PA9;

TIM1_CH3->PA10;

TIM1_CH4->PA11;

TIM2_CH1->PA0;

TIM2_CH2->PA1;

TIM2_CH3->PA2;

TIM2_CH4->PA3;

TIM3_CH1->PA6;

TIM3_CH2->PA7;

TIM3_CH3->PB0;

TIM3_CH4->PB1;

TIM4_CH1->PB6;

TIM4_CH1->PB7;

TIM4_CH1->PB8;

TIM4_CH1->PB9;

普通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的通道

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

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

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

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

5、PWM工作过程

每个定时器有四个通道,每一个通道都有一个捕获比较寄存器,将寄存器值和计数器值比较,通过比较结果输出高低电平,实现输出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为例)

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

通过设置模式1或模式2,决定了比较结果输出有效或无效电平

(2)TIMx_CCER寄存器的CC1P位,设置输入/捕获通道1输出极性

通过设置输出极性,确定有效或无效电平为最终输出的高电平或低电平

总结:

模式1:

CNT<CCR 为有效电平 //(OC1REF = 1)

CNT>CCR 为无效电平 //(OC1REF = 0)

模式2:

CNT<CCR 为无效电平 //(OC1REF = 0)

CNT>CCR 为有效电平 //(OC1REF = 1)

CC1P:

0:高电平有效

1:低电平有效

目录

一、任务要求二、PWM简介1、什么是PWM2、相关概念3、PWM的产生4、PWM的通道5、PWM工作过程6、PWM输出高低电平7、PWM的计数模式8、PWM相关寄存器 三、创建工程四、代码编写五、编译六、烧录1、硬件连接2、烧录3、运行效果 七、总结

7、PWM的计数模式

向上计数模式:

下面是一个PWM模式1的例子。当TIMx_CNT<TIMx_CCRx时PWM信号参考OCxREF为高,否则为低。如果TIMx_CCRx中的比较值大于自动重装载值(TIMx_ARR),则OCxREF保持为’1’。如果比较值为0,则OCxREF保持为’0’:

向下计数模式:

在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)由硬件更新,不要用软件修改它。

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的模式、使能相应的预装载寄存器等操作:

捕获/比较使能寄存器(TIMx_CCER)

作用:在PWM输出模式下,确定PWM的输出极性和输出使能:

捕获/比较寄存器(TIMx_CCR1)

作用:在PWM输出模式下,确定比较的值:

三、创建工程

(1)打开STM32CubeMX,点击ACCEE TO MCU SELECTOR

(2)在搜索框输入STM32F103C8,双击选择STM32F103C8Tx

(3)选择调试接口,点击System Core,选择SYS,在右侧弹出的菜单栏中选Serial Wire

(4)打开外部时钟,点击System Core,选择RCC,在右侧弹出的菜单栏中选择Crystal/Ceramic Resonator

(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 (不分频 )

(6)将TIM4设置的和TIM3一样

(7)配置时钟,将HCLK设置为 72MHz

(8)设置项目的名称、位置和编译环境,生成项目

(9)打开项目,准备代码编辑

四、代码编写

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

//开启 TIMx 的通道x,输出PWMvoid HAL_TIM_PWM_Start(&htimx, TIM_CHANNEL_x);/** @DescriptPWM占空比更改* @paramhtimx相关定时器指针* @paramTIM_CHANNEL_x相关PWM通道* @paramPulseDuty_cycle = Pulse / Counter Period * @returnvoid*/

//修改TIMx的通道x的PWM波形的占空比void __HAL_TIM_SET_COMPARE(&htimx, TIM_CHANNEL_x, Pulse);/** @DescriptPWM频率更改* @paramhtimx相关定时器指针* @paramCounter_PeriodPWM_fre = TIM_frq / ( Prescaler + 1 ) / ( Counter Period + 1 )* @returnvoid*/

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

uint16_t pwm=0; //占空比

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

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

(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

五、编译

(1)点击 Options for Target…,在 Output 下勾选 Create HEX File

(2)在 Debug 下勾选 Use Simulator,将 Dialog DLL下的输入框改为 DARMSTM.DLL,Parameter 输入框改为 -pSTM32F103C8

(3)在 Target 选择使用 V5编译器

(4)点击 Rebuild进行编译

六、烧录

1、硬件连接

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

LED模块连接方法:

其中的PB6->PC13是为了将TIM4_CH1的输出PWM波形接到PC13上,PC13连接着板子上的LED,从而驱动板子上的LED实现呼吸灯

2、烧录

打开FlyMcu烧录助手,选择刚刚生成的HEX文件,点击开始编程进行烧录

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基本知识及配置过程

如果觉得《嵌入式系统开发13——STM32输出PWM实现呼吸灯》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。