| Author |
Message |
semiconductor
Joined: 04 Apr 2003 Posts: 294 Helped: 3 Location: France
|
27 Apr 2005 18:02 timeout in 89C51/89C52 |
|
|
|
|
I'm assigned an exercise to program an AT89C51 for automatic door project.
I'm facing a problem: TIMEOUT
if the outer sensor detects people available, it will open the door and waiting the inner sensor detects people available. After 20s, if no signal is detected, it automatically close the door and return to the beginning of the program (waiting for signal from outer door.
with AT89C51, I'm programming in C but I don't know how to design TIMEOUT algorithm with AT89C51 (20 seconds).
Can someone recommend me solutions?
|
|
| Back to top |
|
 |
IanP
Joined: 05 Oct 2004 Posts: 6490 Helped: 1542 Location: West Coast
|
28 Apr 2005 1:25 Re: timeout in 89C51/89C52 |
|
|
|
|
Use TIMER1 in MODE1 (16-bit counter) to count (Fclock/12) : FFFFh.
If crystal is 11.0952MHz the interrupt will occur every (11095200/12)/65536 = 14.108.. times per second.
Create variable TimeH and TimeL.
Increase TimeHTimeL every interrupt. To reach 20 seconds you will need ≈282 interrupts and that will leave the TimeHTimeL = 01 1A (h) = 0282 (d).
Now you can reset 20s counter (TimeHTimeL) and execute whatever should be done after 20s..
Good luck ..
|
|
| Back to top |
|
 |
Google AdSense

|
28 Apr 2005 1:25 Ads |
|
|
|
|
|
|
| Back to top |
|
 |
mrcube_ns
Joined: 10 Apr 2002 Posts: 429 Helped: 11 Location: Dark side of the Moon
|
28 Apr 2005 21:17 Re: timeout in 89C51/89C52 |
|
|
|
|
IanP is completly right,
but, I suggest to use 12MHz crystal, so one cycle is 1us.
Then, you use timer 1 as 16-bit timer and made 50ms timer (T1H=0x3C T1L=0xAF), so you have 20 counts in one second => to rich 20sec you need exactly 400 counts.
Best regards,
Mr.Cube
|
|
| Back to top |
|
 |
Hero
Joined: 06 Mar 2002 Posts: 145 Helped: 2
|
29 Apr 2005 3:51 Re: timeout in 89C51/89C52 |
|
|
|
|
Hi,
For long time period you need sotware counter.
Use 16-bit hardware counter for periodic intterupt generation.
In the interrupt service routine set CNT_FLAG variable.
unsigned char CNT_FLAG;
unsigned long cnt;
unsigned char TIMEOUT;
unsigned char TIMEOUT_ENABLED;
#define TIMEOUT_THRESHOLD 1024
void interrupt_routine ()
{
CNT_FLAG=1;
}
void main()
{
init();
while(1) {
...
cnt_process();
sleep(); // go to sleep mode
}
}
void cnt_process()
{
if (CNT_FLAG) {
CNT_FLAG=0;
if (TIMEOUT_ENABLED) {
if (cnt < TIMEOUT_THRESHOLD)
cnt++;
TIMEOUT=(cnt==TIMEOUT_THRESHOLD);
}
}
}
When cnt reach TIMEOUT_THRESHOLD TIMEOUT will be set.
Another solution is to increment cnt in the interrupt routine
void interrupt_routine()
{
if (TIMEOUT_ENABLED) {
if (cnt < TIMEOUT_THRESHOLD)
cnt++;
TIMEOUT=(cnt==TIMEOUT_THRESHOLD);
}
}
|
|
| Back to top |
|
 |