4
\$\begingroup\$

I am designing a microcontroller based delay circuit to implement delays of 2 hours, 1 hour, 45 minutes, and 30 minutes. The circuit will automatically turn on off a relay after this time period has elapsed.

I am stuck with a narrow selection of microcontrollers available locally in market:

  • 89C51
  • 89C52
  • 89S51
  • 89S52
  • 89C2051
  • PIC 16C71
  • PIC 16F84

I have checked the datasheets of these microcontrollers but there is no information about the maximum delay they can produce.

What is the maximum delay that can be produced with these microcontrollers?

\$\endgroup\$
  • \$\begingroup\$ Even the 6 pin PIC10 series can do that. You might even want to count the number of sequential watchdog timeouts as suggested in the answer below, if they are longer than the timer 0 max value. \$\endgroup\$ – kenny Dec 15 '11 at 20:22
  • 1
    \$\begingroup\$ @TheNoble-Coder, important aspect, what accuracy do you need? \$\endgroup\$ – Kortuk Dec 16 '11 at 4:34
  • \$\begingroup\$ I agree with @kortuk. If accuracy is an issue, than it will be hard to get an accurate timer from an mcu alone, even with a fairly good crystal. Might I recommend a good RTC module? datasheets.maxim-ic.com/en/ds/DS3231.pdf \$\endgroup\$ – captncraig Dec 16 '11 at 17:16
  • \$\begingroup\$ @CMP, almost everyone wants accuracy but often think in terms of their own accuracy. Many people know it is really easy to get +- a few minutes themselves and assume a microcontroller can easily, but dependably get +-1 minute in 1 year with a microcontroller without knowing what has to be compensated for can be near impossible. \$\endgroup\$ – Kortuk Dec 16 '11 at 17:42
11
\$\begingroup\$

The delay can be as long as you want. If a timer won't give you the delay you need, simply increment a register, or several registers, each time it overflows. Here is a simple program using Timer0 that illustrates the technique:

        #include    "P16F88.INC"

#define LED 0

    errorlevel -302     ;suppress "not in bank 0" message

#define RB0 0
#define INIT_COUNT 0    ;gives (255 - 199) * 17.36 = 972 us between interrupts


    cblock  0x20
    tick_counter
    temp    
    endc

    ;reset vector
    org     0
    nop
    goto    main

    ;interrupt vector
    org     4
    banksel INTCON
    bcf     INTCON,TMR0IF   ;clear Timer0 interrupt flag
    movlw   0x00            ;re-initialise count
    movwf   TMR0
    decf    tick_counter,f
    retfie

main:
    banksel OPTION_REG
    movlw   b'00000111'     ;prescaler 1/128
    movwf   OPTION_REG      ;giving 7.3728 Mz/128 = 57600 Hz (period = 17.36 us)
    banksel TMR0
    movlw   0x00            ;initialise timer count value
    movwf   TMR0
    bsf     INTCON,GIE      ;enable global interrupt
    bsf     INTCON,TMR0IE   ;enable Timer0 interrupt
    banksel TRISB
    bcf     TRISB,LED   ;RB0 is LED output
    banksel 0

mainloop:
    goto    mainloop

    bsf     PORTB,LED
    call    dly
    bcf     PORTB,LED
    call    dly 
    goto    mainloop

dly:
    movlw   20
    movwf   tick_counter
dly1:
    movf    tick_counter,f
    skpz
    goto    dly1
    return

    end
\$\endgroup\$
  • \$\begingroup\$ I just want to ask. Is this concept right that such a long delay can't be produced by 89c51 or 89c52. \$\endgroup\$ – Naeem Ul Wahhab Dec 15 '11 at 14:56
  • 4
    \$\begingroup\$ You can use the same technique with any MCU. \$\endgroup\$ – Leon Heller Dec 15 '11 at 15:02
  • \$\begingroup\$ Ops, I think code format needs editing. \$\endgroup\$ – abdullah kahraman Dec 15 '11 at 17:13
  • 1
    \$\begingroup\$ Being picky, there is a limit. Given that the RAM and the number of registers are finite, the maximum count that you can do with them is also finite, although huge. Your answer is good, and I had already +1 it. \$\endgroup\$ – Telaclavo May 21 '12 at 17:20
  • \$\begingroup\$ @Telaclavo - I addressed the amount or RAM required. It's not much, actually. \$\endgroup\$ – Connor Wolf May 22 '12 at 3:50
15
\$\begingroup\$

It is not specified because any normal micro-controller can by means of software create an essentially unlimited delay - ie, of a far longer time than there's any reason to expect the circuit to still be operational or anyone to care about the result.

Essentially, you find some means of generating a short delay, such as having the processor execute a few instructions, or using a hardware timer, and then you use a counter to do that however many times is necessary to make up the period of time delay you desire.

Each byte of available register or ram storage for the count value would increase your available delay by a factor of 256. With as little as 64 bytes of RAM (most micros have several times that), you'd be able to create delays where the age of the earth pales by comparison.

\$\endgroup\$
  • \$\begingroup\$ Thanks for the reply. Actually this micro controller is only 1byte (8bit). Can I produce so much delay with it? \$\endgroup\$ – Naeem Ul Wahhab Dec 15 '11 at 14:36
  • 4
    \$\begingroup\$ @TheNoble-Coder - you are referring to the width of a single operation. By doing math in multiple operations you can increment numbers near the limit of your memory, just as you can manually do multi-digit arithmetic one digit place at a time. So the essentially unlimited analysis holds. FWIW a C compiler will tend to handle math up to 32 bits for your without any special tricks, doing the combination of operations needed to accomplish that on an 8 bit chip behind the scenes for you. Nested 32 bit for loops would be a simple to implement solution, up to a factor of 4 billion for each loop. \$\endgroup\$ – Chris Stratton Dec 15 '11 at 14:40
  • \$\begingroup\$ hmmm. I got your point. Thankyou so much. \$\endgroup\$ – Naeem Ul Wahhab Dec 15 '11 at 14:52
  • 3
    \$\begingroup\$ Some PIC controllers have as few as 24 bytes of RAM. On the other hand, 24 bytes would be enough to count up to almost 10^58. Plenty of time. \$\endgroup\$ – supercat Dec 16 '11 at 5:44
  • \$\begingroup\$ If you are counting seconds, 16 bits will give you about 4.5 hours. With four possible settings, you need 2 bits for which mode you are in, and maybe two more bits for whether or not you are currently counting, and the current state of your relay. That leaves you 21.5 bytes of RAM for the rest of your program, even on the 24 byte machine. Tight, but just waiting for something is doable even on a very constrained system. \$\endgroup\$ – wrosecrans Dec 16 '11 at 5:58
2
\$\begingroup\$

The maximum attainable delay is based on a combination of the system clock, and available RAM.

Basically, you can create large variables (e.g. 32 bit ints, 64 bit ints) on an 8-bit MCU by spreading the int over multiple 8-bit ram segments. It takes multiple operations to perform addition or multiplication of such numbers (as you have to iterate over the individual bytes), but speed is not exactly critical here, so this is ok.


So, assuming a 20 Mhz clock, how large of a variable do you need?

I'm making a lot of asusmptions here. First, I'm assuming a clock-instruction parity. Many MCUs require several clock-cycles to execute a single instruction, which would reduce the effective clock-rate. Second, I;m assuming your base counter is incrementing at the same rate as the system clock. This is generally only true for hardware counters. Third, the numbers I am using for things (the length of a year, etc...) are rounded versions of the real numbers. Lastly, this whole exercise is rather silly.

\$20 Mhz = 20\times 10^{6} = 20,000,000\$
Well, \$ \frac{log(20,000,000)}{log(2)} = 24.2534966642115\$ , so you need ~24.25 bits to delay for one second.
2 Hours = \$2*60*60 = 7200~\$ seconds, so you need \$ \frac{log(20,000,000*7,200)}{log(2)} = 37.0672778554286\$, so you need 37.06 (or basically 38 bits) bits of ram to represent a 2 hour delay.

So.... Assuming your microcontroller has at least 5 bytes of RAM, all of the listed devices will work.


For fun, let's look at how long a 64 bit long long would last:

\$2^{64} = 18,446,744,073,709,551,616 \$
\$ 18,446,744,073,709,551,616 / 20,000,000 =~ \approx922337203685.478 ~~ \$ Seconds
\$ \frac{922337203685}{60*60*24*365} = ~\approx29247.120~~\$ years

So with only 8 bytes of memory, it looks like you're good for at least the next 30 thousand years.

\$\endgroup\$
  • 1
    \$\begingroup\$ What if it is not enough? \$\endgroup\$ – abdullah kahraman May 22 '12 at 6:07
  • 2
    \$\begingroup\$ Representing your result in 15 significant digits is ridiculous. Even that is not the exact value, so what exactly is the point? Many people don't seem to realize how little \$1\$ in \$10^{15}\$ is. Even in the same line you drop 11 of the digits, making a rounding error for 37.06 in the process. So you start with 15 digits, and end up with 4 where the last one is wrong... \$\endgroup\$ – stevenvh May 22 '12 at 6:11
  • 1
    \$\begingroup\$ The length of the tropical year is about 365.24219 days. Your calculation for the number of years starting with 15 digits for the number of seconds has an error in the 4th digit. Just to illustrate how pointless it all is. \$\endgroup\$ – stevenvh May 22 '12 at 6:27
  • 1
    \$\begingroup\$ "Really, it's just a (somewhat) silly exercise". Of course, I agree on that. But even with the\$~\approx\$ I expect that all but perhaps the last digit are correct. \$\endgroup\$ – stevenvh May 22 '12 at 6:33
  • 1
    \$\begingroup\$ @stevenvh - At that point, I think you can let the heat-death of the universe boil them for you. \$\endgroup\$ – Connor Wolf May 22 '12 at 6:37
2
\$\begingroup\$

Others already explained that there's not really a limit to what you can do, and Fake Name juggled a bit with large numbers to show that 5 bytes would be sufficient on any controller.

Such a waste! :-) By carefully choosing a microcontroller you can use your timer to up to 9h delays with just 1 byte of RAM.

First thing to do is clock your microcontroller as slowly as possible. The MSP430 can run off a 32.768kHz crystal, which is the slowest you can go if you want some accuracy. (Slower clocks won't use a crystal.)

Next use prescalers. The MSP430 can prescale the crystal frequency \$\div\$8 to create an auxiliary clock \$ACLK\$. \$ACLK\$ will then be 4096Hz. You can use \$ACLK\$ to clock a 16-bit timer, but also here you have a \$\div\$8 prescaler option. Using that means the 16-bit timer gets clocked at 512Hz. \$\dfrac{2^{16}}{512 Hz}\$ = 128s. So using a low-frequency crystal and two prescalers the timer will overflow every 128s. Using an 8-bit counter to count the number of timer overflows allows you to count 256 \$\times\$ 128s = 32768s, or more than 9 hours, with just a single byte.

\$\endgroup\$
  • 2
    \$\begingroup\$ Nitpick: A prescaler is a type of memory, since it has internal state. So are timers. :) \$\endgroup\$ – Nick Johnson May 22 '12 at 12:22
  • 1
    \$\begingroup\$ @Nick - But they're not RAM! \$\endgroup\$ – stevenvh May 22 '12 at 12:40
  • \$\begingroup\$ Right, I'm just pointing out that just because you're not using system memory doesn't let you avoid the issue that the upper bound on count is based on the number of bits of state. \$\endgroup\$ – Nick Johnson May 22 '12 at 23:57
-2
\$\begingroup\$

We have four memory banks each with eight registers r0 to r7. Using any number of registers we can generate delay even of 10 hours

\$\endgroup\$
  • \$\begingroup\$ It would help if you could explain your suggestion further. Right now it's unclear if it relates to any of the processors from the question. \$\endgroup\$ – David Jan 11 '15 at 13:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.