9 years ago.

FastPWM not outputting correct frequency

Hi everyone!

I'm using STM NUCLEO-F411RE board and at the moment I'm trying to use one of the GPIO pins to output 8MHz (or close to this value) signal. However, I keep on getting 1.63782MHz which I read by connecting test pin to an osciloscope.

Core clock is 100MHz hence by dividing it by 13 I can potentially get something around 7.69MHz.

I have tried to change pre-scaler value but it makes no change to the output.

Can anyone advice what should I do to solve the problem?

Thanks.

The code:

#include "mbed.h"
#include "FastPWM.h"

Serial pc(USBTX, USBRX);       

DigitalOut test(PA_10);
DigitalOut myled(LED1);

FastPWM my_newpwm(PWM_OUT);
 
int main() 
{
    printf("Hello, shift register \n");
    
    double period = 65*0.000000002;       // same as 1/(SystemCoreClock/13)
    //my_newpwm.prescaler(-1);              // doesn't make any difference
    
    my_newpwm.period_ticks(period);    
    my_newpwm.pulsewidth_ticks(period/2); 
  
    while(1) 
    {    
        test= !test;
    }
}

1 Answer

9 years ago.

I don't see why you get the 1.6MHz, which makes little sense to me. However period_ticks sets the period in clock cycle ticks, if you want a divider of 13, just set it to directly 13. If you want to set the period in seconds/micro seconds, you need to use the period/period_us functions.

Accepted Answer

Hi Erik.

I have tried next combinations:

    my_newpwm.period_us(0.13);    
    my_newpwm.pulsewidth_us(0.065); 

and

    my_newpwm.period_ticks(13);    
    my_newpwm.pulsewidth_ticks(6); 

and

    uint32_t period = 13;
    uint32_t pulsewidth = 6;
      
    my_newpwm.period_ticks(period);    
    my_newpwm.pulsewidth_ticks(pulsewidth); 

Either 0.13us or 13 ticks should provide 7.69MHz output signal. However, it either created a 1.6MHz wave or some noise at 150-400kHz or noise at 2-4.6MHz. I know that my board supports PWM as I have already used it for a different project.

I have already spent couple of days trying to solve this problem but no success yet.

posted by Vitaliy Martynets 14 Apr 2015

I can verify on the F401 that anything below roughly 600us period fails. My first guess is that the lowest prescaler setting does not work, but there is a small range on this prescaler at which it still works.

To be fair I don't have a clue what is causing this, everything seems to be setup correctly. I'll look further into it later, but for now I don't understand why it does not work.

posted by Erik - 14 Apr 2015

Right click on your FastPWM library, click update. Problem solved :).

Luckily the F401 seems to use same timer for default PWM_OUT as F411 otherwise I might well have missed it in trying to verify it. The issue: FastPWM is build on top of the mbed PWM library to handle pesky things like enabling clocks. It also assumes the mbed library sets basic settings correct. It does not. The syncronization logic which determines when the period register gets updated was not enabled. The result was pretty random, but the effect would mainly be visible with short periods: If you set a period shorter than the current count, it would first need to overflow the timer before it would work properly. On a 16-bit timer you don't notice this easily (at least when manually checking a logic analyzer). On a 32-bit timer this takes quite some time, and then it is not outputting a waveform. So I enabled this logic, which makes sure only a new period is actually loaded when the counter is zero: Resulting in nice PWM waveforms which are always correct.

Now you might wonder how the mbed library handles this: The usual way it handles things: "Have you tried turning it off and on again".

posted by Erik - 16 Apr 2015

Hi Erik.

I have just updated the library and tested operation of the FastPWM. Thanks for modifying the library as I can get the desired frequency of 7.69MHz. Although, the signal has some attenuation and slight distortion (only 'high' part of the wave) which I assume is due to the noise in wires and internal noise of the oscilloscope as it's reasonably old and had been used quite a lot.

However, I hope it won't make significant impact on operation of my system.

posted by Vitaliy Martynets 19 Apr 2015

I only have a logic analyzer, so I cannot see what it looks like. It might very well be your scope/wires, especially when using long wires. Ideally you measure with a probe as close to the pin as possible. In software I cannot do much about the analog waveform though :).

If you are worried about it, place a 74 series buffer/inverter before your actual application.

posted by Erik - 19 Apr 2015

Thanks for the help and advice :)

posted by Vitaliy Martynets 19 Apr 2015