Page 412 - Programming Microcontrollers in C
P. 412

Delay Routine    397

                          This rather clumsy loop reads the value contained in ITADR into the
                          variable now. This register is then read into the location next until
                          the value in ITADR is changed by the clock. That should occur 122
                          microseconds later. At this time, count is decremented. When count
                          becomes 0 the time has expired.
                              The variables now and next are both declared to be volatile. This
                          declaration is necessary to avoid loss of the whole loop when the code is
                          optimized. The variable ITADR is declared to be volatile in the header
                          file.  That declaration does not guarantee to the compiler that the variables
                          will ever change, so the optimizer could well remove the code

                   now = ITADR; /* and don’t care how fast your test is */
                   do
                   {
                       next = ITADR;
                   } while(now == next); /* wait until next tick */
                          during the optimization phase. That would make the whole function
                          rather pointless.

            Semaphore

                              This delay function is used in later code to implement debounce
                          routines. A more practical delay routine can be implemented with
                          the use of a semaphore. Here, we are going to develop a semaphore
                                                                                       3
                          that follows that developed in Reusable Software Components .  We
                          will not create a semaphore object as done in that text, but the program
                          will follow the items shown there.
                              A semaphore is merely a flag that is attached to a process like a
                          program or a function. The semaphore is set and the calling program is
                          not able to proceed until the called program resets the semaphore. This
                          reset is usually done in an interrupt service routine implemented in the
                          called program. Let’s look at the elements of a semaphore first.
                              When a semaphore is set, it usually marks a resource as busy. It is
                          interesting, but you will find that many semaphores are used around
                          interrupt service routines and while interrupts are being used. Often a
                          strange race condition can occur that will cause a semaphore to be
                          improperly set. Suppose that I want to set a flag, semaphore, to indicate
                          that a resource is busy. The process of setting the semaphore is to first


            3   Reusable Software Components, Ted Van Sickle, Prentice Hall, Upper Saddle River, NJ, 1997
   407   408   409   410   411   412   413   414   415   416   417