Truncated match.
PICList
Thread
'Accessing text strings.'
1998\02\06@150555
by
Mike Barrett
|
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_OUTbarrettTakeThisOuT
cambridge.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
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
|
> 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
|
-----Original Message-----
From: John Payson <.....supercatKILLspam
@spam@MCS.NET>
To: PICLIST
KILLspamMITVMA.MIT.EDU <.....PICLISTKILLspam
.....MITVMA.MIT.EDU>
Date: Friday, February 06, 1998 6:31 PM
Subject: Re: Accessing text strings.
{Quote hidden}>> 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:
>
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
> 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
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}>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
/ Morgan Olsson, MORGANS REGLERTEKNIK, SE-277 35 KIVIK, Sweden \
\ EraseMEmrtspam_OUT
TakeThisOuTiname.com, ph: +46 (0)414 70741; fax +46 (0)414 70331 /
1998\02\09@154834
by
Darryl Newberry
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
|
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
|
Hi!
12-Feb-98 06:23 PICLIST
spam_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...