Generate an accurate 50Hz waveform

I want to generate an accurate 50Hz waveform on HiFive1, and I use FreedomStudio. My configuration is as follows:

#define PWM_CFG_SCALE 0x0000000D

((volatile uint32_t) (variant_pwm[pwm_num] + PWM_CFG)) = 0;
((volatile uint32_t) (variant_pwm[pwm_num] + PWM_COUNT)) = 0;
((volatile uint32_t) (variant_pwm[pwm_num] + PWM_CMP0)) = 625;
((volatile uint32_t) (variant_pwm[pwm_num] + PWM_CFG)) = (PWM_CFG_ZEROCMP | PWM_CFG_ENALWAYS | PWM_CFG_SCALE);

My understanding is that :
256MHz / (2^13) = 31250Hz
31250Hz / 50Hz = 625

But in fact , I use the oscilloscope to view, the cycle is 213Hz.
And I don’t know how to generate this cycle, and also how to configure to generate 50Hz waveform

Should you not also be setting one of PWM_CMP1 … PWM_COMP3 to something around half of 625, to set how symmetrical you want the mark/space ratio within the wave?

@bruce is correct that you should be using one of the comparators to set the duty cycle, but another question: Which PWM are you using (PWM0, 1, or 2?) On the HiFIve1 PWM0 is only an 8-bit comparator, so if you try to write 625 to PWM0_CMP0 it will be truncated. You may want to read back and check what you have written for each of the above to make sure the values that you wrote are captured as you expect.

Ah, good catch! FE310-G000 manual, page 7: “PWM0 (8 bit timer with 4 cmp)”. I hadn’t realized that…

The only thing is that 625 truncated to 8 bits is 113, which would give an expected frequency of 276 Hz, not 213 Hz. Closer but not what is apparently observed. So there is still a mystery.

I don’t know about everyone else but I often find it really difficult to know whether to look for something in the HiFive1 manual, the FE310-G000 manual, or the E300-platform manual.

In this case (as I guess is the general rule) you need to look in the E300-platform manual to see how to use PWMs in general, in the FE310-G000 manual to learn how many PWMs there are and their memory addresses and that PWM0 is only 8 bits and which pins on the QFN 48 package they connect to, and then the HiFive1 manual to map the QFN 48 pins to the Arduino pins.

@bruce we hear you about the need for fewer seperate docs. We are working to unify this information at least between the E300 Platform Manual and the chip manual. The way the U540-G000 manual looks (with the general and specific info combined into one document/chapter) is the plan going forward, so let us know if there is something you think might be useful to add!

The HiFive1 manual would still be something separate, since it’s specific to how the FE310-G000 is used on the HiFive1 PCB.

Thanks for your reply!

I found out that the previous problem was that I wrote the above configuration in the function call, and each time function call was reconfigured. So It caused a error in the cycle.

And according to suggestions, I successfully configure the duty cycle.

But there are other two questions:

  1. I can use PMW1,2 normally, but when I use PWM0, it doesn’t have any waveform .

  2. The configuration is unchanged. The period is viewed by oscilloscope around 52.6/52.5Hz, not the accurate 50Hz.
    When I change the period 625 to 656,as follow. The period is almost tend to 50Hz.
    ((volatile uint32_t) (variant_pwm[pwm_num] + PWM_CMP0)) = 656;
    What is the reason? And is there a way to generate a percise cycle?

Thanks!

I think you need to ask: is “256 MHz” equal to 256,000,000 or is it 2^28 = 268,435,456?