微控制器
综合设计与实训
实验名称: 实验八 PWM输出实验
1
实验八:PWM输出实验
1 实训任务
(1) 开启TIM时钟,配置定时器通道对应IO口为复用输出;
(2) 利用定时器的PWM输出功能产生波;
(3) 通过调节占空比调节LED的亮度。
1.1 实验说明
脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽度的控制。
STM32的定时器除了TIM6和7。其他的定时器都可以用来产生PWM输出。其中高级定时器TIM1和TIM8可以同时产生多达7路的PWM输出。而通用定时器也能同时产生多达4路的PWM输出。要使STM32的通用定时器TIMx产生PWM输出,除了上一实验的寄存器外,我们还会用到3个寄存器,分别是:捕获/比较模式寄存器(TIMx_CCMR1/2)、捕获/比较使能寄存器(TIMx_CCER)、捕获/比较寄存器(TIMx_CCR1~4)。
本实验仅利用TIM3的CH2产生一路PWM输出。通过重映射TIM_CH2到PB5上,由TIM_CH2输出PWM来控制LED1的亮度。
2
1.2 实验步骤
(1)在实训平台上将PB5连接LED灯;
(2)编写timer.c与timer.h文件,实现通过重映射TIM_CH2到PB5上,由TIM_CH2输出PWM来控制LED1的亮度。
(3)编写main文件,编译成功;
(4) 程序编译无误后下载到实训平台,观察LED亮度的变化:通过示波器观察输出的波形。
2 程序设计
(1) 新建文件夹并命名为PWM输出实验,复制粘贴上一章的实验文件,将工程文件改名为PWM.uvprojx。
(2)timer.h文件只需再添加TIM3_PWM_Init的声明即可。
(3) 编写timer.c文件。
a. 开启TIM3时钟以及复用功能时钟置,配置PB5为复用输出
要使用TIM3,必须先开启TIM3的时钟,使能GPIO外设和AFIO复用功能模块时钟。因为TIM3_CH2通道将重映射到PB5上,此时还要配置PB5为复用输出。
3
库函数使能TIM3时钟的方法是:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //使能定时器3时钟
库函数设置AFIO时钟的方法是:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); //复用时钟使能
GPIO初始化为复用推挽输出:
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
图9.2开启TIM3时钟
b.设置TIM3_CH2重映射到PB5上
因为TIM3_CH2默认是接在PA7上的,所以需要设置TIM3_REMAP为部分重映射(通过AFIO_MAPR配置),让TIM3_CH2重映射到PB5上面。
4
库函数函数里面设置重映射的函数是:
Void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState);
STM32重映射只能重映射到特定的端口。第一个入口参数可以理解为设置重映射的类型,比如TIM3部分重映射入口参数为GPIO_PartialRemap_TIM3。
TIM3部分重映射的库函数实现方法是:
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);
图9.3重映射
c.初始化TIM3,设置TIM3的ARR和PSC
开启TIM3的时钟之后,要设置ARR和PSC两个寄存器的值来控制输出PWM 的周期。当PWM周期太慢(低于50Hz)的时候,就会明显感觉到闪烁了。所以PWM周期在这里不宜设置的太小。
库函数通过TIM_TimeBaseInit函数实现的。调用的格式为:
5
TIM_TimeBaseStructure.TIM_Period = arr; //设置自动重装载值
TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置预分频值
TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx
图9.4初始化TIM3
d.设置TIM3_CH2的PWM模式及通道方向,使能TIM3的CH2输出
要设置TIM3_CH2为PWM模式(默认是冻结的),因为LED是低电平亮,要达到当CCR2的值小的时候,LED就暗,CCR2值大的时候,LED就亮的目的,可以通过配置TIM3_CCMR1的相关位来控制TIM3_CH2的模式。在库函数中,PWM 通道设置是通过
6
函数TIM_OC1Init()~TIM_OC4Init()来设置的,不同的通道的设置函数不一样。这里使用通道2,所以使用的函数是TIM_OC2Init():
Void TIM_OC2Init(TIM_TypeDef* TIMx,TIM_OCInitTypeDef* TIM_OCInitStruct)
TIM_OCInitTypeDef相关的几个成员变量
图9.5 TIM_OCInitTypeDef相关的几个成员变量
参数TIM_OCMode设置模式是PWM还是输出比较,这里是PWM模式。
参数TIM_OutputState用来设置比较输出使能,也就是使能PWM输出到端口。参数TIM_OCPolarity用来设置极性是高还是低。
其他的参数TIM_OutputNState,TIM_OCNPolarity,TIM_OCIdleStateTIM_OCNIdleState是高级定时器TIM1和TIM8才用到的;
7
和
图9.7 设置TIM3_CH2的PWM模式及通道方向
e.在完成以上设置了之后,需要使能TIM3:
TIM_Cmd(TIM3, ENABLE); //使能TIM3
图9.8 使能TIM3
f.最后,在经过以上设置之后,PWM其实已经开始输出了,只是其占空比和频率都是固定的,而通过修改TIM3_CCR2则可以控制CH2的输出占空比。继而控制LED的亮度。
在库函数中,修改TIM3_CCR2占空比的函数是:
void TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2);
对于其他通道,分别有一个函数名字,函数格式为TIM_SetComparex(x=1,2,3,4)。
8
通过以上6个步骤,就可以控制TIM3的CH2输出PWM波了。(注意:在配置AFIO相关寄存器的时候,必须先开启辅助功能时钟。)
(4) 编写main()函数
图9.1 main.c文件
在本实验的main函数中初始化的是TIM3_PWM_Init(899,0);而定时器溢出中断中初始化的是TIM3_Int_Init(4999,7199)。
从死循环函数可以看出,将led0pwmval这个值设置为PWM比较值,也就是通过led0pwmval来控制PWM的占空比,然后控制led0pwmval的值从0变到 300,然后又从300变到0,如此循环,因此LED的亮度也会跟着从暗变到亮,然后又从亮变到暗。
3硬件原理图设计
9
图9.1 LED电路原理图
10
4总结
实验仿真结果:
实验心得:通过本次试验,我明白了PWM控制原理,学会了定时器PWM输出的配置。也对上节的定时器溢出中断进行了复习。
11
脉冲宽度调制(PWM)是一种对模拟信号电平进行数字编码的方法。通过高分辨率计数器的使用,方波的占空比被调制用来对一个具体模拟信号的电平进行编码。PWM信号仍然是数字的,因为在给定的任何时刻,满幅值的直流供电要么完全有(ON),要么完全无(OFF)。电压或电流源是以一种通(ON)或断(OFF)的重复脉冲序列被加到模拟负载上去的。通的时候即是直流供电被加到负载上的时候,断的时候即是供电被断开的时候。只要带宽足够,任何模拟值都可以使用PWM进行编码。
PWM配置流程:
1.设置提供调制方波的片上定时器/计数器的周期
2.在PWM控制寄存器中设置接通时间
3.设置PWM输出的方向,这个输出是一个通用I/O管脚
4.启动定时器
5.使能PWM控制器
12
因篇幅问题不能全部显示,请点此查看更多更全内容