I am programming LPC2103 in a motor control application using PWM on timer0. I have set T0_MR3 to specify the cycle length (let’s say 1000 timer ticks) and I am using T0_MR2 to specify the duty cycle for the motor output on Mat0.2 (P0.16). That all works well
I am concerned about the following scenario: the motor is set to a duty cycle of 700, but I want to reduce the cycle to 600. When I update the register T0_MR2, the current timer value (T0_TC) might be in-between 600 and 700 - and thus the comparison with the match register will not show a hit in this cycle — hence the rising/falling edge for this cycle only occurs during the next cycle, leaving a single very long PWM signal…
I have veryfied this on an oscilloscope - it really does happen!
Is there a trick to avoid that? I know having one extra long pulse doesn’t sound dramatic in motor PWM - but e.g. in servo control it might be a more severe problem! So we should be able to avoid that, shouldn’t we?
Possible fixes:
only change value when T0_TC is at zero (difficult to do for a fast PWM cycle)
only change T0_MR2 in tiny steps (well, doesn’t solve the problem, might still occur, only less likely)
when updating T0_MR2 explicitly check T0_TC against the new setting, and possibly change the PWM-output-pin by hand. How would I do that? The output is configured as PWM pin, so GPIO_SET or GPIO_CLR don’t work (I checked that).
Could you post your code? I’ve only used the LPC2148 for PWM, and it’s quite different from the 2103, but I might be able to help. I’ve got an LPC2103 board here I could try it on. I’d like to try PWM on the 2103, anyway. I’ve got a scope, as well.
You could also try the LPC2000 Yahoo group which I run. I don’t recall anything relevant there, but you are more likely to get some help there (there are over 6,000 subscribers) than on this forum.
I am changing the EMR registers on the fly. The manual is less than clear on what writing to the EMR Registers actually do. As you will be aware you tend to find out what they do the hard way when they come back to bite you !
The problem in my case was that the EMR register can force the state of the match output pins. This makes life tricky as I am trying to use the match outputs independently with a free running timer.
The match outputs are of course hardware controlled. This means that if the match pin changes at the same time you read modify write the EMR register then that change of state is lost when the EMR is written back and all you see on the scope is a glitch. Doh!
We to cut to the chase. The work round I found was to check for imminent changes in the Match Output pins and delay the writing of the EMR register. This bodge works for me. This is because I have quite a bit of time to to get the EMR regitser changed and writing it later has NO effect on the result.
I wonder if you can use a similar trick. If you examine the Free Running counter with some code you can set the PWM register at a time where it will not cause problems.
Thanks for the tips. I have posted the same problem to the Yahoo Group (i completely forgot about that, shame on me… ).
I am perfectly happy to send the source code by mail to interested people, just contact me. However, it’s not super small and not well documented.
fordp: I thought about that (setting the value only when it’s save) - but it might take much CPU time to “monitor” the timer and “wait” for a zero-crossing. So I am still hoping to find a better solution.