I am currently working on a software PWM. I got it to work fine with
1 pin, and now I'm extending it to 8 pins. I am using a regularly
incremented PWMtimer, and 8 GPRs, called PWMlevel 1 to 8. Inside the
PWMupdate function, I use a loop, and indirect addressing to access
each pwmlevel, and check if it's higher or lower than pwmtimer, to
decide when to turn it off. Therefore, the pwmlevel decides on
average, how high the pin is.
All the loop code works just fine, in checking each pwmlevel, but then
I come to set or clear each bit on portb. I need a way to set or
clear a particular bit, depending on a variable, i.e. if the variable
is 4, I want to set/clear bit 4. I cannot think of a way to access a
bit, specified on the fly. The only method I could think of is to use
the variable as a loop counter, and in each loop, bit shift d'1' to
the left, and then move this to portb. Unfortunately, this would
disturb all the other bits in porta.
Dave Turner wrote:
> Hi again guys,
>
> I am currently working on a software PWM. I got it to work fine with
> 1 pin, and now I'm extending it to 8 pins.
Dave,
Rather than answer your question about how one should set a variable bit
in a register, I'll instead point you to another 8-pin PWM routine:
I did actually see that example earlier, but I decided to make my own,
as I need it to be as quick as possible, because I am also running
some other timing critical functions, like strobing 3 7seg led
displays.
> Dave Turner wrote:
> > Hi again guys,
> >
> > I am currently working on a software PWM. I got it to work fine with
> > 1 pin, and now I'm extending it to 8 pins.
>
> Dave,
>
> Rather than answer your question about how one should set a variable bit
> in a register, I'll instead point you to another 8-pin PWM routine:
>
> www.dattalo.com/technical/software/pic/pwm8.asm
>
> Scott
> I did actually see that example earlier, but I decided to make my own,
> as I need it to be as quick as possible, because I am also running
> some other timing critical functions, like strobing 3 7seg led
> displays.
1 You seriously think you can code your PWM faster than Scott did?
2 You think strobing a 7-seg is time critical?
Wouter van Ooijen
-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu
At 07:48 PM 5/26/2005 +0100, you wrote:
>I did actually see that example earlier, but I decided to make my own,
>as I need it to be as quick as possible, because I am also running
>some other timing critical functions, like strobing 3 7seg led
>displays.
Why don't you unroll the loop and access the bits directly?
(more code memory required, but faster)
Or perhaps you could use a register for the loop counter like this
Well, I'm not sure if it's because we're doing an entirely different
think, but his pwm function is 105 lines. Mine is 26. Here is mine
so far (the part I asked this question about goes after the on and off
instructions, replacing the porta,0:
pwm
incf pwmtimer
movlw 0FFh
movwf _255
movlw 08h
movwf FSR0L
clrf FSR0H
pwmloop1 movf pwmtimer,w
subwf _255,w
addwf INDF0,w
btfss STATUS,C
goto on
goto off
Well, even if it doesn't need to be blazingly fast, if I didn't mind
just using other peoples stuff, so you really think I would be coding
a software pwm for fading lights, when I would buy $20 set of xmas
lights? Not all programmers are just learning to get a job and make
$$$. Some of us just like the fun of coding, and the insane rush when
the code you have been writing continuously for a few hours had no
typos, and run's the first time.
BTW, I have a strange feeling this topic will soon be needing an [OT] tag.
> At 07:48 PM 5/26/2005 +0100, you wrote:
> >I did actually see that example earlier, but I decided to make my own,
> >as I need it to be as quick as possible, because I am also running
> >some other timing critical functions, like strobing 3 7seg led
> >displays.
>
> Why don't you unroll the loop and access the bits directly?
> (more code memory required, but faster)
>
> Or perhaps you could use a register for the loop counter like this
>
>
> for (m=0x01; (m & 0xFF)!=0; m<<=1)
> {
> ...
> }
>
>
> Best regards,
>
> Spehro Pefhany --"it's the network..." "The Journey is the reward"
> .....speffKILLspam.....interlog.com Info for manufacturers: http://www.trexon.com
> Embedded software/hardware/analog Info for designers: http://www.speff.com
> ->> Inexpensive test equipment & parts http://search.ebay.com/_W0QQsassZspeff
>
>
>
Dave Turner wrote:
> Well, I'm not sure if it's because we're doing an entirely different
> think, but his pwm function is 105 lines. Mine is 26. Here is mine
> so far (the part I asked this question about goes after the on and off
> instructions, replacing the porta,0:
His == Scott's PWM routine.
Dave,
You can optimize my routine by deleting all of the comments. That should
get you down to 40 some odd lines. But you're right, I'm afraid my
routine is not as short as your's.
First, no, there isn't an "out-of-the-box" method to
specify dynamicly which bit to bcf/bsf. The bit number
is locked into the instruction at assembly time. There are
code snippets to solve that, which you already
understand, as I read it...
Second, Scotts PWM code (which I saw the first time just
a few minutes ago) must be some of the cleanest, best
written and easy to follow code I've seen in a while.
*I* would probably learn from it, and/or use it as
a "component" and just integrate it with my own code.
It *was* written for the old F84, but I see little that
could be done better in any other PIC16 type.
Maybe on a PIC18, but I didn't thought about that...
Of course it more fun to write your own PWM code,
but you will probably not write it *better* then Scott. :-)
> BTW, I have a strange feeling this topic will soon be needing
> an [OT] tag.
> Hi again guys,
>
> I am currently working on a software PWM. I got it to work fine with
> 1 pin, and now I'm extending it to 8 pins. I am using a regularly
> incremented PWMtimer, and 8 GPRs, called PWMlevel 1 to 8. Inside the
> PWMupdate function, I use a loop, and indirect addressing to access
> each pwmlevel, and check if it's higher or lower than pwmtimer, to
> decide when to turn it off. Therefore, the pwmlevel decides on
> average, how high the pin is.
>
> All the loop code works just fine, in checking each pwmlevel, but then
> I come to set or clear each bit on portb. I need a way to set or
> clear a particular bit, depending on a variable, i.e. if the variable
> is 4, I want to set/clear bit 4. I cannot think of a way to access a
> bit, specified on the fly. The only method I could think of is to use
> the variable as a loop counter, and in each loop, bit shift d'1' to
> the left, and then move this to portb. Unfortunately, this would
> disturb all the other bits in porta.
>
> Thanks in advance.
Something like this? (untested code!)
; Be careful where this goes in the program space -- the addwf must
clear the carry bit...
; Uses one scratch file, named scratch
set_bit macro ; bit is in 'w' 0..7
clrf scratch
bsf scratch,0
addwf PCL,f
rrf scratch,f ; 0100 0000
rrf scratch,f ; 0010 0000
rrf scratch,f ; 0001 0000
rrf scratch,f ; 0000 1000
rrf scratch,f ; 0000 0100
rrf scratch,f ; 0000 0010
rrf scratch,f ; 0000 0001
> On 5/26/05, Dave Turner <@spam@dave.w.turnerKILLspamgmail.com> wrote:
> > Hi again guys,
> >
> > I am currently working on a software PWM. I got it to work fine with
> > 1 pin, and now I'm extending it to 8 pins. I am using a regularly
> > incremented PWMtimer, and 8 GPRs, called PWMlevel 1 to 8. Inside the
> > PWMupdate function, I use a loop, and indirect addressing to access
> > each pwmlevel, and check if it's higher or lower than pwmtimer, to
> > decide when to turn it off. Therefore, the pwmlevel decides on
> > average, how high the pin is.
> >
> > All the loop code works just fine, in checking each pwmlevel, but then
> > I come to set or clear each bit on portb. I need a way to set or
> > clear a particular bit, depending on a variable, i.e. if the variable
> > is 4, I want to set/clear bit 4. I cannot think of a way to access a
> > bit, specified on the fly. The only method I could think of is to use
> > the variable as a loop counter, and in each loop, bit shift d'1' to
> > the left, and then move this to portb. Unfortunately, this would
> > disturb all the other bits in porta.
> >
> > Thanks in advance.
>
> Something like this? (untested code!)
>
> ; Be careful where this goes in the program space -- the addwf must
> clear the carry bit...
> ; Uses one scratch file, named scratch
> set_bit macro ; bit is in 'w' 0..7
> clrf scratch
> bsf scratch,0
> addwf PCL,f
> rrf scratch,f ; 0100 0000
> rrf scratch,f ; 0010 0000
> rrf scratch,f ; 0001 0000
> rrf scratch,f ; 0000 1000
> rrf scratch,f ; 0000 0100
> rrf scratch,f ; 0000 0010
> rrf scratch,f ; 0000 0001
>
> movfw scratch
> iorwf PORTA,f
> endm
>
> set_bit macro ; bit is in 'w' 0..7
> clrf scratch
> bsf scratch,0
> addwf PCL,f
> rrf scratch,f ; 0100 0000
> rrf scratch,f ; 0010 0000
> rrf scratch,f ; 0001 0000
> rrf scratch,f ; 0000 1000
> rrf scratch,f ; 0000 0100
> rrf scratch,f ; 0000 0010
> rrf scratch,f ; 0000 0001
> comf scratch,w
> andwf PORTA,f
> endm
>
> --
> You think that it is a secret, but it never has been one.
> - fortune cookie
>
One thing that I discovered when working with those 4-character
alphanumeric LED displays from HP (used on a high-end telecom product)
was that the slightest variation in refresh timing caused very visible
random brightness variations. All who saw it agreed that it was not
acceptable. This was on an 8051-clone, so I ended up doing a "precision
reload" of the timer so that the only variation in display timing was
the 1 or 2 machine cycles of jitter in the interrupt latency (and zero
cumulative error).
1: Don't output the bits for each PWM one at a time. Instead accumulate
them into a single byte of memory using an rrf or rlf instruction, then just
copy that byte to the output.
This code has the disadvantage that it is not isochronous -- ie: it doesn't
take the same amount of time for each execution. That may or may not be
important in the OP's application.
Dave Turner wrote:
> Ooooh, me likey. Perfect code for the job. Thank you so much. After
> changing the rrf to rrcf, it works great. Thanks again.
Actually Dave, Mark's solution may be useful in some application (none
of which I'm aware however), but it certainly is of marginal value for
an isochronous PWM routine. You probably want Mike Keitz's solution.
Once you combine Mike's code with your's and see that it takes nearly 20
cycles per PWM per count interval, you may desire a routine that's an
order of magnitude faster.
First, RE: the first macro, with very many rrfs, no problem about tha
small screw-ups - managed to fix them in about 10 secs.
Second, now I realize that the expanded loops are the same speed as
loops, I still prefer to use loops - it gives tidyer, cleaner code.
Also, it's very easy to add more pins.
Another thing, I figured in PWM the whole point is to get the timing
accurate, hence why it is important for the on and off code to be
symetrical.
Also, I will try Bob's idea of getting all the bits ready, and then
moving them into the port. This should further help to get even
fading.
Also RE Bob, if the the code not being iosync is a problem, it should
be easy to pad it out with NOPs.
On 5/26/05, Bob Ammerman <RemoveMErammermanTakeThisOuTverizon.net> wrote:
> This code has the disadvantage that it is not isochronous -- ie: it doesn't
> take the same amount of time for each execution. That may or may not be
> important in the OP's application.
>
> Bob Ammerman
> RAm Systems
>
OK, if you've got stack space (untested code)... this version
eliminates the scratch file...
; Be careful where this goes in the program space...
mkbitmask:
addwf PCL,f
retlw b'00000001'
retlw b'00000010'
retlw b'00000100'
retlw b'00001000'
retlw b'00010000'
retlw b'00100000'
retlw b'01000000'
retlw b'10000000'
set_bit macro ; bit is in 'w' 0..7
call mkbitmask
iorwf PORTA,f
endm
clear_bit macro ; bit is in 'w' 0..7
call mkbitmask
xorlw 0xff
andwf PORTA,f
endm
--
You think that it is a secret, but it never has been one.
- fortune cookie
At 02:00 PM 5/26/2005, Dave Turner wrote:
>Well, I'm not sure if it's because we're doing an entirely different
>think, but his pwm function is 105 lines. Mine is 26. Here is mine
>so far (the part I asked this question about goes after the on and off
>instructions, replacing the porta,0:
Actually, if you look at Scott's code, you will find within the comments at
the start of the code the following:
;RAM:
; pwm0-pwm7 - pwm counters
; rising_edge - rising edge counter
; pwm_state - current state of the pwm outputs.
;ROM
; 38 instructions
;Execution time
; 23 cycles
In other words, Scott's routine uses 23 cycles to generate 8 separately
adjustable PWM outputs. That would make it about 5 times faster than your
method.
Nothing wrong with the way you are approaching the problem. Scott's method
is different and faster.
Celebrating 21 years of Engineering Innovation (1984 - 2005)
.-. .-. .-. .-. .-. .-. .-. .-. .-. .-
`-' `-' `-' `-' `-' `-' `-' `-' `-'
Do NOT send unsolicited commercial email to this email address.
This message neither grants consent to receive unsolicited
commercial email nor is intended to solicit commercial email.
> > 2 You think strobing a 7-seg is time critical?
>
> Indeed. You think it is not?
Indeed. There are somne timing-related aspects that might matter, but it
does not matter whether the refreshing is done at 200 Hz or 10 kHz.
> One thing that I discovered when working with those 4-character
> alphanumeric LED displays from HP (used on a high-end telecom product)
> was that the slightest variation in refresh timing caused very visible
> random brightness variations.
Which type of variation? I find it hard to believe that for instance a
small change in the frequency is visible att all.
> All who saw it agreed that it was not
> acceptable. This was on an 8051-clone, so I ended up doing a
> "precision
> reload" of the timer so that the only variation in display timing was
> the 1 or 2 machine cycles of jitter in the interrupt latency (and zero
> cumulative error).
The fact that that solved the probleb does not prove (at least not to
me) that it was necesarry.
Wouter van Ooijen
-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu
>
>Which type of variation? I find it hard to believe that for instance a
>small change in the frequency is visible att all.
Any change affecting the average current through the LED can
cause visual effects such as flickering, pulsing, strobing- especially
if there are beat frequencies between the disruption and the display
scan frequency. It's fairly critical, but at reasonable scan frequencies
10 microseconds probably won't matter. But 100 or 200 will. Depends how fussy
you are too-- if you don't care if the display looks "flakey" so long as its
readable you can go further. I design precise measuring and control
instruments, and I like them to be and to look very solid. If it's a
lamp dimmer or something like that, then a bit of flicker probably doesn't
matter to most customers.
If you must do something that disrupts the display, the eye seems to be
more sensitive to slight increases brightness than slight decreases,
so it's better to blank the display than to allow it to get a bit more
scan time, if you can't keep it even enough by other means.
On 5/27/05, Wouter van Ooijen <RemoveMEwouterTakeThisOuTvoti.nl> wrote:
> > > 2 You think strobing a 7-seg is time critical?
> >
> > Indeed. You think it is not?
>
> Indeed. There are somne timing-related aspects that might matter, but it
> does not matter whether the refreshing is done at 200 Hz or 10 kHz.
Not exactly. Is not time critical indeed (from a software point of
view) but is hardware dependent by the:
1. numbers of digits
2. display quality ( the segment wiewing angle and the segment brightness)
3. segment curent flow
A 10KHz refresh rate may cause a display to be hard wievable in intense light.
But of course you knew all these.
>
> > One thing that I discovered when working with those 4-character
> > alphanumeric LED displays from HP (used on a high-end telecom product)
> > was that the slightest variation in refresh timing caused very visible
> > random brightness variations.
>
> Which type of variation? I find it hard to believe that for instance a
> small change in the frequency is visible att all.
>
> > All who saw it agreed that it was not
> > acceptable. This was on an 8051-clone, so I ended up doing a
> > "precision
> > reload" of the timer so that the only variation in display timing was
> > the 1 or 2 machine cycles of jitter in the interrupt latency (and zero
> > cumulative error).
>
> The fact that that solved the probleb does not prove (at least not to
> me) that it was necesarry.
>
> Wouter van Ooijen
>
> -- -------------------------------------------
> Van Ooijen Technische Informatica: http://www.voti.nl
> consultancy, development, PICmicro products
> docent Hogeschool van Utrecht: http://www.voti.nl/hvu
>
>
>> 2 You think strobing a 7-seg is time critical?
>
>Indeed. You think it is not?
>
>One thing that I discovered when working with those 4-character
>alphanumeric LED displays from HP (used on a high-end telecom
>product) was that the slightest variation in refresh timing
>caused very visible random brightness variations. All who saw it
>agreed that it was not acceptable. This was on an 8051-clone, so
>I ended up doing a "precision reload" of the timer so that the
>only variation in display timing was the 1 or 2 machine cycles of
>jitter in the interrupt latency (and zero cumulative error).
I would believe this. And in the OP case I would wrap the 7 segment routine
around the PWM routine, so that every fall through the PWM produced the next
scan of the 7 segment display.
>Also, I will try Bob's idea of getting all the bits ready,
>and then moving them into the port. This should further
>help to get even fading.
And if you do things this way, the load of the port register can be done in
an interrupt routine, from a background (non-interrupt) prepared value. This
means that the write out is done in a very tightly controlled timescale,
without the PWM calculation affecting that time (provided the calculation is
done in less than an interrupt interval) This has an advantage in that you
now do not need to deal with code symmetry for on and off times.
Wouter van Ooijen <wouterEraseME.....voti.nl> wrote:
> > > 2 You think strobing a 7-seg is time critical?
> >
> > Indeed. You think it is not?
>
> Indeed. There are somne timing-related aspects that might matter, but it
> does not matter whether the refreshing is done at 200 Hz or 10 kHz.
No, the specific refresh rate doesn't matter (much), but the duty cycle
has to be dead on. And the refresh rate must be stable, because any
changes in frequency cause momentary changes in duty cycle as well.
On Fri, 2005-05-27 at 11:26 +0100, Alan B. Pearce wrote:
<quoting someone else...>
>>Also, I will try Bob's idea of getting all the bits ready,
>>and then moving them into the port. This should further
>>help to get even fading.
>
> And if you do things this way, the load of the port register can be done
> in
> an interrupt routine, from a background (non-interrupt) prepared value.
It was probably obvious to many people, but the 23-cycle, 8-PWM software
routine I mentioned earlier has this feature of collecting all 8 states
and writing them at once to the I/O port. In addition, the routine is
really intended to be embedded in a Timer interrupt (otherwise, you'd have
to design the rest of your system to be isochronous - and that's a bitch).
If the 23-cycle routine is part of a timer interrupt routine, it'd
probably make sense to set the interrupt period to something like ~50
cycles. Taking interrupt overhead into account, this leaves a little less
than 50% of the CPU available for other things (like deciding the next PWM
level). A 20MHz clocked PIC would update the PWM counters every 50 cycles
* 0.2uS/cycle = 25 uS. The PWM period is 256 * 25uS ~ 6.4mS which
translates into a PWM frequency of 1/6.4mS = 156Hz. Triggering the LED
refresh at this frequency should be fast enough to remove perceivable
flicker.
> A 20MHz clocked PIC would update the PWM counters every 50 cycles
>* 0.2uS/cycle = 25 uS. The PWM period is 256 * 25uS ~ 6.4mS which
>translates into a PWM frequency of 1/6.4mS = 156Hz. Triggering the LED
>refresh at this frequency should be fast enough to remove perceivable
>flicker.
Scott, 156Hz is nowhere near fast enough in most cases. You have to multiply
the minimum "flicker" rate times the number of digits being sequentially muxed
and apply a healthy "quality appearance" multiplier if you don't want the
display
to "break up" visually when it or the user's head moves a bit. 1000Hz is more
like it (or perhaps 500Hz in this case, since he's got only 3 digits).
This could be still done by the PWM routine, by triggering off of every n'th
update, and making sure that the display routine takes less than the
cycles or so available until you have to return so the next interrupt can
take place on schedule. Probably would have less issues than trying to use
nested interrupts or whatever. There would be a bit more overhead in each
interrupt to decide whether to scan the display this int or not. Of course
there would be more room to play with a 40MHz (or 120MHz) PIC.
> At 06:49 AM 5/27/2005 -0700, you wrote:
>
>
> > A 20MHz clocked PIC would update the PWM counters every 50 cycles
> > * 0.2uS/cycle = 25 uS. The PWM period is 256 * 25uS ~ 6.4mS which
> > translates into a PWM frequency of 1/6.4mS = 156Hz.
> > Triggering the LED
> >> refresh at this frequency should be fast enough to remove perceivable
> >> flicker.
>
> Scott, 156Hz is nowhere near fast enough in most cases. You
> have to multiply
> the minimum "flicker" rate times the number of digits being
> sequentially muxed...
Now wait a minute...
Wasn't this thread about dimming *individual discrete" LEDs ??
I understod that that was what Dave (remember? He who started
the thread...) was talking about.
Not displays made up from e.g. 7-seg displays, which is another
issue imho...
And, with my limited knowledge, 156 Hz seems just fine for
dimming LEDs.
I know this is probably a bad idea, because it isn't always perfect at
timing, but I run my pwm routine inside my delay routine - I padded it
out with nops, to get it to the right length, and because my program
spends nearly all it's time in delays, there is only a few
instructions between the delays, meaning it's almost continuously
updating the pwm.
> At 06:49 AM 5/27/2005 -0700, you wrote:
>
>
> > A 20MHz clocked PIC would update the PWM counters every 50 cycles
> >* 0.2uS/cycle = 25 uS. The PWM period is 256 * 25uS ~ 6.4mS which
> >translates into a PWM frequency of 1/6.4mS = 156Hz. Triggering the LED
> >refresh at this frequency should be fast enough to remove perceivable
> >flicker.
>
> Scott, 156Hz is nowhere near fast enough in most cases. You have to multiply
> the minimum "flicker" rate times the number of digits being sequentially muxed
> and apply a healthy "quality appearance" multiplier if you don't want the
> display
> to "break up" visually when it or the user's head moves a bit. 1000Hz is more
> like it (or perhaps 500Hz in this case, since he's got only 3 digits).
>
> This could be still done by the PWM routine, by triggering off of every n'th
> update, and making sure that the display routine takes less than the
> cycles or so available until you have to return so the next interrupt can
> take place on schedule. Probably would have less issues than trying to use
> nested interrupts or whatever. There would be a bit more overhead in each
> interrupt to decide whether to scan the display this int or not. Of course
> there would be more room to play with a 40MHz (or 120MHz) PIC.
>
> Best regards,
>
> Spehro Pefhany --"it's the network..." "The Journey is the reward"
> RemoveMEspeffspam_OUTKILLspaminterlog.com Info for manufacturers: http://www.trexon.com
> Embedded software/hardware/analog Info for designers: http://www.speff.com
> ->> Inexpensive test equipment & parts http://search.ebay.com/_W0QQsassZspeff
>
>
>Now wait a minute...
>
>Wasn't this thread about dimming *individual discrete" LEDs ??
>I understod that that was what Dave (remember? He who started
>the thread...) was talking about.
He said that he wants 8 channels of PWM, *plus* a display scan.
of 3 7-segment LEDs.
>Not displays made up from e.g. 7-seg displays, which is another
>issue imho...
>
>And, with my limited knowledge, 156 Hz seems just fine for
>dimming LEDs.
Yes, I was talking about the display scan. The PWM routine is fine.
> >Wasn't this thread about dimming *individual discrete" LEDs ??
> >I understod that that was what Dave (remember? He who started
> >the thread...) was talking about.
>
> He said that he wants 8 channels of PWM, *plus* a display scan.
> of 3 7-segment LEDs.
Oh oh, can we rewind the tape about an hour and delete
my last post ?? :-)
> Wouter van Ooijen <EraseMEwouterspamspamBeGonevoti.nl> wrote:
>>>> 2 You think strobing a 7-seg is time critical?
>>>
>>> Indeed. You think it is not?
>>
>> Indeed. There are somne timing-related aspects that might matter, but it
>> does not matter whether the refreshing is done at 200 Hz or 10 kHz.
>
> No, the specific refresh rate doesn't matter (much), but the duty cycle
> has to be dead on. And the refresh rate must be stable, because any
> changes in frequency cause momentary changes in duty cycle as well.
Do you think that the user will be able to see a 3% light output change,
caused by a 3% duty cycle variation ? With 1 usec Tcyc and 200 Hz
refresh 3% will be 3% of 1250 Tcyc, or 37 cycles. That is enough leeway
that most times one need not write isochronous code.
At 05:22 PM 5/27/2005 +0100, you wrote:
>Hey,
>
>I know this is probably a bad idea, because it isn't always perfect at
>timing, but I run my pwm routine inside my delay routine - I padded it
>out with nops, to get it to the right length, and because my program
>spends nearly all it's time in delays, there is only a few
>instructions between the delays, meaning it's almost continuously
>updating the pwm.
I guess if it works well enough for your application, it wasn't such a
bad idea after all.. ;-)
This kind of thing works well if you can make it an "update" sort of thing
rather than PWM, like RC servos- the pulse length is the signal rather than
the average level of the signal. That would be easy to do in a delay
routine as you describe.
On 5/27/05, Jan-Erik Soderholm <jan-erik.soderholmSTOPspamspam_OUTtelia.com> wrote:
> > >Wasn't this thread about dimming *individual discrete" LEDs ??
> > >I understod that that was what Dave (remember? He who started
> > >the thread...) was talking about.
> >
> > He said that he wants 8 channels of PWM, *plus* a display scan.
> > of 3 7-segment LEDs.
>
>
> Oh oh, can we rewind the tape about an hour and delete
> my last post ?? :-)
>
> Jan-Erik
>
Spehro Pefhany wrote:
> At 06:49 AM 5/27/2005 -0700, you wrote:
>
>
>> A 20MHz clocked PIC would update the PWM counters every 50 cycles
>> * 0.2uS/cycle = 25 uS. The PWM period is 256 * 25uS ~ 6.4mS which
>> translates into a PWM frequency of 1/6.4mS = 156Hz. Triggering the LED
>> refresh at this frequency should be fast enough to remove perceivable
>> flicker.
>
>
> Scott, 156Hz is nowhere near fast enough in most cases.
<snip>
Sure. Whatever...
What I find incredulous is that many people are stating very obvious
facts but the original poster is having trouble grokking it. What he
should've of said is, " I saw this routine for PWM'ing 8 I/O pins and
since I'm using the 18F452 I figured out how to save 9-bytes of RAM. For
example, you can replace the DECFSZ with a CPFSEQ in the pwm_update
section and write:
pwm_update:
MOVF rising_edge,W
CLRF temp
CPFSEQ pwm0,F ;If the first pwm has not reached the
BSF temp,0 ;end then don't turn it off.
;
CPFSEQ pwm1,F ;Same for the second one
BSF temp,1 ;
;
CPFSEQ pwm2,F ;
BSF temp,2 ;
;
....
MOVF temp,W
ANDWF PWM_LATCH
RETURN
The 8-bytes for the counters in the old routine are no longer needed.
The 9'th byte saved is 'pwm_state'. Now we can use I/O port's latch."
Boy this post is getting out of hand. Can I please get rid of any
responsibility/liability for starying this post, before it get's so
big it crashes a server/blows up someones computer.
> On 5/27/05, Jan-Erik Soderholm <KILLspamjan-erik.soderholmspamBeGonetelia.com> wrote:
> > > >Wasn't this thread about dimming *individual discrete" LEDs ??
> > > >I understod that that was what Dave (remember? He who started
> > > >the thread...) was talking about.
> > >
> > > He said that he wants 8 channels of PWM, *plus* a display scan.
> > > of 3 7-segment LEDs.
> >
> >
> > Oh oh, can we rewind the tape about an hour and delete
> > my last post ?? :-)
> >
> > Jan-Erik
> >
>
> While we're there, let's delete my code examples and replace them with
> the elegant code at
> www.piclist.com/techref/microchip/math/bit/setbit.htm
>
> Regards,
> Mark
> markrages@gmail
> --
> You think that it is a secret, but it never has been one.
> - fortune cookie
>