I'm trying to write a code in Atmel so I can control atmega32 PORTB's pins via switches connected to PINA, it works but there is only one problem, if one switch is left high and an another switch turns high the led connected(relates) to the second pin doesn't change, where did i go wrong?
#include <avr/io.h>
#include <util/delay.h>
#define F_CPU 1000000UL //Setting the CPU frequency to 1MHz
toggle(void){ //Creating a toggle function to call it within the main function
unsigned char input = 0x00; //Creating an 8-bit variable so we can save the input port
int t = 1; //Loop variable
while(PINA != 0x00){
t = t + 1;
_delay_ms(1);
if(t == 100) break;
}
while(t != 100){
if((PINA != 0x00) && (input !=PINA))
{
input = PINA;
PORTB = PORTB^input;
t = t + 1;
_delay_ms(1);
}
else if(input == PINA)
{
t = t + 1;
_delay_ms(1);
}
else if(PINA == 0x00){
t = t + 1;
_delay_ms(1);
input = PINA;
}
}
}
int main(void)
{
DDRA = 0x00; //Setting PORTA as input
DDRB = 0xFF; //Setting PORTB as output
DDRC = 0xFF; //Setting PORTC as output
DDRD = 0x02; //Setting PORTD.2 as output
PORTB= 0x00; //Setting PORTB's output to zero
PORTC= 0x00; //Setting PORTC's output to zero
PORTD= 0x02; //Setting PORTD.2's output to one
while (1)
{
PORTD= 0x02; //Turning on the PORTD LED
toggle(); //Toggling the PORTB's LEDs
PORTD= 0x00; //Turning off the PORTD LED
toggle(); //Toggling the PORTB's LEDs
} }
look at this section
while(PINA != 0x00){
t = t + 1;
_delay_ms(1);
if(t == 100) break;
}
while(t != 100){
//your algorithm body processed here
}
if one of switches (which connected to PORTA) is left high then the first while loop condition PINA != 0x00
is always true
the loop finish only when t==100
, then, when you go to the second while Loop it will not excite because the condition t != 100
is already false
in other words your toggle()
function will not process any data until you release all switches
I have made a simple code for what you try to do
int main(void)
{
DDRA = 0x00; //Setting PORTA as input
DDRB = 0xFF; //Setting PORTB as output
DDRC = 0xFF; //Setting PORTC as output
DDRD = 0x02; //Setting PORTD.2 as output
PORTB= 0x00; //Setting PORTB's output to zero
PORTC= 0x00; //Setting PORTC's output to zero
PORTD= 0x02; //Setting PORTD.2's output to one
unsigned char currentInput=PINA;
unsigned char previousInput=PINA;
unsigned char changedBitsMusk = 0;
while (1)
{
currentInput = PINA; //update current reading
changedBitsMusk = currentInput ^ previousInput; // calculate what is changed from previous reading
if (changedBitsMusk) // if there is change happen
{
if (currentInput&changedBitsMusk) // only process the data if change is HIgh (i.e only when button is pressed)
{
PORTB^=changedBitsMusk; // toggle the corresponding pins
}
}
previousInput = currentInput;
}
}