ATMega32 switch code is extremely simple to implement, and this article looks into how to write the code to make an LED light up when a switch is pressed. The atmega32-switch-code.c program tests the switch input to the ATMega32 Development System. There are many ways to write the code, but I have chosen the simplest way possible so everyone can understand. Therefore, instead of using “case”, I am using “if”, in C programming.
In this system, each switch has a LED behind it, and I have written this code so that when you press a switch, the LED behind it lights up. It functions as a mechanical push-button selector, or a locking switch, because you need to press the same switch again to turn OFF the LED.
Bit Operators in C
1: PORTC |= 0x01; // Set bit 0 only.
2: PORTC &= ~0x01; // Clear bit 0 only.
3: PORTC ^= 0x01; // Toggle bit 0 only.
4: PORTC & 0x01; // Test bit 0 only.
5: PORTC |= 0x80; // Set bit 7 only.
You can set, toggle, clear, and test, bits using bit operators as shown above. However, as you can see, the bit masks are in hexadecimal and not very human friendly to read.
Avr-libc has a special macro known as Bit Value, and a function “_BV ()”, which takes the bit number and converts it to the appropriate bit mask. By using this macro, it is possible to specify the actual bit number without having to figure out the bit mask in hexadecimal. Therefore, it makes programming easier.
1: TCCR2 = _BV(COM20)|_BV(CTC2)|_BV(CS20);
2: DDRD = _BV(PD7);
Is the same as
1: TCCR2 = (1<<COM20)|(1<<CTC2)|(1<<CS20);
2: DDRD = (1<<PD7);
_BV The User Friendly Macro
1: PORTC |= _BV(2); // Set bit 2 only.
2: PORTC &= ~(_BV(1)); // Clear bit 1 only.
3: PORTC ^= _BV(5); // Toggle bit 5 only.
As you can see, this notation is simpler as you only have to specify the bit number instead of the mask.
The Avr-libc contains a built in macro function for reading switch input, which is the following.
1: bit_is_clear(SENSE_PORTC, SWITCHn_BIT);
When the switch is pressed, the I/O pin pulls to the ground. In the ATMega32, the PINx register reflects the state of the pins, and when the pin is at 0 V the bit becomes binary 0, and when the pin is at 5 V, the bit becomes binary 1. Therefore, you simply have to read the PINx register.
In this circuit, the switches connect to the PortC. We therefore detect switch input through the PinC register, and output through PortC register. The PinC register redefines as “SENSE_PORTC” which is more human friendly.
My Prototype Functions
Here are some of my functions and their descriptions. They are extremely simple to understand and use.
This function checks to see if a particular switch n was pressed, where n is a number between 0 and 7, representing the seven switches. When the switch is not pressed, the function returns a binary 0, and when it is depressed it returns a binary 1.
If pressed, it waits for 25 milliseconds and checks again. If the switch remains pressed after 25 milliseconds, then the function considers it de-bounced and lights the LED.
This function simply toggles the led n in question, where n is a number from 0 to 7. The LED lights when the switch is pressed, and turns OFF with the press of the same switch.
This function initialises the ports. The LEDs connect to PortA therefore; the DDRA (Data Direction Register) bits require setting to binary 0b11111111. The function also enables the internal pull-up resistors.
When a switch is pressed, it usually “bounces” before settling. It is usually a damped harmonic response with duration is in the millisecond range. It happens so fast that it is usually not a problem in slow analogue circuits. However, in digital electronics, a fast microcontroller can detect the bounce as well, and therefore a single switch press would register as multiple presses.
Determining the bounce duration of a particular switch is very easy and usually done using an oscilloscope. Many new switches have an average rating for bounce specified in their documentation. In highly critical systems, bounce filtering involves a combination of interrupt circuits as well as software polling. However, in this application I am using only software techniques.
In this program, I am using the DEBOUNCE_TIME variable set to a 25-millisecond delay. This is the amount of time to wait before sensing the switch press again. Once the switch is considered pressed the LED output is toggled.
Engaging Internal Pull-up Resistors
You enable the internal pull-up resistors by sending binary 1 to the port. For example, the following statement enables the internal pull-up resistors.
SWITCH_PORT |= _BV (SWITCHn_BIT);
The SWITCH_PORT is PortC, which enables the individual bit n for the port.
Read More: ATmega32 Switch Toggle Program