Many thanks for those who help me! (:
I got a problem here...
If i were to use 3 types of interrupts(external interrupt0, timer0 and timer1) in one single program, how should i go about writing the codes in the program?
It's not even all that theoretical. For example, you might have an interrupt that represents the arrival of a network packet. This is essentially a random event from the point of view of the program.
If I'm measuring the time between points A and B in the code, or the latency a lower priority interrupt, I can't know how long it will take, because I don't know how many high priority interrupts will occur. Some interrupts, like timer interrupts, may be predictable, but not all of them are. The maximum rate of some interrupts may be so slow, and the handling required so minor, that the CPU can always handle the worst case; but again, that might not be the case.
If you poll, then you know (because you wrote the code) that you'll handle each event once; therefore, the worst case to handle any event is the sum of the times to handle all the other events. (You can of course write a more complex scheduler.) You have a guaranteed time and predictable order for operation, at the cost of not being able to quickly service any event at any time. The latency might or might not be a problem, depending on your application.
Both polling and ISRs have their uses. Neither one is dominant in all possible virtues. Hence it's useful to understand the tradeoffs so as to select the right tool for the job.
High priority interrupts can hog the CPU almost indefinitely, preventing low priority interrupts (and the rest of the program) from being serviced. With polling, this can't happen.
Except for some extremely obscure cases this is incorrect.
If something, if it is done in a high priority interrupt, "can hog the CPU almost indefinitely" then changing to polling in order to service something else, will make what was previously done in the high priority interrupt 'miss'.
If you do not have the time to do it all, you need to redo your code (but NOT by changing to polling) or change processor.
Erik
A level-trigged interrupt can kill an application if the external hardware for some reason gets into trouble and don't deactivate the input signal.
A memory overwrite somewhere that happens to turn on an interrupt source too much which the ISR wasn't supposed to handle, can also result in the application locking up. Every time the ISR returns, the processor generates a new interrupt because the ISR didn't know to clear/acknowledge the event flag.
The interrupt handler would need some protective logic to try and detect an unreasonable amount of interrupts, while a polling loop would iterate through all input sources without needing deadlock-protection.
Remember that even if most embedded applications tend to use interrupts, our toolbox of possible solutions can be very large, and there are always situations where multiple solutions can solve a problem in a good way.
I can't really see a reason to argue against polling. It is just one very valid method to implement something.
In a situation where every single device is interrupt-driven, it can be very hard to know if the main loop is guaranteed to always have enough CPU capacity available to be able to do the required processing of received data.
In a system where some devices are polled, the system may for example gracefully decrease the poll frequency of the polled devices. An example is to poll the ADC to check the voltage of an accumulator. No data is lost by the poll frequency being reduced at high load. It just affects how fast the unit turns off to protect the accumulator from deep-discharge.
A level-trigged interrupt can kill an application if the external hardware for some reason gets into trouble and don't deactivate the input signal. 1) why ever use level triggered 2) how would polling not "kill an application" if the above happened.
A memory overwrite somewhere that happens to turn on an interrupt source too much which the ISR wasn't supposed to handle, can also result in the application locking up. Every time the ISR returns, the processor generates a new interrupt because the ISR didn't know to clear/acknowledge the event flag. 1) "A memory overwrite" will get you in trouble regardless of interrupt or polling. 2) "the ISR didn't know to clear/acknowledge the event flag" is a programming error which will give trouble regardless
The interrupt handler would need some protective logic to try and detect an unreasonable amount of interrupts, while a polling loop would iterate through all input sources without needing deadlock-protection. here you, while being correct in the statemnt are wrong. If "an unreasonable amount of interrupts" happen something is wrong and polling will not remove what is wrong.
Remember that even if most embedded applications tend to use interrupts, our toolbox of possible solutions can be very large, and there are always situations where multiple solutions can solve a problem in a good way. Of course, I agree with this, however, I see waaaay too much interruptifobia getting people in trouble.
I can't really see a reason to argue against polling. It is just one very valid method to implement something. I both agree and disagree. Polling IS a solution in some (rare) instances, however, it should not be a preference because of the side effects or interruptifobia. I have seen way more polling, that ISRs falling by the wayside when an unrelated change was made.
In a situation where every single device is interrupt-driven, it can be very hard to know if the main loop is guaranteed to always have enough CPU capacity available to be able to do the required processing of received data. same for polling. Whether you use an ISR or polling, the "CPU capacity available" must handle the same 'exceptions' (e.g. much UART processing vs none)
In a system where some devices are polled, the system may for example gracefully decrease the poll frequency of the polled devices. An example is to poll the ADC to check the voltage of an accumulator. No data is lost by the poll frequency being reduced at high load. It just affects how fast the unit turns off to protect the accumulator from deep-discharge. equally easy to do in an ISR. just say "if the main do not get every value read in the (2 line ling) ISR processed, so what.
ONE ISSUE: if you use this microcontroller (the '51) as a microprocessor it does, of course, not matter the least which method you use. However in most microcontroller applications the 'cost' of missing an event is very high.
PS I do, very rarely, use polling and IMHO polling routines takes much more care to write re impact than ISRs.
erik, As Per Westermark mentioned in the following post, a level triggered interrupt that remains asserted can cause havoc. That can happen even if a peripheral is shutdown! I still didn't finish reading all posts, but another con I can think of, is that often when using interrupts you are bound to a certain processor pin, making portability a little more difficult.
As Per Westermark mentioned in the following post, a level triggered interrupt that remains asserted can cause havoc. That can happen even if a peripheral is shutdown! It will "cause havoc" even if polled.
which is, of course, true. but it won't if it is edge triggered :)
It will "cause havoc" even if polled.
No. A polling loop will/may run slower, but will continue to run. It is only the loop time that controls how often the signal gets polled. It is only when/if the program contains something silly like:
while (signal_x_active) process_signal_x();
that it gets into troubles if the signal is stuck.
A constantly generated interrupt will totally kill anything that hasn't higher priority than the interrupt. The main loop may not get enough processor time to be able to notice the stuck interrupt.
Since the majority of applications perform most of their jobs outside of interrupts, they are very sensitive to a interrupt handler constantly being trigged.
Per, You are right, but frankly, most of the embedded code I have seen so far does not take into consideration that a signal might "get stuck". I have to admit - I don't always check that either. I do when there is functional reason to do so - a signal remaining high for too long may indicate that the machine is experiencing some mechanial failure, and then I indicate an error and stop everything to prevent somebody from being squashed...
most level triggered interrupts reset "the level" in the ISR. in such a case it is easy to check if the reset "worked" and take action if not.
The exception to the above is some derivatives requirement for a wake up interrupt, but similar detection can be done there.
THUS, even a level triggered interrupt can be detected stuck and disabled.
Erik,
you wrote
what is a wake interrupt in this context? what do you mean?
read any datasheet for modern derivative that can be woken up from sleep mode by e.g. int0. I recall none that will wake up fron an edge int, all I recall require a level int to wake up.
Ah, I understand what you meant.