aboutsummaryrefslogtreecommitdiffstats
path: root/docs/source/pwm.rst
diff options
context:
space:
mode:
Diffstat (limited to 'docs/source/pwm.rst')
-rw-r--r--docs/source/pwm.rst118
1 files changed, 118 insertions, 0 deletions
diff --git a/docs/source/pwm.rst b/docs/source/pwm.rst
new file mode 100644
index 0000000..1a8f4df
--- /dev/null
+++ b/docs/source/pwm.rst
@@ -0,0 +1,118 @@
+.. _pwm:
+
+PWM
+===
+
+Pulse Width Modulation (PWM) is a basic technique to create repeated square
+waves (digital high/low voltage transitions) of user defined length
+and duty cycle. It can be used as a way to encode an "analog" signal
+on a single digital (high/low) line using the time between transitions
+("pulse width") as the variable; this technique is commonly used to
+send servo position and motor speed commands. Another use is to use to
+the ratio of "high" and "low" time to approximate a voltage output;
+this technique can be used to dim an LED or even (with careful
+filtering) generate audio waveforms.
+
+.. contents:: Contents
+ :local:
+
+Overview
+--------
+
+The Maple has a large number of 16-bit PWM outputs, each connected to
+one of 4 timers. Some configuration, such as the clock rate or
+prescaling, must be common to the entire timer; see the :ref:`timer
+documentation <timers>` for more information.
+
+Note that unlike the Arduino, the Maple does not have PWM
+functionality on pin D10; all other pins are :ref:`compatible
+<compatibility>`.
+
+The following table shows which timer can generate which PWM
+outputs. See the :ref:`pin mapping table <pin-mapping-mega-table>` to
+track down exactly which timer *channel* corresponds to each pin.
+
+.. _pwm-timer-table:
+
+.. csv-table::
+ :header: Timer, PWM Headers
+ :delim: |
+
+ Timer1 | D6,D7,D8
+ Timer2 | D0,D1,D2,D3
+ Timer3 | D11,D12,D27,D28
+ Timer4 | D5,D9,D14,D24
+
+Background
+----------
+
+In its simplest form, the device is a single counter with two
+variables. The counter starts at zero, and the output starts at
+"high". The counter increments every clock cycle until it reaches the
+first variable number, at which point the output goes "low". The
+counter continues incrementing until it reaches the second variable at
+which point the output goes "high" again and the counter resets to
+zero. The time spent with output high is called the **pulse duration**
+or **duty**; the total time before repeat is the **period**.
+
+This simple functionality could be approximated in software by setting
+a GPIO high or low, but the beauty of PWM is that user code simply has
+to configure the device and set the two variables and the device will
+function on its own; no further microprocessor cycles will be
+consumed, and a repeated high/low waveform will spew out.
+
+The Maple has 16-bit PWM resolution, which means that the counter and
+variables can be as large as 65535, as opposed to 255 with 8-bit
+resolution. With a 72MHz clock rate, a PWM output could have maximum
+period of about one millisecond; using a :ref:`prescaler
+<lang-hardwaretimer-setprescalefactor>` (clock divider) in front of
+the counter can increase this maximum period. Setting the
+:ref:`period <lang-hardwaretimer-setperiod>` to something other than
+the maximum value gives further control over the total length of the
+waveform. However, this effectively limits the resolution with which
+the duty can be modified: the duty must be less than or equal to the
+period.
+
+Here are some commonly used PWM configurations (note that servos are
+notoriously variable, especially the lower cost models):
+
++-------------+----------+-----------+---------+---------------+------+
+|**Purpose** |**Period**|**Duty** |Prescaler|Period |Duty |
+| |(ms) |(ms) | | | |
++=============+==========+===========+=========+===============+======+
+|LED throb |0.020 |0--0.020 |1 (none) |65535 (default)|0--767|
+| | | | | | |
++-------------+----------+-----------+---------+---------------+------+
+|Servo control|20 |1.25 (0°) |21 |65535 (default)|4096 |
+| | | | | | |
+| | |1.50 (90°) |21 |65535 (default)|4915 |
+| | | | | | |
+| | |1.75 (180°)|21 |65535 (default)|5734 |
+| | | | | | |
++-------------+----------+-----------+---------+---------------+------+
+
+Function Reference
+------------------
+
+- :ref:`lang-pinmode`
+- :ref:`lang-pwmwrite`
+- :ref:`Timer API<lang-hardwaretimer>` (especially :ref:`setOverflow()
+ <lang-hardwaretimer-setoverflow>`, :ref:`setPrescaleFactor()
+ <lang-hardwaretimer-setprescalefactor>`, and :ref:`setPeriod()
+ <lang-hardwaretimer-setperiod>`).
+- :ref:`Timers reference <timers>`.
+
+Recommended Reading
+-------------------
+
+* `Wikipedia Article on Pulse-width modulation
+ <http://en.wikipedia.org/wiki/Pulse-width_modulation>`_
+* `Arduino tutorial on PWM <http://www.arduino.cc/en/Tutorial/PWM>`_
+* `Secrets of Arduino PWM
+ <http://www.arcfn.com/2009/07/secrets-of-arduino-pwm.html>`_ by Ken
+ Shirriff
+* `So You Want To Use PWM, Eh? <http://www.arcfn.com/2009/07/secrets-of-arduino-pwm.html>`_ at Non-Lexical Vocables
+* STMicro documentation for STM32F103RB microcontroller:
+
+ * `Datasheet <http://www.st.com/stonline/products/literature/ds/13587.pdf>`_ (pdf)
+ * `Reference Manual <http://www.st.com/stonline/products/literature/rm/13902.pdf>`_ (pdf)