Author Topic: Read from data table (PIC)  (Read 11287 times)

0 Members and 1 Guest are viewing this topic.

Offline katzohkiTopic starter

  • Frequent Contributor
  • **
  • Posts: 381
  • Country: us
    • My Blog
Read from data table (PIC)
« on: June 02, 2014, 05:08:04 pm »
Hi all,

My project is using a PIC10F322. I have a data table set up using the dt directive and I love the way that works, but I'm having difficulty reading from the table. I can read the data fine, but I can only get up to 10 characters from it (it's an ASCII string) before it stops working. I'm about 95% sure that it's the method I'm using:

Code: [Select]
main
    call    message  ;I want to read letter at a message counter
    movwf   letter
    call    send
    call    message+1
    movwf   letter
    call    send
    call    message+2
    movwf   letter
    call    send
...
...
    call    message+9
    movwf   letter
    call    send
    goto    main

I tried all the way up to "message+13" but either way it skipped any characters in the string after the 10th. I tried a few things to get this to work, "message+mc" and "incf mc" wouldn't compile... Probably "call" is not the way to go. Anyone have some advice or better method?

Trying to refresh my knowledge on MCUs.
Thanks
--Katz


EDIT: Whoops, should have mentioned that "message" is the name of my data table.
 

Offline Mr Smiley

  • Frequent Contributor
  • **
  • Posts: 324
  • Country: gb
Re: Read from data table (PIC)
« Reply #1 on: June 02, 2014, 07:10:04 pm »
Does your table pass over a page boundary ?

I had lots of problems with very large tables on the 16F and 12F chips and mplab-x a while ago, it, for some unknown reason automatically updated pclath when it should not have done so and all worked perfectly in simulation but not on the hardware. I only found out by stepping through the code and watching the pclath register. When i started calculating my own pclath values it worked on the hardware.

Machine code, you have to work out your own pclath values, in C i believe its all done for you behind the scenes.

 :)

There is enough on this planet to sustain mans needs. There will never be enough on this planet to sustain mans greed.
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4382
  • Country: us
Re: Read from data table (PIC)
« Reply #2 on: June 02, 2014, 07:19:18 pm »
"The default radix for MPASM is Hex."
So (if you haven't changed anything) after "message+9", you need to use something like "message+0A"
Or include a "radix dec" at the top of your program...
(that's a horrible way to read a table, BTW!  "For more information refer to Application Note AN556, ?“Implementing a Table Read?” (DS00556).")
 

Offline katzohkiTopic starter

  • Frequent Contributor
  • **
  • Posts: 381
  • Country: us
    • My Blog
Re: Read from data table (PIC)
« Reply #3 on: June 02, 2014, 07:26:57 pm »
Does your table pass over a page boundary ?

Nope, the table is not that large.

"The default radix for MPASM is Hex."
So (if you haven't changed anything) after "message+9", you need to use something like "message+0A"
Or include a "radix dec" at the top of your program...
(that's a horrible way to read a table, BTW!  "For more information refer to Application Note AN556, ?“Implementing a Table Read?” (DS00556).")


Ahah! OK, I didn't realize that about the radix being hex. But yeah I sort of figured it's a horrible way. I'll read the app note. Here's my latest attempt:

Code: [Select]
    movf    message,w
    movwf   mc

main
    movf    mc,w
    movwf   PCL     ;had addwf    PCL,f here
    movwf   letter
    call    send
    incf    mc
    goto    main
 

Offline Mr Smiley

  • Frequent Contributor
  • **
  • Posts: 324
  • Country: gb
Re: Read from data table (PIC)
« Reply #4 on: June 02, 2014, 07:35:54 pm »
Does your table pass over a page boundary ?

Quote
Nope, the table is not that large.



It may not be large, it depends where the compiler puts it, unless you specify it's location you won't know and it could pass over a page boundary.

I'd say westfw is very likely  :-+


There is enough on this planet to sustain mans needs. There will never be enough on this planet to sustain mans greed.
 

Offline Mark Hennessy

  • Frequent Contributor
  • **
  • Posts: 305
  • Country: gb
    • My electronics and audio website
Re: Read from data table (PIC)
« Reply #5 on: June 02, 2014, 07:47:59 pm »


Code: [Select]
    movf    message,w
    movwf   mc

main
    movf    mc,w
    movwf   PCL     ;had addwf    PCL,f here
    movwf   letter
    call    send
    incf    mc
    goto    main

Don't forget that incf requires a destination - it defaults to F when omitted, so often the code appears to work, but do get in the habit of including it always, then you won't forget about it when you need it to be W. The assembler will issue a warning about the missing dest, BTW...

As you probably know, when using dt to make a lookup table, that gets turned into a series of retlw instructions. So you need to get to your table with call, not just by manipulating PCL in your main code. The first line of the lookup table subroutine is usually where you manipulate PCL, and it's normal to pass the required offset in W - that app-note should explain all.

My template program includes "R=DEC" on the first line, along with the processor definition and that sort of stuff. Far better to actively define these things than make assumptions :)

Good luck,

Mark
 

Offline katzohkiTopic starter

  • Frequent Contributor
  • **
  • Posts: 381
  • Country: us
    • My Blog
Re: Read from data table (PIC)
« Reply #6 on: June 02, 2014, 08:02:33 pm »

Don't forget that incf requires a destination - it defaults to F when omitted, so often the code appears to work, but do get in the habit of including it always, then you won't forget about it when you need it to be W. The assembler will issue a warning about the missing dest, BTW...

As you probably know, when using dt to make a lookup table, that gets turned into a series of retlw instructions. So you need to get to your table with call, not just by manipulating PCL in your main code. The first line of the lookup table subroutine is usually where you manipulate PCL, and it's normal to pass the required offset in W - that app-note should explain all.

My template program includes "R=DEC" on the first line, along with the processor definition and that sort of stuff. Far better to actively define these things than make assumptions :)

Good luck,

Mark

You have a point, I will try to remember to specify destinations.

My latest version was indeed not using a call to get to the table. Perhaps where I need help then is in how and where to properly build my table subroutine? I tried this, but it did not work (this is before "MAIN CODE"):

Code: [Select]
STORAGE CODE

Table
    addwf   PCL,f
message     dt      "DATADATA \n"

I will try to re-implement a table subroutine correctly. Thanks for all the help! I'm edging closer to solution, which is to understand, not just to do.
 

Offline 22swg

  • Frequent Contributor
  • **
  • Posts: 274
  • Country: gb
Re: Read from data table (PIC)
« Reply #7 on: June 02, 2014, 08:03:49 pm »
I always put tables at the start of code memory like below. then at the end of the table(s) put an ORG xxxx . gets a bit sticky for large amount of data...



   ORG    0
    GOTO    BOOTSTART
       ORG   4
   GOTO   ISR
;
;-------- RETURNS ASCII MESSAGE ------------------------
;
DMTAB   BRW   ; BRANCH RELATIVE PC+W
   ; MESSAGE 0 BOOT
   DT    0X0D,0X0D,"** qPIC-875x *BOOT*  v1.03 **",0x0D
   DT          "**   PROGRAMMER
Check your tongue, your belly and your lust. Better to enjoy someone else’s madness.
 

Offline katzohkiTopic starter

  • Frequent Contributor
  • **
  • Posts: 381
  • Country: us
    • My Blog
Re: Read from data table (PIC)
« Reply #8 on: June 02, 2014, 08:24:19 pm »
I decided to go back and scroll through my code to see if I made any mistakes. Here's what I did wrong:
The table subroutine was above my main code, therefore started adding to the program counter and causing unexpected behavior. So I added a goto main and now it is reading the data correctly! YAY! ;D

Next step will be to check the length of the message and then reset the offset when that length is reached. Thank you everyone for all the help!
 

Offline Mark Hennessy

  • Frequent Contributor
  • **
  • Posts: 305
  • Country: gb
    • My electronics and audio website
Re: Read from data table (PIC)
« Reply #9 on: June 02, 2014, 11:07:40 pm »
Good job - sounds like you're getting there.

Yes, tables can be anywhere, providing you don't accidentally "flow" into them. The assembly process is "2-pass", so they (like subroutines, etc), don't need to appear before they are used. If you're coming from C or similar, then you might not be accustomed to doing that.

Incidentally, I must admit that "BRW" was new to me. At first I wondered if it might be an assembler "shortcut", that gets translated into a 2 or more assembly instructions (like BANKSEL, PAGESEL, etc). But it seems that there are 14 new "native" instructions:

ww1.microchip.com/downloads/en/DeviceDoc/41375A.pdf

I have to say, from a quick read, that I like the thinking behind some of these - maybe it's time to explore some of the newer devices. In the meantime, thanks for (indirectly!) pointing this out to me :-+

Oh, and when dealing with strings, you could make the first byte equal the string length (though it's a minor pain to make sure this is updated should you change the text. Alternatively, you might choose to terminate the string with a control code (I use 13). Either is valid, depending on your needs.

Code: [Select]
words movwf PCL
W_mute dt "Mute",13
W_db dt "dB",13
W_volume dt "Volume",13

scroll movwf PCL
S_record dt 42,"Press STORE to confirm Record selection..."
S_access dt 24,"Press STORE to access..."

In these extracts, the regular text routine just keeps writing characters to the display until it meets 13 (decimal). But the scrolling text routine is much easier to code when it is given the length of the string in advance. As I say, either approach is valid...

All the best,

Mark
 

Offline katzohkiTopic starter

  • Frequent Contributor
  • **
  • Posts: 381
  • Country: us
    • My Blog
Re: Read from data table (PIC)
« Reply #10 on: June 03, 2014, 12:09:11 am »
Yes, BRW and BRA sound very well suited to what I am doing, but alas I am not using a micro that accepts those instructions.

As for handling the "end of string" scenario, I added a clrf command to reset the offset followed by a retlw "\n". In my code "\n" implements a long delay. For my purposes this is working perfectly and will be easy to change should a different behavior be required at end of string.

As an aside, putting the data table before the main program makes me a little nervous because that means any time the message changes length, program locations shift around. I know it will be fine, but I can't help feeling uneasy about that so I may place the message data at a defined location instead.

Thanks! :-+
--Katz
 

Offline 22swg

  • Frequent Contributor
  • **
  • Posts: 274
  • Country: gb
Re: Read from data table (PIC)
« Reply #11 on: June 03, 2014, 09:03:46 am »
In my example the end of "message" I have been using a null 0x00  , the message sub uses a pre loaded number and counts the nulls then TX's  the ascii until the null hence the 0x0D , PIC's without the enhanced instructions I use addwf  pcl,f        the andlw  limits the value in w ... just in case !

SSTAB      ANDLW   0X1F      ; MAX 1F
             ADDWF   PCL,F      ; LCD SEVEN SEG TABLE
                                                   ;0-9 a-f    DIGIT   
   RETLW   B'00111111'   ; 0 
   RETLW   B'00000110'   ; 1
   RETLW   B'01011011'   ; 2
   RETLW   B'01001111'   ; 3
« Last Edit: June 03, 2014, 09:10:41 am by 22swg »
Check your tongue, your belly and your lust. Better to enjoy someone else’s madness.
 

Offline Mark Hennessy

  • Frequent Contributor
  • **
  • Posts: 305
  • Country: gb
    • My electronics and audio website
Re: Read from data table (PIC)
« Reply #12 on: June 03, 2014, 09:13:29 am »
Yes, BRW and BRA sound very well suited to what I am doing, but alas I am not using a micro that accepts those instructions.

Oops - the mention of BRW was in the post from "22swg". Sorry - that'll teach me to be posting so late at night! In which case, "thanks" to 22swg for bringing the mid-range enhancements to my attention. No idea how I missed that, but then I tend to stick with the "old school" processors like the 16F877...



Quote
As an aside, putting the data table before the main program makes me a little nervous because that means any time the message changes length, program locations shift around. I know it will be fine, but I can't help feeling uneasy about that so I may place the message data at a defined location instead.

Yes, I know what you mean. For a small program, it's rarely an issue, but as you cross page boundaries things start to get "interesting". Watch out for 256 byte boundaries too. In my code, I incf PCLATH if the pointer variable overflows - easy enough, but easily forgotten. For what it's worth, I tend to put my tables at the end of the code, and sometimes I'll use ORG to put them at a nice place. On larger processors, I'll often stick them away in another page. But every scenario is different...

BTW, at the risk of stating the obvious, a lookup table doesn't have to contain retlw statements - it could be a bunch of goto statements. A nice way to do a "computed goto" that could deal with different scenarios. E.g., as you step through several menu screens, are you calling a bargraph routine, a list of options, or a binary choice?

Cheers,

Mark :)
 

Offline bequest333

  • Contributor
  • Posts: 16
  • Country: jp
Re: Read from data table (PIC)
« Reply #13 on: June 03, 2014, 03:50:12 pm »
Hi, All

I am New Here.

This is My code.



org 0040

M001:
DW 0x0D*0x80+0x0A                  ;new line
DW 'A'*0x80+'D'                           ;ADRS+00+01+02+03+04+05+06+07
DW 'R'*0x80+'S'
DW '+'*0x80+'0'
DW '0'*0x80+'+'
DW '0'*0x80+'1'
DW '+'*0x80+'0'
DW '2'*0x80+'+'
DW '0'*0x80+'3'
DW '+'*0x80+'0'
DW '4'*0x80+'+'
DW '0'*0x80+'5'
DW '+'*0x80+'0'
DW '6'*0x80+'+'
DW '0'*0x80+'7'
DW 0x0d*0x80+0x0A                   ;new line
DW 0                              ;0=data end

M002:
DW 'T'*0x80+'e'
DW 's'*0x80+'t'
DW '1'*0x80+0                   ;0=data end



[Subroutine]

PUT2:
        MOVWF    PMADRL                ;set PMADR
        CLRF        PMADRH                ;Data Address<0x0100
;       INCF           PMADRH,F             ;if Data Address>=0x0100
LOOP:
        BSF          PMCON1,RD          ;read flash
        NOP                                      ;PMDATH <- 00ABCDEF
        NOP                                      ;PMDATL <- Gabcdefg
        INCF        PMADRL,F              ;PMADRL = PMADRL + 1
        RLF          PMDATL,F              ;Carry=G, PMDATL=abcdefgX
        RLF          PMDATH,W            ;Carry=0, W=0ABCDEFG
        RRF          PMDATL,F              ;Carry=X, PMDATL=0abcdefg
        CALL        PUTC                     ;OUTPUT upper 7bits
        MOVF       PMDATL,W             ;W=lower 7bits
        SKPNZ                                   ;skip if W<>0
        RETURN

        CALL        PUTC                     ;OUTPUT lower 7bits
        GOTO       LOOP                    ;loop



[Main]

        MOVLW       M001
        CALL           PUT2
        MOVLW       M002
        CALL           PUT2

 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4382
  • Country: us
Re: Read from data table (PIC)
« Reply #14 on: June 03, 2014, 07:23:22 pm »
MPASM has a "DA" directive for packing two 7-bit ascii characters per 14bit instruction word...
Code: [Select]
msg:  DA "\r\nADRS+00+01+02+03+04+05+06+07", 0(probably.  I didn't check whether it does \r and \n)
 

Offline bequest333

  • Contributor
  • Posts: 16
  • Country: jp
Re: Read from data table (PIC)
« Reply #15 on: June 04, 2014, 05:31:03 am »
Hi, westfw


Thank you so much for letting me know.

I appreciate it. ;D
 

Offline dannyf

  • Super Contributor
  • ***
  • Posts: 8221
  • Country: 00
Re: Read from data table (PIC)
« Reply #16 on: June 04, 2014, 09:20:50 pm »
Alternatively, you can code in C and don't have to worry about that.
================================
https://dannyelectronics.wordpress.com/
 

Offline westfw

  • Super Contributor
  • ***
  • Posts: 4382
  • Country: us
Re: Read from data table (PIC)
« Reply #17 on: June 04, 2014, 11:18:06 pm »
Would a C compiler produce 7bit flash character strings?  (or: what are the commands to make it do so?) (genuinely curious!)
I seem to recall all sorts of problems trying to convince C to run on a system that used 7bit bytes for ascii strings (I don't THINK that was just because they were stored 5 per 36bit word...)
 

Offline 22swg

  • Frequent Contributor
  • **
  • Posts: 274
  • Country: gb
Re: Read from data table (PIC)
« Reply #18 on: June 05, 2014, 08:04:56 am »
And ... you could store strings bytes in the pic eeprom  . move them to a data memory bank and output them from there ,  makes modifying them easy and you can include 8 bit custom / control characters. re PIC enhanced instructions , the 2 FSR registers and the INDF0++ etc improve asm code for data moves .  I use C for PIC24's but still come back to asm for pic16's .
Check your tongue, your belly and your lust. Better to enjoy someone else’s madness.
 

Offline katzohkiTopic starter

  • Frequent Contributor
  • **
  • Posts: 381
  • Country: us
    • My Blog
Re: Read from data table (PIC)
« Reply #19 on: June 05, 2014, 01:36:16 pm »
I thought I would share my solution with you guys. Once I got the hang of one data table I was able to implement another 2 for a drastic reduction in my code size:
Code: [Select]
Table
    addwf   PCL,f   ;add w to the program counter, so 0 goes to first char, 1 goes to 2nd etc
message     dt      "MESSAGE GOES HERE"    ;stores each character in ASCII format followed by retlw
                                            ;so returns with current char in w
    clrf    offset      ;end of message reset - if you get here you've gone past the end of the message
    retlw   "\n"        ;for me "\n" creates a long pause before moving on to the next char

main
    movf    offset,w    ;put offset in w
    incf    offset,f        ;increment offset for next time
    call    Table           ;go get the current char and return with it in w
    movwf   letter       ;put it into letter
    clrf    soffset         ;clear this
    clrw                      ; and this (probably don't need this here actually)
    call    send
    goto    main

AlphaTable
    addwf   PCL,f       ;This addition here is setting the Z flag to zero!
alphabet    dt  "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.? \n"
;;;letter not found if you make it this far, so...
;    need to handle error somehow

nextL
    incf    soffset,f       ;increment the alphabet offset
send    ;coming from main with current char stored in w and soffset set to 0
    movf    soffset,w   ;alphabet offset
    call    AlphaTable   ;return from alphabet with message char stored in "letter", alphabet char in "w", alphabet # in "soffset"
    subwf   letter,w     ; subtract the message char, from the alphabet char
    btfss   STATUS,Z    ;if zero (STATUS,Z=1), character was a match, soffset holds offset of correct character to display/print/send so skip next inst.
    goto    nextL         ;otherwise check next letter
    movf    soffset,w   ;put the alphabet offset into w and then add it to the program counter
    addwf   PCL,f        ;if 0 sendA, if 1 sendB, if 2 send C...
JumpTable
    goto    sendA
    goto    sendB
    goto    sendC
...
...
...
    goto    hell    ;("\n" long pause)
 

Online Jeroen3

  • Super Contributor
  • ***
  • Posts: 4235
  • Country: nl
  • Embedded Engineer
    • jeroen3.nl
Re: Read from data table (PIC)
« Reply #20 on: June 05, 2014, 02:27:10 pm »
Would a C compiler produce 7bit flash character strings?
No, since the typical minimum alignment width is one byte. There are bitfields, but the standard is rather undefined there.
But if you type 'A' you will get 0x41. And if you type "A" you will get 0x41 0x00. So that won't change.

If you want special bit width data types you'd have to manually shift them together, preferably not until you send to the special bit width device.

Why on earth would someone use a 14 bit wide flash?

« Last Edit: June 05, 2014, 02:31:32 pm by Jeroen3 »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf