Problems with program counter and lookup table

Thread Starter

wannaBinventor

Joined Apr 8, 2010
180
I've got a program that has an ADC measurement transmitted to it. I've gotten that to work great as evidenced by clearing or setting bits on a port with LED attached to each an giving a BCD of what the measurement was.

Now I'm trying to send that to an LCD display by way of a lookup table. Long story short, I'm receiving a temp reading, then breaking it out into the tens place and the ones place. From there, the program will clock each number individually into the display. So I'm getting the measurement, extracting the tens place number, sending that to the W reg, then calling a lookup table which adds the w reg to the program counter: (memory address 02 in the PIC16F818). The problem is MPLAB SIM shows it skipping off widely, but consistently, do a different part of the code. I understand the program counter at address 02 to be the lower 8 bits, so if its 132 and I add 12 the PC should increment to 144, but this is not happening at all. I've even got a book that I've read that says its suppose to happen that way, but no dice.

Below is a snip of the code. I'm making calls from within the lookup table so my numbers will clock into the LCD, with a RETLW 0 between each one so it doesn't keep calling everything below it if the W+PC puts it at the beginning of the table.

Rich (BB code):
TMR0            EQU         1           ;means TMR0 is file 1.  
PC                EQU            2            ;means Program Counter is file 2.
STATUS          EQU         3           ;means STATUS is file 3.        
PORTA           EQU         5              ;means PORTA  is file 5.        
PORTB           EQU         6           ;means PORTB is file 6. 
ZEROBIT         EQU         2           ;means ZEROBIT is bit 2.        
ADCON0          EQU         1FH           ;A/D Configuration reg.0
ADCON1          EQU         9FH           ;A/D Configuration reg.1
ADRES           EQU         1EH         ;A/D Result register.
CARRY           EQU         0           ;CARRY IS BIT 0.
TRISA            EQU            85H            ;PORTA Configuration Register
TRISB            EQU            86H            ;PORTB Configuration Register 
OPTION_R         EQU            81H            ;Option Register
OSCCON            EQU            8FH            ;Oscillator control register.
CCPR1L            EQU            15H
CCPR1H            EQU            16H
CCP1CON            EQU            17H
PR2                EQU            92H 
T2CON            EQU            12H
TMR2            EQU            11H
;USER FILES ARE BELOW
COUNT           EQU         20H         ;COUNT a register to count events.
COUNTERA        EQU            21H
COUNTERB        EQU            22H
COUNTERC        EQU            23H            
RCVDNUM            EQU            24H   
NUMERATOR        EQU            25H
DIVISOR            EQU            26H
ANSWER            EQU            27H
REMAINDER        EQU            28H
MULTIPLIER        EQU            29H
MULTWORK        EQU            30H

;********************************************

    LIST        P=16F818             ;we are using the 16F818.
    ORG         0                   ;the start address in memory is 0
    GOTO          START               ;goto start!

;;;SUBROUTINE SECTION  (abbreviated for posting here)

;PIC Time Delay = 0.00012700 s with Osc = 4000000 Hz
;this should be same time as NOP on 31.25KHz

CLKDLAY    movlw    D'42'
        movwf    COUNTERA
LOOPNOP    decfsz    COUNTERA,1
        goto    LOOPNOP
        RETLW    0

CLOCK   BSF        PORTA,4
        CALL    CLKDLAY                ;SUBSTITUTED FOR "NOP" WHICH          WORKS ON 32.25KHZ BUT NOT ON 4MHZ
        BCF     PORTA,4
        CALL    CLKDLAY                ;SUBSTITUTED FOR "NOP" WHICH WORKS ON 32.25KHZ BUT NOT ON 4MHZ
        RETLW   0

HERE ARE THE LOOKUP TABLES THAT SEEM TO BE GOING WILD IN THE SIMULATOR

TENSLU    ADDWF    PC            ;ADD W TO PROGRAM COUNTER
        CALL    NUM0        ;0 ADDED    
        RETLW    0            ;1 ADDED
        CALL    NUM1        ;2 ADDED    
        RETLW    0            ;3 ADDED
        CALL    NUM2        ;4
        RETLW    0            ;5
        CALL    NUM3        ;6
        RETLW    0            ;7
        CALL    NUM4        ;8
        RETLW    0            ;9
        CALL    NUM5        ;10
        RETLW    0            ;11
        CALL    NUM6        ;12
        RETLW    0            ;13
        CALL    NUM7        ;14
        RETLW    0            ;15
        CALL    NUM8        ;16
        RETLW    0            ;17
        CALL    NUM9        ;18
        RETLW    0            ;19

ONESLU    ADDWF    PC            ;ADD W TO PROGRAM COUNTER
        CALL    NUM0        ;0 ADDED    
        RETLW    0            ;1 ADDED
        CALL    NUM1        ;2 ADDED    
        RETLW    0            ;3 ADDED
        CALL    NUM2        ;4
        RETLW    0            ;5
        CALL    NUM3        ;6
        RETLW    0            ;7
        CALL    NUM4        ;8
        RETLW    0            ;9
        CALL    NUM5        ;10
        RETLW    0            ;11
        CALL    NUM6        ;12
        RETLW    0            ;13
        CALL    NUM7        ;14
        RETLW    0            ;15
        CALL    NUM8        ;16
        RETLW    0            ;17
        CALL    NUM9        ;18
        RETLW    0            ;19


;abbreviated program, with just the affected area.  all else works properly in MPLAB SIM

        MOVF    REMAINDER,W            ;WHERE THE CORRESPONDING NUMBER IS CLOCKED IN
        MOVWF    MULTIPLIER
        MOVLW    .2                    ;MULTS REMAINDER BY TWO FOR THE LU TABLE
        CALL    MULTPLY
        MOVF    MULTIPLIER,W
        CALL    ONESLU                ;DISPLAY THE # FROM THE ONES PLACE
        
        CALL    DEG                    ;DISPLAY DEGREE SYMBOL
        CALL    F                    ;DISPLAY AN "F"    

        CALL    SECDLAY                ;THESE DELAYS WILL DISPLAY THE TEMP FOR 5 SECS
        CALL    SECDLAY
        CALL    SECDLAY
        CALL    SECDLAY
        CALL    SECDLAY
        GOTO    BEGIN
As always, thank you very much for the help.

I should add that the watch window shows the value of PC becoming W + PC + 1 instruction, but obviously something else is wrong because its obviously affecting the program. Also, I noticed that I didn't add a "direct command" (0,1/w,f) after ADDWF PC, but I have sense added that into the command with the same result.
 
Last edited:

Markd77

Joined Sep 7, 2009
2,806
The problem is almost certainly that the table is not in the first memory page.
For more info download AN556 from the microchip site.
It should explain all.
 

Thread Starter

wannaBinventor

Joined Apr 8, 2010
180
SUCCESS!

Thanks for the help there. I love this place. I don't think I had to wait 10 minutes for a solution.

I don't really fully understand AN556, but I did move my tables to the top of my subroutine section and MPLAB SIM seems to be happy with that.

I would like to try and understand what AN556 is saying, however.

When I look at my code in MPLAB ASM, how do I know what memory page a particular line or subroutine is in?

Does the "memory page" that I am at in the code when I make the call matter if the lookup table is always on page 0?

I've looked on the datasheet in the memory organization section. I'm having trouble deciphering what the page breaks are in memory.

This is code from AN556:
Rich (BB code):
EXAMPLE 3A:
org 0x80
movlw HIGH Table
movwf PCLATH
movlw offset
call Table
.
.
.
org 0x320
Table:
addwf PCL,F
retlw ’A’
retlw ’B’
Is the "org 0x80" and "org 0x320" actually required in the code, or is it just telling the reader where that piece of memory is for demonstrative purposes.
I'm assuming "MOVLW HIGH TABLE" means to move a literal value to W that is equivalent to the memory page that the table is on. Is this correct?

Thanks for the help. Much appreciated.
 

Markd77

Joined Sep 7, 2009
2,806
If you look at the disassembly listing view, you can work out which page it is in, 0-255 is page 0, etc. Or you can look at PCLATH while stepping through code.
It doesn't matter where you call it from unless you are using more than 2K of program memory.
The ORGs are just for demo purposes, but it can be useful to put a table at the start of the last page (for example) if you don't want it to cross a boundary and don't want to keep track of it.
The assumption about HIGH is correct - it gets the high byte from a 16bit number.
 
Last edited:
Top