I have a program that's supposed to read input values from a dip switch connected to PORTA and when button on PC0 is pressed, then it outputs the bits to the LEDs on PORTB, or if PC7 is pressed, then it shows up in PORTD. When PC3 is pressed, it's supposed to multiply both bytes for a 16-bit value stored as a high and low bytes.
The issue is that once I press the button once, the result does show up in the LEDs. However, after the first button press, the logic stops working. For example, when switching input on PORTA, it still shows up in the LEDs regardless of whether the button is pushed or not.
I cannot pinpoint where the issue is exactly and I really need help debugging this.
I'm using an atmega32, programming in Atmel studio, and simulating in Proteus.
I appreciate any help.
.cseg
.org 0x0000
; set stack pointer
ldi r29, low(ramend)
out spl, r29
ldi r29, high(ramend)
out sph, r29
start:
ser r16
out ddrb, r16 ; portb output
out ddrd, r16 ; portd output
clr r16
out ddra, r16 ;porta input
out ddrc, r16 ;portc input
ser r16
out portc, r16 ;pull-up resistor on PORTC
rjmp main
main:
sbic pinc, 0 ;skip if button is not pressed on PC0
call Load_Low ;call subroutine function to load the lower bit
sbic pinc, 7
call Load_High ;call subroutine function to load the higher bit
sbic pinc, 3
call Multiply ;call subroutine function to multiply both stored values
rjmp main
Load_High:
in r20, pina ;read bits in PINA to R20
mov r30, r20 ;store copy
out portb, r30 ;output to LEDs on PORTB
cbi portc, 0 ;clear bit
ret
Load_High:
in r20, pina
mov r31, r20
out portd, r31
cbi portc, 7
ret
Multiply:
mul r31, r30
out portd, r0
out portb, r1
cbi portc, 3
ret
In the schematics there is no pull-down resistor which could make a low logical level when the button is released. Therefore voltage is undefined, in real life voltage will be floating causing unexpected logical level change on the inputs.
Instead of adding external pull-down resistors you can connect buttons to the "GND" and engage internal pull-up resistors (setting corresponding bits of PORTC
to 1 while in DDRC
those bits are 0)
Also in all your routines there are strange lines without explanation:
cbi portc, 0 ;clear bit
cbi portc, 7
cbi portc, 3
those are the button inputs, why you're clearing PORTC
bits each time?