since yours is so much faster, I would need to run it almost three times (because the variables can range from 0 to whatever SOMETHING is scaled to).![]()
![]()
Totally Lost me on that one.
<br>
since yours is so much faster, I would need to run it almost three times (because the variables can range from 0 to whatever SOMETHING is scaled to).![]()
![]()
Totally Lost me on that one.
<br>
DT
Okay, let me background this first.
For each of 5 channels: A 0-5V value is read (derived from an op-amp) by an ADC channel (presently at 10 bits, so 0-1023). That value is manipulated depending on other data (an offset or a correction, for example). The complementary value (1023-value), scaled so that 0 (1023-1023) can be managed in x repetitions (the maximum that can be fit into about 7.8ms) of the loop, is how long the delay in the interrupt handler must be before turning on the corresponding output pin to a triac driver. Normally, a 5us pulse would be adequate to keep the triac on until the end of the AC phase, but the indicator for the channel is an LED, so the pin is left high until the end of the phase.
Just sending a pulse on a pin means running the FOR . . . NEXT loop only up to the scaled value and sending the pulse; keeping the indicator on proportionately (well, somewhat) means the pin must stay high until near the end of the phase.
Your code running to 255 and finishing in 2.6ms means that only 36 percent of the 7.8ms period is controlled, because it is so fast. Proportionately, the phase would have to be scaled something like 0-765, probably a little less.
Could I just run additional cycles of the tests before incrementing the INDEX to stretch it out?
The code works as is, but over a very limited signal range.
Last edited by RussMartin; - 8th February 2010 at 05:30.
Russ
N0EVC, xWB6ONT, xWN6ONT
"Easy to use" is easy to say.
I have not tested the idea.
Instead of writing each IF-THEN test to the port, writing to a variable and at the end that variable to the port will be faster?
Ioannis
Hi Russ,
Have you considered using timer derived periodic interrupts and performing just one PWM "step" per interrupt? Perhaps spreading out 256 "steps" across the 8.333-msec period (8333-usecs/256 = 32.55-usec interrupts)?
Here's another method like Darrel's which would work well if you group the outputs consecutively (B7..B3 or B4..B0 for example). Updating the port from a 'shadow' register allows precise bit update timing (multiple bits with same duty cycle value will update at exactly the same time).
Regards, Mike
Code:; ; 1/256th step, 18 cycles (isochronous), active high output ; on duty cycle match until end-of-period ; clrf shadow ; clear 'shadow' |B0 movf led+4,W ; led[4] duty cycle, 0..255 |B0 subwf dcy,W ; C = led[4] >= dcy |B0 rlf shadow,F ; |B0 movf led+3,W ; led[3] duty cycle, 0..255 |B0 subwf dcy,W ; C = led[3] >= dcy |B0 rlf shadow,F ; |B0 movf led+2,W ; led[2] duty cycle, 0..255 |B0 subwf dcy,W ; C = led[2] >= dcy |B0 rlf shadow,F ; |B0 movf led+1,W ; led[1] duty cycle, 0..255 |B0 subwf dcy,W ; C = led[1] >= dcy |B0 rrf shadow,F ; |B0 movf led+0,W ; led[0] duty cycle, 0..255 |B0 subwf dcy,W ; C = led[0] >= dcy |B0 rlf shadow,W ; W = led 'step' output |B0 movwf PORTB ; update LEDs |B0 incf dcy,F ; bump duty cycle counter |B0 ;
Thanks, Ioannis and Mike. Let me noodle with your suggestions for a bit.
Meanwhile, for anyone interested:
For an IF A [comparison] B THEN statement, without the appended action, the execution time at 8MHz if A and B are WORDs appears to be about 22-24us; if A and B are BYTEs, it appears to be about 5-6us. These numbers are not down to a gnat's whisker; they are as measured on my scope (Tektronix 465M).
Russ
N0EVC, xWB6ONT, xWN6ONT
"Easy to use" is easy to say.
Bookmarks