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.

  • 相关阅读:
    Freedur为什么会免费?
    Cocos2d-x中使用音频CocosDenshion引擎介绍与音频文件的预处理
    AssetManager asset的使用
    Android AsyncHttpClient
    UI标签库专题十三:JEECG智能开发平台 ckfinder(ckfinder插件标签)
    UBUNTU 下如何升级 gcc, g++
    java 泛型深入之Set有用工具 各种集合泛型深入使用演示样例,匿名内部类、内部类应用于泛型探讨
    最新Connectify注冊码(序列号) Connectify3.7序列号 破解版
    简单单元測试思想
    Dijkstra算法
  • 原文地址:https://www.cnblogs.com/qsyll0916/p/6501224.html
Copyright © 2011-2022 走看看