Now there's an endorsement I can be proud of.
Thanks Bruce!
Thanks Darrel and Bruce for your great examples. I would have to say I like Darrel's approach the best, since it seems less cryptic as to what the messages are (i.e; you can give them meaningfull names). Also I like the idea that they can be located anywhere in the program (kinda like my 6502 example). However I am using an 18F252 for my project, and apparently this approach wont work with a 16 bit processor. Any ideas how this could be changed?
You now have meaningful names for your strings. It's not that cryptic onceCode:' Text message addresses w/specific names Intro CON 0 PumpOn CON 16 PumpOFF CON 32 ' etc,, ptr_pos = Intro ' print intro message CALL Start ptr_pos = PumpON ' print pump on message, etc,,, CALL Start
you've played with it a bit. The 18F series are easier to code in .asm than
16F parts.
Make your strings as long as you like. That was just a quick/simple example.
I don't have an example for placing strings all over code space since I would
never do that. PBP library functions & my app code get first pick. Huge
chunks of text messages get the left-overs at the bottom...;o]
Hi again Michael,
I guess it was about time anyhow. Haven't updated it since 2003.
I've modified the Strings program to be able to work with 16-bit devices.
Between Bruce's example and the new one, I'm sure you'll get what you need.
It's still in the same place ... How to store and retrieve strings in Code Space
Best regards,
Darrel
Hi Bruce,
I have been studying your code that you posted here on doing message tables from assembly code, and quite frankly I am baffled by parts of it. This wouldn't be problem if I could use it as is, but I really need to have the pointer increments to be by 1 (i.e.; 0,1,2,3,4,5,6, ect.).
Here are some snippits of your code with some questions I have next to them. If you get a chance can you please explain what is going on?
If I was better versed in the assembly aspects of the 18F series I could probably figure this out on my own, but I only recently began working with this series of PIC chips.Code:; This section appears to be locating the message table, but Im not ; really sure specifically what is going on especially with the first part ; where you are moving Upper msg_table into TBLPTRU ; (what is UPPER? I've used HIGH and LOW before, but never UPPER). ; TBLPTR is obviously short for Table Pointer. movlw UPPER msg_table movwf TBLPTRU movlw HIGH msg_table movwf TBLPTRH movlw LOW msg_table movwf TBLPTRL ; Now here we seem to be adding an offset into the message table using ; the same pointers we previously set to what I am asuming is the base ; address of our message table. This is where the beginning of a particular ; message resides within the table (correct?). Now here comes the questions ; of particular interest to me; does the fact that your pointers are in 16 byte ; increments mean that each message string can only be up to 16 bytes long? ; Or can the pointer be changed to any increment desired? movf _ptr_pos,W ;prt_pos must hold message address addwf TBLPTRL,F clrf WREG addwfc TBLPTRH,F addwfc TBLPTRU,F ; Ok now that we have our index to a message set, we can begin retrieving ; the characters one by one, until we see the EOM character "~". What is ; tblrd *+ or more specifically *+ (is this doing a read and then increment?) ; Oh and what is "goto $-2" doing? (specifically $-2). Next_Char tblrd *+ movff TABLAT,_temp bra Test_EOM ;test for EOM character Continue movf _temp,W ;move temp to w movwf TXREG ;send it btfss TXSTA,TRMT ;wait for data TX goto $-2 bra Next_Char ;fetch next message character from table ; This part is fairly obvious, although there are some more of those $-2 ; which I don't understand the purpose of, and what does "\r" ; and "\n" do? Actually to be more specific since I can see your comments, ; what my question really is; what or how does moving a literal of "\r" into ; W actually move the data (which I assume is a character from the table). Test_EOM movlw "~" ;check for EOM character cpfseq _temp, 1 ;compare temp with w, if temp = ~ then end bra Continue ;no EOM, so continue movlw "\r" ;move data into TXREG movwf TXREG ;send carriage return btfss TXSTA,TRMT ;wait for data TX goto $-2 movlw "\n" ;move data into TXREG movwf TXREG ;send line feed btfss TXSTA,TRMT ;wait for data TX goto $-2 return ;finished with message, return to caller
Any help you can offer is appreciatted.
Thanks,
Hi Michael,
Download the PICmicro® 18C MCU Family Reference Manual... or just the chapters you need from here;
http://www.microchip.com/stellent/id...GE&nodeId=2054
There's a whole section on table read/write with detailed explanations that should answer every question you have.
Much easier than me re-typing it all. If you have questions after reading section 8 let me know.
Hi Darrel - Hi Bruce,
Darrel I checked out your new message table code for 16 bit pics. Very Nice!
Bruce I read up on the info you linked me to, and I have a pretty good grasp of what you are doing in your code. I also figured out that the GOTO $-2 is just a slick way to skip backwards without having to use a labeled reference.
Well of course after getting my brain filled with a bit more knowledge I decided to try my hand at writing yet another variation on message string handling, but not without problems (and a smoking head). Check out this code:
It's more of a variation of what Darrel's code does. Only I wanted to try using the POP and PUSH functions on the PIC18F to allow me to have embedded message strings (this is a pet peeve of mine). Anyway if you run the code as is (leave the 2nd message string commented out) everything works great. However if you try to use more then one message (uncomment the 2nd message string) then all hell breaks loose, and you end up with garbled messages and a runaway processor.Code:DEFINE LOADER_USED 1 DEFINE OSC 40 ' change to suit oscillator speed DEFINE HSER_RCSTA 90h DEFINE HSER_TXSTA 20h DEFINE HSER_BAUD 19200 ' change to suit baud rate message var byte[40] stringsize var byte x var byte temp var byte Clr Main: Call getSTR @ data "This is a string",0 Gosub putSTR ' Call getSTR '@ data "yet another string again",0 ' Gosub putSTR Done: Goto Done putSTR: For x = 0 To (stringsize-1) temp = message[x] Hserout [temp] Next x Hserout [$0D,$0A] ; send carriage return + line feed stringsize = 0 ; reset for next message Return asm _getSTR LFSR FSR0,_message ; set message array base address ;copy return address to TBLPTR and then pop it off the stack movf TOSU,W movwf TBLPTRU movf TOSH,W movwf TBLPTRH movf TOSL,W movwf TBLPTRL POP ;TBLPTR should now be pointing to 1st character in string Next_Char tblrd *+ ; table read and post increment TBLPTR movf TABLAT,W ; retrieve character to W register movwf POSTINC0 ; xfer to message array and increment FSR incf _stringsize,F ; keep track of message string size movf TABLAT,W ; Is character = 0? bnz Next_Char ; If not, then get next character ;use incremented value of TBLPTR as new return address (push it) movf TBLPTRU,W movwf TOSU movf TBLPTRH,W movwf TOSH movf TBLPTRL,W movwf TOSL PUSH return ;finished with message, return to caller endasm
Any ideas what I am doing wroung?
Well.. that certainly is a creative approach. I guess you did do some
reading ehh..;o]
Initialize your stringsize variable before you start incrementing it.
Move the PUSH up to the entry point of the section "before" modifying
TOS.
See how this works.
Code:DEFINE LOADER_USED 1 DEFINE OSC 40 ' change to suit oscillator speed DEFINE HSER_RCSTA 90h DEFINE HSER_TXSTA 20h DEFINE HSER_BAUD 19200 ' change to suit baud rate message var byte[40] stringsize var byte stringsize = 0 ; <-- initialize to zero here. Don't wanna incf if it's not x var byte ; starting at zero temp var byte Clr Main: Call getSTR @ data "This is a string",0 Gosub putSTR Call getSTR @ data "yet another string again",0 Gosub putSTR Done: Goto Done putSTR: For x = 0 To (stringsize-1) temp = message[x] Hserout [temp] Next x Hserout [$0D,$0A] ; send carriage return + line feed stringsize = 0 ; reset for next message Return asm _getSTR LFSR FSR0,_message ; set message array base address ;copy return address to TBLPTR and then pop it off the stack movf TOSU,W movwf TBLPTRU movf TOSH,W movwf TBLPTRH movf TOSL,W movwf TBLPTRL POP ;TBLPTR should now be pointing to 1st character in string Next_Char tblrd *+ ; table read and post increment TBLPTR movf TABLAT,W ; retrieve character to W register movwf POSTINC0 ; xfer to message array and increment FSR incf _stringsize,F ; keep track of message string size movf TABLAT,W ; Is character = 0? bnz Next_Char ; If not, then get next character ;use incremented value of TBLPTR as new return address (push it) PUSH ; <--- moved up to here movf TBLPTRU,W movwf TOSU movf TBLPTRH,W movwf TOSH movf TBLPTRL,W movwf TOSL ; PUSH return ;finished with message, return to caller endasm
Bookmarks