We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I need to write a delay routine in C for a 80C251 . The delay has got to be about 30 seconds . Any ideas welcomed.
Create a timer ISR that fires every 10ms. Then create volatile variables that this ISR decrements every: 1 interrupt, 10 interrupts, and 100 interrupts. Then put volatile gating variables that allow the ISR to decrement the vars. In your background (non-ISR code) create functions called delay10ms(), delay100ms(), and delay1s(). Each of these functions will protect their respective counters from the ISR by clearing the gate var, writing the new count down value, setting the gate var to allow counting down via ISR, and pending on the count down var reaching zero. Be sure the count down vars. atomically accessible. E.g. an 8-bit quantity on an 8-bit machine. If not, you can use the gate vars for checking countdown complete by just telling the ISR to clear the gate when the countdown var hits zero.
/* Timer.c */ volatile static Bool s_gate10ms; volatile static Bool s_gate100ms; volatile static Bool s_gate1s; volatile static U8 s_countDown10ms; volatile static U8 s_countDown100ms; volatile static U8 s_countDown1s; static void timerIsr(void) { static U16 count10ms; /* 10ms timing 2.55 second duration max. */ if (s_gate10ms && s_countDown10ms) { --s_countDown10ms; } if (!(count10ms % 10)) { /* 100ms timing */ if (s_gate100ms && s_countDown100ms) { --s_countDown100ms; } if (!(count10ms % 100)) { /* 1s timing */ if (s_gate1s && s_countDown1s) { --s_countDown1s; } } } } /* Public functions */ void delay10ms(U8 num10msTicks) { s_gate10ms = 0; s_countDown10ms = num10msTicks; s_gate10ms = !0; while (s_countDown10ms); } void delay100ms(U8 num100msTicks) { s_gate100ms = 0; s_countDown100ms = num100msTicks; s_gate100ms = !0; while (s_countDown100ms); } void delay1s(U8 num1sTicks) { s_gate1s = 0; s_countDown1s = num1sTicks; s_gate1s = !0; while (s_countDown1s); } /* ------------------------------------------------ */ /* Timer.h */ void delay10ms(U8 num10msTicks); void delay100ms(U8 num100msTicks); void delay1s(U8 num1sTicks); /* ------------------------------------------------ */
In my timerIsr(), the count10ms function var. should be incremented before leaving the ISR and modulo'd with 100, thus allowing it to be a U8. Sorry. Also, for bonus points, in a real-time system why doesn't it help to do the 1s check inside the 100ms timing region? Why would this be desireable in a non-real-time system? - Mark