Introduction
In a previous example, we have demonstrate how to use Timer/Counter0 to regularly multiplex a display, without using a polling delay library. Similarly we can use Timer/Counter0 timer ticks to activate some more inputs. These inputs are time and event driven. Event driven here refers to any change of input logic state.
ATMega16 Programming
This programming example is just an addition to previous example that perform as a free running counter displaying on a multiplexing display. It’s value is regularly update for every 100ms.
Additionally, I added three input buttons which are,
- Decreasing the counter
- Resetting the counter
- Increasing the counter
Counter value is displayed on the multiplexing display on AVR development board. Its maximum value is one million since the display’s digit count is six digits.
Hardware Preparation
Schematic diagram of this programming example follows the design on AVR development board with three extra add-on buttons.
Schematic Diagram of “ATMega16 Time And Event Driven System Using Timer/Counter0” |
Three input buttons for counter variation are wired externally on a small bread board. All other remaining constructions are ready to use as they are soldered on the development board.
AVR Program Preparation
The multiplexing display section is ignored, as it’s described in previous example. We are going to talk about the inputs.
Each digits of the display activated for every 2ms. An input button is active within a duration of 120ms. Whenever a button is pressed, it changes the value of counter and program jumps to find for next present of button pressing.
AVR GCC program for this embedded programming example lists below.
/* * timer_0_multiplexed_disp_inp.c * * Created: 12/10/2020 9:18:13 AM * Author : admin */ #include <avr/io.h> /*Each Button is active for every 120ms*/ #define buttonTime 120 /*Buttons Pressing Macro*/ #define DEC ((PINA&0x20)==0) #define CLR ((PINA&0x40)==0) #define INC ((PINA&0x80)==0) void driveDisplay(void); void timerTick(void); void inputTask(void); unsigned char oneMillis=0; unsigned int buttonMillis=0; unsigned char buttonTick=0; unsigned long buttonCount=0; int main(void) { /*Port A 5...7 Input*/ DDRA=0x1F; /*Turn Port A 5...7 On*/ PORTA=0xE0; /*Port B drive the segments*/ DDRB=0xFF; /*Port C drive the digits*/ DDRC=0xFF; /*Timer/Counter0 Set to 1:64 Pre-scaler*/ TCCR0=(1<<CS01)|(1<<CS00); /*Clear TOV0 Flag*/ TIFR=(1<<TOV0); /*Clear Timer/Counter0 Register*/ TCNT0=0; while (1) { /*Timer Task*/ timerTick(); /*Display The Numbers*/ driveDisplay(); /*Check Button Input*/ inputTask(); } } void driveDisplay(void){ unsigned char cCathode[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; switch(oneMillis){ /*100000's digit*/ case 0: PORTC=0x00; PORTB=cCathode[buttonCount/100000]; PORTC=(1<<5); break; /*10000's digit*/ case 2: PORTC=0x00; PORTB=cCathode[(buttonCount%100000)/10000]; PORTC=(1<<6); break; /*1000's digit*/ case 4: PORTC=0x00; PORTB=cCathode[(buttonCount%10000)/1000]; PORTC=(1<<7); break; /*100's digit*/ case 6: PORTC=0x00; PORTB=cCathode[(buttonCount%1000)/100]; PORTC=(1<<2); break; /*10's digit*/ case 8: PORTC=0x00; PORTB=cCathode[(buttonCount%100)/10]; PORTC=(1<<3); break; /*1's digit*/ case 10:PORTC=0x00; PORTB=cCathode[buttonCount%10]; PORTC=(1<<4); break; } } void timerTick(void){ /*Check the 1ms timer tick*/ if (TIFR&(1<<TOV0)) { TIFR=(1<<TOV0); /*this variable drive all six digits*/ if(oneMillis>10) oneMillis=0; else oneMillis++; buttonMillis++; } /*Check if it's 0.1 second*/ if (buttonMillis>=buttonTime) { buttonTick++; buttonMillis=0; } } void inputTask(void){ switch(buttonTick){ /*Check PA5*/ case 0: if (DEC) { if(buttonCount<1000000) buttonCount++; /*Go to next pin*/ buttonTick++; } break; /*Check PA6*/ case 1: if (CLR) { if(buttonCount!=0) buttonCount=0; /*Go to next pin*/ buttonTick++; } break; /*Check PA7*/ case 2: if (INC) { if(buttonCount>0) buttonCount--; /*Go to next pin*/ buttonTick++; } break; /*Clear all remaining*/ default: buttonTick=0; break; } }
Zip file for this programming example is here. I have test this program on the AVR development board.
A running embedded program on the AVR development board showing the counting value of “15”. |
Hardware experiment runs smoothly without interruption, flickering, and switch bouncing. However, without a physical hardware as shown here the programmer can use Proteus simulator, that requires a software license.
A software image while the program is running in Proteus, showing the counter of “36”. |
No comments:
Post a Comment