It's hard to say without seeing your code. As for the long ISR, I suppose it all depends on how long you can tolerate locking out other ISRs (if any).
Or are there situations where long ISRs are OK.
Not really, no.
If there's only one ISR in the system, then you only have to worry about it locking out the main program, but its still a situation best avoided really.
If you show your code it might suggest an alternate approach to what you are trying to achieve.
If there's only one ISR in the system, then you only have to worry about it locking out the main program, but its still a situation best avoided really.
It also blocks serial data reception/transmission, if any, other external interrupts, if any, timers, if any are used, and a variety of other things. None of which might matter, but we'd need to see the code to be sure.
You can handle the ugly computation parts off-interrupt by setting a flag inside the ISR, then handling the lower priority parts in the loop(). When you're done, disable interrupts, clear the flag, then re-enable interrupts.
And yes, long ISRs are evil. Especially on a platform without multiple level interrupts, nested interrupts, etc.
You can re-enable interrupts in your ISR to allow other background operations to happen. That should not cause a problem unless the current ISR takes longer than the interrupt interval that triggers it. Does the interrupt ever happen again in less than 100 microseconds?
You can do it with multiplication -- multiply by the reciprocal times some big number. Let's say you're dividing by 12.34. Pick a big number, like 65536 and get 5,311.
To divide 9,876 by 12.34 you multiply 9876 by 5311 and that yields 52,451,436. Now divide that by 65536 (shift by 16, which is fast ...) and you get 800. Checking the floating point math, 9876.0 / 12.34 = 800.324.
The only restrictions are that the product of the multiplier and multiplicand must always fit in whatever size variable you're using and the divisor must be a constant one way or the other.
Delta_G:
jfhaugh:
You can handle the ugly computation parts off-interrupt by setting a flag inside the ISR, then handling the lower priority parts in the loop(). When you're done, disable interrupts, clear the flag, then re-enable interrupts.And yes, long ISRs are evil. Especially on a platform without multiple level interrupts, nested interrupts, etc.
The thing I'm scared of is the interrupt firing twice before the loop has got back around to handle calculating the new value to put in OCR1A for the top. Or if the interrupt fires and then the loop is too late getting OCR1A reset and ends up setting it to a value lower than the current count.
What Bad Thing happens in those cases?
You can't always be perfect with real-time programming. You have to know what kinds of things are going to happen if you miss a deadline. If it's a "bad thing", you have to figure out how to give yourself more time, or how to stretch out the interval between actions.
One approach is to calculate (in loop) the value to be used in the next ISR. In other words, always be one out. So each ISR you update the timer for the value calculated the previous time around. That way the calculations are outside the ISR.
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.