定时器实验-PWM

PWM - 脉冲宽度调制–一种模拟控制方式

文章目录

PWM 概述

工作单元

定时器实验-PWM

工作过程

定时器实验-PWM
以向上计数举例,0->ARR(自动重装载值),与输入捕获寄存器中的值CCRRx进行比较,高便产生一个高电平(无效电平),低便产生一个低电平(有效电平),向下计数也一样,即产生一个PWM波。

内部实现

定时器实验-PWM
CCR1:捕获比较寄存器,设置比较值
OC1M[2:0]位:
对于PWM方式下,用于设置PWM模式1【110】或者模式2【111】
CC1P位:输入捕获1输出极性。0:高电平有效,1:低电平有效。
CC1E位:输入捕获1输出使能。0:关闭,1:打开。

向上计数->PWM 示意图

定时器实验-PWM
可知PWM(脉冲宽度调制)模式下产生的信号频率由TIMx_ARR寄存器确定、占空比由TIMx_CCRx寄存器确定。

配置寄存器库函数

使能预装载寄存器
定时器实验-PWM
ARPE位为0,ARR下个周期生效。
ARPE位为1,ARR本周期生效。

常用寄存器和库函数配置

void TIM_OCxInit(TIM_TypeDef*Timx,TIM_OCInitTypeDef*TIM_OCInitStruct);

typedef struct
{
uint16_t TIM_OCMode;//PWM模式一或者模式二
uint16_t TIM_OutputState//输出使能或者失能
uint16_t TIM_Pulse;//比较值,写CCRx
uint16_t TIM_OCPolarity;//比较输出极性

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; 
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; 
TIM_OCInitStructure.TIM_ Pulse = 100;
TIM_OCInitStructure.TIM_ OCPolarity = TIM_OCPolarity_High;
TIM_OC2Init(TIm3,&TIM_OCInitStructure);

void TIM_SetCompareX(TIM_TypeDef*TIMx,unit16_t Comparex);//设置比较值函数

void TIM_OCxPreloadConfig(TIM_TypeDef*TIMx,uint16_t TIM_OCPreload);//使能输出比较预装载

void TIM_ARRPreloadConfig(TIM_TypeDef*TIMx,FunctionalState NewState);//使能自动重装载的预装载寄存器允许位

PWM输出实验

要求

PWM功能->占空比可变PWM波->驱动LED灯->亮暗循环

输出配置步骤

①使能定时器14和相关IO口时钟

RCC_APB1PeriphClockCmd();//使能定时器14时钟
RCC_AHB1PeriphClockCmd();//使能GPIOF时钟

②初始化IO口为复用功能输出。

GPIO_Init();
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

③GPIOF9复用映射到定时器14

GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14);

④初始化定时器

TIM_TimeBaseInit();

⑤初始化输出比较参数

TIM_OC1Init();

⑥使能预装载寄存器:

TIM_OC1PreloadConfig(TIM14,TIM_OCPreload_ENable);

⑦使能定时器。

TIM_ARRPreloadConfig(TIM14,ENABLE);

⑧不断改变比较值CCRx,达到不同的占空比效果

TIM_SetCompare1();
代码
#include "pwm.h"
#include "led.h"
#include "usart.h"
 

// TIM14 pwm部分初始化
//pwm输出初始化
//arr:自动重装值
//psc:时钟预分频数
void TIM14_PWM_Init(u32 arr,u32 psc)
{		 					 
	
	GPIO_InitTypeDef GPIO_InitStructure;
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
	TIM_OCInitTypeDef  TIM_OCInitStructure;
	
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE);  	//  TIM14时钟使能
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); 	//PORTF时钟使能
	
	GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14); //GPIOF9复用为定时器14
	
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;           //GPIOF9
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;        //复用
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;	//速度100MHz
	GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;      //推挽复用输出
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;        //上拉
	GPIO_Init(GPIOF,&GPIO_InitStructure);              //初始化PF9
	
	GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14);
	  
	TIM_TimeBaseStructure.TIM_Prescaler=psc;  //定时器分频
	TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数
	TIM_TimeBaseStructure.TIM_Period=arr;   //自动重装载值
	TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1; 
	
	TIM_TimeBaseInit(TIM14,&TIM_TimeBaseStructure);//初始化定时器14
	
	TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式
 	TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
	TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性
	TIM_OC1Init(TIM14, &TIM_OCInitStructure);  //初始化外设TIM1 4OC1

	TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable);  //使能TIM14在CCR1上的预装载寄存器
 
  TIM_ARRPreloadConfig(TIM14,ENABLE);//APRE使能
	
	TIM_Cmd(TIM14, ENABLE);  //使能TIM14
 
										  
}  

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "pwm.h"


int main(void)
{ 
	u16 led0pwmval=0;    
	u8 dir=1;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级
	delay_init(168); //初始化延时函数
	uart_init(115200);//初始化串口波特率115200
 	TIM14_PWM_Init(500-1,84-1);	// 84M/84 = 1MHz的计时频率,重装载值500,pwm频率为1M/500 = 2khz
   while(1) //实现比较值从0-300递增,到300后从300-0递减,循环
	{
 		delay_ms(10);	 
		if(dir)led0pwmval++;//递增
		else led0pwmval--;	//递减 		if(led0pwmval>300)dir=0;
		if(led0pwmval==0)dir=1;	
 
		TIM_SetCompare1(TIM14,led0pwmval);//修改比较值,修改占空比
	}
}```

上一篇:和12岁小同志搞创客开发:设计一款亮度可调节灯


下一篇:一起玩转树莓派(3)——点亮RGB炫彩LED灯