on Monday, 21 October 2013
In the 'Intermediate Project' section this is our 3rd project. I recommend you to read my previous post i.e tutorial on 7segment display before reading this post

  1.  Interfacing 7-segment Displays
  2. Generating accurate time delays using Timer register
  3. Implementing Timer Interrupts
  4. Fast switching between two 7-Segment Displays
AIM: Aim of this project is to display numbers from 0 to 99 with  time delays of 5sec between each count on to the two 7-Segment displays.

Before we look at the algorithm we need to understand few concepts.  In fact i have explained more clearly in my previous tutorial on 7segment display but few more basic concepts regarding this project need to be explained. 
As we know we need to switch very fast among two 7segment displays (using E1 and E2). First we enable E1 and send required value to the 'portc' again we disable E1 and enable E2 and we send required display value to the portc. 
For example we want to show 45 i.e 4 on 1st display and 5 on 2nd display , then first we enable the E1 and sent the value corresponding to 4(i.e MSB) to the portc, again we disable the E1 & enable the E2 we send 5(LSB) to portc. We switch this very fast so that our eyes look like both displays are ON at a time. In our project we switch E1 and E2 for every 4milli sec.
To do this we use timer interrupt concept. 

What is timer interrupt?? 
We set the required time value in the timer registers in our case its 4milli sec, how do we know that the time we set have been completed? To know when time have been elapsed microcontroller will set the interrupt flag after completion of that time. As soon as the interrupt occurs the control of our program will shift to interrupt service routine. Interrupt service routine is nothing but a 'interrupt function' , whenever interrupt occurs our program control will shift to that 'interrupt function' after execution of that function it come backs to its main program from where it has been left. 
For example , our main program have 10 lines of code, we set the timer values to 4milli sec. Our program executes one line after the other, suppose control is at 7th line then 4milli sec have been completed then program will shift its control to  'interrupt routine' function and it will execute that function and come back to the 7th line and executes each line after that i.e 8th,9th and 10th line.

We set timer to 4ms and wait for timer interrupt to occur. we write program for 'switching E1 and E2 and displaying values' in the interrupt function, whenever interrupt occurs our control shifts to that function and executes it and come back to our main program.


Assign default value of the variable 'cnt' to 00
Assign Timer value to 4ms i.e for every 4ms 'Timer interrupt' occurs
In Interrupt Service Routine Function
Extract Msb of 'cnt'
Enable  'E1' and send corresponding hex value of 'MSB' to portc
Extract Lsb of 'cnt'
Disable E1 and Enable E2 and send the corresponding hex value of 'LSB' to portc
End of Interrupt service Routine Function
Increment variable 'cnt' after 5sec.
Whole process repeats


To produce our required time delay we need to load certain values in the 'Timer' Register. We will look how to find the timer register values for our desired time delay.
For instance we look at Timer0, we will look other timers in our upcoming projects.
Timer0 is operated in 8-bit mode. Formula is given below

TMR0L= 256 -    --------------------------------  
                               4* Clock period * Prescaler     

TMR0L is the register in which we need to load the value(which we find from this formula)
Time  is the desired time delay
Clock period is the inverse of the crystal oscillator clock frequency.
Prescaler is the prescale (You can use any value 2,4,8,16,32,64,128,256).

In our program we are generating time delay of 4milli sec, we use crystal frequency of 4Mhz i.e clock period will be 1/4mhz = 0.25us, we use  prescaler value as 32

TMR0L= 256-  --------------------------------------            = 131
                                             4* (0.25)*32                           

So we got all the values, which has to be loaded in the register as shown below.
Look at the last 3 bits i.e prescale bits. we have used prescaler value as 1 0 0 for 32. We have a table to find its prescale value, look below
000 = 1:2 prescale
001 = 1:4 prescale
010 = 1:8 prescale
011= 1:16 prescale
100= 1:32 prescale
101= 1:64 prescale
110= 1:128 prescale
111= 1:256 presclae
As we have used 32 as prescale so we filled those 3 Lsb bits with 100. Other bits are self explanatory. 
To produce required time delay we have loaded timer register with its corresponding values. To initialize the interrupt we need to load interrupt register with its value. 

As we are using timer0 interrupt so TMR0 bit as 1, to interrupt register works we make 'Enable global interrupt' bit 1 and other all bits  as 0. Indicated with 'x' dont care, also make it 0.

T0CON=11000100 =C4 (in hex)
INTCON=10100000= A0(in hex)



Before we go to programming, few small concepts we should know.
If any number suppose 67 saved in any variable, to extract 6 if we divide(/) that variable by 10 then we will get 6, to get 7 if we modulo divide(%) then we will get 7.( i.e 67/10=6 , 67%10=7).
Same concept we use in the program to extract Msb and Lsb data from "cnt" variable. Analyze the program carefully

volatile flag_bit=0,cnt=0;
//Function to send number pattern to portC there by 7segment display
unsigned char show(unsigned char numb)
         unsigned char hex_values[]={0x3F,0x06,0x5B,0x4F,
         //you will know this if you red my mytutorial on 7segment display
         unsigned char pattern;
         pattern= hex_values[numb];
         return(pattern);//return hex_value of the number

//Interrupt service routine function, which will execute for every 4ms.
void interrupt()
         unsigned char Msb,Lsb;
         TMR0L=131;//Timer value for 4ms
         INTCON=0x20;// Interrupt values
         flag_bit= ~flag_bit;//flag
         if(flag_bit==0)//if flag is 0
                 PORTD.F1=0;//2nd display disable
                 Msb=cnt/10;// extracting Msb
                 PORTC=Show(Msb);//Show() function to display
                 PORTD.F0=1;//1st display enable
                 PORTD.F0=0;//1st display disable
                 Lsb=cnt%10;//extract lsb
                 PORTC=Show(Lsb);//show function to display
                 PORTD.F1=1;//2nd display enable

//Main function
void main()
       TRISD = 0;//output
       TRISC = 0;//output
       PORTD.F0 = 0;//all bits 0
       PORTC.F1 = 0;//all bits 0
       T0CON=0xC4;// Timer control register value
       TMR0L=131;//Timer value for 4ms
       INTCON=0xA0;//Interrupt value
       Delay_ms(5000);//delay 5sec
       while(1)// infinite loop
             cnt++;//increment cnt variable
             if(cnt==100)cnt=0;//if cnt is 100 then make it 0
             Delay_ms(5000);//delay of 5sec

You might get doubt regarding 'Flag_bit' variable. For every 4ms our program control enters into ISR function. For first time when it enters into ISR we need to show Msb( i.e first display), for the 2nd time when it enters ISR we need to show Lsb(i.e 2nd display),  for the 3rd time Msb(1st display) and for the 4th time Lsb(i.e 2nd display), so on...So , for this purpose we use flag_bit for alternate process. Understand each line carefully to understand better.

I have explained as simple as possible now its on you how much you concentrate to understand it well.


Syed Zain Nasir said...

You should also check [url=https://www.TheEngineeringProjects.com/]The Engineering Projects[/url] because they have posted a lot of [url=http://www.theengineeringprojects.com/2015/03/arduino-projects.html]Arduino Projects[/url] and [url=http://www.theengineeringprojects.com/2015/03/pic-microcontroller-projects.html]PIC Mirocontroller Projects[/url] and have also designed many new [url=http://www.theengineeringprojects.com/2013/03/a-complete-tutorial-on-how-to-use-proteus-isis-ares.html]Proteus Tutorials[/url]. I hope you guys are gonna like them.

Syed Zain Nasir said...

You should also check The Engineering Projects because they have posted a lot of Arduino Projects and PIC Mirocontroller Projects and have also designed many new Proteus Tutorials. I hope you guys are gonna like them.

Post a Comment