I've got the simple PWM tutorial running in the simulator. All seems to work as expected, for duty cycles ranging from 2 up to 1000. I found a surprising result when setting the duty to 1. Instead of being "off" for most of the time, the outputs are on most of the time.
I wonder if that's because there's just not enough time in the main loop, and it 'misses' the trigger?
PWM tutorial - limits with low values Topic is solved
-
- Active Member
- Posts: 32
- Joined: Thu Sep 25, 2014 1:19 am
-
Verified
- XCore Legend
- Posts: 1164
- Joined: Thu May 27, 2010 10:08 am
"I wonder if that's because there's just not enough time in the main loop, and it 'misses' the trigger?"
yes - this is pretty much the size of it. This example is about as simple as a PWM component gets in XC. It uses a port timer to cause a transition in the future. Each port can be setup for a single transition in the future (Ie. go to value x at time y). It gives very good resolution (10ns steps) but has a few drawbacks...
Firstly, port timers only fire on a compare (rather than a greater or equal than for general purpose timers). This means if the time between the last port operation and the next is very short, you might miss the time trigger. This is what you are seeing. So without an "if" statement with a special case looking for duties that are close to (not just equals) 0 or 100%, you will have a practical limit on modulation depth due to instrcution timing. Secondly, port timers are only 16b, so you will get a max period of 655ns or about 1.5KHz - see http://www.xcore.com/questions/2026/wha ... timers-xs1
If you want a "perfect" pwm with a linear response from 0 to 100%, then it is necessary either to use extra software to handle special cases, or use buffererd ports (shift register effecively) to load bit streams (with a single transiton) out to an I/O port.
There is a 0-100% duty capable, reset synchrnoised PWM component lurking in here (see pwm.xc) http://www.xcore.com/projects/nixmos-li ... controller if you want one. It provides mutliple PWMs on 1b ports from a single task running on a logical core. It can support 4x 10b, 20KHz PWMs (or more channels lower freq or vice versa).
yes - this is pretty much the size of it. This example is about as simple as a PWM component gets in XC. It uses a port timer to cause a transition in the future. Each port can be setup for a single transition in the future (Ie. go to value x at time y). It gives very good resolution (10ns steps) but has a few drawbacks...
Firstly, port timers only fire on a compare (rather than a greater or equal than for general purpose timers). This means if the time between the last port operation and the next is very short, you might miss the time trigger. This is what you are seeing. So without an "if" statement with a special case looking for duties that are close to (not just equals) 0 or 100%, you will have a practical limit on modulation depth due to instrcution timing. Secondly, port timers are only 16b, so you will get a max period of 655ns or about 1.5KHz - see http://www.xcore.com/questions/2026/wha ... timers-xs1
If you want a "perfect" pwm with a linear response from 0 to 100%, then it is necessary either to use extra software to handle special cases, or use buffererd ports (shift register effecively) to load bit streams (with a single transiton) out to an I/O port.
There is a 0-100% duty capable, reset synchrnoised PWM component lurking in here (see pwm.xc) http://www.xcore.com/projects/nixmos-li ... controller if you want one. It provides mutliple PWMs on 1b ports from a single task running on a logical core. It can support 4x 10b, 20KHz PWMs (or more channels lower freq or vice versa).
Engineer at XMOS