【STM32开发之寄存器版】(七)-PWM脉冲宽度调制

一、前言

PWM简介

PWM(脉宽调制)是一种通过调节信号的脉冲宽度来控制功率输出的技术。其基本原理是保持固定频率的信号,将其高电平和低电平的持续时间调整,达到控制平均功率的目的。应用方面,PWM广泛用于电机控制、LED调光、音频放大、以及电源管理等领域,因为它能有效提高能效并减少热量生成。

STM32F103ZET6的PWM

STM32F103ZET6的定时器,除了TIM6和TIM7,都可以用来产生PWM。高级定时器1和8甚至同时可以产生7路PWM输出,通用定时器也可以同时各自产生4路PWM输出。STM32定时器的脉冲宽度调制模式可以产生一个由TIMx_ARR寄存器确定频率、由TIMx_CCRx寄存器确定占空比的信号。如下图所示:

图中显示的是向上计数模式的PWM,且当 CNT<CCRx 时,输出 0,当 CNT>=CCRx 时输出 1。那么就可以得到如上的 PWM示意图:当 CNT 值小于 CCRx 的时候,IO 输出低电平(0),当 CNT 值大于等于 CCRx 的时候,IO 输出高电平(1),当 CNT 达到 ARR 值的时候,重新归零,然后重新向上计数,依次循环。改变 CCRx 的值,就可以改变 PWM 输出的占空比,改变 ARR 的值,就可以改变 PWM 输出的频率,这就是 PWM 输出的原理。

本次DEMO目标

本次DEMO我们将使用TIM3的CH2,并将CH2重映射到PB5,产生PWM来控制DS0的亮度。

二、时钟树分析

对于时钟树的分析与【STM32开发之寄存器版】(六)-通用定时器中断 相同,供给TIM3的时钟TIM3CLK=72MHz,具体的时钟树配置如下图所示:

三、寄存器介绍

对于PWM的设置主要涉及以下几个寄存器:

寄存器作用
TIMx_CCMR1/2捕获/比较模式寄存器1/2
TIMx_CCER捕获/比较使能寄存器
TIMx_CCR1-4捕获/比较寄存器1-4
AFIO_MAPR复用重映射和调试I/O配置寄存器

下面将对这四个寄存器进行一一介绍:

3.1 TIMx_CCMR捕获/比较模式寄存器

《STM32中文参考手册》对TIMx_CCMR寄存器的描述如下:

TIMx_CCMR寄存器总共有 2 个,TIMx _CCMR1和 TIMx _CCMR2。TIMx_CCMR1 控制 CH1 和 2,而 TIMx_CCMR2 控制 CH3 和 4。本文使用PB5,即TIM3_CH2,故仅需关注TIMx _CCMR1即可

TIMx_CCMR1中的某些位,在输入和输出模式下具备不同的功能,因此将这个寄存器分为2层,上面这层表示输出,下面这层表示输入,本次DEMO仅需关注输出PWM。这里我们需要说明的是模式设置位 OCxM,此部分由 3 位组成。总共可以配置成 7 种模式,我们使用的是 PWM 模式,所以这 3 位必须设置为 110/111。这两种 PWM 模式的区别就是输出电平的极性相反。另外 CCxS 用于设置通道的方向(输入/输出)默认设置为 0,就是设置通道作为输出使用。

3.2 TIMx_CCER捕获/比较使能寄存器

《STM32中文参考手册》对TIMx_CCER寄存器的描述如下:

对于这个寄存器,我们只用到了CC2E位,该位是输入/捕获 2 输出使能位,要想PWM 从 IO 口输出,这个位必须设置为 1

3.3 TIMx_CCR捕获/比较寄存器

《STM32中文参考手册》对TIMx_CCR寄存器的描述如下:

对于TIM3,CCR寄存器共有4个,分别对应CH1-CH4,本文使用的PB5对应CH2,故我们仅需关注TIM3_CCR2寄存器。在输出模式下,该寄存器的值与 CNT 的值比较,根据比较结果产生相应动作。利用这点,我们通过修改这个寄存器的值,就可以控制 PWM 的输出脉宽了。本章,我们使用的是 TIM3 的通道 2,所以我们需要修改 TIM3_CCR2 以实现脉宽控制 DS0 的亮度。

3.4 AFIO_MAPR复用重映射和调试I/O配置寄存器

《STM32中文参考手册》对AFIO_MAPR寄存器的描述如下:

由于本文要使用TIM3的CH2输出PWM来控制DS0的亮度,但是TIM3_CH2默认接在PA7上面,而DS0接在PB5上面,因此需要通过重映射功能,将TIM3_CH2映射到PB5上。描述重映射的寄存器是AFIO_MAPR,我们只需要关注其TIM3_REMAP[1:0]位。在本DEMO中,我们要将TIM3_REMAP[1:0]设置为10,部分映像可以将CH2通道映射到PB5引脚上。

四、程序设计

本DEMO的程序主要涉及定时器3的PWM功能初始化和轮询主函数。

4.1 定时器3的PWM功能初始化

该部分代码位于HARDWARE/timer.c/TIM3_PWM_Init(),主要功能是完成定时器3时钟使能、PB5复用功能配置、PWM模式配置和使能。具体代码如下所示:

//TIM3 PWM部分初始化 
//PWM输出初始化
//arr:自动重装值
//psc:时钟预分频数
void TIM3_PWM_Init(u16 arr,u16 psc)
{		 					 
	//此部分需手动修改IO口设置
	RCC->APB1ENR|=1<<1; 	//TIM3时钟使能    
	RCC->APB2ENR|=1<<3;    	//使能PORTB时钟	
	GPIOB->CRL&=0XFF0FFFFF;	//PB5输出
	GPIOB->CRL|=0X00B00000;	//复用功能输出 	  	 
	   
	RCC->APB2ENR|=1<<0;     //开启辅助时钟	   
	AFIO->MAPR&=0XFFFFF3FF; //清除MAPR的[11:10]
	AFIO->MAPR|=1<<11;      //部分重映像,TIM3_CH2->PB5

	TIM3->ARR=arr;			//设定计数器自动重装值 
	TIM3->PSC=psc;			//预分频器不分频
	
	TIM3->CCMR1|=7<<12;  	//CH2 PWM2模式		 
	TIM3->CCMR1|=1<<11; 	//CH2预装载使能	   
	TIM3->CCER|=1<<4;   	//OC2 输出使能	   
	TIM3->CR1=0x0080;   	//ARPE使能 
	TIM3->CR1|=0x01;    	//使能定时器3 											  
}  	 

4.2 轮询主函数 

该部分代码位于USER/test.c,具体作用是不断改变TIM3的CCR2装载值,从而改变PWM占空比,实现DS0的亮度调整。具体代码如下所示:

#include "sys.h"
#include "delay.h"
#include "usart.h" 
#include "led.h" 
#include "timer.h" 
 
int main(void)
{					   
	u16 led0pwmval=0;    
	u8 dir=1;	
	Stm32_Clock_Init(9);	//系统时钟设置
	uart_init(72,115200);	//串口初始化为115200
	delay_init(72);	   	 	//延时初始化 
	LED_Init();		  		//初始化与LED连接的硬件接口
  	TIM3_PWM_Init(899,0);	//不分频。PWM频率=72000/(899+1)=80Khz
   	while(1)
	{
 		delay_ms(10);	 
		if(dir)led0pwmval++;
		else led0pwmval--;	 
 		if(led0pwmval>300)dir=0;
		if(led0pwmval==0)dir=1;	   					 
		LED0_PWM_VAL=led0pwmval;	   
	}
}

五、上机实验

将代码烧录到STM32F103ZET6,可以观察到DS0的呼吸灯效果。如下所示:

至此完成PWM呼吸灯实验! 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值