1、pwm输出介绍
2、函数配置
3、源码
1、pwm输出介绍
脉冲调制(pwm),其根本原理就是通过控制占空比来控制输出。STM32的定时器除了TIM6和7之外都可以产生pwm输出,其中高级定时器1和8可以同时产生7路pwm输出,而通用定时器可以同时产生4路pwm输出。本次实验我使用的STM32F103ZET芯片进行实验,这边选取TIM3的CH2产生一路PWM输出。其中大部分的函数都是与之前的定时器中断的函数相同,但也有不同的点。首先我们需要明白pwm到底是咋样控制的,下面说下简单的理解,这边采取向上计数来说明:首先我们给定时器设定一个装载值,比如设定装载值为(899+1)=900,这边计数器就会开始从0到900开始计数,此时我在一个比较寄存器中设定一个值比如500,他会一直判断计数器的值和比较值哪个大,倘若我们设定当计数器的值大于比较值大的时候有效,并且一旦有效就输出高电平,这样的话计数器的值小于500时输出的就是低电平,高于500时就输出高电平,通过改变装载值和预分频系数就可以设置pwm的周期,通过设置比较寄存器的值就可以设定占空比,何时有效和有效为高电平还是低电平我们都可以设定,这样就可以实现pwm输出。
2、函数配置?
1、开启GPIOB的时钟、开启定时器3的时钟、开启端口复用的时钟
?? ?RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能GPIOB的时钟 ?? ?RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能定时器3的时钟 ?? ?RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO ,ENABLE);//开启复用时钟
2、初始化IO口,这里需要注意,我们需要将端口的模式选择为复用输出 ?? ?GPIO_Init(GPIOB,&GPIO_InitStucture);//初始化GPIO口
3、将端口重映射到定时器三上,这里我们需要去查芯片手册看一下这边时部分重映射、全映射还是无映射,这里我们的B5口映射到TIM3是部分映射。
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);//将B5部分重映射到定时器3
4、定时器初始化,这里定时器初始化还是上一篇提到的三个主要设置,一个是计数模式、二是预分频系数psc、三是重装载值arr。
?TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitTypeStucture)
5、pwm的设置。这边我们的B5是定时器的通道2(ch2),所以我们在选择pwm的设置的时候需要选择oc2init。这里用到其中的几个,一个是pwm模式设置,这里选择的是pwm模式2,也就是计数器的值大于我们比较寄存器的值有效,模式1是计数器的值小于寄存器的值为有效。二、有效输出的是高电平还是低电平。三、使能pwm输出,即你定时器要使能之后才能从io口输出。
?? ?TIM_OC2Init(TIM3,&TIM_OCInitTypeStucture)
6、使能预装载寄存器,同样的我们使能的时候选择通道2的函数进行预装载寄存器初始化。
TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);//使能预装载寄存器
7、使能定时器
8、经过上诉的步骤,我们定时器的pwm输出的初始化,就结束了,我们可以在主函数中调用TIM_SetCompare2()就可以实现
3、源码
定时器初始化
#include"timer.h"
#include"sys.h"
void TIM3_PWM_Init(u16 crr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStucture;
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitTypeStucture;
TIM_OCInitTypeDef TIM_OCInitTypeStucture;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能GPIOB的时钟
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE);//使能定时器3的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO ,ENABLE);//开启复用时钟
GPIO_InitStucture.GPIO_Mode=GPIO_Mode_AF_PP;
GPIO_InitStucture.GPIO_Pin=GPIO_Pin_5;
GPIO_InitStucture.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStucture);//初始化GPIO口
GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3,ENABLE);//将B5部分重映射到定时器3
TIM_TimeBaseInitTypeStucture.TIM_ClockDivision=0;//时钟分割
TIM_TimeBaseInitTypeStucture.TIM_CounterMode=TIM_CounterMode_Up;//向上计数模式
TIM_TimeBaseInitTypeStucture.TIM_Period=crr;//重装载值
TIM_TimeBaseInitTypeStucture.TIM_Prescaler=psc;//预分频系数
TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitTypeStucture);
TIM_OCInitTypeStucture.TIM_OCMode=TIM_OCMode_PWM2;//设置pwm模式位2,即计数器的值大于设定值有效
TIM_OCInitTypeStucture.TIM_OCPolarity=TIM_OCPolarity_High;//若判定有效,有效为高电平,无效则为低电平
TIM_OCInitTypeStucture.TIM_OutputState=TIM_OutputState_Enable;//比较输出使能
TIM_OC2Init(TIM3,&TIM_OCInitTypeStucture);
TIM_OC2PreloadConfig(TIM3,TIM_OCPreload_Enable);//使能预装载寄存器
TIM_Cmd(TIM3,ENABLE);//使能定时器3
}
主函数
#include "sys.h"
#include "delay.h"
#include "led.h"
#include"timer.h"
int main(void)
{
u16 pwm=0;
u8 dir=1;
delay_init();
LED_Init();
TIM3_PWM_Init(899,0);
while(1)
{
delay_ms(10);
if(dir)pwm++;
else pwm--;
if(pwm>300)dir=0;
if(pwm==0)dir=1;
TIM_SetCompare2(TIM3,pwm);
}
}
|