MPLAB X IDE code for PIC18F452 microcontroller (indirect addressing)

152 Views Asked by At

Using Indirect addressing I'm trying to copy the value 77H into RAM memory locations 50H to 55H. The issue I'm running into is a build error where it says FSR and INDF are not previously defined values. When I try to specify them as as symbols then I dont get the expected results. Instead off loading 77H to 50H-55H I get 77 in 00H and 55 in 04H. I'm using a PIC18F452 in the MPLAB X IDE for reference.

P.S. This is using MPLAB X IDE version 4.01 as directed by my school due to the mpasm assembler not being available in later versions

EDIT I tried correcting again based on comments. It completes the build now without error but its not storing in the memory locations 50H-55H like I want it to:

I tried correcting again based on your advise, its building without error now but there's nothing stored in any memory locations let alone 50H-55H

INCLUDE <P18F452.INC>

ORG   0x00         ; Define the start of the code at address 0x00    
; Load value 77H into WREG  
MOVLW 77H 
; Load FSR0 register with the starting address (50H) 
MOVLW 50H      ; Load low byte of the address into WREG 
MOVWF FSR0L    ; Move WREG to FSR0L register 
MOVLW 00H      ; Load high byte of the address into WREG
MOVWF FSR0H    ; Move WREG to FSR0H register
; Copy the value from WREG into RAM using register indirect addressing mode 
MOVWF INDF0    ; Copy 77H to location 50H
INCF  FSR0L,F   ; Increment FSR0L to point to the next location (51H) 
MOVWF INDF0    ; Copy 77H to location 51H 
INCF  FSR0L,F   ; Increment FSR0L to point to the next location (52H)   
MOVWF INDF0    ; Copy 77H to location 52H 
INCF  FSR0L,F   ; Increment FSR0L to point to the next location (53H)  
MOVWF INDF0    ; Copy 77H to location 53H 
INCF  FSR0L,F   ; Increment FSR0L to point to the next location (54H) 
MOVWF INDF0    ; Copy 77H to location 54H
INCF  FSR0L,F   ; Increment FSR0L to point to the next location (55H) 
MOVWF INDF0    ; Copy 77H to location 55H
END
"

Original code: "

ORG   0x00         ; Define the start of the code at address 0x00
MOVLW 50H        ; Load FSR with 50H  
MOVWF FSR        ; Set FSR to 50H 
MOVLW 77H        ; Load WREG with 77H  
MOVWF INDF       ; Copy WREG (77H) to memory location pointed by FSR (50H)  
INCF  FSR, F      ; Increment FSR to point to 51H 
MOVLW 77H        ; Load WREG with 77H
MOVWF INDF       ; Copy WREG (77H) to memory location pointed by FSR (51H)  
INCF  FSR, F      ; Increment FSR to point to 52H    
MOVLW 77H        ; Load WREG with 77H    
MOVWF INDF       ; Copy WREG (77H) to memory location pointed by FSR (52H)    
INCF  FSR, F      ; Increment FSR to point to 53H    
MOVLW 77H        ; Load WREG with 77H    
MOVWF INDF       ; Copy WREG (77H) to memory location pointed by FSR (53H)    
INCF  FSR, F      ; Increment FSR to point to 54H    
MOVLW 77H        ; Load WREG with 77H  
MOVWF INDF       ; Copy WREG (77H) to memory location pointed by FSR (54H)   
INCF  FSR, F      ; Increment FSR to point to 55H    
MOVLW 77H        ; Load WREG with 77H    
MOVWF INDF       ; Copy WREG (77H) to memory location pointed by FSR (55H)    
END         

How I tried to correct it:

ORG   0x00         ; Define the start of the code at address 0x00

FSR   equ 0x04      ; Define FSR as a symbol representing address 0x04    
INDF  equ 0x00     ; Define INDF as a symbol representing address 0x00    
MOVLW 50H        ; Load WREG with 50H    
MOVWF FSR        ; Set FSR to 50H    
MOVLW 77H        ; Load WREG with 77H    
MOVWF INDF       ; Copy WREG (77H) to the memory location pointed by FSR (50H)    
INCF  FSR, F      ; Increment FSR to point to 51H    
MOVLW 77H        ; Load WREG with 77H    
MOVWF INDF       ; Copy WREG (77H) to the memory location pointed by FSR (51H)    
INCF  FSR, F      ; Increment FSR to point to 52H    
MOVLW 77H        ; Load WREG with 77H    
MOVWF INDF       ; Copy WREG (77H) to the memory location pointed by FSR (52H)    
INCF  FSR, F      ; Increment FSR to point to 53H    
MOVLW 77H        ; Load WREG with 77H    
MOVWF INDF       ; Copy WREG (77H) to the memory location pointed by FSR (53H)    
INCF  FSR, F      ; Increment FSR to point to 54H    
MOVLW 77H        ; Load WREG with 77H    
MOVWF INDF       ; Copy WREG (77H) to the memory location pointed by FSR (54H)    
INCF  FSR, F      ; Increment FSR to point to 55H    
MOVLW 77H        ; Load WREG with 77H   
MOVWF INDF       ; Copy WREG (77H) to the memory location pointed by FSR (55H)    
END

What my registers are reading: enter image description here

I need it to read 77H in memory locations 50H-55H and utilize indirect addressing.

2

There are 2 best solutions below

0
Rameau On

You are not writing to FSR0L here:

        ORG     0x0     ; 
        MOVLW   50H     ; W = 50h 
        MOVWF   FSR0L   ; @E9h (general purpose register in bank 0) = W 
        ...

RAM address you are writing to in "MOVWF FSR0L" instruction is a combination of: upper 4 bits (BSR << 8) and lower 8 bits (FSR0L & 0xFF). BSR is cleared after reset (POR, BOR) so you are writing to address 0x0E9 instead of 0xFE9.

SFRs are located in bank 15 and MPASM uses BSR (bank select register) by default when you omit RAM access bit in assembly instruction.

You can switch to bank 15 first:

        ...
        MOVLB   15      ; BSR = 15
        MOVLW   50H     ; W = 50h
        MOVWF   FSR0L   ; @0FE9h (FSR0L) = W 
        ...

or use access bank (RAM access bit a=0):

        ...
        MOVLW   50H     ; W = 50h
        MOVWF   FSR0L,0 ; @0E9h (FSR0L address in access bank) = W       
        ...

Check out MPASM assembler documentation: 33014j.pdf, page 251 table A.6

0
Kozmotronik On

Although the MPASM assembler compiler is case insensitive, there may be some exceptions for the expressions other than the op-codes. The chip's include file name is one of them. You should've written the file name in lower case form:

INCLUDE <p18f452.inc>
; or
include <p18f452.inc>
; or
INCLUDE "p18f452.inc"
; or
include "p18f452.inc"
; or
#include "p18f452.inc"

But your version was:

INCLUDE <P18F452.INC>

Otherwise you will get undefined symbols error.

The code you get before your edit is written for the PIC models which has only one set of indirect addressing registers. That's why the register names do not have numbers like FSR0 but only the name. However the PIC18F452 has 3 sets of indirect addressing registers, hence their name should be unique. That's why their name have numeric suffixes like FSR0, FSR1... FSRn etc.
Moreover, the PIC18 devices are more enhanced and have more features than PIC12 and PIC16 devices. As you will see in code they have a specific instruction to load the FSRn registers which is LFSR, also more operational mode registers like POSTINCn POSTDECn registers which increments or decrements respectively the FSRn register automatically after the data is written to the target. Considering this, the code will not be portable to PIC16 and PIC12 devices.
For anything about the specific device you use, you better to refer to its datasheet to get more specific information of any kind. For example you can refer to section 4.12 for more information on indirect addressing mode.

Now that we have some background about the indirect addressing mode, we can code the the solution. I provide you the solution both with straight code for faster execution and with a loop for compact code.

Straight (faster) version

    #include "p18f452.inc"
    
    ORG 0

    ; Load the starting address to the FSR0 registers
    LFSR    FSR0, 50H

    ; Load the data from 0x50 to 0x55 locations
    MOVLW   77H
    MOVWF   POSTINC0 ; Write the value and autoincrement the FSR
    MOVWF   POSTINC0
    MOVWF   POSTINC0
    MOVWF   POSTINC0
    MOVWF   POSTINC0
    MOVWF   INDF0 ; No need to increment since this is the last one
    
    GOTO    $ ; Halt here
    END

Compact (loop) version

    #include "p18f452.inc"
    
    ORG 0

    ; Load the starting address to the FSR0 registers
    LFSR    FSR0, 50H

    ; Load the data from 0x50 to 0x55 locations
    NEXT:
    MOVLW   77H
    MOVWF   POSTINC0
    MOVLW   55H
    CPFSGT  FSR0L ; Has the location address 55h loaded with data
    GOTO    NEXT ; No, not reached to 55h address yet, keep loading
    
    GOTO    $ ; Halt here
    END

The code is tested in MPLABX v4.01 and here is a picture that shows the end result. indirect addresing result