dylzad747
dylzad747

Reputation: 1

AVR ASM, EEPROM being written to before being specified

enter image description hereIm trying to build a digital safe using the ATMEGA32A micrcontroller. Ive read through the date sheet for read/ writes to EEPROM which is fine but my program seems to output random values to EEPROM( Even before I have specified what to write) Whats wrose is some values increment/ decrement throughout running the program. Can somebody with more experience in the area point me in the right direction?

; Define variables.
.def  TEMP  = r16
.def EEPROM = R17
.EQU SP = 0xDF
.def numberLocation = R19
.def numberActual = R20
.def keyPressed = R21
.def keyDisplayed = R22

; Reset Vector.
reset:
   rjmp start

;***********************************************************
; This program reads a single number from the keypad.
;***********************************************************
; Program starts here after Reset
start:
    //LDI TEMP, HIGH(RAMEND)
    //OUT SPH, TEMP
    //LDI TEMP, LOW(RAMEND)
    //OUT SPL, TEMP
    LDI TEMP, SP
    OUT 0x3D, TEMP


    CALL Init           ; Initialise the system.

loop:       
    ; Get a single key from the keypad and return it in R16 (temp)
    CALL ReadKey 
    
    ; Get what the current value is from the display and if it's Zero, do not display it (until a different value shows up) 
    CPI keyDisplayed, 0xFF
    BREQ loopBack

    ; Once the key has been recieved, put it on the PORTB leds.             
    CALL EEPROM_WRITE
    
loopBack:
    ; If this directive isn't used and BREQ is used on the loop, the program is bricked. 
    RJMP     loop           ; Do all again - You don't need to reinitialize

;************************************************************************
;
Init:
; uses:    R16
; returns: nothing
;
; Initialise the 16-key keypad connected to Port C
; This assumes that a 16-key alpha numeric keypad is connected to
; Port C as follows (see keypad data):
; Keypad   Function                      J2 pin
;  1      Row 1, Keys 1, 2, 3, A       1   PC0
;  2      Row 2, Keys 4, 5, 6, B       2   PC1
;  3      Row 3, Keys 7, 8, 9, C       3   PC2
;  4      Row 4, Keys *, 0, #, D       4   PC3
;  5      Column 1, Keys 1, 4, 7, *    5   PC4
;  6      Column 2, Keys 2, 5, 8, 0    6   PC5
;  7      Column 3, Keys 3, 6, 9, #    7   PC6
;  7      Column 4, Keys A, B, C, D    8   PC7

    ; Set the pull-up resistor values on PORTC.

    LDI TEMP, 0xF0
    OUT DDRC, TEMP

    LDI TEMP, 0x0F
    OUT PORTC, TEMP

    LDI TEMP, 0xFF
    OUT DDRB, TEMP

    LDI TEMP, 0x00
    OUT PORTB, TEMP

    CLR TEMP

    RET 
;************************************************************************
;
; ReadKey - Read a single digit from the keypad and store in TEMP
; Uses:  R16 (Temp)
; Returns: Temp
;
 ReadKey:
    RCALL   ReadKP          ; Read one number from keypad and return in Temp (R16)
    RET                     ; Exit back to calling routine
;
;********************************************************************
; ReadKP will determine which key is pressed and return that key in Temp
; The design of the keypad is such that each row is normally pulled high
; by the internal pullups that are enabled at init time
;
; When a key is pressed contact is made between the corresponding row and column.
; To determine which key is pressed each column is forced low in turn
; and software tests which row has been pulled low at micro input pins
;
; To avoid contact bounce the program must include a delay to allow
; the signals time to settle
;
ReadKP:
        
    LDI ZH, high(keyTable << 1)
    LDI ZL, low(keyTable << 1)  

    LDI TEMP, 0xEF
    OUT PORTC, TEMP
    //CALL Delay
    IN keyPressed, PINC
    CP keyPressed, TEMP
    BRNE ReadLoop

    LDI TEMP, 0xDF
    OUT PORTC, TEMP
    //CALL Delay
    IN keyPressed, PINC
    CP keyPressed, TEMP
    BRNE ReadLoop

    LDI TEMP, 0xBF
    OUT PORTC, TEMP
    //CALL Delay
    IN keyPressed, PINC
    CP keyPressed, TEMP
    BRNE ReadLoop

    LDI TEMP, 0x7F
    OUT PORTC, TEMP
    //CALL Delay
    IN keyPressed, PINC
    CP keyPressed, TEMP
    BRNE ReadLoop

    RET

ReadLoop:
    LPM numberActual, Z+
    INC numberLocation
    CP numberLocation, keyPressed
    BRNE ReadLoop
    LPM numberActual, Z
    MOV keyPressed, numberActual 
    MOV keyDisplayed, keyPressed
    CLR numberActual
    CLR numberLocation
    //CALL Delay
    RET
;************************************************************************
;
; Takes whatever is in the Temp register and outputs it to the LEDs
//EEPROM write function, gets KEYPRESSED and stores in EEPROM (eight values 
Display:
        OUT PortB, keyDisplayed
        RET
;*************************************
;
; Delay routine
;
; this has an inner loop and an outer loop. The delay is approximately
; equal to 256*256*number of inner loop instruction cycles.
; You can vary this by changing the initial values in the accumulator.
; If you need a much longer delay change one of the loop counters
; to a 16-bit register such as X or Y.
;
;*************************************
Delay:
    PUSH R16            ; Save R16 and 17 as we're going to use them
    PUSH R17            ; as loop counters
    PUSH R0         ; we'll also use R0 as a zero value
    CLR R0
    CLR R16         ; Init inner counter
    CLR R17         ; and outer counter
L1: 
    DEC R16         ; Counts down from 0 to FF to 0
    CPSE R16, R0    ; equal to zero?
    RJMP L1         ; If not, do it again
    CLR R16         ; reinit inner counter
L2: 
    DEC R17
    CPSE R17, R0    ; Is it zero yet?
    RJMP L1         ; back to inner counter

    POP R0          ; Done, clean up and return
    POP R17
    POP R16
    RET


EEPROM_WRITE:

SBIC EECR, EEWE
RJMP EEPROM_WRITE

LDI R17, 0x00
OUT EEARH, R17
LDI R17, 0x10
OUT EEARL, R17

OUT EEDR, KeyDisplayed
SBI EECR, EEMWE
SBI EECR, EEWE

INC EEPROM
rjmp EEPROM_WRITE

keyTable:

;    0     1     2     3     4     5     6     7     8     9     A     B     C     D     E     F
.db 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff ; O TO 0F
.db 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff; 1O TO 1F
.db 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff; 2O TO 2F
.db 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff; 3O TO 3F

.db 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff; 4O TO 4F
.db 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff; 5O TO 5F
.db 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff; 6O TO 6F
.db 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0d, 0xff, 0xff, 0xff, 0x0c, 0xff, 0x0b, 0x0a, 0xff; 7O TO 7F

.db 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff; 8O TO 8F
.db 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff; 9O TO 9F
.db 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff; AO TO AF
.db 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x12, 0xff, 0xff, 0xff, 0x09, 0xff, 0x06, 0x03, 0xff; BO TO BF

.db 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff; CO TO CF
.db 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0x08, 0xff, 0x05, 0x02, 0xff; DO TO DF
.db 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x2a, 0xff, 0xff, 0xff, 0x07, 0xff, 0x04, 0x01, 0xff; EO TO EF
.db 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff; FO TO FF

I thought it might have something to do with the stack pointer initilisaion but changing that has not seemed to fix anything. Taking the EEPROM code block out into another confirms that it is working as intended.

Upvotes: 0

Views: 64

Answers (0)

Related Questions