Sub string match.
PICList
Thread
'PIC 16C84 fails to execute decfsz'
1999\01\04@102132
by
Stefan Sczekalla-Waldschmidt
|
Hi,
Yesterday I found a very odd behaviour using a PIC16C84.
While debugging a program which runs fine using MP-Lab simulator,
the same program doesn4t seemed to work within the real PIC.
Well normaly nothing new, but I checked everything twice. So I started
to add some LED4s to get a glue about the portions of software executed.
After fixing some minor bugs, I could see the IRQ flashing a certain
led,
and see the program running through the initialisation, till the
Main-Program.
There it seemed to get somewhow screwed-up. by moving the point where
one of
my LED4s got enlightet, I could break the point of malfunction down.
Code was as below:
wait: movlw 0x30 ;
movwf dwncntr
bsf PORTB, 3 ; set LED to on executed as possible
decfsz dwncntr, F
goto $-1
bsf PORTB, 4 ; set LED to on NEVER EXECUTET !!!!!!!
return
As I found the decfsz op must cause this failure. Fortunately I had some
16F84 on "Stock" so I tryed one of them in opposite to the previousely
used 16C84.
Well - they worked - the above with "NEVER EXECUTED" marked instruction
was executed,
the Led got switched on as expected.
Now I4m wondering if the batch of 16C84 is errenous, my programmer is
unreliable ...
Because I tryed to be aware of setting PCLATH according to the
requirements, I think
I can exclude the possibility of jump into the nirwana, I also checked
the absolute listing.
Any comments, suggestions ??
Best wishes to the new jear, much success with your projects.
Kind regards
Stefan
1999\01\04@110400
by
Morgan Olsson
|
Only thing i can think of right now,
is the watchdog triggering while counting down dwncounter.
And the watchdog have varying time between chip individuals.
Is it enabled? Any other interrupt enabled?
Stable supply? Tested other supply?
Other voltages maybe work if slightly bad chip or not fully programmed.
Oh, is the PORTB correctly set up?
Can you light the led using another routine?
{Quote hidden}>Code was as below:
>
>wait: movlw 0x30 ;
> movwf dwncntr
>
> bsf PORTB, 3 ; set LED to on executed as possible
>
> decfsz dwncntr, F
> goto $-1
>
> bsf PORTB, 4 ; set LED to on NEVER EXECUTET !!!!!!!
> return
>
>As I found the decfsz op must cause this failure. Fortunately I had some
>16F84 on "Stock" so I tryed one of them in opposite to the previousely
>used 16C84.
>Well - they worked - the above with "NEVER EXECUTED" marked instruction
>was executed,
>the Led got switched on as expected.
>
>Now I4m wondering if the batch of 16C84 is errenous, my programmer is
>unreliable ...
Have you tried several C84?
(probably slightly varying watchdog timeout)
Isolate test, no goto, something like this: (no dealy loop, just test decfsz)
wait: movlw 2
movwf dwncntr
decfsz dwncntr, F
bsf PORTB, 3 ;Shall light (dwncntr not reaching zero)
bsf PORTB, 4 ;Will light unless in nirvana mode...
decfsz dwncntr, F
bsf PORTB, 5 ;Shall not light (dwncntr reaching zero)
bsf PORTB, 6 ;Will light unless in nirvana mode...
>Because I tryed to be aware of setting PCLATH according to the
>requirements, I think
>I can exclude the possibility of jump into the nirwana, I also checked
>the absolute listing.
Er.. Do 16C84 need setting the PCLATH before GOTO?
>
>Any comments, suggestions ??
>
>Best wishes to the new jear, much success with your projects.
>
>Kind regards
>
> Stefan
>
>
Morgan Olsson ph +46(0)414 70741
MORGANS REGLERTEKNIK fax +46(0)414 70331
H€LLEKS (in A-Z letters: "HALLEKAS")
SE-277 35 KIVIK, SWEDEN spam_OUTmrtTakeThisOuT
iname.com
___________________________________________________________
1999\01\04@113241
by
Stefan Sczekalla-Waldschmidt
|
Hi Morgan
Morgan Olsson wrote:
>
> Only thing i can think of right now,
> is the watchdog triggering while counting down dwncounter.
> And the watchdog have varying time between chip individuals.
> Is it enabled?
for sure, I had the watchdog disabled.
> Any other interrupt enabled?
Yes but it worked es expected, given a periodical output I4ve seen on my
scope.
timing also as expected.
> Stable supply?
Hope so, commercial 19" Power-Supply with 5V and 12V output.
> Tested other supply?
No
> Other voltages maybe work if slightly bad chip or not fully programmed.
Tomething I could try again, just to verify the failure ...
Hm... the programmer did the verify correct, but I think it didn4t test
at more then
one voltage.
>
> Oh, is the PORTB correctly set up?
> Can you light the led using another routine?
yes, also using a 16F84 from a different batch than the 16C84 gives no
errors.
> Have you tried several C84?
Yes, all the same batch - all behaves odd.
> (probably slightly varying watchdog timeout)
>
no watchdog used as stated above.
{Quote hidden}> Isolate test, no goto, something like this: (no dealy loop, just test decfsz)
> wait: movlw 2
> movwf dwncntr
>
> decfsz dwncntr, F
> bsf PORTB, 3 ;Shall light (dwncntr not reaching zero)
> bsf PORTB, 4 ;Will light unless in nirvana mode...
>
> decfsz dwncntr, F
> bsf PORTB, 5 ;Shall not light (dwncntr reaching zero)
> bsf PORTB, 6 ;Will light unless in nirvana mode...
When having some more time I will test the erroneous assumed chips again
with
the different supply-voltages and the code above.
>
> >Because I tryed to be aware of setting PCLATH according to the
> >requirements, I think
> >I can exclude the possibility of jump into the nirwana, I also checked
> >the absolute listing.
>
> Er.. Do 16C84 need setting the PCLATH before GOTO?
normaly no, because the address range of goto is sufficient for the
16X84. But just
to be sure.
Kind regards
Stefan
1999\01\04@123421
by
Dmitry Kiryashov
Hello Stefan.
decfsz command do work nicely in PIC16F84. I've no trouble with
this cmd. Try to seek reason in other place - for instance F84
& C84 have a different fuses data, also check the WDT disabling.
Make sure that all vars located in correct RAM places, something
else...
WBR Dmitry.
{Quote hidden}> Code was as below:
>
> wait: movlw 0x30 ;
> movwf dwncntr
>
> bsf PORTB, 3 ; set LED to on executed as possible
>
> decfsz dwncntr, F
> goto $-1
>
> bsf PORTB, 4 ; set LED to on NEVER EXECUTET !!!!!!!
> return
1999\01\05@111431
by
Peter L. Peres
> decfsz dwncntr, F
> goto $-1
imho, get rid of the '$-1' and use a label, as in:
dec_dwnctr:
decfsz dwnctr, F
goto dec_dwnctr
I assume that you have checked all the other things, such as the Watchdog
etc.
$0.02
Peter
1999\01\05@133557
by
Mark Willis
|
Um, I don't *ever* use those "goto $-1" type jumps, so I may be wrong
here, but: Am I remembering correctly that a goto $-1 will decrement
the instruction counter (which has already been incremented) so this
will loop in place? Or am I hallucinating here? (Could be thinking of
a different processor; THAT is why I always use labels, having used
Z80's, 80x86's, 8008's, Pics, and a few MOT parts, you get really tired
of shooting your feet to swiss cheese by this sort of thing, as well as
having to go re-code all the relative jumps each time the code's desired
behavior changes!)
Probably sticking my foot in my mouth, so I'll go wash my foot now,
need some chocolate soap here! <G> But, I thought I'd ask (This sort of
thing is exactly why I use labels not relative jumps & let the assembler
(or translator) handle the translations for me <G>
Need to get recovered from having crashed the PicStart Plus machine to
toast so I can get back to running code here <G>
Mark, .....mwillisKILLspam
@spam@nwlink.com
Peter L. Peres wrote:
{Quote hidden}>
> > decfsz dwncntr, F
> > goto $-1
>
> imho, get rid of the '$-1' and use a label, as in:
>
> dec_dwnctr:
> decfsz dwnctr, F
> goto dec_dwnctr
>
> I assume that you have checked all the other things, such as the Watchdog
> etc.
>
> $0.02
>
> Peter
1999\01\05@152237
by
Adam Bryant
|
Mark,
I do use relative jumps in many situations. With the PIC you can think of
the "$" being evaluated BEFORE the instruction counter is incremented. So
$-1 means "jump back to the previous instruction", $ means "jump to this
instruction" (an endless loop), and $+1 means "jump to the next
instruction" (I use this one all the time in timing loops as it is a 1
instruction method to get a 2 cycle delay). I use relative instructions in
macros and in loops where I don't want to clutter up the code with an extra
label. But I do limit the use of relative jumps to places where I am
jumping a short distance (usually < 10 instructions).
You are right, you do need to be careful if you change the code to insure
that the relative jump is still correct. But using them for small jumps in
non-changing segments of code is pretty safe.
Adam
mwillis
KILLspamNWLINK.COM on 01/05/99 11:36:04 AM
Please respond to .....PICLISTKILLspam
.....MITVMA.MIT.EDU
To: EraseMEPICLISTspam_OUT
TakeThisOuTMITVMA.MIT.EDU
cc: (bcc: Adam Bryant/PEAK/MOORE)
Subject: Re: PIC 16C84 fails to execute decfsz
Um, I don't *ever* use those "goto $-1" type jumps, so I may be wrong
here, but: Am I remembering correctly that a goto $-1 will decrement
the instruction counter (which has already been incremented) so this
will loop in place? Or am I hallucinating here? (Could be thinking of
a different processor; THAT is why I always use labels, having used
Z80's, 80x86's, 8008's, Pics, and a few MOT parts, you get really tired
of shooting your feet to swiss cheese by this sort of thing, as well as
having to go re-code all the relative jumps each time the code's desired
behavior changes!)
Probably sticking my foot in my mouth, so I'll go wash my foot now,
need some chocolate soap here! <G> But, I thought I'd ask (This sort of
thing is exactly why I use labels not relative jumps & let the assembler
(or translator) handle the translations for me <G>
Need to get recovered from having crashed the PicStart Plus machine to
toast so I can get back to running code here <G>
Mark, mwillis
spam_OUTnwlink.com
Peter L. Peres wrote:
{Quote hidden}>
> > decfsz dwncntr, F
> > goto $-1
>
> imho, get rid of the '$-1' and use a label, as in:
>
> dec_dwnctr:
> decfsz dwnctr, F
> goto dec_dwnctr
>
> I assume that you have checked all the other things, such as the Watchdog
> etc.
>
> $0.02
>
> Peter
1999\01\06@041110
by
Stefan Sczekalla-Waldschmidt
Hi Peter,
"Peter L. Peres" wrote:
>
> > decfsz dwncntr, F
> > goto $-1
>
> imho, get rid of the '$-1' and use a label, as in:
>
> dec_dwnctr:
> decfsz dwnctr, F
> goto dec_dwnctr
Tried this too - without success ...
>
> I assume that you have checked all the other things, such as the Watchdog
> etc.
Yes. btw - same code with different batch of 16X84 runs definitely.
>
> $0.02
>
> Peter
While I didnt tested I think it may have to do something with a odd
sensibility
to the supplied voltage.
1999\01\06@043414
by
Stefan Sczekalla-Waldschmidt
|
Hi,
Mark Willis wrote:
>
> Um, I don't *ever* use those "goto $-1" type jumps, so I may be wrong
> here, but: Am I remembering correctly that a goto $-1 will decrement
> the instruction counter (which has already been incremented) so this
> will loop in place?
Also Peter mentioned this - I thought - and think - the reference is the
current PC -
well because of not trusting the assembler I took a look into th
absolute listing.
The Addres in the Adresspart of the GOTO was correctely pointing to the
address
before - the address of the decfsz.
> Or am I hallucinating here? (Could be thinking of
> a different processor; THAT is why I always use labels, having used
> Z80's, 80x86's, 8008's, Pics, and a few MOT parts, you get really tired
> of shooting your feet to swiss cheese by this sort of thing, as well as
> having to go re-code all the relative jumps each time the code's desired
> behavior changes!)
Well your somewhat right, I use this kind "$-+X" only for very short
jumps in
compare-like sequences or loops like the used one. A "benefit" of this
kind of
notation is, that it gives a clearer reference ( kind of tight binding )
to it4s
( in this case close ) context.
> Probably sticking my foot in my mouth, so I'll go wash my foot now,
> need some chocolate soap here! <G>
nice saying :-) would like to be so flexible :-)
> But, I thought I'd ask (This sort of
> thing is exactly why I use labels not relative jumps & let the assembler
> (or translator) handle the translations for me <G>
>
> Need to get recovered from having crashed the PicStart Plus machine to
> toast so I can get back to running code here <G>
You "toasted" your Picstart-Plus ??? Well - Here we sometimes say "ein
Programm in ein Eprom brennen" (burning a program into a EPROM) but I
never thought about "toasing" a programm into a chip <G>
Kind regards
Stefan
@spam@sswKILLspam
oikossw.de
1999\01\06@043747
by
Stefan Sczekalla-Waldschmidt
|
Adam Bryant wrote:
>
> Mark,
> I do use relative jumps in many situations. With the PIC you can think of
> the "$" being evaluated BEFORE the instruction counter is incremented. So
> $-1 means "jump back to the previous instruction", $ means "jump to this
> instruction" (an endless loop), and $+1 means "jump to the next
> instruction" (I use this one all the time in timing loops as it is a 1
> instruction method to get a 2 cycle delay).
> I use relative instructions in
> macros and in loops where I don't want to clutter up the code with an extra
> label. (#)
> But I do limit the use of relative jumps to places where I am
> jumping a short distance (usually < 10 instructions).
>
> You are right, you do need to be careful if you change the code to insure
> that the relative jump is still correct. But using them for small jumps in
> non-changing segments of code is pretty safe.
Yes, thats the way I use it.
(#): another benefit I forgot to mention - I think it was my original
idea for
using this notation.
Kind regards
Stefan
1999\01\06@053317
by
Mark Willis
Stefan Sczekalla-Waldschmidt wrote:
>
> Hi,
>
> Mark Willis wrote:
> > <Snipped down>
>
> You "toasted" your Picstart-Plus ??? Well - Here we sometimes say "ein
> Programm in ein Eprom brennen" (burning a program into a EPROM) but I
> never thought about "toasing" a programm into a chip <G>
>
> Kind regards
>
> Stefan
> KILLspamsswKILLspam
oikossw.de
Nope, the machine had a HDD formatting problem (My mistake, for once)
and I need to completely re-install Windows & MPLab & all as the drive's
blank now (It was easier to just re-start from scratch.) Gotta be
careful when using some tools as the wrong keystrokes will happily nuke
a drives' contents, inconveniencing us a LOT! What I get for trying to
do Tech work at 4 AM, when I have time but no brainpower left <G>
Mark, RemoveMEmwillisTakeThisOuT
nwlink.com
1999\01\06@053727
by
Morgan Olsson
|
At 13:16 1999-01-05 -0700, you wrote:
>Mark,
>I do use relative jumps in many situations. With the PIC you can think of
>the "$" being evaluated BEFORE the instruction counter is incremented. So
>$-1 means "jump back to the previous instruction", $ means "jump to this
>instruction" (an endless loop), and $+1 means "jump to the next
>instruction" (I use this one all the time in timing loops as it is a 1
>instruction method to get a 2 cycle delay). I use relative instructions in
>macros and in loops where I don't want to clutter up the code with an extra
>label. But I do limit the use of relative jumps to places where I am
>jumping a short distance (usually < 10 instructions).
>
>You are right, you do need to be careful if you change the code to insure
>that the relative jump is still correct. But using them for small jumps in
>non-changing segments of code is pretty safe.
>
>Adam
>
Nonono!
** There is no relative jump instructions _in_the_PIC_ **
The compiler converts them to absolute,
(and OBS: in that code page), however you express the adress.
Using relative _notation_ makes the code clearer for short jumps, and
minimizes the number of labels. Not using labels can however make
debugging slightly more difficult.
/Morgan
Morgan Olsson ph +46(0)414 70741
MORGANS REGLERTEKNIK fax +46(0)414 70331
H€LLEKS (in A-Z letters: "HALLEKAS")
SE-277 35 KIVIK, SWEDEN spamBeGonemrtspamBeGone
iname.com
___________________________________________________________
1999\01\06@073857
by
paulb
|
Stefan Sczekalla-Waldschmidt wrote:
> Yes. btw - same code with different batch of 16X84 runs definitely.
Hey, look, let«s face it, he has tried exactly the same code and
*everything else* on at least two production batches of 16C84s and on
16F84s. *One* production batch is faulty. From what I read, it would
be nothing like the first time this happened.
But that«s the end of the story, faulty batch; don«t use them, at
least with this program. For a program they execute alright, use them
and get them out the door! ;-)
So you want to know *why* they are faulty? Well, my hypothesis is that
there is a multiplexer in the pipleine which must respond appropriately
in one fashion to the "bit test and skip" instruction, and in another
to the "goto". Both these affect the Program Counter in some way or
another, so it seems plausible that the juxtaposition of the
instructions stresses a critical timing issue in this multiplexer and in
these chips - it just doesn«t make it.
Another way of looking at it, the "Skip if" instruction has to "turn
off" the following instruction, probably by purging or halting the
pipeline. The "Goto" does something similar as it also takes two
cycles. Maybe the gates for these instructions are interconnected by
accident in this mask set.
--
Cheers,
Paul B.
1999\01\06@121846
by
Peter L. Peres
|
Hello Stefan,
On Wed, 6 Jan 1999, Stefan Sczekalla-Waldschmidt wrote:
> The Addres in the Adresspart of the GOTO was correctely pointing to the
> address before - the address of the decfsz.
imho, to be sure, look at the offset of the goto instruction in the .LST
file and extract that byte from the object file, and compare to the binary
instruction code in the Mchip catalog. If the code is correct (should jump
to that location -1) then there is something funny going on in your chip,
else it is the compiler.
If you get paranoid about this, read the code back from a programmed chip,
and get the byte from there for examination.
> You "toasted" your Picstart-Plus ??? Well - Here we sometimes say "ein
> Programm in ein Eprom brennen" (burning a program into a EPROM) but I
> never thought about "toasing" a programm into a chip <G>
Toasting a machine is a little bit worse than burning an EPROM afaik. It
means that it needs to be replaced ;) The whole of it ;) Steart with the
OS Mark ;) ;)
good luck,
Peter
'[PIC]: Does DECFSZ...?'
2001\04\28@212910
by
Jose S. Samonte Jr.
Hello everybody!
In the Easy PIC'n book, it is written that decfsz takes 1 clock cycle, and 2
clock cycle if result is 0.
But in another book I have borrowed and read, it say that it only takes one
clock cycle, eventhough the result is 0.
Please help...
____________________________________________________________________
Get free email and a permanent address at http://www.netaddress.com/?N=1
--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics
2001\04\28@214614
by
Drew Vassallo
|
>In the Easy PIC'n book, it is written that decfsz takes 1 clock cycle, and
>2
>clock cycle if result is 0.
>But in another book I have borrowed and read, it say that it only takes one
>clock cycle, eventhough the result is 0.
If you look in the MPLAB user's manual (or any datasheet that has an
Instruction Set Summary page), you can see that it clearly describes it as
requiring 1 cycle if nonzero and 2 cycles if zero. If it is nonzero, it
really still takes 2 cycles to get to the same point in your code, except
that it executes the next line instead of skipping it. When it "skips on
zero", it really executes a "nop" instruction before it continues on. For
example:
decfsz FILE; 1 instruction cycle
bsf FLAG, 1 ; executed normally if F != 0, or a NOP if F=0
movlw 0xFF ; this is instruction cycle 3, regardless of whether or not F=0
You can't "save" instruction cycles if it's zero or nonzero in going through
your code. In the example above, it will always take 2 cycles to get from
"decfsz" to "movlw". It doesn't matter if F=0 or F!=0.
--Andrew
_________________________________________________________________
Get your FREE download of MSN Explorer at http://explorer.msn.com
--
http://www.piclist.com hint: The list server can filter out subtopics
(like ads or off topics) for you. See http://www.piclist.com/#topics
2001\04\29@012850
by
Dmitry Kiryashov
|
As a practical observation is showing the
real difference is in two examples:
;
decfsz some_reg
non_goto_command_here
;
will take 1(decfsz)+1(non_goto_command executed or skipped) clocks
to get through for any given value of some_reg
and
;
decfsz some_reg
goto_somewhere ;very particular case of it is call_somewhere ;)
;
will take 1(decfsz)+1(skipped) to get through with skipping
goto and 1(decfsz+2(goto) to get somewhere (in case of call
it can take much longer ;)
WBR Dmitry.
Drew Vassallo wrote:
{Quote hidden}>
> >In the Easy PIC'n book, it is written that decfsz takes 1 clock cycle, and
> >2
> >clock cycle if result is 0.
> >But in another book I have borrowed and read, it say that it only takes one
> >clock cycle, eventhough the result is 0.
>
> If you look in the MPLAB user's manual (or any datasheet that has an
> Instruction Set Summary page), you can see that it clearly describes it as
> requiring 1 cycle if nonzero and 2 cycles if zero. If it is nonzero, it
> really still takes 2 cycles to get to the same point in your code, except
> that it executes the next line instead of skipping it. When it "skips on
> zero", it really executes a "nop" instruction before it continues on. For
> example:
>
> decfsz FILE; 1 instruction cycle
> bsf FLAG, 1 ; executed normally if F != 0, or a NOP if F=0
> movlw 0xFF ; this is instruction cycle 3, regardless of whether or not F=0
>
> You can't "save" instruction cycles if it's zero or nonzero in going through
> your code. In the example above, it will always take 2 cycles to get from
> "decfsz" to "movlw". It doesn't matter if F=0 or F!=0.
>
> --Andrew
> _________________________________________________________________
> Get your FREE download of MSN Explorer at
http://explorer.msn.com
>
> --
>
http://www.piclist.com hint: The list server can filter out subtopics
> (like ads or off topics) for you. See
http://www.piclist.com/#topics
--
http://www.piclist.com hint: The PICList is archived three different
ways. See http://www.piclist.com/#archives for details.
2001\04\29@084725
by
Bob Ammerman
Any instruction which can skip takes one cycle when it doesn't skip and two
when it does.
This is because of the way mchip implemented these skip instructions.
PICs use a pipelined scheme to process instructions: as each instruction is
being executed, the next instruction in the program is being fetched.
All a PIC does in the case of a skip is ignore the fetched instruction and
substitute a nop instead.
So, instead of thinking of skipping instructions as taking two cycles when
they skip, you can think of the skip taking one cycle and the following
forced nop taking the second cycle.
Bob Ammerman
RAm Systems
(contract development of high performance, high function, low-level
software)
{Original Message removed}
2001\04\29@090722
by
Olin Lathrop
>>
In the Easy PIC'n book, it is written that decfsz takes 1 clock cycle, and 2
clock cycle if result is 0.
But in another book I have borrowed and read, it say that it only takes one
clock cycle, eventhough the result is 0.
<<
The only book that really matters is the Microchip data sheet. Go to the
chapter "Instruction Set Summary" and look up the DECFSZ instruction.
********************************************************************
Olin Lathrop, embedded systems consultant in Littleton Massachusetts
(978) 742-9014, TakeThisOuTolinEraseME
spam_OUTembedinc.com, http://www.embedinc.com
--
http://www.piclist.com hint: The PICList is archived three different
ways. See http://www.piclist.com/#archives for details.
2001\04\29@095106
by
Jose S. Samonte Jr.
Thank you sir Bob! =)
That made it so much clearer!
Kindest regards...
Bob Ammerman <RemoveMERAMMERMAN
TakeThisOuTPRODIGY.NET> wrote:
Any instruction which can skip takes one cycle when it doesn't skip and two
when it does.
This is because of the way mchip implemented these skip instructions.
PICs use a pipelined scheme to process instructions: as each instruction is
being executed, the next instruction in the program is being fetched.
All a PIC does in the case of a skip is ignore the fetched instruction and
substitute a nop instead.
So, instead of thinking of skipping instructions as taking two cycles when
they skip, you can think of the skip taking one cycle and the following
forced nop taking the second cycle.
Bob Ammerman
RAm Systems
(contract development of high performance, high function, low-level
software)
{Original Message removed}
'[PIC:] Cascading decfsz'
2003\10\17@122840
by
Harold Hallikainen
|
Hello Listmembers!
decfsz is a real nice instruction for loop counting. For example,
movlw NumLoops
movwf LoopCounter
Loop
[do something]
decfsz LoopCounter,f
goto Loop
return
This works GREAT for NumLoops<256 (though you can set NumLoops to 0 and get 256 loops). But, how can you initialize the loop counter if it's more than a single byte (more than 256 loops)? Here are a few problems I've found...
Let NumLoops=256
movlw high(NumLoops)
movwf LoopCounterHi ; puts 1 in LoopCounterHi
movlw low(NumLoops)
movwf LoopCounterLo ; puts 0 in LoopCounterLo
Loop
[something useful]
decfsz LoopCounterLo,f ; Drops LoopCounterLo to 0xff
goto Loop ; keep looping til we hit 0
decfsz LoopCounterHi,f ; After 256 loops, drops to 0
goto Loop ; keep looping til we hit 0
return ; exit
The above code DOES properly loop 256 times. Now, let's try another...
Let NumLoops=257
movlw high(NumLoops)
movwf LoopCounterHi ; puts 1 in LoopCounterHi
movlw low(NumLoops)
movwf LoopCounterLo ; puts 1 in LoopCounterLo
Loop
[something useful]
decfsz LoopCounterLo,f ; Drops LoopCounterLo to 0
goto Loop ; skipped on first pass
decfsz LoopCounterHi,f ; drops to 0
goto Loop ; skipped on first pass
return ; exit
So, even though we wanted 257 loops, we got 1!
The problem seems to be in setting the high byte of the loop counter. It SEEMS that if the low byte is zero, you can just use high() and low() to initialize the counter. But, if the low byte is non-zero, it SEEMS that we need to increment the high byte after initialization to get it to loop right.
Of course, we could do stuff with subtracting from the loop counter (or adding -1), dealing with carries, then checking for an overall value of zero across the multiple bytes of the loop counter, but that's far more complex than cascaded decfsz instructions. The only problem with cascaded decfsz appears to be in the initialization of the counter.
Comments????
Thanks!
Harold
FCC Rules Online at http://www.hallikainen.com
________________________________________________________________
The best thing to hit the internet in years - Juno SpeedBand!
Surf the web up to FIVE TIMES FASTER!
Only $14.95/ month - visit http://www.juno.com to sign up today!
--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email listservEraseME
.....mitvma.mit.edu with SET PICList DIGEST in the body
2003\10\17@135531
by
Peter Donahue
|
Your code will result in:
low(NumLoops) + (high(NumLoops)-1)*256 loops
The problem is that a value of 0x00 will result in an equivalent value of 256 i.e. Let NumLoops=255 will result in not 255 loops, but 255+256*256 loops since high(NumLoops) will be 0.
incrementing the value of high(NumLoops) is a step in the right direction.
Hope this helps,
Pete
Harold Hallikainen wrote:
{Quote hidden}> Hello Listmembers!
>
> decfsz is a real nice instruction for loop counting. For example,
>
> movlw NumLoops
> movwf LoopCounter
> Loop
> [do something]
> decfsz LoopCounter,f
> goto Loop
> return
>
> This works GREAT for NumLoops<256 (though you can set NumLoops to 0 and get 256 loops). But, how can you initialize the loop counter if it's more than a single byte (more than 256 loops)? Here are a few problems I've found...
>
> Let NumLoops=256
>
> movlw high(NumLoops)
> movwf LoopCounterHi ; puts 1 in LoopCounterHi
> movlw low(NumLoops)
> movwf LoopCounterLo ; puts 0 in LoopCounterLo
> Loop
> [something useful]
> decfsz LoopCounterLo,f ; Drops LoopCounterLo to 0xff
> goto Loop ; keep looping til we hit 0
> decfsz LoopCounterHi,f ; After 256 loops, drops to 0
> goto Loop ; keep looping til we hit 0
> return ; exit
>
> The above code DOES properly loop 256 times. Now, let's try another...
>
> Let NumLoops=257
>
> movlw high(NumLoops)
> movwf LoopCounterHi ; puts 1 in LoopCounterHi
> movlw low(NumLoops)
> movwf LoopCounterLo ; puts 1 in LoopCounterLo
> Loop
> [something useful]
> decfsz LoopCounterLo,f ; Drops LoopCounterLo to 0
> goto Loop ; skipped on first pass
> decfsz LoopCounterHi,f ; drops to 0
> goto Loop ; skipped on first pass
> return ; exit
>
> So, even though we wanted 257 loops, we got 1!
>
> The problem seems to be in setting the high byte of the loop counter. It SEEMS that if the low byte is zero, you can just use high() and low() to initialize the counter. But, if the low byte is non-zero, it SEEMS that we need to increment the high byte after initialization to get it to loop right.
>
> Of course, we could do stuff with subtracting from the loop counter (or adding -1), dealing with carries, then checking for an overall value of zero across the multiple bytes of the loop counter, but that's far more complex than cascaded decfsz instructions. The only problem with cascaded decfsz appears to be in the initialization of the counter.
>
> Comments????
>
> Thanks!
>
> Harold
>
> FCC Rules Online at
http://www.hallikainen.com
>
> ________________________________________________________________
> The best thing to hit the internet in years - Juno SpeedBand!
> Surf the web up to FIVE TIMES FASTER!
> Only $14.95/ month - visit
http://www.juno.com to sign up today!
>
> --
>
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
> email
EraseMElistserv
mitvma.mit.edu with SET PICList DIGEST in the body
--
____________________________________________
Peter Donahue
AMTS (Code Monkey)
COM DEV International, R&D
P (519) 622-2300 x2439
F (519) 622-8706
--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email RemoveMElistservEraseME
EraseMEmitvma.mit.edu with SET PICList DIGEST in the body
2003\10\17@145314
by
Ken Pergola
Hi Harold,
How about something like this?:
(Not the fastest and does not use DECFSZ, but can easily be expanded for
multi-byte variables)
LOOP_ITERATIONS EQU .257 ; # of loop iterations
; *** LoopIteration = LOOP_ITERATIONS
MOVLW high LOOP_ITERATIONS
MOVWF LoopIteration_MSB
MOVLW low LOOP_INTERATIONS
MOVWF LoopIteration_LSB
; ***
Loop
; { Your favorite loop action code goes here }
; *** Decrement composite loop iteration variable by 1
; ( LoopIteration = LoopIteration - 1 )
DECF LoopIteration_LSB, F
BTFSS STATUS, C
DECF LoopIteration_MSB, F
; ***
; *** Does LoopIteration = 0 ?
MOVF LoopIteration_LSB, W
IORWF LoopIteration_MSB, W
BTFSS STATUS, Z
GOTO Loop ; No, keep looping
; ***
; If code flows here, we are "out of the loop"
Regards,
Ken Pergola
--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email RemoveMElistservspam_OUT
KILLspammitvma.mit.edu with SET PICList DIGEST in the body
2003\10\17@161801
by
Bob Ammerman
Use INCFSZ with the twos-complement of the desired loop count:
Let NumLoops=<whatever>
movlw high(-NumLoops)
movwf LoopCounterHi
movlw low(-NumLoops)
movwf LoopCounterLo
Loop
[something useful]
incfsz LoopCounterLo,f
goto Loop ; keep looping til we hit 0
incfsz LoopCounterHi,f
goto Loop ; keep looping til we hit 0
return ; exit
Bob Ammerman
RAm Systems
--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email RemoveMElistservTakeThisOuT
spammitvma.mit.edu with SET PICList DIGEST in the body
2003\10\17@162421
by
John N. Power
|
{Quote hidden}> From: Harold Hallikainen[SMTP:
EraseMEharoldhallikainenspam
spamBeGoneJUNO.COM]
> Sent: Friday, October 17, 2003 12:01 PM
> To:
RemoveMEPICLISTKILLspam
MITVMA.MIT.EDU
> Subject: [PIC:] Cascading decfsz
> Let NumLoops=257
> movlw high(NumLoops)
> movwf LoopCounterHi ; puts 1 in LoopCounterHi
> movlw low(NumLoops)
> movwf LoopCounterLo ; puts 1 in LoopCounterLo
> Loop
> [something useful]
> decfsz LoopCounterLo,f ; Drops LoopCounterLo to 0
> goto Loop ; skipped on first pass
> decfsz LoopCounterHi,f ; drops to 0
> goto Loop ; skipped on first pass
> return ; exit
> So, even though we wanted 257 loops, we got 1!
This is exactly what you asked for. The number 257 has
hex representation 0x0101. Your are loading 01 into the lower
loop counter, and 01 into the higher one. Nested loops
execute the number of times which is the product of the two
loop counts: 01 x 01 = 01.
You must factor the desired count into two factors which
multiply to what you want. Since 257 is prime, this isn't
going to happen.
John Power
--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email listservSTOPspam
spam_OUTmitvma.mit.edu with SET PICList DIGEST in the body
2003\10\17@174522
by
Scott Dattalo
|
On Fri, 17 Oct 2003, Ken Pergola wrote:
{Quote hidden}> Hi Harold,
>
> How about something like this?:
>
> (Not the fastest and does not use DECFSZ, but can easily be expanded for
> multi-byte variables)
>
>
>
>
> LOOP_ITERATIONS EQU .257 ; # of loop iterations
>
> ; *** LoopIteration = LOOP_ITERATIONS
> MOVLW high LOOP_ITERATIONS
> MOVWF LoopIteration_MSB
>
> MOVLW low LOOP_INTERATIONS
> MOVWF LoopIteration_LSB
> ; ***
>
>
> Loop
>
> ; { Your favorite loop action code goes here }
>
>
> ; *** Decrement composite loop iteration variable by 1
> ; ( LoopIteration = LoopIteration - 1 )
> DECF LoopIteration_LSB, F
> BTFSS STATUS, C
> DECF LoopIteration_MSB, F
CAUTION: this only works on the 18F series (the midrange pics DECF
instruction does not disturb C).
Of course, a better approach is this:
beginning_of_loop:
; stuff
decf LoopIteration_LSB,F
skpnz
decfsz LoopIteration_MSB,F
goto beginning_of_loop
Or even better for the 18f series:
dcfsnz LoopIteration_LSB,F
decfsz LoopIteration_MSB,F
goto beginning_of_loop
Scott
--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email spamBeGonelistservSTOPspam
EraseMEmitvma.mit.edu with SET PICList DIGEST in the body
2003\10\17@174936
by
Brendan Moran
>This is exactly what you asked for. The number 257 has
>hex representation 0x0101. Your are loading 01 into the lower
>loop counter, and 01 into the higher one. Nested loops
>execute the number of times which is the product of the two
>loop counts: 01 x 01 = 01.
So, if I put 0x0102, it should loop two times, right? Wrong! It will
still loop once because of the bug in the outer loop.
--Brendan
--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email KILLspamlistservspamBeGone
mitvma.mit.edu with SET PICList DIGEST in the body
2003\10\17@190236
by
Ken Pergola
Scott Dattalo wrote:
> CAUTION: this only works on the 18F series
> (the midrange pics DECF instruction does not disturb C).
Hi Scott,
Yes, you are definitely right -- thanks for pointing that out.
You've just drove home the point on why peer code reviews work so well!
Sorry everyone for creating confusion -- I should have stated that the code
was targeted for a PIC18F PICmicro.
Regards,
Ken Pergola
--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email EraseMElistserv
EraseMEmitvma.mit.edu with SET PICList DIGEST in the body
2003\10\17@191505
by
Phillip Vogel
And, in the spirit of the recent discussion of the efficiency of C vs.
hand assembly:
for (n = 0; n < 257; n++)
{
(your stuff here)
}
Note that in most c compilers, n could be a multi-byte variable,
allowing for some rather large values of n. Also, to spill into the
16F877 a/d probrlem thread, I have NEVER experienced a bank switching
issue with a high level language (yet).
Phillip
Phillip Vogel
Bartal Design Group, Inc.
318 Marlboro Road Englewood, NJ 07631-1416
Phone: 201-567-1343 Fax: 201-568-2891
Cell: 201-232-5208
@spam@phillip@spam@
spam_OUTbartal.com http://www.VisualConductor.com
Ask me about the Visual Conductor
--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email spamBeGonelistserv
KILLspammitvma.mit.edu with SET PICList DIGEST in the body
2003\10\17@194032
by
Ken Pergola
Scott Dattalo wrote:
> Or even better for the 18f series:
> dcfsnz LoopIteration_LSB,F
> decfsz LoopIteration_MSB,F
> goto beginning_of_loop
Hi Scott,
This code does not work (for the intended purpose) -- it will not iterate
the expected number of times.
Regards,
Ken Pergola
--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email .....listservspam_OUT
mitvma.mit.edu with SET PICList DIGEST in the body
2003\10\17@194241
by
piclist
On Fri, 17 Oct 2003, Phillip Vogel wrote:
> And, in the spirit of the recent discussion of the efficiency of C vs.
> hand assembly:
>
> for (n = 0; n < 257; n++)
> {
> (your stuff here)
> }
Hi-Tech, for example, will generate more efficient code with a
decrementing loop, since it can use decfsz:
n = 10;
do {
stuff;
} while (--n);
> Note that in most c compilers, n could be a multi-byte variable,
Anything for which that is not true is not a C compiler.
--
John W. Temples, III
--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email TakeThisOuTlistserv.....
TakeThisOuTmitvma.mit.edu with SET PICList DIGEST in the body
2003\10\17@200808
by
Ken Pergola
Scott Dattalo wrote:
> Of course, a better approach is this:
> beginning_of_loop:
> ; stuff
> decf LoopIteration_LSB,F
> skpnz
> decfsz LoopIteration_MSB,F
> goto beginning_of_loop
Hi Scott,
This code does not work either (for the intended purpose) -- again, it will
not iterate
the expected number of times.
Regards,
Ken Pergola
--
http://www.piclist.com#nomail Going offline? Don't AutoReply us!
email TakeThisOuTlistservKILLspam
spammitvma.mit.edu with SET PICList DIGEST in the body
2003\10\18@140238
by
Scott Dattalo
|
On Fri, 17 Oct 2003, Ken Pergola wrote:
> Scott Dattalo wrote:
>
> > Or even better for the 18f series:
>
> > dcfsnz LoopIteration_LSB,F
> > decfsz LoopIteration_MSB,F
> > goto beginning_of_loop
>
> Hi Scott,
>
> This code does not work (for the intended purpose) -- it will not iterate
> the expected number of times.
Really? This test code works just fine:
Main:
LOOPS EQU 25
MOVLW LOW(LOOPS)
MOVWF XL
MOVLW HIGH(LOOPS + 0x00FF) ; Adjust the high byte.
MOVWF XH ; If the low one is nonzero
CLRF CH ; A 16-bit counter
CLRF CL
L2:
INFSNZ CL,F ;count the times through.
INCF CH,F
dcfsnz XL,F ;decrement the 16-bit loop counter.
decfsz XH,F
bra L2
; Check to make sure we looped the right number of times.
MOVLW LOW(LOOPS)
CPFSEQ CL
bra Err
MOVLW HIGH(LOOPS)
CPFSEQ CH
bra Err
bra Main
Err:
bra Main
The constant has been adjusted by incrementing the high byte only if the
low one is non-zero. The only case where it fails is when the value of
LOOPS is zero. However, since this is a constant, one could do this:
if LOOPS == 0
bra AroundLoop
endif
Or even better:
if LOOPS
; place the looping code here.
endif
If the loop count is not derived from a constant, then you could do this
MOVF XL,W
IORWF XH,W
BZ AroundLoop ; don't loop if the loop counter is
; zero
TSTFSZ XL ; Adjust the high byte
INCF XH,F ; only if the low one is nonzero
Scott
--
http://www.piclist.com hint: To leave the PICList
.....piclist-unsubscribe-request
RemoveMEmitvma.mit.edu
2003\10\18@171305
by
Ken Pergola
|
Scott Dattalo wrote:
> Really? This test code works just fine:
Hi Scott,
Yes, it works *now* because you just made the '+ 0x00FF' fix to it (i.e.,
MOVLW HIGH(LOOPS + 0x00FF) ), but I think you are failing to see my point
about your *original* code that did not work as posted.
My point is: how was anyone supposed to know that the addition of the '+
0x00FF' part should have been added to the original code when it wasn't
included in your original response?
I just wanted to raise this issue since the original code could get readers
who try to use it into trouble (just as the code I posted could get readers
into trouble if they don't use it with PIC18 PICmicros). I appreciate you
reminding us about one of the nuances between PIC18 and non-PIC18 assembly
instructions (DECF) -- it has been brought up before. These nuances are easy
to forget, but they can get you into trouble.
Thanks and take care Scott,
Ken Pergola
--
http://www.piclist.com hint: To leave the PICList
RemoveMEpiclist-unsubscribe-request
spamBeGonemitvma.mit.edu
2003\10\18@225412
by
Bob Ammerman
> Scott Dattalo wrote:
>
> > Or even better for the 18f series:
>
> > dcfsnz LoopIteration_LSB,F
> > decfsz LoopIteration_MSB,F
> > goto beginning_of_loop
>
> Hi Scott,
>
> This code does not work (for the intended purpose) -- it will not iterate
> the expected number of times.
>
> Regards,
> Ken Pergola
>
This reversed version will work with a two's complemented count:
infsnz LoopIteration_LSB,F
incfsz LoopIteration_MSB,F
goto beginning_of_loop
Bob Ammerman
RAm Systems
--
http://www.piclist.com hint: To leave the PICList
spamBeGonepiclist-unsubscribe-request@spam@
spam_OUTmitvma.mit.edu
2003\10\19@165533
by
John N. Power
|
> From: Brendan Moran[SMTP:TakeThisOuTannirackspam
SHAW.CA]
> Sent: Friday, October 17, 2003 5:49 PM
> To: PICLISTEraseME
MITVMA.MIT.EDU
> Subject: Re: [PIC:] Cascading decfsz
>>This is exactly what you asked for. The number 257 has
>>hex representation 0x0101. Your are loading 01 into the lower
>>loop counter, and 01 into the higher one. Nested loops
>>execute the number of times which is the product of the two
>>loop counts: 01 x 01 = 01.
> So, if I put 0x0102, it should loop two times, right? Wrong! It will
> still loop once because of the bug in the outer loop.
> --Brendan
No it won't. Here is the original code:
{Quote hidden}>> movlw high(NumLoops)
>> movwf LoopCounterHi ; puts 1 in LoopCounterHi
>> movlw low(NumLoops)
>> movwf LoopCounterLo ; puts 1 in LoopCounterLo
>> Loop
>> [something useful]
>> decfsz LoopCounterLo,f ; Drops LoopCounterLo to 0
>> goto Loop ; skipped on first pass
>> decfsz LoopCounterHi,f ; drops to 0
>> goto Loop ; skipped on first pass
>> return ; exit
>> So, even though we wanted 257 loops, we got 1!
Let NumLoops = 0x0102
Then LoopCounterHi = 01, LoopCounterLo = 02.
Starting from Loop:
Do something useful.
decrement LoopCounterLo, with result 01
Ii's not zero, so go back to Loop
do something useful for the second time
decrement LoopCounterLo again
now its zero
decrement LoopCounterHi, with result 00
return
"Something useful" was done twice.
John Power
--
http://www.piclist.com hint: PICList Posts must start with ONE topic:
[PIC]:,[SX]:,[AVR]: ->uP ONLY! [EE]:,[OT]: ->Other [BUY]:,[AD]: ->Ads
'[PIC] Baseline: decfsz on FSR'
2008\02\16@120504
by
Tamas Rudnai
Hi All,
I could not get any information on this:
I have a 10F200, and when decreasing FSR with decfsz, it could not identify
that it reached the 0, az the bits <7-5> is always 1...
Same with decf, Z would not go high.
When I use incfsz, it seems that it works perfectly - I suppose because
before the instruction the value was 0xFF, and does not matter that it turns
to 0xE0 instead of 0x00. Is that how it should work, can I count on it, or
just forget and do some other way to check the end of the buffer?
Thanks,
Tamas
2008\02\16@122148
by
Dario Greggio
Tamas Rudnai wrote:
> I have a 10F200, and when decreasing FSR with decfsz, it could not identify
> that it reached the 0, az the bits <7-5> is always 1...
> Same with decf, Z would not go high.
>
> When I use incfsz, it seems that it works perfectly - I suppose because
> before the instruction the value was 0xFF, and does not matter that it turns
> to 0xE0 instead of 0x00. Is that how it should work, can I count on it, or
> just forget and do some other way to check the end of the buffer?
Am not sure in your case, but I often used some other code for that
check about FSR. If the upper bits are unimplemented, then I'd not trust
them.
--
Ciao, Dario
2008\02\16@152607
by
Dwayne Reid
At 10:04 AM 2/16/2008, Tamas Rudnai wrote:
>Hi All,
>
>I could not get any information on this:
>
>I have a 10F200, and when decreasing FSR with decfsz, it could not identify
>that it reached the 0, az the bits <7-5> is always 1...
>Same with decf, Z would not go high.
This is expected behavior. As you mention, bits 7..5 always read as
"1". Datasheet DS41239A page 23.
>When I use incfsz, it seems that it works perfectly - I suppose because
>before the instruction the value was 0xFF . . .
Also expected behavior, for exactly the reason you mention.
dwayne
--
Dwayne Reid <RemoveMEdwaynerEraseME
spam_OUTplanet.eon.net>
Trinity Electronics Systems Ltd Edmonton, AB, CANADA
(780) 489-3199 voice (780) 487-6397 fax
http://www.trinity-electronics.com
Custom Electronics Design and Manufacturing
2008\02\16@183933
by
Tamas Rudnai
Thanks Dwayne and Dario,
Finally I choose the safest option instead of the incfsz "correct"
behaviour, so looking at the top most bit to change and works great.
Thanks again
Tamas
On Feb 16, 2008 8:26 PM, Dwayne Reid <@spam@dwaynerRemoveME
EraseMEplanet.eon.net> wrote:
{Quote hidden}> At 10:04 AM 2/16/2008, Tamas Rudnai wrote:
> >Hi All,
> >
> >I could not get any information on this:
> >
> >I have a 10F200, and when decreasing FSR with decfsz, it could not
> identify
> >that it reached the 0, az the bits <7-5> is always 1...
> >Same with decf, Z would not go high.
>
> This is expected behavior. As you mention, bits 7..5 always read as
> "1". Datasheet DS41239A page 23.
>
>
> >When I use incfsz, it seems that it works perfectly - I suppose because
> >before the instruction the value was 0xFF . . .
>
> Also expected behavior, for exactly the reason you mention.
>
> dwayne
>
> --
> Dwayne Reid <
EraseMEdwayner
@spam@planet.eon.net>
> Trinity Electronics Systems Ltd Edmonton, AB, CANADA
> (780) 489-3199 voice (780) 487-6397 fax
>
http://www.trinity-electronics.com
> Custom Electronics Design and Manufacturing
>
> -
More... (looser matching)
- Last day of these posts
- In 2008
, 2009 only
- Today
- New search...