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 #include unsigned char LED[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,125,0x07,0x7F,111}; unsigned char AMPM[2]={119,115}; 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

Reply to
bromio
Loading thread data ...

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

Reply to
Glenn Gundlach

A loop in an interrupt service routine? No. Interrupt service routines should do what is needed at that time and nothing more. They should be as quick as possible.

Reply to
GaryKato

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.

Reply to
Neil

He's using the loop to refresh the LEDs and provide a delay, I think. Commented code is usually required for assignments--Profs and TAs hate to guess what code is supposed to do. That code should not be in the ISR. If you are trying to adjust the ISR rate to once per second this way, give up. There are other ways to get a one second (more or less) tick for your clock, and none of them involve running off a second in your ISR. Hint: think in terms of averages for one approach.

How does am ever change? How do you expect to reset this clock--wait until midnight and plug it in? Why do you use different bases for values in LED? Why does LED use a different base than (some of) AMPM? The if-clauses at the end of the ISR should logically be nested--only if sec==60 does min need to be checked for 60.

I wouldn't expect much of a grade out of this effort. :-/ _Rethink_ then rewrite.

~Dave~

Reply to
Dave

[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>=60) { 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

Reply to
Anton Erasmus

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.