Searching \ for 'first time programming questions' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: techref.massmind.org/techref/microchip/devprogs.htm?key=programming
Search entire site for: 'first time programming questions'.

Truncated match.
PICList Thread
'first time programming questions'
1995\08\16@155311 by Mike Keitz

flavicon
face
>First, I am using PSIM v 2.42 , PASM v2.3, and DS30015I data sheet for the
>PIC16c56.
>  I just wrote some code to do a BCD to binary coversion (the hard way, a 10X
>loop of ADDWF) and I had to redo some of the code and I don't really have a
>good grasp of why.

John Payson and I have been looking at the BCD conversion problem.  He had
some really good ideas that I haven't fully explored yet.  Here's my
routine, which is probably a little faster, though by no means optimal:

cvBCD
;  Converts a binary number (known to be less than 100) to packed BCD.
;  Process:  Trial-subtractions of 80, 40, 20, and 10 are done.  If the
;    number is greater than these, the corresponding bit in the high BCD
;    digit is set.  The remainder forms the low BCD digit.
;  Input: Binary number in W.
;  Output: Packed BCD number in bcd0
;  RAM: tmp, tmp+1, bcd0 (stores result)
cvBCD
       movwf   tmp             ;Store number being converted.
       clrf    bcd0            ;Clear result.
       movlw   .80             ; 80 decimal is 01010000.
       movwf   tmp+1
cvBCDl
       movfw   tmp+1           ;Get base (80, 40, 20, or 10)
       subwf   tmp,0           ;form number - current base.
       skpnc                   ;If less, don't restore.
       movwf   tmp             ;It was more.  Store adjusted value.
       rlf     bcd0,1          ;Rotate result into bcd0 (brings 0 out C)
       rrf     tmp+1,1         ;Reduce base number by half.
       btfss   tmp+1,0         ;Is base number 5 yet?
       goto    cvBCDl          ;No, do another bit in MS digit.
; Now we have the low 4 bits of BCD0 being the high digit, and the low 4
; bits of tmp being the low digit (known to be less than 10).
       swapf   bcd0,1          ;Put high digit in place.
       movfw   tmp             ;Get the low digit.
       iorwf   bcd0,1          ;OR in the low digit.

This is untested as well, and is also about an order of magnitude below what
John sent me privately (I will await his permission before posting).  But
it's something to think about.  The really fast way (6 instruction cycles)
is of course a table of 100 entries.  Not unfeasible if you don't need the
space for anything else.


>
>This piece of code always resulted in a skip, even if carry was set
>          BTFSC STATUS,C
>  but this worked
>          BTFSC STATUS,0       I thought C was a predefined equate?

With MPALC (the only one I'm familar with), you need an include file with
the standard names of all the special-purpose stuff.  (It is possible that
STATUS is not a predefined equate either)  However, MPALC includes the
pre-defined psuedo-instructions SKPC (skip if C set), and SKPNC (skip if C
not set), which assemble to BTFSS 3,0 etc.  Look at your .LST file and
decode what was actually assembled.
>
>
>  in a single call jump/return
>          RETLW TEMP         W didn't contain the variable TEMP, I had to
>                            do a MOVF TEMP,W after the return.

This is a flawed concept.  It is not possible to return a variable in W with
the 16C5x series, other than with multiple RETLWs.  The RETLW loads a
constant from ROM (what you ended up with in your case was always the
*address* of TMP in W).  Since this is the only way to return on the 5x, any
value left in W by the subroutine will be lost.  One work-around if you have
only a few possible values to return is to end your subroutine with a table:

; return 0, 1, or 2 in W.  Will crash if W>2.  Must execute from first half of
;   a program page.
       addwf   PC,1      ;Skip to apropriate location in table
       retlw   0
       retlw   1
       retlw   2
The ADDWF will affect C, DC, and Z though.  In most cases keeping the result
in RAM and loading it after return is the best way to do it.


>
>  This statement didn't move the value TEMP to W
>          MOVF TEMP        but this did
>          MOVF TEMP,W      If the destination register is not given, I thought
>                           it would put the contents in W.

The default in MPALC is F.  I always specify it explicitly either way to
avoid confusion.  MPALC also has the psuedo-instruction MOVFW which makes it
clearer what is going on.

>
>  Same thing with ADDWF, This didn't put the result into W
>         ADDWF TEMP              but this did
>         ADDWF TEMP,0     could I have typed in ADDWF TEMP,W?

Same problem, same solution.  The default is F.  Generally I use 0 and 1
rather than W and F but I think most assemblers would be smart enough to
handle either.
The binary opcodes in the instruction table will help you figure out exactly
what your assembler is doing by examining the resultant opcode in the .LST file.

-Mike

More... (looser matching)
- Last day of these posts
- In 1995 , 1996 only
- Today
- New search...