10 years, 2 months ago.

PWM signal with variable frequency

Hello all,

I am using LPC 1768 and would like to generate signal from the microcontroller. Please see attached picture:

The d pulse should be constant and equal to 12.25usec, D (the period) should be variable and changing from 60KHz to 160KHz. I need that signal to control DC motor.

Please advice, Thank you, Alex

/media/uploads/Allex/max_exp_pwm.png

2 Answers

10 years, 2 months ago.

Edit: Posted this before I knew Erik did. Listen to him :)

First of all; are you sure that you need to do this? On average what you're describing sounds the same as just having a fixed frequency PWM and varying the duty cycle.

However, you get what you ask for! Here is a bit of untested (I don't own an LPC 1768) code that should demonstrate a constant pulse width with a varying frequency. I've set it up for the LED on your board so you should see it change brightness over time. Just change the PwmOut pin to use on your motors.

Variable Frequency PWM

#include "mbed.h"

PwmOut led(LED1);

int main()
{
    int frequency = 0;
    led.pulsewidth(0.000001225); //Set pulsewidth to 12.25us in s - Could use the pulsewidth_us function but would limit you to an integer value of 12us

    while(1) {
        for(frequency = 60000; frequency <= 160000; frequency++) { // increment frequency in Hz
            led.period(1/frequency); //set your period as the inverse of frequency
            wait_us(100);
        }
    }
}

Accepted Answer
10 years, 2 months ago.

You can simply change the period of a PwmOut signal. By default that will also generate a new pulsewidth, since it keeps the duty cycle constant, but you can either directly overwrite it with the old pulsewidth (which can sometimes be too late for one period), or alter the code a bit.

For your requirements I would use http://mbed.org/users/Sissors/code/FastPWM/, same as regular PWM on the LPC1768, but it is way more accurate at high frequencies because it runs the PWM at full clock frequency and the code actually uses that accuracy.

Now for your pulsewidth, the period code is for example: (found in common.cpp, there are several codes):

void FastPWM::period_us(double us) {
    if (dynamicPrescaler)
        calcPrescaler((uint64_t)(us * (double)(SystemCoreClock / 1000000)));
        
    period_ticks(us * dticks_us + 0.5);
    pulsewidth_ticks(getPeriod() * _duty);
}

Simply delete the pulsewidth line from there.