pwm最后的解释

之前学东西总是模模糊糊,前几天看了pwm,虽然知道怎么配置,但是如果让我自己去写一个pwm的程序,我却不知如何下手。

不知道如何配置他的频率和占空比。今天痛定思痛,决定彻底搞懂pwm。

百度给 的答案是:

pwm的频率是指每秒钟信号从高电平到低电平再回到高电平的次数,占空比是高电平持续时间和低电平持续时间之间的比例。
pwm的频率越高,其对输出的响应就会越快,频率越低输出响应越慢。

首先pwm要知道他的频率,频率该如何设定呢?

看了这一位博主的文章让我名表了很多:http://blog.csdn.net/huang_jinjin/article/details/7292166?locationNum=6&fps=1

他的最后有这一段话,不分频的话,时钟是72mhz,就是每秒计数72m,而TIM_Period就是定义了pwm的一个周期记的次数,比如说是2000,就是经过2000/72m这个时间是一个周期,

那么频率就是周期的倒数,这个pwm的频率就是72m/2000(hz),这样就确定了频率。

那么TIMx_ARR寄存器的值是怎样来确定pwm的频率的呢?TIM_Period(即是TIMx_ARR寄存器的值) 的大小实际上表示的是需要经
过TIM_Period 次计数后才会发生一次更新或中断。接下来需要设置时钟预分频
数TIM_Prescaler,这里有一个公式,我们举例来说明:例如时钟频率=72MHZ/(时
钟预分频+1)。(假设72MHZ为系统运行的频率,这里的时钟频率即是产生这个pwm的时钟的频率)说明当前设置的这个TIM_Prescaler,直接决定定时器的时钟频率。
通俗点说,就是一秒钟能计数多少次。比如算出来的时钟频率是2000,也就是
一秒钟会计数2000 次,而此时如果TIM_Period 设置为4000,即4000 次计数后就会中断一次。由于时钟频率是一秒钟计数2000 次,因此只要2 秒钟,就会中
断一次。
还有一个需要注意的,就是我们一般采用向上计数模式。

 

接下来,就是占空比的配置了,注意下面这一句话:

TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式

 

已经选择定时器为pwm1,所以下面直接给TIMx_CCRx赋值就可以了。在pwm1模式下,IMx_CCRx的值越大,占空比就越大。

TIMx_CCRx寄存器,确定PWM的占空比。TIMx_CCR1—TIMx_CCR4确定定时器的CH1—CH4四路PWM的占空比。直接给该寄存器赋0—65535值即可确定占空比。占空比计算方法:TIMx_CCRx的值除以ARR寄存器的值即为占空比,因为占空比在0—100%之间,所以一般TIMx_CCRx寄存器值不能超过ARR寄存器的值,否则可能会引起PWM的频率或占空比的准确性。

 

好了,下面就是我自己写的并理解的程序了,只是简单的输出占空比

#include "stm32f10x.h"

void gpio_init(void);///tim3的ch1,在pa6上面
void TIM2_init(void);

int  main(void)
{
  gpio_init();
    TIM2_init();
    while(1);
    
}


void gpio_init()
{
    GPIO_InitTypeDef GPIO_InitStructure;
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); 
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; 
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    TIM2_init();
    
}

void TIM2_init()
{
    TIM_TimeBaseInitTypeDef        TIM_TimeBaseStructure;
    TIM_OCInitTypeDef              TIM_OCInitStructure;
    
     RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
    
    //PWM频率 = 72000000 / 4 / 1000 = 18Khz
    TIM_TimeBaseStructure.TIM_Period = 1000 - 1; //PWM计数上限     
    TIM_TimeBaseStructure.TIM_Prescaler = 4 - 1; //设置用来作为TIM2时钟频率除数的预分频值,4分频
    TIM_TimeBaseStructure.TIM_ClockDivision = 0; //设置时钟分割:TDTS = Tck_tim
    TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIMx向上计数模式
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据TIM_TimeBaseStructure中指定的参数初始化外设TIM2
    
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
    TIM_OCInitStructure.TIM_Pulse = 200; //设置待装入捕获比较寄存器的脉冲值
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出极性:TIM输出比较极性高
    
    TIM_OC1Init(TIM3, &TIM_OCInitStructure); 
    TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable); //使能TIM2在CCR1上的预装载寄存器

    TIM_ARRPreloadConfig(TIM3, ENABLE); //使能TIM2在ARR上的预装载寄存器
    TIM_Cmd(TIM3, ENABLE);  //使能TIM2外设
}

 

固定的pwm波,实验证实,这里不需要中断函数,定时器会自动重装数值,32真是强大在这里啊。定时器自带BGM.

 

posted @ 2017-03-04 14:05  Andrew_qian  阅读(6781)  评论(0编辑  收藏  举报