【问题标题】:How do I clear the RAM correctly when using indirect addressing with PIC16F1829使用 PIC16F1829 间接寻址时如何正确清除 RAM
【发布时间】:2021-01-04 10:40:45
【问题描述】:

在使用 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

【问题讨论】:

    标签: debugging assembly microcontroller pic microchip


    【解决方案1】:

    答案是你的代码:

    ; 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.
    

    【讨论】:

    • 非常感谢。我整天都在扯头发,试图找出是我做错了,尽管我知道共享变量,但我从未想过要这样声明它们。澄清一下,在UDATA和UDATA_SHR下声明变量,除了刚才学到的教训,还有其他区别吗?
    • @aLoHa,最重要的是公共(共享)RAM 很小。对于 PIC16F1829,它是 16 字节,当使用在线调试作为 ICD 工具时需要一个公共 RAM 位置来保存断点的上下文。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-16
    • 1970-01-01
    • 2012-11-12
    • 2019-07-25
    相关资源
    最近更新 更多