Reputation: 1
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