Searching \ for 'Accessing text strings.' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/index.htm?key=accessing+text+strings
Search entire site for: 'Accessing text strings.'.

Truncated match.
PICList Thread
'Accessing text strings.'
1998\02\06@150555 by Mike Barrett

flavicon
face
I have a program that I am running on a 16c74, this read data from the A/D
and converts it to ASCII and sends it down the serial port to a PC. This
all works, I've got the A/D and serial stuff all sorted..
What I want to do is to send a text message when the program starts, just a
short message such as
"Mikes logging program Version 1.00"
At the moment I can do this by moving each character into W and then
calling my serial routine which sends it down the serial port  to the PC

MOVLW H'4D'                           ; move code for ASCII M into W
CALL    SERIAL_SEND          ; sends W to serial

and so on for each character..........


I feel there must some way of doing using the DW statement.

dw      "Mike logging program Version 1.00\n"

This puts the text into  memory,  but how do I then access it?
I sure this is one of those things that are really easy when you know
how.....:)

Thanks

Mike Barrett

=============================================
Mike Barrett                E-mail: spam_OUTbarrettTakeThisOuTspamcambridge.scr.slb.com
Schlumberger Cambridge Research      Phone: 01223 325200
High Cross,  Cambridge, CB3 OEL. U.K    Fax: 01223 327019
=============================================

1998\02\06@161743 by Darryl Newberry

flavicon
face
Mike,

You wrote:
>What I want to do is to send a text message when the program starts, just a
>short message such as
>"Mikes logging program Version 1.00"

You need to encode the string into a jump table...

MyString
       addwf   pcl,f
       retw    "My string",0

Then create a routine that retrieves the characters and prints them...

       clrf    CharCount
loop
       movf    CharCount,w
       call    MyString        ; returns char in w
       andlw   255             ; 0?
       btfsc   Z               ; no, skip
       goto    exit            ; yep, quit
       call    PrintW          ; your serial output routine.
       incf    CharCount       ; bump char index
       goto    loop            ; go until you hit 0
exit
       ...

Yes, strings are a pain on the PIC. You could also get fancy and have
predefined constant offsets into a string table, i.e.

StrTable
       retw    "String1",0
       retw    "Long String",0
       retw    "3rd string",0

and then
STR1 equ 0
STR2 equ 8
STR3 equ 21
...etc.

-dn

1998\02\06@183142 by John Payson

picon face
> Yes, strings are a pain on the PIC. You could also get fancy and have
> predefined constant offsets into a string table, i.e.
>
> StrTable
>         retw    "String1",0
>         retw    "Long String",0
>         retw    "3rd string",0

There are some other tricks that can be handy for such things, e.g. if
there were an "addwf PC" at StrTable above, you could use something
like:

DumpStringN:
       movwf   N       ; Procedure to dump Nth string in above table [1=1st]
       clrf    Index
DumpLoop:
       movf    Index,w
       incf    Index,f
       call    StrTable
       iorlw   0       ; Check if W is zero
       btfss   Z
        goto   FindLoop
       decfsz  N
        goto   FindLoop
DumpLoop:
       movf    Index,w
       incf    Index,f
       call    StrTable
       iorlw   0       ; Check if W is zero
       btfsc   Z
        retlw  0
       call    PrintChar
       goto    DumpLoop

A bit of a hack, but I've found similar techniques to be sometimes useful
with the CCS compiler which does not include any really good methods for
doing the above.

BTW, another useful trick when writing code that should be equivalent to
 printf("Answer=%3d Result=%05D", answer, result);
is to code it like this [more or less]; note that if there weren't very
many printfs, it might be better to put more of the work in the "format"
section and less in the library section.  Note that "Format" is designed
to be used as a string in a string-print procedure.

Format:
       db      "Answer="
       movlw   answer
       call    IntPConvert
       goto    BGetHund
       goto    BGetTens
       goto    GetOnes
       db      " Result="
       call    IntPConvert
       goto    GetTenK
       goto    GenThou
       goto    GetHund
       goto    GetTens
       goto    GetOnes
       retlw   0

IntPConvert:
       bsf     blankflag
       movwf   FSR
       movf    IND,w
       movwf   TempL
       incf    IND
       movf    IND,w
       movwf   TempH
       goto    Convert ; My wonderful bin->dec convert routine

BGetThou:
       movf    Thou,w
       goto    GetWBlank
BGetHund:
       movf    Hund,w
       goto    GetWBlank
BGetTens:
       movf    Tens,w
GetWBlank:
       btfss   Z
        bcf    BlankFlag
       btfsc   BlankFlag
        movlw  $F0
       addlw   48
       return
GetTenK:
       movf    TenK,w
       goto    GetDigit
GetThou:
       movf    Thou,w
       goto    GetDigit
GetHund:
       movf    Hund,w
       goto    GetDigit
GetTens:
       movf    Tens,w
       goto    GetDigit
GetOnes:
       movf    Ones,w
GetDigit:
       addlw   48
       return

1998\02\06@200120 by Brian Schousek

picon face
-----Original Message-----
From: John Payson <.....supercatKILLspamspam@spam@MCS.NET>
To: PICLISTspamKILLspamMITVMA.MIT.EDU <.....PICLISTKILLspamspam.....MITVMA.MIT.EDU>
Date: Friday, February 06, 1998 6:31 PM
Subject: Re: Accessing text strings.


{Quote hidden}

Ok... I've been watching this thread for a while and have a very basic
observation: what is the mnemonic retw supposed to imply? I don't recognize
it. In my thinking you would have to use the directive dt to achieve the
jump table John is indicating.

>Format:
>       db      "Answer="
>      movlw   answer
>        call    IntPConvert
>        goto    BGetHund
>        goto    BGetTens
>        goto    GetOnes
>        db      " Result="
>        call    IntPConvert

Also: what purpose does db serve in this instance? (1) In garden variety
PICs there is no way to access program memory directly, so without the retlw
prefix, this db data appears useless. (2) The db and dw directives 'pack'
the data into program memory as if it were a sequence of 8 bit bytes. The
net result in, for example, a 14 bit architecture is that the two high-order
bits of every other byte is discarded. See a code snippet following, along
with the resultant MPASM 2.01 listing.

Brian


+++begin of code snippet

LIST  p=16f84
org 0xff

db   "abc"
dw   "abc"
dt   "abc",0
retlw 0            ;(this line demonstrates that dt 0 does indeed generate
the retlw machine language. look at the listing)
       END
+++end of code snippet

+++begin of MPASM 2.01 output due to code snippet
                   00001
                   00002         LIST  p=16f84
00FF                00003         org 0xff
                   00004
Message[303]: Program word too large.  Truncated to core size. (6162)
Message[303]: Program word too large.  Truncated to core size. (6300)
00FF 2162 2300      00005         db   "abc"      ;this packs data byte
Message[303]: Program word too large.  Truncated to core size. (6162)
Message[303]: Program word too large.  Truncated to core size. (6300)
0101 2162 2300      00006         dw   "abc"
0103 3461 3462 3463 00007         dt   "abc",0
    3400
0107 3400           00008         retlw 0
                   00009         END

1998\02\07@164646 by John Payson

picon face
> Also: what purpose does db serve in this instance? (1) In garden variety
> PICs there is no way to access program memory directly, so without the retlw
> prefix, this db data appears useless. (2) The db and dw directives 'pack'
> the data into program memory as if it were a sequence of 8 bit bytes. The
> net result in, for example, a 14 bit architecture is that the two high-order
> bits of every other byte is discarded. See a code snippet following, along
> with the resultant MPASM 2.01 listing.

All depends upon the assembler; it's been awhile since I've coded strings,
but if memory serves, ASPIC uses "db" as the mnemonic to store data using
"retlw" tables; other assemblers use other things like "dt".  Too bad I
really don't like the MPASM standard, since it means I sometimes confuse
people with ASPIC.  Oh well...

1998\02\07@183200 by Morgan Olsson

picon face
It«s not healthy to be needing to think too much...
Why not let the assembler set the string offsets by itself?
And also check for too long table:

StrTable:
       VARIABLE tablestart = $
       addwf   PCL,F
STR_Hello EQU $-tablestart-1
       dt    "Hello",0
STR_world EQU $-tablestart-1
       dt    "world",0
STR_presentation EQU $-tablestart-1
       dt    "Morgan Olsson 1998",0
       ;
       IF high $ != high tablestart
               ERROR "Probable addwf PCL overflow in table; relocate or divide
in parts"
       ENDIF

/Morgan

{Quote hidden}

/  Morgan Olsson, MORGANS REGLERTEKNIK, SE-277 35 KIVIK, Sweden \
\  EraseMEmrtspam_OUTspamTakeThisOuTiname.com, ph: +46 (0)414 70741; fax +46 (0)414 70331    /

1998\02\09@154834 by Darryl Newberry

flavicon
face
At 19:58 2/6/98 -0500, you wrote:
>Ok... I've been watching this thread for a while and have a very basic
>observation: what is the mnemonic retw supposed to imply? I don't recognize
>it. In my thinking you would have to use the directive dt to achieve the
>jump table John is indicating.

"retw" is a Parallax "instruction", actually a macro, which expands to a
series of retlw instructions with successive bytes from the argument, i.e.

       retw "String"

becomes

       retlw 'S'
       retlw 't'
       retlw 'r'
       retlw 'i'
       retlw 'n'
       retlw 'g'

-dn

1998\02\13@144400 by vmk

flavicon
face
Hi!
6-Feb-98 17:21 John Payson wrote about "Re: Accessing text strings.":

>> > Yes, strings are a pain on the PIC.
   :(


>> BTW, another useful trick when writing code that should be equivalent to
>>   printf("Answer=%3d Result=%05D", answer, result);
>> is to code it like this [more or less]; note that if there weren't very
>> many printfs, it might be better to put more of the work in the "format"
>> section and less in the library section.  Note that "Format" is designed
>> to be used as a string in a string-print procedure.
>>
>> Format:
>>         db      "Answer="
>>         movlw   answer
>>         call    IntPConvert
>>         goto    BGetHund
>>         goto    BGetTens
>>         goto    GetOnes
>>         db      " Result="
       .....
>> IntPConvert:
>>         bsf     blankflag
>>         movwf   FSR
>>         movf    IND,w
>>         movwf   TempL
>>         incf    IND
>>         movf    IND,w
>>         movwf   TempH
>>         goto    Convert ; My wonderful bin->dec convert routine
       .....


   Unfortunatly, one should note that this code can't be used
exactly as a string. The string planned to be read is:
    0123456789     (index in "CALL ReadFormat")
   "Answer=ddd"..  (string to be read; ddd is the decimal value
                   of the two bytes pointed by answer)

Actually, we shell read "Answer=", but then some strange effects
will be produced. (I suppouse that "Convert" makes convertion only).

   If index==7 then instructions "movlw answer" and
"call IntPConvert" will be done. So, the value returned by
conversion rotine "Convert" will be obtained by caller instead
of the first digit of ansver (hundreds).

   If index==8 then only "call IntPConvert" will be done, and W
will cotain value of 8 (if "addwf PCL,f" is used). So, TempL and
TempH will be replaced with the values of SFR's 0x08 and 0x09
"Convert" routine will be called again. The value returned by
"Convert" will be included into the string too.

   The string will be like this:
    0123456789012      (index in CALL ReadFormat)
   "Answer=??ddd"..    (string; '?' is unpredictable chars
                       returned by "Convert")

   To avoid this one should perform additional increment by 2
the value of "index" in routine "Convert" or in code labeled
with "IntPConvert" (it is better, because routine "Convert"
remain unchanged and can be called with no connection with any
strings). But generally, nobody can know what variable was used
as index in "CALL ReadFormat". Thus we have to use the same
variable ("format_index") for every format string.

   Another method is to make some improvements. Every char of
the desired string should be represented by the only command. It
may be something like this:

Format:
       db      "Answer="

;        movlw   answer
;        call    IntPConvert
;        goto    BGetHund
       goto    GetAnswer_And_Hund  ;;  !!!

       goto    BGetTens
       goto    GetOnes
       db      " Result="
   .....

GetAnswer_And_Hund:
       movlw   answer
       call    IntPConvert
       goto    BGetHund

IntPConvert:
       bsf     blankflag
       movwf   FSR
       movf    IND,w
       movwf   TempL
       incf    IND
       movf    IND,w
       movwf   TempH
       goto    Convert ; My wonderful bin->dec convert routine
   .....

   Now if index==7 then "goto GetAnswer_And_Hund" will be
executed. The desired value vill be transfered into TempL,TempH;
"Convert" will be called and executed but returned value
ignored; then "goto BGetHund" will be executed and the digit of
hundreds of the desired number will be returned as a next char
of the string. The next call (index==8) will cause the
"goto BGetTens" executed and so on.


   I use method like described above for an interfacing to
formatted output library. But I don't build a "string-like" code.
Instead of this I build an "output list". Here is a siplified
example (FMT... are entry points of library routines; index of
current processing element is mantained in the library):

Example:
   goto    FMT_BLANK
   goto    proc_answer_string
   goto    proc_asnwer_value
   goto    FMT_BLANK   ; there are special entries for often used chars
   goto    FMT_COMMA   ;   like " .,;:+-*"
   goto    FMT_ENDLIST ; No comments :)

proc_answer_value:
   movlw   answer
   goto    FMT_03D_I   ; Use "%03d" coversion, "FMT..._I" means
                       ;   indirect addressing
proc_answer_string:
   movlw   high(answer_string)
   movwf   hi_addr
   movlw   low(answer_string)
   goto    FMT_S_ROM

answer_string:  db  "Answer=",0


   This example was mentioned as simplified because this
library has many other entry points. For example it is not
efficient to use FMT_03D_I in this case. There is another entry
(let us refer it as FMT_03D_I_ALT). It produce the same effect
as FMT_03D_I but index of current processing element will be
incremented by 2. So, we can eliminate one GoTo command and one
label. (It's not joke, total number of labels will be too high
and the risk of undetected mistypes will be very high too.) The
example became as follows:

   printf(" Answer=%03d, ", *answer);

Example:
   goto    FMT_BLANK
   goto    proc_answer_string
   movlw   answer
   goto    FMT_03D_I_ALT
   goto    proc_asnwer_value
   goto    FMT_COMMA   ; there are special entries for often used chars
   goto    FMT_BLANK   ;   like " .,;:+-*". It was not necessary to use
                       ;   this possibility here. It's illustration only
   goto    FMT_ENDLIST         ; No comments :)

proc_answer_string:
   movlw   high(answer_string)
   movwf   hi_addr
   movlw   low(answer_string)
   goto    FMT_S_ROM

answer_string:  db  "Answer=",0

   Entry point FMT_S_ROM (and other string rotines) maintain
its own internal index (rather than index of the list elements)
for access to procesing string.



   This library can be used to implement more complicated
printfs. For example:

   printf("Status is \'%s\'", ok==0?"Failed":"OK!");
Actually will be implemented some other printf:
   printf("%s%s%c", "Status is \'", ok==0?"Failed":"OK!",'\'');

Example2:
   goto    proc_status_string
   goto    proc_status_report
   movlw   "'"
   goto    FMT_C_ALT

1998\02\17@022231 by vmk

flavicon
face
Hi!
12-Feb-98 06:23 PICLISTspamspam_OUTMITVMA.MIT.EDU wrote about "Re: Accessing text
strings.":

>> Hi!
>>  6-Feb-98 17:21 John Payson wrote about "Re: Accessing text strings.":
>>
>>  >>
>>  >> Format:
>>  >>         db      "Answer="
>>  >>         movlw   answer
>>  >>         call    IntPConvert
>>  >>         goto    BGetHund
>>  >>         goto    BGetTens
>>  >>         goto    GetOnes
>>  >>         db      " Result="
>>         .....
>>  >> IntPConvert:
>>  >>         bsf     blankflag
>>  >>         movwf   FSR
>>  >>         movf    IND,w
>>  >>         movwf   TempL
>>  >>         incf    IND
                       ^^^^ mistype? "FSR", I think...

>>  >>         movf    IND,w
>>  >>         movwf   TempH
>>  >>         goto    Convert ; My wonderful bin->dec convert routine
>>         .....
   .....


>> Actually, we shall read "Answer=", but then some strange effects
>> will be produced. (I suppouse that "Convert" makes conversion only).
>>
>>     If index==7 then instructions "movlw answer" and
>> "call IntPConvert" will be done. So, the value returned by
>> conversion rotine "Convert" will be obtained by caller instead
>> of the first digit of ansver (hundreds).
>>
>>     If index==8 then only "call IntPConvert" will be done, and W
>> will cotain value of 8 (if "addwf PCL,f" is used). So, TempL and
>> TempH will be replaced with the values of SFR's 0x08 and 0x09
>> "Convert" routine will be called again. The value returned by
>> "Convert" will be included into the string too.


   I'm sorry, my explanation wasn't exact. :( It is necessary
to replace "CALL IntPConvert" with "GOTO IntPConvert" in quoted
program to make this explanation true.

   But the key problem was noted correctly. Instruction follow
"movlw answer"  will be executed twice: when index=7 (OK, we
want to do this) and when index=8 (unexpected). It is illegal,
because no "movlw answer" executed before it; so, routine
"Convert" will get "garbage value" in W. Furthermore, it should
not be executed at all.

--

                                   Vladimir M. Klochko

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