Introduction
A an ATMega16 Timer/Counter0 tutorial, we have briefly demonstrated about its technical details and usage. Setting up its clock source, prescaler, and checking/clearing its interrupt flag is done with less than a dozen of codes in AVR GCC.
As it’s usually mentioned, a timer could be used to create a timing
delay. But a delay time powered by a timer is very flexible. The program
doesn’t need to wait until the delay time ended. It just required to
check the timer interrupt flag for a short time as the code was written.
Remaining CPU time will execute others remaining task.
With this advantage we can use this timer delay to multiplex a multi-digits seven-segments display without wasting the CPU cycle time executing the program. As it’s implemented in a previous article, a multiplexing display was driven by a delay which was not responsive.
Timer/Counter0 Programming For A Multiplexing Display
Overview
We will use Timer/Counter0 to create a timer tick with a rate of 1ms. This 1ms timer tick drive a six-digits seven-segments display. But Each digit was active for only a 2ms period.
The program use Timer/Counter0 timer tick to drive the display. This timer tick also activate a counting variable that will regularly update on the display for every 100ms.
Hardware Preparation
This program will test on an AVR development board. So the schematic diagram is no other than the one’s on-board, as it’s appeared in some previous article.
Schematic Diagram for this example |
The display is a green, 0.36″ common cathode type display. The ATMega16 microcontroller clocks at 16MHz from an on-board crystal clock. Port B drives the segments while Port C drive the digits.
AVR Programming Preparation
Driving Timer/Counter0 clock source directly from the on-board crystal oscillator should be inappropriate. The software must scale this clock frequency to a reasonable frequency. The software is coded to scale this clock frequency to 1:64 that will beat TCNT0 at the rate of,
64*(1/16MHz) = 4 us
Timer/Counter0 trigger its interrupt flag for every,
256*4us = 1024us which approximate to 1 ms.
As the real hardware test, each digit must be activated for within a duration of 2ms. So an additional counter variable must be place to keep track of this 1ms timer tick.
Source code is written using a higher level programming language AVR GCC in Atmel Studio 7.
/* * timer_0_multiplexed_disp.c * * Created: 12/9/2020 10:04:30 AM * Author : admin */ #include <avr/io.h> void driveDisplay(void); void timerTick(void); unsigned char oneMillis=0; unsigned int oneSecond=0; unsigned long secondCount=0; int main(void) { /*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(); } } 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[secondCount/100000]; PORTC=(1<<5); break; /*10000's digit*/ case 2: PORTC=0x00; PORTB=cCathode[(secondCount%100000)/10000]; PORTC=(1<<6); break; /*1000's digit*/ case 4: PORTC=0x00; PORTB=cCathode[(secondCount%10000)/1000]; PORTC=(1<<7); break; /*100's digit*/ case 6: PORTC=0x00; PORTB=cCathode[(secondCount%1000)/100]; PORTC=(1<<2); break; /*10's digit*/ case 8: PORTC=0x00; PORTB=cCathode[(secondCount%100)/10]; PORTC=(1<<3); break; /*1's digit*/ case 10:PORTC=0x00; PORTB=cCathode[secondCount%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++; oneSecond++; } /*Check if it's 0.1 second*/ if (oneSecond>98) { oneSecond=0; secondCount++; } }
Program testing on the ATMega16 AVR development board |
The number shown on the display was a result of a long term running program since the board powered up.
Without a development board, or an absence of physical hardware prototyping we can use Proteus to test this programming example in simulator.
Programming running on simulator |
This program works well on the ATMega16 AVR development board. This is a video of this example on YouTube.
No comments:
Post a Comment