Sunday, May 24, 2020

Driving a multiplexing SSD display and keys scanning using timer 0 interrupt of ATMega32

In the previous post I use timer 0 interrupt to create a timing delay. Now I use this method again to schedule two tasks, multiplexed SSD and key scanning.

The program process is describing as follow:
  1. A four-digit multiplexed SSD display activated by timer 0 interrupt. Each digit is activated within 5 milli seconds period. The period created by timer 0 ISR.
  2. Three keys, up counter , reset counter and down counter are activated for every 200 milli seconds. Again this 150 milli seconds period generated by timer 0 ISR.
I do not describe the core programming of timer 0 here since I have done it in the previous post.

Driving a multiplexing SSD display and keys scanning using timer 0 interrupt of ATMega32
Schematic diagram.
ATMega32 fed from a 4 MHz clock source.
PD0 is an up counter. PD1 is a reset counter. PD2 is a down counter.
Each button becomes active after 200 milli seconds.
The four-digit multiplexed SSD is a timer interrupt driven display.
Each digit activated for every 5 milli seconds.

The C source codes is here.

#include <avr/io.h>
#include "avr/interrupt.h"
#define upButton ((PIND&0x01)==0)
#define resetButton ((PIND&0x02)==0)
#define downButton  ((PIND&0x04)==0)
/*System clock ticks for SSDs*/
unsigned char ssdTick=0,digit=0;
/*System clock ticks for keys*/
unsigned int found1=0,found2=0,found3=0;
unsigned int pressedCounter=1234;
void display(void){
 unsigned char patterns[16]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,
 0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
 switch(digit){
  case 1:
   PORTD=0x07;
   PORTC=patterns[pressedCounter/1000];
   PORTD=0x17;
   break;
  case 2:
   PORTD=0x07;
   PORTC=patterns[(pressedCounter%1000)/100];
   PORTD=0x27;
   break;
  case 3:
   PORTD=0x07;
   PORTC=patterns[(pressedCounter%100)/10];
   PORTD=0x47;
   break;
  case 4:
   PORTD=0x07;
   PORTC=patterns[pressedCounter%10];
   PORTD=0x87;
   break;
  case 5:
   digit=0;
   break;
 }
}
void buttonScan(){
 if (found1>=200)
 {
  if(upButton)
   if(pressedCounter<10000)
    pressedCounter+=1;
  found1=0;
 }
 if (found2>=200)
 {
  if(resetButton)
   pressedCounter=0;
  found2=0;
 }
 if (found3>=200)
 {
  if(downButton)
   if(pressedCounter>0)
    pressedCounter-=1;
  found3=0;
 }
}
int main(void)
{
 //Set PortC to Output
 DDRC=0xFF;
 //Clear PortC
 PORTC=0x00;
 DDRD=0xF8;
 PORTD=0x07;
 PORTC=0x00;
 //Set 1:256 prescaler
 TCCR0=0x04;
 //Clear overflow flag
 TIFR=0x01;
 //Enable Timer 0 interrupt
 TIMSK=0x01;
 //set global interrupt
 sei();
 while (1)
 {
  display();
  buttonScan();
 }
}
ISR(TIMER0_OVF_vect){
  //Load -16 to make 1 mS interrupt time
 TCNT0=-16;
 ssdTick+=1;
 //increase counters for SSD
 if(ssdTick>=5){
  digit+=1;
  ssdTick=0;
 }
 found3+=1;
 found2+=1;
 found1+=1;
 //Clear Flag
 TIFR=0x01;
}
Back to main tutorial page ATMega32 tutorials in C with Atmel Studio 7.





No comments:

Post a Comment

Search This Blog

Labels

25AA010A (1) 8051 (7) 93AA46B (1) ADC (30) Analog Comparator (1) Arduino (15) ARM (6) AT89C52 (7) ATMega32 (54) AVR (57) CCS PICC (28) DAC (1) DHT11 (2) Display (105) Distance Sensor (3) DS18B20 (3) dsPIC (2) dsPIC30F1010 (2) EEPROM (5) Environment Sensor (4) esp8266 (1) I2C (29) Input/Output (67) Interrupt (19) Keil (5) Keypad (10) LCD (46) Master/Slave (1) MAX7221 (1) MCP23017 (5) MCP23S17 (4) Meter (3) MikroC (2) Motor (15) MPLABX (66) Nokia 5110 LCD (3) OLED (2) One-Wire (6) Oscillator (8) PCB (6) PCD8544 (3) PCF8574 (5) PIC (107) PIC12F (2) PIC16F628A (2) PIC16F630 (1) PIC16F716 (3) PIC16F818 (10) PIC16F818/819 (2) PIC16F84A (15) PIC16F876A (1) PIC16F877A (9) PIC16F88 (1) PIC16F887 (60) PIC18 (19) PIC18F1220 (4) PIC18F2550 (3) PIC18F4550 (12) PWM (11) RTC (8) Sensor (10) SH1106 (1) Shift Register (11) Shift Registers (2) SPI (24) STM32 (6) STM32 Blue Pill (6) STM32CubeIDE (6) STM32F103C8T6 (6) SysTick (3) temperature sensor (11) Thermometer (21) Timer/Counter (30) TM1637 (2) UART (7) Ultrasonic (4) Voltmeter (7) WDT (1) XC16 (2) XC8 (94)