zoukankan      html  css  js  c++  java
  • 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.

  • 相关阅读:
    ASP.NET在禁用视图状态的情况下仍然使用ViewState对象【转】
    Atcoder Regular Contest 061 D Card Game for Three(组合数学)
    Solution 「CERC 2016」「洛谷 P3684」机棚障碍
    Solution 「CF 599E」Sandy and Nuts
    Solution 「洛谷 P6021」洪水
    Solution 「ARC 058C」「AT 1975」Iroha and Haiku
    Solution 「POI 2011」「洛谷 P3527」METMeteors
    Solution 「CF 1023F」Mobile Phone Network
    Solution 「SP 6779」GSS7
    Solution 「LOCAL」大括号树
  • 原文地址:https://www.cnblogs.com/qsyll0916/p/6501224.html
Copyright © 2011-2022 走看看