首页 > 解决方案 > 使用 PIC16F1829 间接寻址时如何正确清除 RAM

问题描述

使用 PIC16F1829 间接寻址时,如何正确清除 RAM 并初始化 FSR0 寄存器?

该代码有效。我的问题是,在调试时,尽管 FSR0 寄存器保存 0x70 地址,但其值应存储在地址 0x70 和 0x71 的变量(即本例中的 Delay1 和 Delay2)分别存储在 0x120 和 0x121。

在此处输入图像描述

我不知道我错过了什么,因为使用 16 位 FSR 寄存器的例子并不多。因此,任何人都可以提供的任何帮助将不胜感激。

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 declares a section of uninitialised data
VARIABLES   UDATA       ; VARIABLES is the name of the section of memory
Delay1      RES 1       ; uninitialised data, placed by linker in GPR's.
Delay2      RES 1       ; uninitialised data, placed by linker in GPR's.


;-------------------------------------------------------------------------
; RESET VECTOR
;-------------------------------------------------------------------------

RESET_VECTOR    CODE    0x0000
    GOTO    START   

;-------------------------------------------------------------------------
; INTERRUPT SERVICE ROUTINE
;-------------------------------------------------------------------------

INT_VECTOR  CODE    0x0004  ; Interrupt vector location
    GOTO    START

;-------------------------------------------------------------------------
; MAIN PROGRAM
;-------------------------------------------------------------------------

MAIN_PROG   CODE

START

;-------------------------------------------------------------------------
; SET OSCILLATOR TO FACTORY FREQUENCY AND CLEAR GPR's
;-------------------------------------------------------------------------

    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 to RAM
    MOVWF   FSR0L
    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

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

; Configure the LEDs        
    BCF     TRISC,0             ; Make I/O Pin C0 an output for DS1
    
    BANKSEL LATC            ; Selects memory bank containing LATC
    CLRF    LATC            ; Start by turning off all of the LEDs

MAINLOOP:
    BSF LATC, 0         ; Turn LED on
 
ONDELAYLOOP:
    DECFSZ  Delay1,f        ; Waste time.
    BRA     ONDELAYLOOP     ; The Inner loop takes 3 instructions per loop * 256 loops = 768 instructions
    DECFSZ  Delay2,f        ; The outer loop takes an additional 3 instructions per lap * 256 loops
    BRA     ONDELAYLOOP     ; (768+3) * 256 = 197376 instructions / 125K instructions per second = 1.579 sec.
    BCF     LATC,0          ; Turn off LED C0 - NOTE: do not need to switch banks with 'banksel' since bank2 is still selected

OFFDELAYLOOP:
    DECFSZ  Delay1,f        ; same delay as above
    BRA     OFFDELAYLOOP
    DECFSZ  Delay2,f
    BRA     OFFDELAYLOOP
    BRA     MAINLOOP        ; Do it again...

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

    END         ; End of program

标签: debuggingassemblymicrocontrollerpicmicrochip

解决方案


答案是您的代码:

; UDATA declares a section of uninitialised data
VARIABLES   UDATA       ; VARIABLES is the name of the section of memory
Delay1      RES 1       ; uninitialised data, placed by linker in GPR's.
Delay2      RES 1       ; uninitialised data, placed by linker in GPR's.

告诉汇编器将这些放在存储区内存中。

要将数据放在公共(非存储)内存中,请将此语法与 MPASM 一起使用:

; UDATA_SHR declares a section of uninitialised data common to all banks
VARIABLES   UDATA_SHR   ; VARIABLES is the name of the section of memory
Delay1      RES 1       ; uninitialised data, placed by linker in GPR's.
Delay2      RES 1       ; uninitialised data, placed by linker in GPR's.

推荐阅读