极客工坊

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 14011|回复: 4

关于如何设定PWM口的频率的解决方案

[复制链接]
发表于 2012-12-29 17:17:55 | 显示全部楼层 |阅读模式
我们的PWM口只能通过输出占空比来输出模拟量,但是如果要输出1-60KHz或更高的脉冲频率的话,就不好做到啦。我一直在需找解决方案,无意中找到啦,现提供给大家分享,希望能有所帮助。

源代码如下:

Here are some usage examples of the function:

// Set pin 9's PWM frequency to 3906 Hz (31250/8 = 3906)
// Note that the base frequency for pins 3, 9, 10, and 11 is 31250 Hz
setPwmFrequency(9, 8);

// Set pin 6's PWM frequency to 62500 Hz (62500/1 = 62500)
// Note that the base frequency for pins 5 and 6 is 62500 Hz
setPwmFrequency(6, 1);

// Set pin 10's PWM frequency to 31 Hz (31250/1024 = 31)
setPwmFrequency(10, 1024);




Please keep in mind that changing the PWM frequency changes the Atmega's timers and disrupts the normal operation of many functions that rely on time (delay(), millis(), Servo library).


/**
* Divides a given PWM pin frequency by a divisor.
*
* The resulting frequency is equal to the base frequency divided by
* the given divisor:
*   - Base frequencies:
*      o The base frequency for pins 3, 9, 10, and 11 is 31250 Hz.
*      o The base frequency for pins 5 and 6 is 62500 Hz.
*   - Divisors:
*      o The divisors available on pins 5, 6, 9 and 10 are: 1, 8, 64,
*        256, and 1024.
*      o The divisors available on pins 3 and 11 are: 1, 8, 32, 64,
*        128, 256, and 1024.
*
* PWM frequencies are tied together in pairs of pins. If one in a
* pair is changed, the other is also changed to match:
*   - Pins 5 and 6 are paired on timer0
*   - Pins 9 and 10 are paired on timer1
*   - Pins 3 and 11 are paired on timer2
*
* Note that this function will have side effects on anything else
* that uses timers:
*   - Changes on pins 3, 5, 6, or 11 may cause the delay() and
*     millis() functions to stop working. Other timing-related
*     functions may also be affected.
*   - Changes on pins 9 or 10 will cause the Servo library to function
*     incorrectly.
*
* Thanks to macegr of the Arduino forums for his documentation of the
* PWM frequency divisors. His post can be viewed at:
*   http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1235060559/0#4
*/
void setPwmFrequency(int pin, int divisor) {
  byte mode;
  if(pin == 5 || pin == 6 || pin == 9 || pin == 10) {
    switch(divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 64: mode = 0x03; break;
      case 256: mode = 0x04; break;
      case 1024: mode = 0x05; break;
      default: return;
    }
    if(pin == 5 || pin == 6) {
      TCCR0B = TCCR0B & 0b11111000 | mode;
    } else {
      TCCR1B = TCCR1B & 0b11111000 | mode;
    }
  } else if(pin == 3 || pin == 11) {
    switch(divisor) {
      case 1: mode = 0x01; break;
      case 8: mode = 0x02; break;
      case 32: mode = 0x03; break;
      case 64: mode = 0x04; break;
      case 128: mode = 0x05; break;
      case 256: mode = 0x06; break;
      case 1024: mode = 0x7; break;
      default: return;
    }
    TCCR2B = TCCR2B & 0b11111000 | mode;
  }
}

提供参考网址:
http://arduino.cc/playground/Code/PwmFrequency
http://arduino.cc/playground/Main/TimerPWMCheatsheet


回复

使用道具 举报

发表于 2012-12-29 22:51:57 | 显示全部楼层
这个就是标准的avr编程,其实在arduino ide下完全支持avr的寄存器配置
回复 支持 反对

使用道具 举报

发表于 2012-12-30 10:35:47 | 显示全部楼层
挺好,有用。还有一点,分辨率是多少?
回复 支持 反对

使用道具 举报

发表于 2014-8-11 11:17:07 | 显示全部楼层
请问,一般设置占空比0~255调节,用这段代码是不是可以设置高于255的占空比,如果反馈给电机,是不是可以让电机转的更快呢?
回复 支持 反对

使用道具 举报

发表于 2014-8-12 08:35:52 | 显示全部楼层
收录下来,学习了!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|联系我们|极客工坊

GMT+8, 2026-6-16 13:00 , Processed in 0.043022 second(s), 22 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表