18F24k22 LOOK up table not working

Thread Starter

Dodgydave

Joined Jun 22, 2012
11,318
I am using these pics 18F24K22 and 18F2321 have got the look up table working ok an a 16f722 no problem.

Right here is the headache when i call the look up table it always returns with the first line of the look up, it wont add thw W to the PCL, and retlw like it should do.


Even if i pre-load the W with a value it still returns with the first Retlw

here is the ASM file which works ok on the 16F722

Rich (BB code):
Show_Units
	movf UNITS,w
	Call Convert	                          
	movwf PORTB	
	bcf PORTC,5  ; Units mux
	bsf PORTC,6  ; Tens mux            
	bsf PORTC,7  ; Huns mux
	call Delay
	return

Convert	
	                   ;NOTE CHANGE    ADDWF PCL,F TO W  TO MAKE LOOKUP TABLE WORK ALSO ON 18F2321
	ADDWF PCL,f       ; now get dispaly seven segment bits (0= 0n 1= Off)             
	retlw	b'00000011';0           b7=a                         aaaaa           77777
	retlw	b'10011111';1           b6=b                        f     b         2     6
	retlw	b'00100101';2           b5=c                        f     b         2     6
	retlw	b'00001101';3           b4=d                        f     b         2     6
	retlw	b'10011001';4           b3=e                         ggggg           11111
	retlw	b'01001001';5           b2=f                        e     c         3     5
	retlw	b'01000001';6			b1=g                        e     c         3     5
	retlw	b'00011111';7           b0=dp                       e     c         3     5
	retlw	b'00000001';8                                        ddddd           44444
	retlw	b'00011001';9                                                dp            O
	                                                      ; Segment bits         PORT bits  


***********************************************************************
and this is the ASM for the new pics  NOTE I HAVE TO CHANGE THE
 ADDWF PCL, F TO  ADDWF PCL ,W 

 or it wont return at all and crashes??
****************************************************************************
Show_Units
	movf UNITS,w
	Call Convert	                          
	movwf PORTB	
	bcf PORTC,5  ; Units mux
	bsf PORTC,6  ; Tens mux            
	bsf PORTC,7  ; Huns mux
	call Delay
	return

Convert	
	                   ;NOTE CHANGE    ADDWF PCL,F TO W  TO MAKE LOOKUP TABLE WORK ALSO ON 18F2321
	ADDWF PCL,w       ; now get dispaly seven segment bits (0= 0n 1= Off)             
	retlw	b'00000011';0           b7=a                         aaaaa           77777
	retlw	b'10011111';1           b6=b                        f     b         2     6
	retlw	b'00100101';2           b5=c                        f     b         2     6
	retlw	b'00001101';3           b4=d                        f     b         2     6
	retlw	b'10011001';4           b3=e                         ggggg           11111
	retlw	b'01001001';5           b2=f                        e     c         3     5
	retlw	b'01000001';6			b1=g                        e     c         3     5
	retlw	b'00011111';7           b0=dp                       e     c         3     5
	retlw	b'00000001';8                                        ddddd           44444
	retlw	b'00011001';9                                                dp            O
	                                                      ; Segment bits         PORT bits  



EVEN IF I PUT THIS LINE IN
it crashes and hangs because of   ",F"

" movlw  .4"
  addwf pcl,f                                                       
 retlw . xxxxxxxx                                                    
 retlw  .xxxxxxxx                                                 
  ETC......                                                          


OR THIS LINE  ,W just returns with first value of retlw?

" movlw  .4"
  addwf pcl,w                                                      
 retlw . xxxxxxxx                                                   
 retlw  .xxxxxxxx                                                      
  ETC......
WHY WONT IT WORK ON THESE NEW 18F SERIES PICS?
 
Last edited:

joeyd999

Joined Jun 6, 2011
5,355
This is a common mistake made when porting from 16f to 18f silicon. An instruction in the 18f uses 2 memory locations, not 1 like the 16f. All instructions start at an even address. If you wish to make a computed jump, you will need to double the value of WREG before adding to PCL.

As an alternative, consider this:

http://forum.allaboutcircuits.com/showthread.php?t=56583

Even better, to better enjoy your 18f experience, learn to use the tblrd instruction. It'll cut your program memory use in half.
 

MaxHeadRoom

Joined Jul 18, 2013
28,757
I have just started using the 18f series, but the 18f has a different memory access capability than the 16f.
For data memory use the LFSR command, load FSR0/FSR1 etc
for assigned ROM data tables the new commands are easier to use that the 16f RETLW type once you get the hang of it.
The new ones are:
TBLRD*
TBLRD*+
TBLRD*-
etc,

Rich (BB code):
;=============================================================================
;
;  
; 
;=============================================================================
;    Filename:    PIC18g.asm
;=============================================================================
;    Demonstrate Create a table and read data in memory transmits to USART
;    USART routine not shown
;    Assembled using MPASMWIN V8.9 PICIT-2
;=============================================================================
;    Include Files:    p181220.inc    V1.3
;=============================================================================
;    PIC18XXX USART 
;=============================================================================

        list p=18f1220        ;list directive to define processor
        #include <p18f1220.inc>    ;processor specific definitions

;   Oscillator Selection:
    config    OSC = INTIO2, FSCM = OFF, IESO = OFF                 ;1H
    config  PWRT = ON, BOR = ON, BORV = 27                         ;2L
    config WDTPS = 1,  WDT = OFF                                ;2H
    config STVR = OFF, LVP = OFF, DEBUG = OFF                    ;4L
    config MCLRE = OFF
;----------------------------------------------------------------------------
;Constants

SPBRG_VAL    EQU    .25        ;set baud rate 9600 for 4Mhz clock

;----------------------------------------------------------------------------
;Bit Definitions

    GotNewData    EQU    0        ;bit indicates new data received
    Mcount    EQU 0x001
    Ncount    EQU 0X000
;----------------------------------------------------------------------------
;Variables

        CBLOCK    0x000
        count
        Flags            ;byte to store indicator flags
        ENDC

;----------------------------------------------------------------------------
;This code executes when a reset occurs.

        ORG     0x0000        ;place code at reset vector

ResetCode:    bra    Main        ;go to beginning of program

;----------------------------------------------------------------------------
;This code executes when a high priority interrupt occurs.

        ORG    0x0008        ;place code at interrupt vector

HiIntCode:    ;do interrupts here

        reset            ;error if no valid interrupt so reset

;----------------------------------------------------------------------------
;This code executes when a low priority interrupt occurs.

        ORG    0x0018        ;place code at interrupt vector

LoIntCode:    ;do interrupts here

        reset            ;error if no valid interrupt so reset

;----------------------------------------------------------------------------

Main:
        movlw    0x60
        movwf    OSCCON
        bcf        ADCON0, 0
        setf    ADCON1
        clrf    PORTA
        clrf    LATA
        clrf    TRISA
;Set up for memory access
        bsf        EECON1, 7
        bsf        EECON1, 6
;Set upf for table read
        movlw    0x10    ;inilialize counter number of charachters
        movwf    count
        movlw    upper msg_table
        movlw    TBLPTRU
        movlw    high msg_table
        movwf    TBLPTRH
        movlw    low    msg_table
        movwf    TBLPRTL
;access table

Advance:
        TBLRD*+    ;Read increment table pointer
        movf   TABLAT, W
        call     Tx_byte
        decfsz    count
        goto advance
;-----------------------
;Done
Circle:
        goto     Circle
;-----------------------
msg_tbl db    0x0a, 0x0d,'T','e','s','t',' ','M','e','s','s'.'a','g','e'
0x0a,0x0d
;----------------------
;transmit subroutine
Tx_byte:
        btfss    PIR1, TXIF
        goto     Tx_byte
        movwf    TXREG
        return
;---
        end
;
The message table can go anywhere in memory.
Max.
 
Last edited:

MaxHeadRoom

Joined Jul 18, 2013
28,757
Once you set up a table with the db inst, the TBLRD*+ reads the contents of the first location into the TABLAT register and then increments its counter, (*+), the data is then moved from the reg to the WREG and then you do what ever with the data.
The next time you do the TBLRD*+ it reads the next location, and so on.
There are ways to read one particular location if needed.
This is one way.
Rich (BB code):
; Access fourth table loc:
;output to PORTB
        movlw    0x03    ;define offset
        bcf     STATUS, C    ;prep for math
        addwfc    TBLPTRL, F    ;table pointer = table pointer +W
        clrf    WREG        ;
        addwfc    TBLPTRH, F
        addwfc    TBLPTRU, F
        tblrd*        ;read: no increment of pointer
        movf    TABLAT, W
        clrf    PORTB    ;clear port
        movwf    PORTB    ;output data to port.
Circle:
        goto    Circle
        end
All you do is add an offset to the TBLPTRL
This is the basic concept you can improve on it probabally.
I sent an 18f Ebook via email.

Max.
 

MaxHeadRoom

Joined Jul 18, 2013
28,757
Compiled and debugged.
Does now perform OK,
Rich (BB code):
;=============================================================================
;
;  
; 
;=============================================================================
;    Filename:    PIC18g.asm
;=============================================================================
;    Demonstrate Create a table and read data in memory transmits to USART
;    USART routine not shown
;    Assembled using MPASMWIN V8.9 PICIT-2
;=============================================================================
;    Include Files:    p18F2221.inc    V1.3
;=============================================================================
;    PIC18XXX USART 
;=============================================================================

        list p=18f2221        ;list directive to define processor
        #include <p18f2221.inc>    ;processor specific definitions

;   Oscillator Selection:
    config    OSC = INTIO2, FCMEN = OFF, IESO = OFF                 ;1H
    config  PWRT = ON, BOR = ON, BORV = 2                         ;2L
    config WDTPS = 1,  WDT = OFF                                ;2H
    config STVREN = OFF, LVP = OFF, DEBUG = OFF                    ;4L
    config MCLRE = OFF
;----------------------------------------------------------------------------
;Constants

SPBRG_VAL    EQU    .25        ;set baud rate 9600 for 4Mhz clock

;----------------------------------------------------------------------------
;Bit Definitions

GotNewData    EQU    0        ;bit indicates new data received
Mcount    EQU 0x001
Ncount    EQU 0X000
;----------------------------------------------------------------------------
;Variables

        CBLOCK    0x000
        UNITS
        count
        Flags            ;byte to store indicator flags
        ENDC

;----------------------------------------------------------------------------
;This code executes when a reset occurs.

        ORG     0x0000        ;place code at reset vector

ResetCode:    bra    Main        ;go to beginning of program

;----------------------------------------------------------------------------
;This code executes when a high priority interrupt occurs.

        ORG    0x0008        ;place code at interrupt vector

HiIntCode:    ;do interrupts here

        reset            ;error if no valid interrupt so reset

;----------------------------------------------------------------------------
;This code executes when a low priority interrupt occurs.

        ORG    0x0018        ;place code at interrupt vector

LoIntCode:    ;do interrupts here

        reset            ;error if no valid interrupt so reset

;----------------------------------------------------------------------------
Main:
        movlw    0x60
        movwf    OSCCON
        bcf        ADCON0, 0
        setf    ADCON1
        clrf    PORTA
        clrf    LATA
        clrf    TRISA
;Set up for memory access
        bsf        EECON1, 7
        bsf        EECON1, 6
;------------------------------------------
; Rest of code here.....
;----------------------------------------
;show units routine called when needed with 0-9 in UNITS.
Show_Units:
        movlw    upper Seven_seg
        movwf    TBLPTRU
        movlw    high Seven_seg
        movwf    TBLPTRH
        movlw    low Seven_seg
        movwf    TBLPTRL
       
Digit:
        movf    UNITS, W    ;UNITS contains 0-9
        bcf     STATUS, C    ;prep for math
        addwfc    TBLPTRL, F    ;table pointer = table pointer +W
        clrf    WREG        ;
        addwfc    TBLPTRH, F
        addwfc    TBLPTRU, F
        tblrd*        ;read: no incrment of pointer
        movf    TABLAT, W
        movwf    PORTB    ;output data to port.
        return
;access table
;Store digits in memory
Seven_seg db 0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x19
        end
Working fine on Sim.
Max.
 
Last edited:

MaxHeadRoom

Joined Jul 18, 2013
28,757
Seven_seg is where the 0-9 digits are stored in memory with the 'db' instruction.
All you need to do is call the Show_Units routine with 0-9 in UNITS and it should return it in WREG.
TBLPTRx is the where the address of the look up table Seven_seg, 20 bit (3 byte wide memory locations) memory address is stored using movff.
Max.
 
Last edited:

MaxHeadRoom

Joined Jul 18, 2013
28,757
Its all there.
Go from Show_units to the very end, and this is the routine, nothing more.
This should replicate your original code?
It is a subroutine that needs to be called with the segment you want to display (0-9) pre-loaded in a Variable called UNITS
The routine I show will also output this segement value to the PORTB, but it is returned in W so you can put it where you want.
So say you call the routine with 0 (zero) in Units, it should return '00000011' as per your original lookup, from your original look up table there is no indication what you did with the value other than outputting to PORTB?
Max.
 
Last edited:
Try running it through MPLAB's built in simulator. Makes debugging that sort of thing easy. Any reason you don't want to use the much superior table instructions?
 

ErnieM

Joined Apr 24, 2011
8,377
Yes, because its working fine now, if i could use the table read instruction i would use it, but i don't know how to do it, and from the previous posts it looks like other people don't know either, or its not made easy. Why don't you look at my asm file and create one for me, that's what i have been trying to achieve, then i can see how its done. The datasheet is utter SHITE! in explaining it. Cheers Dave
Yeah, right. For custom jobs I accept payment thru PayPal IN ADVANCE of any work for 50% of the total, remainder upon receipt of work.
 
Yes, because its working fine now, if i could use the table read instruction i would use it, but i don't know how to do it, and from the previous posts it looks like other people don't know either, or its not made easy. Why don't you look at my asm file and create one for me, that's what i have been trying to achieve, then i can see how its done. The datasheet is utter SHITE! in explaining it. Cheers Dave
If you bothered reading through the link on my earilier post the Table instruction is laid out pretty clearly including an example. It's very easy and doesn't have page limitations the old RETW command has. Again learn to use the simulator and this should be a cakewalk.

Actually the PIC datasheets are not to tough but can be daunting, a good PIC book on the 18F would be worth a read.
 
Top