How can I exit my lookup table instruction with the desired value on PIC16F1829

不想你离开。 提交于 2021-01-29 08:19:34

问题


How can I get my code to work correctly when I include ADC conversion in it?

I have a working code that displays two digits on 2 LED displays using a p16f1829. However, a problem arises when I try to include a code block that collects the results of an ADC conversion to display on the LED display (see below).

A2D:
; Start the ADC
        NOP                         ; Requried ADC delay of 8uS => (1/(Fosc/4)) = (1/(500KHz/4)) = 8uS
        BANKSEL     ADCON0          ; Selects memory bank containing ADCON0 register 
        BSF         ADCON0, GO      ; Start the ADC
        BTFSC       ADCON0, GO      ; This bit will be cleared when the conversion is complete
        GOTO        $-1             ; Keep checking the above line until GO bit is clear

; Grab Results and write to the LEDs
        SWAPF       ADRESH, w       ; Get the top 4 MSbs (remember that the ADC result is LEFT justified!)
        MOVWF       L0
        RETURN

To be more precise, it seems to occur at the very point where I am trying to grab the corresponding value from the lookup table (see below):

The result in W-reg after that instruction should be 0x7D. However, it exits the Lookup table without returning the expected value.

The original working code without the ADC block is below:

    LIST        p=16f1829   ;list directive to define processor
    #INCLUDE    <p16f1829.inc>  ;processor specific variable definitions

    __CONFIG _CONFIG1, (_FOSC_INTOSC & _WDTE_OFF & _PWRTE_OFF & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF);
    __CONFIG _CONFIG2, (_WRT_OFF & _PLLEN_OFF & _STVREN_OFF & _LVP_OFF);

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

; UDATA_SHR declares a section of shared (all across the banks) uninitialised data
INT_VAR     UDATA_SHR   ; INT_VAR is the section name in ACCESS RAM
TempC       RES     1   ;
L0          RES     1   ;
w_temp      RES     1   ; variable used for context saving
pclath_temp     RES 1   ; variable used for context saving
status_temp RES     1   ; variable used for context saving

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

LEDtrisA    EQU     TRISA
LEDtrisC    EQU     TRISC
LEDlatA     EQU     LATA
LEDlatC     EQU     LATC

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

RESET_VECTOR    CODE    0x0000
        GOTO    START   ; When using debug header, ICD2 may not stop
                        ; on instruction 0 during reset.

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

INT_VECTOR      CODE    0x0004  ; Interrupt vector location
    
ISR             ; Relocatable Interrupt Service Routine
;   Context saving for ISR
    MOVWF   w_temp      ; save off current W register contents
    MOVF    STATUS, w   ; move status register into W register
    MOVWF   status_temp ; save off contents of STATUS register
    MOVF    PCLATH, w   ; Saves value in register PCLATH
    MOVWF   pclath_temp

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

;   If the interrupt came from the timer, execute the TMR0 interrupt 
;   service routine. 

    BANKSEL     TMR0
    MOVLW       .96
    MOVWF       TMR0
    BTFSC       INTCON, TMR0IF  
    CALL        Service_TMR0    
    BRA         UpdateDisplay   ; Refresh the display

UpdateDisplay
    BANKSEL     LATA        ; Selects memory bank containing LATA register 
    MOVF        LEDlatA, w  ; display status -> w register
    ANDLW       0x0f        ; Separate the lower half byte
    MOVWF       TempC       ; Save display status in TempC
    BSF         TempC, 4    ; Beginning status of LSD display
    RRF         TempC, F    ; Set the status of the next display
    BTFSS       STATUS, C   ; C = 1?
    BCF         TempC, 3    ; If not, turn off the LSD display
    BTFSC       TempC, 0

    BRA         UpdateMsd   ; If it is turned on, display the MSD
                            ; digit of the number
UpdateLsd
    BCF         TempC, 3    
    BSF         TempC, 1                
    BTFSS       STATUS, Z   ; If it is, skip
    MOVF        L0, w       ; Third LSD digit -> w
    ANDLW       0x0f        ;   /
    BRA         DisplayOut  ; Show it on the display

UpdateMsd
    SWAPF   L0, w       ; MSD figure - >
    ANDLW   0x0f        ;   /
    BTFSC   STATUS, Z   ; MSD = 0?
    MOVLW   0x0a        ; If it is, skip

DisplayOut
    CALL    LedTable    ; Take the mask for a digit
    MOVWF   LEDlatC     ; Set the mask on port B
    MOVF    TempC, W    ; Turn on displays
    MOVWF   LEDlatA
    BRA ISR_END

LedTable
    ADDWF   PCL, F
    RETLW   B'00111111' ; mask for digit 0
    RETLW   B'00000110' ; mask for digit 1
    RETLW   B'01011011' ; mask for digit 2
    RETLW   B'01001111' ; mask for digit 3
    RETLW   B'01100110' ; mask for digit 4
    RETLW   B'01101101' ; mask for digit 5
    RETLW   B'01111101' ; mask for digit 6
    RETLW   B'00000111' ; mask for digit 7
    RETLW   B'01111111' ; mask for digit 8
    RETLW   B'01101111' ; mask for digit 9
    RETLW   B'00000000' ; no digit ......

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

ISR_END
;   Restore contents before returning from interrupt    
    MOVF    pclath_temp,w   ; PCLATH is given its original content
    MOVWF   PCLATH
    MOVF    status_temp,w   ; STATUS is given its original content
    MOVWF   STATUS
    SWAPF   w_temp,f        ; W is given its original content
    SWAPF   w_temp,w

    BSF     INTCON,GIE  ; Global interrupt enabled
    RETFIE              ; Return from interrupt routine

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

MAIN_PROG   CODE

START

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

    ERRORLEVEL -302     ; Disable warning accessing register not in bank 0
    BANKSEL OSCTUNE     ; Configure OPTION_REG and TMR0
    MOVLW   0x00        ; Set oscillator to factory calibrated frequency
    MOVWF   OSCTUNE     ;
    BANKSEL STATUS
    ERRORLEVEL +302     ; Enable warning accessing register not in bank 0

CLEAR_RAM                   ; code sequence initialises all GPR's to 0x00   
    MOVLW       0x70        ; initialise pointer
    MOVWF       FSR0        ; to RAM
    CLRF        FSR0H

NEXT
    CLRF        INDF0       ; Clear INDF0 register
    INCF        FSR0L, F    ; Inc pointer
    BTFSS       FSR0L, 7    ; All done?
    GOTO        NEXT        ; No, clear NEXT

CONTINUE                    ; Yes, CONTINUE
    NOP

;-------------------------------------------------------------------------
; MAIN BODY OF PROGRAM
;-------------------------------------------------------------------------

; Setup main init
        BANKSEL     OSCCON      ; Selects memory bank containing OSCCON register 
        MOVLW       b'01011000'     ; Set CPU clock speed of 500KHz -> correlates to (1/(500K/4)) for each instruction
        MOVWF       OSCCON          ; OSCCON <- 0x38

; Setup pins as digital I/O 
    BANKSEL     ANSELA      ; Selects memory bank containing ANSELA register 
    CLRF        ANSELA      ; All pins are digital
    CLRF        ANSELC

; Configure the input & output pins 
    BANKSEL     TRISA           ; Selects memory bank containing TRISA register 
    MOVLW       b'11111100'     ; RA0 and RA1 are configured as outputs and
                                ; used for 7-segment display multiplexing
                                ; RA2 is input push-button for initialization
    MOVWF       TRISA
    CLRF        LEDtrisC    ; Port C is output


    BANKSEL     LATA        ; Selects memory bank containing LATA register 
    CLRF        LEDlatA     ; Set all outputs to "0"
    CLRF        LEDlatC ;
    BSF         LEDlatA, 1  ; Turn on MSD display 

; Setup Timer0 as the delay
    BANKSEL OPTION_REG
    MOVLW   b'10000100'     ; TMR0 is incremented each 32us (Fclk=8MHz)
    MOVWF   OPTION_REG  ; ps = 32

    BANKSEL     TMR0        ; Selects memory bank containing TMR0 register
    BSF         INTCON, GIE     ; Global interrupt enabled
    BSF         INTCON, TMR0IE  ; Timer TMR0 interrupt enabled

    MOVLW       0x79
    MOVWF       L0

MAINLOOP
    BRA         MAINLOOP    ; Continue forever

; TIMER 0 Interrupt routine clears the TMR0 interrupt flag.
Service_TMR0:
    BANKSEL     INTCON
    BCF         INTCON, TMR0IF  ; MUST ALWAYS clear this in software or else stuck in the ISR forever
    RETURN          

;-------------------------------------------------------------------------
; END OF PROGRAM
;-------------------------------------------------------------------------

    END         ; End of program   

I have tried all sorts and have currently a mental block on how to proceed. Any insights that anyone can provide will be very much appreciated.

来源:https://stackoverflow.com/questions/65621679/how-can-i-exit-my-lookup-table-instruction-with-the-desired-value-on-pic16f1829

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!