创客百科

姿势共享,有节操无门槛参与的创客百科,创客动力之源 \ (^_^) /

用户工具

站点工具


arduino:libraries:pwm_frequency

PWM 频率




I discovered in a recent project involving an Arduino microcontroller that there was no method to change PWM frequency without directly manipulating low-level memory. As far as I can Google, there is no general purpose library that can change PWM frequencies on Arduino Microcontrollers. The internet is full of partial examples and code snippets for changing PWM frequency, but in the end I still had to consult the 400+ page sec sheet (http://www.atmel.com/Images/doc2549.pdf) to get the code for my Mega functional.
我发现在最近的一个涉及Arduino单片机的项目,内容是在没有直接操纵低端内存的情况下,是没有方法改变PWM频率。据我谷歌搜索到的,在Arduino微控制器里,是没有通用库可以改变PWM频率。互联网上到处都是来改变PWM频率的部分例子和代码片段,但最后我还是不得不咨询400 +page sec sheet (http://www.atmel.com/Images/doc2549.pdf)来为我的Mega功能获取代码。

It is my speculation that the programmers at Arduino have not released any methods for changing PWM frequency because it is difficult to write a simple and intuitive wrapper for hardware timers that wont run the risk of confusing a beginner (the whole draw to Arduino in the first place). The hardware is has very specific limitations that present themselves in odd ways. Allow me to share a few:
这是我的猜测,程序员在Arduino尚未发布任何方法来改变PWM频率,因为很难给硬件定时器编写一个简单的和直观的包装器,因此不会冒使初学者困惑的风险(首先整体上把他们吸引到Arduino上来)。硬件是有非常特定的限制,并以奇怪的方式描述。请允许我分享一些:

PWM behavior is determined by integrated components called timers. Every timer has two to four channels. Each channel is connected to a pin. Changing one pin's frequency requires changes to the timer it connects to. Which in turn changes the frequency of other pins connected to that same timer.
PWM的特性是由叫做定时器的组件集成的。每个定时器有两至四个通道。每个通道都与一个端口连接。要改变一个端口的频率,则要求改变它连接的定时器。从而改变其他连接到相同的计时器端口的频率。

Timer 0 is usually used for Arduino's time keeping functions, (i.e. the millis() function). Changing the frequency on timer 0 will break the time keeping functions you may or may not be using in other parts of your project.
定时器0通常用于Arduino的时间保持功能,(即米尔斯()函数)。在定时器0上改变频率将破坏你的项目的其他部分中你可以或不可以使用记时功能。

There are two types of timer, 8bit and 16bit. Long story short, they have nuances that make common code difficult to implement without limiting one or the other.
这里有两种类型的计时器,8位的和16位的。长话短说,他们有细微差别,在不限制一个或另一个的情况下,使得通用代码很难实现。

Creating custom frequencies (beyond messing with the prescaler) with an 8bit timer requires the sacrifice of one channel. In other words, each 8bit timer that creates a custom frequency loses the ability to perform PWM on one pin (the one connected to the A channel to be more precise). All Arduinos except the Leonardo have two 8bit timers, meaning that setting all timers to a particular frequency will sacrifice a total of two pins on said Ardiuno.
创建一个8位定时器的自定义频率(除了打乱预定标器)需要牺牲一个频道。换句话说,创建一个自定义频率的每个8位定时器,失去执行一个PWM端口的能力(一个连接到更为精确的通道)。 Ardiuno表示,所有Arduinos除了Leonardo都有两个8位定时器,这意味着设置所有定时器到特定频率将总共牺牲两个端口。
Regardless of this, I still felt it would still be worth while to make a library/wrapper for hardware timers so that I, and anyone else who chooses to use this, will not have to spend quite as many hours needlessly digging through blocks of bug prone bit wise and preprocessor slurry.
不管这个,我还是觉得这仍然是值得做一个库或硬件定时器的包装器,这样我和其他人谁选择使用这个的时候,则不需要花那么多不必要的时间翻出资料段里的程序错误和预处理器的流动性。

The library has five global functions:
此库有五个全局函数:

InitTimers() Initializes all timers. Needs to be called before changing the timers frequency or setting the duty on a pin
初始化所有计时器。在一个端口改变计时器频率或设置工作状态之前需要被呼叫。
InitTimersSafe() Same as InitTimers() except timer 0 is not initialized in order to preserve time keeping functions
与InitTimers()函数一样,但除了定时器0不是为了时间保持功能而进行初始化的

InitTimers

pwmWrite(uint8_t pin, uint8_t val) Same as 'analogWrite()', but it only works with initialized timers. Continue to use analogWrite() on uninitialized timers
与“analogWrite()”函数一样,但它只适用于初始化计时器。在未初始化计时器继续使用analogWrite()

SetPinFrequency(int8_t pin, int32_t frequency) Sets the pin's frequency (in Hz) and returns a bool for success
设置端口的频率(单位赫兹)并成功返回布尔函数
SetPinFrequencySafe(int8_t pin, int32_t frequency) Same as SetPinFrequency except it does not affect timer 0
与SetPinFrequency一样,但它不影响定时器0

The library also has five functions for each Timer 'object'. I could not get the code size down to what I felt was reasonable so I ditched C++ classes and did some fancy macro work instead. Each of these functions are technically preprocessor macros with nice self explanatory names that swap out for more cryptic functions inside the library header just before compile time. For timer 1 the functions are:
库里也有五个功能来对应每个定时器的“object”。我不能将代码内存缩小至我觉得是合理的,所以我抛弃了C + +类并做了一些精心设计的巨集工作代替。这些功能是有技术上的预处理器巨集,并有着自我解释性好的名字,在编译时间之前换出更多隐藏的功能在库首。定时器1的功能是:
Timer1_GetFrequency() Gets the timer's frequency in HZ 获取定时器的频率以赫兹为单位 Timer1_SetFrequency(int frequency) Sets the timer's frequency in Hz 设置定时器的频率以赫兹为单位 Timer1_GetPrescaler() Gets the value (not bits) of the prescaler. Don't know what this means? Don't worry about it, just use SetFrequency(int frequency)
获得预定标器的值(不是比特)。不知道这意味着什么吗?但别担心,只是使用SetFrequency(int频率) Timer1_SetPrescaler(enum value) Sets the prescaler* 设置预定标器 Timer1_GetTop() Gets the timer register's maximum value
获得定时器寄存器的最大值 Timer1_SetTop(int top) Sets the timer register's maximum value
设置定时器寄存器的最大值 Timer1_Initialize() Initializes the timer
初始化定时器
*The prescaler is inconsistent among different timers. I figured using enumerators was the best solution because most types of invalid input will be caught at compile time. For a normal timer, use one of these as a parameter: ps_1, ps_8, ps_64, ps_256, ps_1024. If those give a type error, then the timer you are using is one of the inconsistent ones, and you should use psalt_1, psalt_8, psalt_32, psalt_64, psalt_128, psalt_256, or psalt_1024 instead.
在不同的计时器,预定标器是不一致的。我想使用枚举器是最好的解决方案,因为大多数类型的无效输入将在编译时被捕捉到。对于一个正常的定时器,使用其中一个作为一个参数:ps 1、ps 8,ps_64,ps_256,ps_1024。如果给了一个类型错误,那么你正在使用的定时器是(与预定标器)是不一致中的一个,你应该使用psalt_1,psalt_8,psalt_32,psalt_64,psalt_128,psalt_256,或psalt_1024代替。
If you want to mess with a different timer, just change the number (i.e Timer2_GetFrequency() to get timer 2's frequency). It is up to your discretion whether or not you want to use the timer specific functions. The global ones should be good enough for most situations.
如果你想打乱一个不同的定时器,就改变数字(i.e Timer2_GetFrequency()得到定时器2的频率)。这取决于你是否你想使用定时器的特定功能。大多数情况下,所有人都应该适用。

With this Library, 16bit timers have a frequency range from 1Hz to 2MHz. 8bit timers have a range from 31Hz to 2MHz. As the frequency becomes larger, the smaller the range power duties for a pin becomes. It is technically possible to push the frequency to 8MHz, but the range of possible power duties get stupidly small by that point. To be sure the frequency was correctly set, be sure to check the return value. If you don't want to sacrifice any 8bit PWM pins, don't call the initialize function for that timer, try changing the prescaler to manipulate frequency instead. There are many tutorials on how the prescaler affects timers and this library contains methods that make easier and less bug prone to manipulate. So far, I have tested this library on an Uno and a Mega. This library should be compatible with all Arduinos except the Leonardo and Due. If you have an Arduino that is not a Mega or Uno, please test it and tell me how it went. If somebody has an oscilloscope on hand to verify the frequencies being generated are correct, that would also be helpful.
在这个库中,16位定时器有一个从1赫兹到2 mhz的频率范围。8位定时器有从31赫兹到2 mhz频率范围。随着频率变大,形成端口的耗能越小。它在技术上是可以推到8 mhz的频率,但到那个时候可能耗能范围将降到极小。确定频率的正确设置,确定检查过返回值。如果你不想牺牲任何8位的PWM别针,那么就不为定时器使用initialize函数,尝试改变用预定标器来操纵频率代替。有很多教程来说明预定标器是如何影响定时器,以及库包含的更容易和更少的错误且容易操纵的方法,。到目前为止,我已经测试了这个库一个Uno和Mega。这个库应该兼容所有Arduinos除了Leonardo和Due。如果你有一个不是Mega或Uno的Arduino,请测试它并告诉我操作过程。如果有人用示波器来验证生成的频率是正确的,这也是有帮助的。

For now, consider this library to be in beta. Developments on this library are described in later posts.
现在,考虑这个库是测试版。此库的发展将在以后的文章中介绍。

Here are some of the current features of this library:
以下是此库的当前具备的特征:

Wraps timer specific properties (such as timer top and prescaler) with functions
包装定时器特定属性(如定时器的顶部和预定标器)功能

Has pin based (timer agnostic) functions
有端口基础(定时器不可知论者)功能

Has functions for getting and setting frequency at the timer level and pin level
在计时器水平和端口水平上,有能获取和设置频率的函数

Has tools for measuring timer resolution at the timer level and pin level
在定时器在测量水平和端口水平上,可以用工具测量计时器分辨率

The latest is version .05
新的版本是. 05

link: http://code.google.com/p/arduino-pwm-frequency-library/downloads/list
连接至http://code.google.com/p/arduino-pwm-frequency-library/downloads/list

本页面的其他翻译:
arduino/libraries/pwm_frequency.txt · 最后更改: 2016/12/25 22:15 (外部编辑)