Koduino
Functions
PWM output and input

Detailed Description

Usage

PWM output:

  1. (Optionally) call pinRemap() to change the timer connected to a pin
  2. (Optionally) call analogWriteFrequency() to change output PWM frequency
  3. Call pinMode() with PWM
  4. Call analogWrite()

PWM input can be accomplished using two underlying methods: using a timer input channel (pin needs to be connected to a general purpose timer channel), or using an external interrupt (can only have one per PinSource—this is the last digit in 0–15 of the pin name).

  1. (Optionally) if using PWM_IN, call pinRemap() to change the timer connected to a pin
  2. Call pinMode() with PWM_IN or PWM_IN_EXTI
  3. Call pwmIn()

Example: PWM output

#include <Arduino.h>
void setup() {
// (Optional) non Arduino-like function to assign a different timer to PB6
pinRemap(PB6, 11, TIMER19, 1);
// Arduino-like configuration for PWM
analogWriteFrequency(PB6, 25000);
// Unlike in Arduino, this *MUST* be called before analogWrite()
pinMode(PB6, PWM);
}
void loop() {
// 75% duty cycle PWM at 25 KHz
analogWrite(PB6, 0.75);
}

Example: PWM input (loopback) test

#include <Arduino.h>
// Connect PA0 and PA6 for this test
void setup() {
Serial1.begin(115200);
pinMode(PA0, PWM);
pinMode(PA6, PWM_IN);
}
void loop() {
analogWrite(PA0, 0.3);
Serial1 << "Read " << pwmIn(PA6) << "\n";
delay(10);
}

Functions

void analogWriteResolution (uint8_t nbits)
 Set the resolution for the analogWrite() function. More...
 
void analogWriteFrequency (uint8_t pin, int freqHz)
 Assign a PWM frequency to the specified pin (default = 1000 Hz) More...
 
void analogWriteFloat (uint8_t pin, float duty)
 Change the PWM duty cycle on a pin. More...
 
void analogWrite (uint8_t pin, uint32_t duty)
 Change the PWM duty cycle on a pin. More...
 
float pwmIn (uint8_t pin)
 Read a PWM signal (non-blocking) More...
 
void pwmInExpectedPeriod (int expectedUs)
 Set the expected period for PWM_IN or PWM_IN_EXTI. More...
 

Function Documentation

void analogWrite ( uint8_t  pin,
uint32_t  duty 
)

Change the PWM duty cycle on a pin.

This should have the same effect as the Arduino function, but it is not efficient on systems without a floating point (as implemented), since it calls analogWriteFloat() under the hood.

Parameters
pin
dutyThe new duty cycle in [0,2^n] where n is the bit resolution set by analogWriteResolution() (default 8)
void analogWriteFloat ( uint8_t  pin,
float  duty 
)

Change the PWM duty cycle on a pin.

Unlike Arduino, pinMode() must have been called on the pin beforehand with PWM. Also, the duty cycle is specified in floating point, and the resolution is only limited by the timer (see analogWriteFrequency()).

Parameters
pin
dutyThe new duty cycle in normalized floating point from 0.0 (0%) to 1.0 (100%).
void analogWriteFrequency ( uint8_t  pin,
int  freqHz 
)

Assign a PWM frequency to the specified pin (default = 1000 Hz)

Please see the pin remapping documentation for more details about connected timers to pins, including defaults. This function will change the PWM frequency for all pins connected to the same timer.

Gory details:

  • There is a 36MHz base clock.
  • Resolution: When PWM freq = 20KHz, resolution = 36000/20 = 1800 ~= 11 bits, and better for lower frequencies
  • Minimum freuency is 36000000/65535 = 549Hz
Parameters
pinPin to change frequency on
freqHzNew frequency in Hz (default is 1000)
void analogWriteResolution ( uint8_t  nbits)

Set the resolution for the analogWrite() function.

Note that this has no effect on the actual PWM resolution, which is determined by the period of the PWM (see analogWriteFrequency()). This also has no effect on analogWriteFloat()

Parameters
nbitsNumber of bits used in analogWrite() (default is 8, as in Arduino)
float pwmIn ( uint8_t  pin)

Read a PWM signal (non-blocking)

pinMode() with PWM_IN must have been called on the pin before-hand. Unlike Arduino, this function does not block and wait. It uses high-speed timer interrupts to catch rising and falling edges, and keeps track of the time when these happen to estimate the PWM duty cycle.

Advanced:

  • Period: The period of the PWM is also available in low-level form. The command

~~~ TIMER_MAP[ PIN_MAP[ pin ].timer ].channelData[ PIN_MAP[ pin ].channel-1].period

  • ~~~ will return the PWM period in units such that 36000 -> 1ms, 3600 -> 0.1ms etc.

    Parameters
    pinPin to read
    Returns
    A float from 0.0 to 1.0 corresponding to PWM duty cycle
void pwmInExpectedPeriod ( int  expectedUs)

Set the expected period for PWM_IN or PWM_IN_EXTI.

Parameters
expectedUsExpected period in microseconds (default 1000)