#debugging #assembly #microcontroller #pic #microchip
#отладка #сборка #микроконтроллер #рис #микросхема
Вопрос:
Как вы очищаете оперативную память и правильно инициализируете регистр FSR0 при использовании косвенной адресации с PIC16F1829?
Код работает. Моя проблема в том, что при отладке переменные (т. Е. Delay1 и Delay2 в данном случае), значения которых должны храниться по адресам 0x70 и 0x71, сохраняются в 0x120 и 0x121 соответственно, несмотря на регистр FSR0, содержащий адрес 0x70.
Я не знаю, что я пропустил, так как существует не так много примеров использования 16-битного регистра FSR. Поэтому любая помощь, которую кто-либо может оказать, будет очень признательна.
LIST p=16f1829 ;list directive to define processor
#INCLUDE <p16f1829.inc> ;processor specific variable definitions
__CONFIG _CONFIG1, (_FOSC_INTOSC amp; _WDTE_OFF amp; _PWRTE_OFF amp; _MCLRE_OFF amp; _CP_OFF amp; _CPD_OFF amp; _BOREN_ON amp; _CLKOUTEN_OFF amp; _IESO_OFF amp; _FCMEN_OFF);
__CONFIG _CONFIG2, (_WRT_OFF amp; _PLLEN_OFF amp; _STVREN_OFF amp; _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
Ответ №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.
Комментарии:
1. Большое спасибо за это. Я весь день рвал на себе волосы, пытаясь понять, что я поступил неправильно, и хотя я знал об общих переменных, мне никогда не приходило в голову объявлять их такими. Для пояснения, существуют ли какие-либо другие различия между объявлением переменных в UDATA и UDATA_SHR, помимо только что усвоенного урока?
2. @aLoHa, самое главное, что общая (общая) оперативная память мала. Для PIC16F1829 это 16 байт, 15 байт при использовании внутрисхемной отладки, поскольку для инструмента ICD требуется одно общее местоположение ОЗУ для сохранения контекста для точек останова.