3.21. pwm_soft — Software pulse width modulation

This module implements software PWM on all digital pins. In general, software PWM outputs an inaccurate, low frequency signal. Keep that in mind designing your application.

If an accurate and/or high frequency PWM signal is required, a hardware PWM should be used instead.

Here is a short example of how to use this module. A software PWM driver is initialized for digital pin 3 (D3). A software PWM signal with duty cycle 10% is outputted on D3 after the calling pwm_soft_start().

struct pwm_soft_driver_t pwm_soft;

pwm_soft_module_init(500);
pwm_soft_init(&pwm_soft, &pin_d3_dev, pwm_soft_duty_cycle(10));
pwm_soft_start(&pwm_soft);

Change the duty cycle to 85% by calling pwm_soft_set_duty_cycle().

pwm_soft_set_duty_cycle(&pwm_soft, pwm_soft_duty_cycle(85));

Stop outputting the software PWM signal to D3 by calling pwm_soft_stop().

pwm_soft_stop(&pwm_soft);

Source code: src/drivers/pwm_soft.h, src/drivers/pwm_soft.c

Test code: tst/drivers/pwm_soft/main.c


Functions

int pwm_soft_module_init(long frequency)

Initialize the software PWM module. This function must be called before calling any other function in this module.

The module will only be initialized once even if this function is called multiple times.

Return
zero(0) or negative error code.
Parameters
  • frequency: PWM module frequency in Hertz. All software PWM:s will run at this frequency. The frequency can later be changed by calling pwm_soft_set_frequency().

int pwm_soft_set_frequency(long value)

Set the frequency. The frequency is the same for all software PWM:s. All software PWM:s must be stopped before calling this function, otherwize a negative error code will be returned.

Return
zero(0) or negative error code.
Parameters
  • value: Frequency to set in Hertz. All software PWM:s will run at this frequency.

long pwm_soft_get_frequency(void)

Get current frequency.

Return
Current frequency in Hertz.

int pwm_soft_init(struct pwm_soft_driver_t *self_p, struct pin_device_t *pin_dev_p, long duty_cycle)

Initialize given software PWM driver object.

Return
zero(0) or negative error code.
Parameters
  • self_p: Driver object to be initialized.
  • pin_dev_p: Pin device to use.
  • duty_cycle: Initial duty cycle.

int pwm_soft_start(struct pwm_soft_driver_t *self_p)

Start outputting the PWM signal on the pin given to pwm_soft_init().

Return
zero(0) or negative error code.
Parameters
  • self_p: Driver object to start.

int pwm_soft_stop(struct pwm_soft_driver_t *self_p)

Stop outputting the PWM signal on the pin given to pwm_soft_init().

Return
zero(0) or negative error code.
Parameters
  • self_p: Driver object to stop.

int pwm_soft_set_duty_cycle(struct pwm_soft_driver_t *self_p, long value)

Set the duty cycle. Calls pwm_soft_stop() and pwm_soft_start() to restart outputting the PWM signal with the new duty cycle.

Return
zero(0) or negative error code.
Parameters
  • self_p: Driver object.
  • value: Duty cycle. Use pwm_soft_duty_cycle() to convert a duty cycle percentage to a value expected by this function.

unsigned int pwm_soft_get_duty_cycle(struct pwm_soft_driver_t *self_p)

Get current duty cycle. Use pwm_soft_duty_cycle_as_percent() to convert a duty cycle to a percentage.

Return
Current duty cycle.
Parameters
  • self_p: Driver object.

long pwm_soft_duty_cycle(int percentage)

Convert a duty cycle percentage to a value for pwm_soft_init() and pwm_soft_set_duty_cycle().

Return
Duty cycle.
Parameters
  • percentage: Duty cycle percentage.

int pwm_soft_duty_cycle_as_percent(long value)

Convert a duty cycle value for pwm_soft_init() and pwm_soft_set_duty_cycle() to a percentage.

Return
Duty cycle percentage.
Parameters
  • value: Duty cycle.

struct pwm_soft_driver_t
#include <pwm_soft.h>

Public Members

struct pin_device_t *pin_dev_p
long frequency
long duty_cycle
unsigned int delta
struct thrd_t *thrd_p
struct pwm_soft_driver_t *next_p