Exact match. Not showing close matches.
PICList
Thread
'[PIC] String retrieval macro'
2008\06\19@232210
by
Jinx
Does anyone have such a thing for the 18F ? I've got a bunch
of retlw messages for an LCD, of the type
addwf pcl
dt "message1"
in lower memory, 0x100 - 0x580, and some cross boundaries,
which means updating PCLATH. Normally I don't have such a
large number of messages, and would arrange it so that page
straddling is avoided
Options for me are
1) re-write them as tables. Not so bad but that seems defeatist
2) possibly re-invent the wheel by writing my own macro
Ideally I'd want a macro that's self-modifying, perhaps using
something like
get message1
which would find PCLATH (ie high(message1)) then correct
PCLATH if ADDWF PCL goes over a boundary
Any offerings or thoughts ?
2008\06\20@041428
by
Picbits Sales
I just use table reads on the 18F series - you can get two bytes of data in
the same space as a RETLW instruction and using the TABLTRU/H/L registers
makes it nice and easy to read long strings.
I don't think I'd go back to the RETLW method after setting up my routines
for the table reads.
Dom
{Original Message removed}
2008\06\20@043606
by
Jinx
> I just use table reads on the 18F series - you can get two bytes
> of data in the same space as a RETLW instruction and using the
> TABLTRU/H/L registers makes it nice and easy to read long
> strings
I think you're probably right. Had a quick play around and all
that messing with PCL isn't really worth it. Plus, as you say, a
table is much more efficient space-wise. It's what I do on other
18F projects with 100+ character AT strings
It would be nice though to have a generic macro that could call a
target RETLW routine by name, test/adjust PCL and pass W back
to the CALL routine. Maybe another day .....
2008\06\20@053959
by
Tamas Rudnai
Also it's good that you have auto incremental table pointers, so you can
save time and programming difficulty with table read operations.
Tamas
On Fri, Jun 20, 2008 at 9:35 AM, Jinx <spam_OUTjoecolquittTakeThisOuT
clear.net.nz> wrote:
{Quote hidden}> > I just use table reads on the 18F series - you can get two bytes
> > of data in the same space as a RETLW instruction and using the
> > TABLTRU/H/L registers makes it nice and easy to read long
> > strings
>
> I think you're probably right. Had a quick play around and all
> that messing with PCL isn't really worth it. Plus, as you say, a
> table is much more efficient space-wise. It's what I do on other
> 18F projects with 100+ character AT strings
>
> It would be nice though to have a generic macro that could call a
> target RETLW routine by name, test/adjust PCL and pass W back
> to the CALL routine. Maybe another day .....
>
> -
2008\06\20@054745
by
Jinx
> I just use table reads on the 18F series
Wrote a table macro, keeps the listing a bit tidier. Seems to be
OK so far
display macro var ;load TBLPTR with string address
clrf tblptru
movlw high(var)
movwf tblptrh
movlw low(var)
movwf tblptrl
tblrd*+
call get_txt
endm
Use as eg display calib
;retrieve characters from memory
get_txt movfw tablat ;get characters until
btfsc wreg,7 ;W > 0x7f (ie FF terminator)
return
dispw ;"print W to LCD" macro
tblrd*+
bra get_txt
;data strings padded to even number of characters with FF terminator
compress data "Compress",0xffff
serial data "Serial port",0xffff
calib data "Calibrate",0xff
;macro - display contents of W on LCD via write_d entry point
dispw macro
call write_d
endm
2008\06\20@065712
by
Tamas Rudnai
I hope you would not mind if I share a modification of your macro set. I'd
use 0 termination for strings so it would be compatible with C if at any
stage you would need to mix C with your existing code base. Also it makes
things easier with the end-of-string checking, see below:
display macro var ;load TBLPTR with string address
movlw upper(var) ; I wouldn't save on this 1 instruction
movwf tblptru
movlw high(var)
movwf tblptrh
movlw low(var)
movwf tblptrl
call get_txt
endm
Use as eg display calib
;retrieve characters from memory
get_loop
dispw ;"print W to LCD" macro
get_txt ; i'd put the function entry here,
; so can save a tblrd*+ in the macro
tblrd*+
movf tablat,w ; we have to read the data to W anyway
bnz get_loop ; ...so easier to check end-of-string
return
;data strings padded to even number of characters with FF terminator
; i'd use db instead as the trailing zero occupy 1 space in that way
; (see the program memory view to see what happens with different data
definitions)
compress db "Compress",0
serial db "Serial port",0
calib db "Calibrate",0
;macro - display contents of W on LCD via write_d entry point
dispw macro
call write_d
endm
Tamas
On Fri, Jun 20, 2008 at 10:47 AM, Jinx <.....joecolquittKILLspam
@spam@clear.net.nz> wrote:
{Quote hidden}> > I just use table reads on the 18F series
>
> Wrote a table macro, keeps the listing a bit tidier. Seems to be
> OK so far
>
> display macro var ;load TBLPTR with string address
> clrf tblptru
> movlw high(var)
> movwf tblptrh
> movlw low(var)
> movwf tblptrl
> tblrd*+
> call get_txt
> endm
>
> Use as eg display calib
>
> ;retrieve characters from memory
>
> get_txt movfw tablat ;get characters until
> btfsc wreg,7 ;W > 0x7f (ie FF terminator)
> return
> dispw ;"print W to LCD" macro
> tblrd*+
> bra get_txt
>
> ;data strings padded to even number of characters with FF terminator
>
> compress data "Compress",0xffff
> serial data "Serial port",0xffff
> calib data "Calibrate",0xff
>
> ;macro - display contents of W on LCD via write_d entry point
>
> dispw macro
> call write_d
> endm
>
> -
2008\06\20@071016
by
olin piclist
Jinx wrote:
> Does anyone have such a thing for the 18F ? I've got a bunch
> of retlw messages for an LCD, of the type
>
> addwf pcl
> dt "message1"
There is no need for RETLW style tables on a PIC 18 since they can all read
program memory and it is nicely byte addressable. Change the DT to DB and
remember to put it in a CODE_PACK section instead of a CODE section.
Accessing a byte in the string is easy. You load TBLPTR with the address of
the byte and execute one of the table read instructions. If the same
routine is geting successive string bytes, you can use TBLRD+, which
automatically post increments the table read address. After a table read,
the byte value is in TABLAT.
> in lower memory, 0x100 - 0x580, and some cross boundaries,
> which means updating PCLATH. Normally I don't have such a
> large number of messages, and would arrange it so that page
> straddling is avoided
With the table read method, there are no special considerations about
whether the table straddles a 256 byte boundary or not.
> 1) re-write them as tables. Not so bad but that seems defeatist
Why? That's the right way to do it on a PIC 18. The weird thing is that
you ever used RETLW tables for this in the first place. If the source needs
to be compatible with a PIC 16, then you can create a string definition
macro that does the appropriate thing depending on what machine you are on.
> 2) possibly re-invent the wheel by writing my own macro
This can't be more than a few lines of code.
> Ideally I'd want a macro that's self-modifying, perhaps using
> something like
>
> get message1
>
> which would find PCLATH (ie high(message1)) then correct
> PCLATH if ADDWF PCL goes over a boundary
I'm not sure what the GET macro is exactly supposed to do. You can't really
"get" a whole string on a PIC. You probably want one macro to set up for
reading a string, then a subroutine to call to get each byte. All this
together should be 1/2 page of code, so I'm not sure what you're really
asking about.
********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014. Gold level PIC consultants since 2000.
2008\06\20@072654
by
olin piclist
Jinx wrote:
> display macro var ;load TBLPTR with string address
> clrf tblptru
Bad idea. Some day you'll be on a PIC 18 with more than 64Kb and this will
break. If you're going to make a general purpose macro, spend the extra
instruction and load TBLPTRU right.
If you want to get fancy, you can use assembly time conditionals to either
clear TBLPTRU or load it, depending on whether the current PIC has a large
or small program memory. My PIC development environment defines the
constant PROGADRB just for this purpose. It is the number of bytes required
to hold a full program memory address. If it's 2 or less, just clear
TBLPTRU. If it's 3, set it properly.
> ;data strings padded to even number of characters ...
Why? There is no harm in having a table start on a odd address. I don't
understand the problem you are trying to solve here.
********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014. Gold level PIC consultants since 2000.
2008\06\20@075422
by
Jinx
> I hope you would not mind if I share a modification of your
> macro set
No, that's great, thanks. For this particular application I'm using
all 8 redefined characters, so can't have 0 as the terminator, as
it will be a character in some strings. But otherwise your mods
are good and I'd use your version when I could
2008\06\20@075422
by
Jinx
> > display macro var ;load TBLPTR with string address
> > clrf tblptru
>
> Bad idea
Yes, it was
> > ;data strings padded to even number of characters ...
>
> Why? There is no harm in having a table start on a odd address. I
> don't understand the problem you are trying to solve here.
Hmmm, I thought there was a problem. For simulation, W was being
sent to RAM pointed at by FSR0. Odd addresses weren't working,
and, as you say, they should, but padding to an even address seemed
to be a fix. However, MPLAB has been doing a couple of odd things
today (right-click stops working, and builds of good code fail). A re-
boot appears to have made it come right. Also Tamas chipped in with
the db suggestion before I got to having another look at that padding
issue
2008\06\20@083438
by
Harold Hallikainen
Here's some stuff I wrote about 5 years ago.
MsgToLcd macro msg
; Set up table pointers and send a messag to LCD
movlw upper(msg)
movwf tblptru
movlw high(msg)
movwf tblptrh
movlw low(msg)
movwf tblptrl
call LcdMsg
endm
LcdMsg
; Put up a message pointed to by tblprt (u:h:l)
tblrd *+ ; Read the table character to tablat, then increment tblptr
movfw tablat ; Get the character from the table
addlw 0 ; Test w (above may not set condition codes correctly)
skpnz
return ; if we just got a zero byte, exit
call LcdPutChar ; Go put it on the LCD
goto LcdMsg ; Go do next
LcdSignOnMsg
call LcdClear
call LcdCursorOff
msgToLcd(signOnMessageL1)
call LcdRow2
msgToLcd(SignOnMessageL2)
return
SignOnMessageL1
db " IQ512",0 ; Line 1 - Message with terminator
SignOnMessageL2
db "dovesystems.com",0 ;
Harold
--
FCC Rules Updated Daily at http://www.hallikainen.com - Advertising
opportunities available!
2008\06\20@083720
by
olin piclist
Jinx wrote:
>> Why? There is no harm in having a table start on a odd address. I
>> don't understand the problem you are trying to solve here.
>
> Hmmm, I thought there was a problem.
There shouldn't be. The PIC 18 program memory is byte addressable, and
TBLPTR can hold odd values and even values. Instructions do need to be even
aligned, but that has no bearing on data tables. You do have to remember to
put data tables into a CODE_PACK section, not a CODE section. Forgetting
that can cause padding to be added in unexpected places.
> For simulation, W was being
> sent to RAM pointed at by FSR0. Odd addresses weren't working,
> and, as you say, they should, but padding to an even address seemed
> to be a fix.
I'm not sure what you're saying here, as the FSRs point to data memory, not
program memory. Whatever was going on is worth investigating since this
smells like a bug you don't want to cover up then have it bite you when
you've forgotten all about it later.
********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014. Gold level PIC consultants since 2000.
2008\06\20@091053
by
Jinx
> > For simulation, W was being sent to RAM pointed at by FSR0.
> I'm not sure what you're saying here, as the FSRs point to data
> memory not program memory
Correct. What I was saying is that in an MPLAB simulation, instead
of going to the LCD routine, data from program memory was being
sent to RAM, via POSTINC0, so I could see it in a Watch window
> Whatever was going on is worth investigating since this smells like
> a bug you don't want to cover up then have it bite you when you've
> forgotten all about it later
Very true, and I do not like string and sticky-tape fixes. The 'bug'
is/was actually in MPLAB (currently 7.50 installed). It does appear
to lose a marble or two from time to time. Not often, perhaps once
a month, especally after heavy use. This evening happened to be
one of those times. A re-boot always puts it right. I don't think it's
the PC, although it is about time this one had a good clean out, as
these anomolies also happen on a much less used PC as well
More... (looser matching)
- Last day of these posts
- In 2008
, 2009 only
- Today
- New search...