Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC18F Series read the RETLW values from the FSR0 pointer

Status
Not open for further replies.

ryteker

New Member
Hi all,
When the 'DT' directive is used to assemble a text string, what actually gets assembled is a list of RETLW instructions as 'OCxx' (where 'xx' is the ASCII code of the character, and 'OC' is the instruction code.
If I point the FSRO register to the first (or subsequent data words), what instruction(s) do I use to obtain the ascii character into an 8 bit variable.
Any pointers (excuse the 'pun') would be appreciated.

Regards
Roy
 
Hi Roy,
I can't think of a way to read the value from the RETLW instruction using an FSR. On a PIC16 this is an example of how to read out a string from a table of RETLW instructions

uiDspStr1
movwf DataPointer

uips1_001
movlw HIGH strTable1 ; This must point to start of page (0c800 used)
movwf PCLATH
movf DataPointer, W
call strTable1
clrf PCLATH ; back to this page
xorlw 0 ; if character is 0x00 then exit
btfsc STATUS, Z
goto uips1_002
call dspPutChar ; send character to display
incf DataPointer, F
goto uips1_001 ; Loop

uips1_002
clrf PCLATH
return



ORG 0x800



strTable1
addwf PCL, F
st1m1
retlw 'D'
retlw 'D'
retlw '/'
retlw 'M'
retlw 'M'
retlw '/'
retlw 'Y'
retlw 'Y'
retlw ' '
retlw ' '
retlw 'H'
retlw 'H'
retlw ':'
retlw 'M'
retlw 'M'
retlw 0

st1m2
retlw 'P'
retlw 'r'
retlw 'e'
retlw 's'
retlw 's'
retlw ' '
retlw 'a'
retlw 'n'
retlw 'y'
retlw ' '
retlw 'k'
retlw 'e'
retlw 'y'
retlw 0

I think it should work on a PIC18.
Basically you precede the string of RETLWs with a subroutine entry that sets the PC to point to the required RETLW instruction. You first load the PC to point to the first RETLW of the table. You then add the value in W to the PCL. Each the subroutine is entered the value in W has been incremented. The last RETLW contains the value of zero as an end of string marker so the code that calls the subroutine terminates looping.

I hope that helps.
Les.
 
Hi Ian / Les,
Many thanks for your quick replies, it is appreciated.
Checking out Ian's link seems to be the way to go, mainly because of the solving of the table boundary problem in using the Adding a value to the PCL register and rolling over through OO.
I'll give it a go tomorrow.
Regards
Roy.
 
Hi all,
When the 'DT' directive is used to assemble a text string, what actually gets assembled is a list of RETLW instructions as 'OCxx' (where 'xx' is the ASCII code of the character, and 'OC' is the instruction code.
If I point the FSRO register to the first (or subsequent data words), what instruction(s) do I use to obtain the ascii character into an 8 bit variable.
Any pointers (excuse the 'pun') would be appreciated.

Regards
Roy

You are mixing concepts, Roy.

FSR points to data registers (RAM) and the list of RETLW is in Program (flash) memory.

I have no manual handy. I suggest you to reread carefully about this:

a) FSR / INDF registers - you go through data registers, that is, RAM - incredibly simple and powerful.

b) TBLRD instructions - an organized way to go through program (flash) memory.

c) Look up tables - what involves what is called "computed GOTO". You mess with the PC.

Once you can distinguish the three concepts as different, you could answer your own post (or better, simply discard the idea).

Buena suerte
 
Hi again,
I've been trying out the code in Ian's link, (bottom section for the PIC18's)
I tried a direct copy into my MPLAB (Ver 8.92) - (commenting out the 'rcall put232' instruction, but when I assemble the code I get the following error message :

Warning[207] ..\U2-U3___COMMON___INC.ASM 72 : Found label after column 1. (_Print)
Error[108] ..\U2-U3___COMMON___INC.ASM 72 : Illegal character (")
Warning[207] ..\U2-U3___COMMON___INC.ASM 73 : Found label after column 1. (_Print)
Error[108] ..\U2-U3___COMMON___INC.ASM 73 : Illegal character (")
Warning[207] ..\U2-U3___COMMON___INC.ASM 74 : Found label after column 1. (_Print)
Error[108] ..\U2-U3___COMMON___INC.ASM 74 : Illegal character (")
Halting build on first failure as requested.
-

I suspect there may be something I've not set up in the assembler (or the assembler version) to do with the configuration of the MACRO and its parameters.
I've never used a macro before, so not sure what I'm doing wrong.

Again, any help is appreciated.

Roy
 
Show code lines 72, 73 and 74.
 
Hi atferri',
thanks for your quick reply.
I think I may have found the problem, a bit of 'Googling' indicated I should specify the MACRO code at the very head of the file, before any code, which I did not appreciate.
This has 'solved' the problem of the error messages.
The original lines were these :
_Print "ABCDE"
_Print "FGHIJ"
_Print "KLMNO"

However, I think I may have found a small 'issue' with the number of characters in the string, it appears to have to be an even number.
When the code is generated and the disassembly code generated for the following : with 4 characters in the string:
_Print "ABCD"
_Print "FGHI"
_Print "KLMN"
the assembled code is :
0250 EC37 CALL 0x26e, 0 72: _Print "ABCD"
0252 F001 NOP
0254 4241 RRNCF 0x41, F, ACCESS
0256 4443 RLNCF 0x43, W, ACCESS
0258 0000 NOP
025A EC37 CALL 0x26e, 0 73: _Print "FGHI"
025C F001 NOP
025E 4746 RLNCF 0x46, F, BANKED
0260 4948 INFSNZ 0x48, W, BANKED
0262 0000 NOP
0264 EC37 CALL 0x26e, 0 74: _Print "KLMN"
0266 F001 NOP
0268 4C4B DCFSNZ 0x4b, W, ACCESS
026A 4E4D DCFSNZ 0x4d, F, ACCESS
026C 0000 NOP

The ASCI codes for the characters are indicated in addresses 0254,0256 - 025e,0260 and 0268,026a
with the 'nop' (0000) being generated by the macro.
----------------------------------------------------

If I add another character into the strings :
_Print "ABCDE"
_Print "FGHIJ"
_Print "KLMNO"
the assembled code is :
0250 EC37 CALL 0x26e, 0 72: _Print "ABCDE"
0252 F001 NOP
0254 4241 RRNCF 0x41, F, ACCESS
0256 4443 RLNCF 0x43, W, ACCESS
025A EC37 CALL 0x26e, 0 73: _Print "FGHIJ"
025C F001 NOP
025E 4746 RLNCF 0x46, F, BANKED
0260 4948 INFSNZ 0x48, W, BANKED
0264 EC37 CALL 0x26e, 0 74: _Print "KLMNO"
0266 F001 NOP
0268 4C4B DCFSNZ 0x4b, W, ACCESS
026A 4E4D DCFSNZ 0x4d, F, ACCESS

It appears that the last ASCII code is missing from the listing, and also the 'terminator' 0000 code is missing .....

I've not tested it out fully yet, (i.e. on an a serial lcd or something) but just thought the disassembly was intersting.

Roy
 
I was wrong,
it does work fine, just tested it driving a serial LCD display, and it does actually display the last character of an odd length string, but can't see how its doing it ... I'll need to study it a bit more.

The main thing is, the amazing response to solving my problem in such a short time, less then 12 hours. ... I spend a lot of time on Electro-Tech -Online reading all the interesting and helpful tips and tricks that people submit.
Thanks to you all again ..... back to 'head down' coding till the next problem ;)

Regards
Roy
 
In several projects I used intensively data tables. Those that are to be read and then displayed on the LCD are ended with a NULL char what tells "no more text in this line".

Macros. Not sure how you use, that is, where you define them. Just for the organization sake, I put them all in three files. Those files are INCLUDEd in the main one, always following the same scheme.

In the first file, goes the group of macros that I consider "canned" so I would not even dream to change them AT ALL. I worked them out when starting with the 16C57, and were successively adapted to the 16F and now 18F family.

There is a group just for debugging (eliminated when I am done) and a third group (file) of those specific to the application.

I am light years from professionals but there is a point: it works for me and has been like that for maybe 20 years now.

Would you like to see that? I could post some code here.
 
Those that are to be read and the,n displayed on the LCD are ended with a NULL char what tells "no more text in this line".

Known as 'C style' strings :D

Pascal strings use the first byte to tell you how long the string is (so a start byte rather than a stop one), both types have advantages and disadvantages.
 
Known as 'C style' strings :D

Pascal strings use the first byte to tell you how long the string is (so a start byte rather than a stop one), both types have advantages and disadvantages.

More overhead those C style, I guess?
 
Would you like to see that? I could post some code here.

I would be interested in seeing your method /code, thanks, always interested I'm learning new stuff.
Roy
 
Last edited by a moderator:
Having a well defined place for everything, helps to know where to look at, always.

You will find the formatting in some files somewhat messed up. It seems to happen from time to time. Sorry for that.
 

Attachments

  • 000 CAN BASIC 04.ASM
    3.3 KB · Views: 212
  • 004 MACROS 01.asm
    11.1 KB · Views: 209
  • 006 MACROS 03.ASM
    1.7 KB · Views: 216
  • 005 MACROS 02.asm
    678 bytes · Views: 218
Thanks atferrari.
Some interesting idea's in your asm files, makes for very portable and re-usable code modules, I tend to use similar methods, but not so many macros, mainly multiple parameterised subroutine calls with a ram block for parameter interchange (this is similar to how PLC's (Programmable Logic Controllers) use 'Function Blocks' where the same code executes with multiple variables) this saves a lot of code space, but does chew away at the ram, so is only really practical with larger ram based PICs.

Many thanks for all your comments, I now have all the systems running with 'in-line' command and data strings being sent out over dual RS232 ports at different baud rates.

The next thing for me to have a look at is a combination of both boot loaders and auto baud rate detection via RS232 on a large (ish) multi pic (116 of them) network acting as both remote I/O and DCS functions .... getting to be a bit of a pain to 'update' the firmware in these 'spread out' cards, especially if its only a minor mod, but is required in all the remote systems.

Still, that's another story, I'm sure I'll be back for your help and suggestions again in the not to distant future on these and other points when I get 'stuck'.

Thanks again to all.
Roy
 
Some interesting idea's in your asm files, makes for very portable and re-usable code modules, I tend to use similar methods, but not so many macros, mainly multiple parameterised subroutine calls with a ram block for parameter interchange (this is similar to how PLC's (Programmable Logic Controllers) use 'Function Blocks' where the same code executes with multiple variables) this saves a lot of code space, but does chew away at the ram, so is only really practical with larger ram based PICs.

A comment: if you refer to macros (?), they only make your writen code shorter (and hopefully much easier to write and to understand) but program memory wise you save nothing because the actual code is inserted every time the macro shows up. Just in case, write some simple code with several macros repeating many times each, assemble it and then look at the .list. Every instance of each macro, got its place in program memory. Macros are for lazy (very frequently, smarter) people. :happy:

BTW, never used one, but I recall one micro (18F family) able of auto baud detect.

EDIT

Oh, you said "subroutine calls". My bad.

/EDIT
 
Status
Not open for further replies.

Latest threads

Back
Top