microcontroller AT89S52 programing advice

im required to make a digital clock , i made several codes using iteration for delay which give not perfect delay. So i want to have
suggestion about how to use timer interrupts to have perfect 1 sec delay each time. ive written code please see am i using interrupts correctly..
#include <reg51.h> #include <stdio.h> unsigned char LED[10]=; unsigned char AMPM[2]=; long int x,sec=0,min=0,hour=0,lmin=0,hmin=0,c=0;hhour=0,lhour=0,le=0,am=0; sbit a=P3^0; sbit b=P3^1; sbit d=P3^4; sbit e=P3^7; sbit f=P3^6; void init_timer() { ET1=1; TMOD=0x20; TH1=0x6; EA=1; TR1=1; }
timer1() interrupt 3 { hmin=min/10; lmin=min%10; hhour=hour/10; lhour=hour%10;      while(c<@00)      {      le++;      c++;      switch(le) { case 1: a=0; b=1; d=1; e=1;             f=1;          P0=~LED[hhour];             break;
         case 2: a=1;             b=0;             d=1;             e=1;             f=1;             P0=~LED[lhour];             break;
         case 3:             a=1;             b=1;             d=0;             e=1;             f=1;             P0=~LED[hmin];             break;
         case 4:             a=1;             b=1;             d=1;             e=0;             f=1;             P0=~LED[lmin];             break;          case 5:          a=1;             b=1;             d=1;             e=1;             f=0;             P0=~AMPM[am];             le=0;             break;      }      }c=0;      sec++;      if(sec=`)      {sec=0;      min++;      }      if(min=`)      {min=0;      hour++;      }
} main() {
EA=1; am=0; le=0; sec = 0; min = 0; hour= 0; c=0;     init_timer(); for(;;) {} }
Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload
bromio wrote:

<snip code>
I take it C is the required language? The timer is a snap in assembler - less than 10 lines. I'm not a C guy but that interrupt routine looks all wrong to me. Oh well.
GG
Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload
bromio wrote:

Too much in the interrupt. Set a flag or inc a counter in the interrupt. Do the work in main. I assume this is a school project. CPU Xtals are do not have the tolerance to keep time very well. It can be off by several minutes a month.
Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload

[Code Snipped]

[more code snipped]
Doing devides on a 8051 in an interrupt routine is not a good idea. Using a switch statement in an interrupt routine on a 8051 using many of the 8051 compilers not a good idea. (Switch statement code is not re-entrant, so if you use a switch statement anywhere else you will have very strange bugs)
Do the minimum in the interrupt routine. In stead of doing a divide and a mod, rather have a timer counter that you increment every interrupt. You then increment the "second" interrupt every n number of timer interrupts. something like:
int_counter++; if(int_count>=NUMBER_OF_INTS_PER_SECOND) { int_counter=0; sec_counter++; if(sec_counter>`) { sec_counter=0; min_counter++; } }
Remember that if you are reading these variables from outside the interrupt routine, they should be volatile.
Regards Anton Erasmus
Add pictures here
<% if( /^image/.test(type) ){ %>
<% } %>
<%-name%>
Add image file
Upload

Polytechforum.com is a website by engineers for engineers. It is not affiliated with any of manufacturers or vendors discussed here. All logos and trade names are the property of their respective owners.