本帖最后由 e芯凌 于 2019-11-22 23:59 编辑
STM32PWM工作过程
CCR1:捕获比较(值)寄存器(x=1,2,3,4):设置比较值。 CCMR1: OC1M[2:0]位: 对于PWM方式下,用于设置PWM模式1【110】或者PWM模式2【111】 CCER:CC1P位:输入/捕获1输出极性。0:高电平有效,1:低电平有效。 CCER:CC1E位:输入/捕获1输出使能。0:关闭,1:打开。
PWM模式1 & PWM模式2 寄存器TIMx_CCMR1的OC1M[2:0]位来分析:
简单的说,ARPE=1,ARR立即生效。。。APRE=0,ARR下个比较周期生效。
STM32 定时器3输出通道引脚
①使能定时器3和相关IO口时钟。 使能定时器3时钟:RCC_APB1PeriphClockCmd(); 使能GPIOB时钟:RCC_APB2PeriphClockCmd(); ② 初始化IO口为复用功能输出。函数:GPIO_Init(); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 这里我们是要把PB5用作定时器的PWM输出引脚,所以要重映射配置, 所以需要开启AFIO时钟。同时设置重映射。 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE); ④ 初始化定时器:ARR,PSC等:TIM_TimeBaseInit(); ⑤ 初始化输出比较参数:TIM_OC2Init(); ⑥ 使能预装载寄存器: TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); ⑦ 使能定时器。TIM_Cmd(); ⑧ 不断改变比较值CCRx,达到不同的占空比效果:TIM_SetCompare2();
函数代码:
- void TIM3_PWM_Init(u16 arr,u16 psc)
- {
-
- GPIO_InitTypeDef GPIO_InitStructure;
- TIM_TimeBaseInitTypeDef TIM_TimeBaseInitstruct;
- TIM_OCInitTypeDef TIM_OCInitStructure;
-
-
- RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
-
-
- GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
- GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5;
- GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
- GPIO_Init(GPIOB,&GPIO_InitStructure);
- GPIO_SetBits(GPIOB,GPIO_Pin_5);
-
- GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);
-
- TIM_TimeBaseInitstruct.TIM_ClockDivision=TIM_CKD_DIV1;
- TIM_TimeBaseInitstruct.TIM_CounterMode=TIM_CounterMode_Up;
- TIM_TimeBaseInitstruct.TIM_Period=arr;
- TIM_TimeBaseInitstruct.TIM_Prescaler=psc;
- TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitstruct);
-
- TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; //选择 PWM 模式 2,CNT>CCR1时为有效电平
- TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
- TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性高,即高电平有效,有效电平置1
- TIM_OC2Init(TIM3, &TIM_OCInitStructure); //初始化 TIM3 OC2
-
- TIM_Cmd(TIM3, ENABLE);
-
- TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable);
- }
复制代码
main.c
- #include "stm32f10x.h"
- #include "led.h"
- #include "delay.h"
- #include "time.h"
- int main()
- {
- u16 led0pwm=0;
- u8 dir=1;
-
- delay_init();
- LED_Init();
-
- NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
- TIM3_PWM_Init(899,0);//PWM频率为72000000/900=80Khz,也就是溢出时间为900/72us,也即是到达中断的时间
-
-
- while(1)
- {
- delay_ms(10);
- if(dir)
- led0pwm++;
- else
- led0pwm--;
- if(led0pwm>300)
- dir=0;
- if(led0pwm==0)
- dir=1;
- TIM_SetCompare2(TIM3,led0pwm);//此处led0pwm越大,也就是高电平的占空比小,led越暗
- }
-
- }
复制代码我们将led0pwmval 这个值设置为 PWM 比较值,也就是通过 led0pwmval 来控制 PWM 的占空比,然后控制 led0pwmval 的值从 0 变到 300,然后又从300 变到 0, 如此循环,因此 DS0 的亮度也会跟着从暗变到亮,然后又从亮变到暗。至于这里的值,我们为什么取300,是因为 PWM 的输出占空比达到这个值的时候,我们的 LED 亮度变化就不大了(虽然最大值可以设置到 899),因此设计过大的值在这里是没必要的。
|