Tuesday, August 24, 2021

ATMega16 Time And Event Driven System Using Timer/Counter0

 

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.

ATMega16 Time And Event Driven System Using Timer/Counter0
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.

  1. /*
  2.  * timer_0_multiplexed_disp_inp.c
  3.  *
  4.  * Created: 12/10/2020 9:18:13 AM
  5.  * Author : admin
  6.  */
  7.  
  8. #include <avr/io.h>
  9.  
  10. /*Each Button is active for every 120ms*/
  11. #define buttonTime 120
  12.  
  13. /*Buttons Pressing Macro*/
  14. #define DEC ((PINA&0x20)==0)
  15. #define CLR ((PINA&0x40)==0)
  16. #define INC ((PINA&0x80)==0)
  17.  
  18. void driveDisplay(void);
  19. void timerTick(void);
  20. void inputTask(void);
  21.  
  22. unsigned char oneMillis=0;
  23. unsigned int buttonMillis=0;
  24. unsigned char buttonTick=0;
  25. unsigned long buttonCount=0;
  26.  
  27. int main(void)
  28. {
  29. /*Port A 5...7 Input*/
  30. DDRA=0x1F;
  31. /*Turn Port A 5...7 On*/
  32. PORTA=0xE0;
  33. /*Port B drive the segments*/
  34. DDRB=0xFF;
  35. /*Port C drive the digits*/
  36. DDRC=0xFF;
  37. /*Timer/Counter0 Set to 1:64 Pre-scaler*/
  38. TCCR0=(1<<CS01)|(1<<CS00);
  39. /*Clear TOV0 Flag*/
  40. TIFR=(1<<TOV0);
  41. /*Clear Timer/Counter0 Register*/
  42. TCNT0=0;
  43. while (1)
  44. {
  45. /*Timer Task*/
  46. timerTick();
  47. /*Display The Numbers*/
  48. driveDisplay();
  49. /*Check Button Input*/
  50. inputTask();
  51. }
  52. }
  53.  
  54. void driveDisplay(void){
  55. unsigned char cCathode[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
  56. switch(oneMillis){
  57. /*100000's digit*/
  58. case 0: PORTC=0x00;
  59. PORTB=cCathode[buttonCount/100000];
  60. PORTC=(1<<5);
  61. break;
  62. /*10000's digit*/
  63. case 2: PORTC=0x00;
  64. PORTB=cCathode[(buttonCount%100000)/10000];
  65. PORTC=(1<<6);
  66. break;
  67. /*1000's digit*/
  68. case 4: PORTC=0x00;
  69. PORTB=cCathode[(buttonCount%10000)/1000];
  70. PORTC=(1<<7);
  71. break;
  72. /*100's digit*/
  73. case 6: PORTC=0x00;
  74. PORTB=cCathode[(buttonCount%1000)/100];
  75. PORTC=(1<<2);
  76. break;
  77. /*10's digit*/
  78. case 8: PORTC=0x00;
  79. PORTB=cCathode[(buttonCount%100)/10];
  80. PORTC=(1<<3);
  81. break;
  82. /*1's digit*/
  83. case 10:PORTC=0x00;
  84. PORTB=cCathode[buttonCount%10];
  85. PORTC=(1<<4);
  86. break;
  87. }
  88. }
  89.  
  90. void timerTick(void){
  91. /*Check the 1ms timer tick*/
  92. if (TIFR&(1<<TOV0))
  93. {
  94. TIFR=(1<<TOV0);
  95. /*this variable drive all six digits*/
  96. if(oneMillis>10) oneMillis=0;
  97. else oneMillis++;
  98. buttonMillis++;
  99. }
  100. /*Check if it's 0.1 second*/
  101. if (buttonMillis>=buttonTime)
  102. {
  103. buttonTick++;
  104. buttonMillis=0;
  105. }
  106. }
  107.  
  108. void inputTask(void){
  109. switch(buttonTick){
  110. /*Check PA5*/
  111. case 0:
  112. if (DEC)
  113. {
  114. if(buttonCount<1000000)
  115. buttonCount++;
  116. /*Go to next pin*/
  117. buttonTick++;
  118. }
  119. break;
  120. /*Check PA6*/
  121. case 1:
  122. if (CLR)
  123. {
  124. if(buttonCount!=0)
  125. buttonCount=0;
  126. /*Go to next pin*/
  127. buttonTick++;
  128. }
  129. break;
  130. /*Check PA7*/
  131. case 2:
  132. if (INC)
  133. {
  134. if(buttonCount>0)
  135. buttonCount--;
  136. /*Go to next pin*/
  137. buttonTick++;
  138. }
  139. break;
  140. /*Clear all remaining*/
  141. default:
  142. buttonTick=0;
  143. break;
  144. }
  145. }

 Zip file for this programming example is here. I have test this program on the AVR development board.

ATMega16 Time And Event Driven System Using Timer/Counter0
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.



ATMega16 Time And Event Driven System Using Timer/Counter0

A software image while the program is running in Proteus, showing the counter of “36”.

All program testing in software and hardware can be view on my YouTube video.


 

No comments:

Post a Comment

Labels

ADC (10) Analog (14) Arduino (12) Atmega16 (19) Audio (2) AVR (20) Charger (1) Cortex-M0 (1) Counter (10) CPLD (25) Digital I/O (22) Display (34) EEPROM (2) Environment Sensor (1) esp8266 (2) Experiment Board (10) I2C (4) Interrupt (7) LCD (1) LDmicro (29) measurement and instrumentation (7) Microchip Studio (3) MikroC (1) One-Shot (3) OpAmp (1) PCB (31) PIC16 Microcontrollers (16) PIC16F877A (2) PIC16F887 MikroC (22) PLC (35) PWM (11) Regulator (1) RTC (2) Sensor (8) Shift Registers (5) SPI (5) Timer (34) UART (2) ultra-sonic sensor (1) USB (1) VHDL (21) xc8 (1) XC95108 (9) XC9536 (15) XC9572 (1) Xilinx (23) Xilinx ISE (22)