Using Timers to count the occurrence of an event
As we discussed in the lesson on creating delays using timers,Timers are usually used to perform three kinds of tasks; creating delays, counting events and measuring the time between events.
In the previous lesson, we looked at the basics of Timers- how to find the Timer interval value based on the frequency of your microcontroller and how to create delays in units of microseconds, milliseconds and seconds. We also explained the meanings of the various Timer configuration modes such 16-bits vs. 32-bits, up vs. down counter as well as Periodic vs. One-shot modes. If you are not familiar with these topics, please take a look at Creating delays with Timers.
In this lesson, we are going to talk about the second use case of Timers- counting events. Events are detected by signal(voltage) level transitions. For example when a switch connected to a microcontroller as an input is pressed, the microcontroller detects this press action because of the signal changes that occur at the pin. As we can see in the diagram below. one leg of the pin is connected to DC 5V and the other leg is connected to the microcontroller pin. When we press the switch to turn it is on, the microcontroller pin receives HIGH signal which in this case is DC 5v and when the switch is off, the microcontroller is disconnected from the DC 5V therefore it goes back to LOW.
Rising-Edge vs. Falling-Egde
The transition of the signal from LOW-to-HIGH gives as the rising-edge and the transition of the signal from HIGH-to-LOW gives as the falling-edge. Besides, we move from DC0V to DC5V by rising and move from DC5V to DC0V by falling.
It is quite important to grasp this concept because this how we really count the occurrence of events and also calculate the duration of particular events.
In this lesson we used a switch as an example because it is the most basic input component. However, the principle works the same way for all other input components such as sensors and the external logic gates we connect to our microcontrollers.
Lets look at a use case. Lets say we are designing a system that count the number of people passing through airport security.We can design a simple low cost “people counter” with a single laser light, a light dependent resistor (LDR) and our microcontroller.
All we have to do is decide on where we want the cross-line, place the laser light on one end and the LDR connected to our microcontroller on the other end and then turn on the laser light and make sure it pointing exactly on the head of the LDR.
Remember the LDR is a light sensor, it changes resistance based on the amount of light shone on its head, because we are not interested in calculating the amount of light, we simply set the microcontroller pin of our LDR as a digital input pin. Now it basically becomes the switch we discussed earlier.
When the path of light between the laser light and LDR is broken, which will happen when people walk-cross the the laser light, the voltage at the microcontoller input pin changes and this change happens in the form rising-edge (or falling-edge depending on how you connect your LDR, whether to GND or DC5V). We can count the number of these changes to determine the number of people who have cross the line.
NOTE : This system is not entirely fool-proof. For instance, when two people walk side-by-by, it will be difficult to count them both. However we hope it provides sufficient explanation on how edge counting works.
Steps to Program Cortex-M Timers for Counting Events
- Enable clock to Timer block
- Disable Timer while changing configuration
- Select Timer mode, 16-bits vs. 32-bits
- Select Timer mode one-shot vs. periodic ,down vs. up, rising-edge vs.falling-edge vs. both
- Set counter limit
- Clear timeout flag
- Enable Timer
- Wait for timeout flag to be set
Apart from the standard steps required to set up the Timer which we talked in about in the previous lesson, there are two more steps we need to take in order to configure the Timer to count edges.
In the Timer Mode Register, we have to configure it as capture mode, and then clear the Timer Capture Mode Register. When this is done, the Timer counts whenever the input pin is triggered. Details of this can be found in the datasheet of the particular cortex-microcontroller we are using. However we provide an example for TM4C Tiva C Launchpad.
In the Timer Control Register, we have to select whether we want to count on a falling-edge, a rising-edge or both. See the example in the link below