I am using AVR AtMega 32, and developed a driver for the GPIO of the microcontroller.
On start up, the LED is OFF. The following code's purpose is to toggle a LED only once if a switch (dip switch or push button) is pressed, and if it is not pressed the LED's state (On/OFF) remains the same.
Meaning that on startup the LED is OFF, if the switch is pressed the LED should turn ON, if the switch is pressed again the LED should turn OFF again, and so on.
At any one of the two states of LED(ON/OFF), if the switch is released the LED remains on its state ON or OFF. But the code wrongly turns the LED ON if the switch is pressed and turns it OFF if the switch is released.
int main(void) { Bool received; uint8 sw_count = 0; GPIO_init(PORTA_ID, GPIO_LOW, GPIO_INPUT); GPIO_init(PORTB_ID, GPIO_LOW, GPIO_INPUT); GPIO_init(PORTC_ID, GPIO_LOW, GPIO_INPUT); GPIO_init(PORTD_ID, GPIO_LOW, GPIO_INPUT); GPIO_writePinVal(PORTB_ID, P0, GPIO_HIGH); GPIO_setPinDir(PORTC_ID, P0, GPIO_OUTPUT); GPIO_writePinVal(PORTC_ID, P0, GPIO_HIGH); GPIO_setPinDir(PORTC_ID, P7, GPIO_OUTPUT); GPIO_writePinVal(PORTC_ID, P7, GPIO_HIGH); while(1) { GPIO_readPinVal(PORTB_ID, P0, &received); if(received == GPIO_LOW) { sw_count++; if(sw_count == 1) { GPIO_togglePinVal(PORTC_ID, P0); } } else { sw_count = 0; } } return 0; }
Please forget about the details of the functions like GPIO_init, GPIO_writePinVal, their code is long to place here. These functions work properly, I tested them. The switch is connected on Port B pin 0 and the LED is connected on Port C pin 0. The switch gives LOW to the AVR if it is pressed, and the AVR used its pull-up feature if it is not pressed. The LED is connected in a negative logic manner, a LOW from the AVR turns it ON and a HIGH turns it OFF. I used port C pin 7 to produce a HIGH signal to use it as the VCC for the LED.
The code is supposed run like that :
1. In the beginning of the program, 'received' variable has a value of "HIGH", when the switch is not pressed.
2. The loop continues until sometime the switch is pressed, the 'received variable' gets a value of 'LOW' and sw_count gets a value of 1(increments).
3. The if condition makes the LED to toggle,.
4. While the switch is still pressed, the loop continues increasing sw_count greater than 1, which makes the if(received == GPIO_LOW) condition be entered but the if(sw_count == 1) condition be skipped, so nothing should happen.
5. The loop continues incrementing sw_count and nothing happens, until the switch is released sometime.
6. Now the else clause in the outer if condition executes, assigning sw_count to 0.
7. The 0 value fo sw_count continues until the switch is pressed again, now sw_count increments to 1 and toggles the LED. And so on.
May anybody clarify the problem for me please ?