5 years, 6 months ago.

PWM output ratio != 0% on pins 1, 2, 18, but on pin 24?

Hello there,

I'm using all PWM-channels for LED-dimming purposes. When I transferred already working code from LPC1768 to LPC1114 I encountered problems - not all channels dim down towards 'full off' state. Tracking down this strange behaviour lead to the fact that pin 24 uses an 32bit-counter, all others use 16bit-counters (if I got this right).

With a logic-analyzer I can see one spike of 0.7 microseconds at 50Hz, when the PWM-channel is enabled, this is long enough to see the leds shining, which isn't desired.

I can't see a similar spike on the '32bit-resolution-channel', but the sample-rate of the analyzer is limited to 24MHz, so this is no surprise - I guess there is a similar spike, but this can't be seen by human eyes...

Is there an elegant way to switch off the channel in case 'duty-cycle==0', which I could do in my code when dimming down to zero (And switch output on again without a short flash or similar effects)?

Thanks,

Michael

Question relating to:

The LPC1114FN28 is an ARM Cortex-M0 based, low-cost 32-bit MCU, designed for 8/16-bit microcontroller applications, offering performance, low power, simple instruction set and memory addressing together with reduced code size ...

Hi Michael,

Thank you for your report. I have reproduced the issue. I've locally fixed the issue to avoid the extra spike when duty is 0% and testing now. I will let you know when I have done my test and pull request.

Regards, Toyo

posted by Toyomasa Watarai 24 Jun 2014

Hello Toyo,

I made a quick fix which fits for my needs (I didn't check if returned values when using read() are correct) when I took a look on the source:

pwmout_api.c

void pwmout_write(pwmout_t* obj, float value) {
    if (value < 0.0f) {
        value = 0.0;
    } else if (value > 1.0f) {
        value = 1.0;
    }
    
    timer_mr tid = pwm_timer_map[obj->pwm];
    LPC_TMR_TypeDef *timer = Timers[tid.timer];

/* original version:
    uint32_t t_off = timer->MR3 - (uint32_t)((float)(timer->MR3) * value);
*/
// changed to:

    uint32_t t_off;
    if (value==0)  t_off = timer->MR3+1;
    else  t_off = timer->MR3 - (uint32_t)((float)(timer->MR3) * value);

// end of changed lines
        
    timer->TCR = TCR_RESET;
    timer->MR[tid.mr] = t_off;
    timer->TCR = TCR_CNT_EN;
}

Best regards,

Michael

posted by Michael Malms 24 Jun 2014
Comment on this question

1 Answer

5 years, 5 months ago.

Hi Michael,

Thanks for providing your code. My code is very similar than yours, but I also modified the pwmout_read() function as well. The pull request was accepted and just merged below:

https://github.com/mbedmicro/mbed/pull/371

You can get this fix in next release of the mbed library.

Regards, Toyo