Prof. Leod ECE3375, Winter 2022
This lesson discusses timers. Every microcontroller has at least one, and often several timers, for various pur- poses. The basic operation of timers is discussed, and specific examples of watchdog timers and system clocks are given. Two peripherals that are based on timers: output compare units, and input capture units are dis- cussed. Finally, the structure and operation of the in- terval timers on the DE1-SoC board is explained, with example code given in Assembly and C.
General Motivation
Microcontrollers are usually required to interact with other devices. This often requires the ability to accurately measure intervals of time — and it should be self-evident that a timer is just the sort
Copyright By PowCoder代写 加微信 powcoder
of peripheral for handling this. The basic component of a timer
is an n-bit counter, like the ones you previously studied in digital logic. Of course a useful times has a bunch of extra functionality to control this counter, and as the interval timers on the DE1-SoC board demonstrate all-to-well, using a timer in software can be frustatingly complicated. Fortunately, this handy lesson note is with you every step of the way.
Timing Peripherals
Every microcontroller contains on or more timing peripherals. These are essential for synchronizing the microcontroller with other peripherals, or for allowing controlled delays in program execution. A microcontroller often has several timing peripherals, many with special purpose.
Definition: A timing peripheral, or timer, is a device that counts incre- ments of a well-defined time interval.
This time interval is often not the same as the CPU clock, but is usually a multiple of the clock.
• Some timers may only count up, some may only count down, and others may be configurable to count up or down.
• Timers can be started or stopped.
• Timers may count to some limit and then stop, or may count and then repeat.
Consequently, most timers are reasonably complicated peripherals, and have some structure.
• Most timers have a set of control bits (in a control register) that determine how the timer operates.
• Timers also have a counter register (a data register) that is adjusted to keep track of the time.
• Many timers also have a register that can store a time limit which tells the counter when to stop (another data register).
• The operating state of the timer may also be indicated by a set of status bits (in a status register).
Clearly a timer needs to accept both input and output, as control flags and count limits must be set and the current time needs to be read.
Watchdog Timers
Microcontrollers are typically programmed to run continuously in an endless loop. But — as everyone who has ever used Windows knows all too well — sometimes things go wrong in software. To prevent a microcontroller system from getting stuck forever, and to allow it to restart without user input, every microcontroller has at least one watchdog timer. When the watchdog timer is used:
• The watchdog timer is always counting, and if the count ever wraps around, 1 the microcontroller completely resets.
• Under normal operation, the microcontroller software always rolls back the watchdog timer before it overflows.
• If the system ever gets stuck, the watchdog timer will eventu- ally cause a reset.
• This process is entirely transparent to the user.
Each of the two CPU cores in the Cortex-A9 has a watchdog timer, and two additional watchdog timers are present outside of the CPU on the DE10-Standard board (the HPS L4 Watchdog Timers). There is more than one watchdog because each of these timers has a control bit that determines whether they are to act as a watchdog timer or as a normal general-purpose timer. 2 There isn’t any point in using more than one timer as a watchdog at once.
1 Meaning the counter overflows when counting up, or underflows when counting down.
2 I couldn’t figure out how to fool the online simulator into generating a watchdog-related reset, so there isn’t much I can demonstrate on this subject.
Example: Consider a system with a 1 MHz 16-bit counter watchdog timer. The counter on this timer will overflow in:
216 × (1 MHz)−1 = 65.536 ms.
Before 65.536 ms have elapsed, the CPU needs to manually roll
back, or otherwise reset the watchdog timer.
• If the CPU ever freezes for any reason, it will automati-
cally reset after hanging for 65.536 ms.
System Clock Timers
The most fundamental use of timers is to allow us to perform some action at regular intervals. This is accomplished by setting the counting interval of a timer, and monitoring the appropriate sta- tus bit to determine when that interval is complete.
• This only works if the timer interval is significantly longer than the CPU clock speed (as is often the case) — we typi- cally assume that software instructions are executed instanta- neously.
The exact operation of a system clock timer depends on whether it counts up or down.
Example: An up-counting system clock with a 16-bit counter will set
its timeout flag status bit on each overflow from 0xFFFF to 0x0000. To set a specified time interval ∆t, we should write 0x10000 − f∆t to the data register, where f is the clock speed.
• The timer will start counting at this value, and count up to 0xFFFF before setting the flag.
• If f = 1MHz, and we want to measure an interval of 1ms, we should set the 16-bit counter to (64 536)10.
Example: A down-counting system clock with a 16-bit counter will set its timeout flag status bit on each underflow from 0x0000 to 0xFFFF. To set a specified time interval ∆t, we should write f∆t to the data register, where f is the clock speed.
• The timer will start counting at this value, and count down to 0x0000 before setting the flag.
• If f = 1MHz, and we want to measure an interval of 1ms, we should set the 16-bit counter to (1000)10.
In a simple timer, you may need to reset the interval each time you want to count for that period. More sophisticated timers can “re- member” the time interval, so after a timeout you just need to tell the timer to restart counting. Often these timers can also be oper- ated in a continuous counting mode, where the flag is set after an overflow or underflow, but the count doesn’t stop.
Model Timer
For conceptual questions in this course we will use a very simpli- fied model for a timer, as shown in Figure 1.
• This timer always counts down.
• The timer interval is written to the timer data register.
• The current counting time can also be read from this register.
• Bit 0 in the status register is set to 1 when the timer reaches zero.
It is worth stressing that this is not how the ARM timers work (see below for those gory details).
151413121110 9 8 7 6 5 4 3 2 1 0 [base] + 0x02:Status 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 [base] + 0x00: Timer
Figure1: Structureofthesimplifiedmodelofa timer used in conceptual questions in this course. Note the addresses are based on 16-bit registers, not the 32-bit registers used in an ARM.
Output Compare Units
One common peripheral that is based on a timer is an output com- pare unit. This is a hardware peripheral that will generate some particular output event at specific, precise times.
• Essentially, the output compare unit responds to instructions like: “I want bit 4 of port C to turn on in exactly 100 ms from now”.
• Of course, this can also be done in software, but then the CPU constantly needs to check the status of the timer and may need to suddenly branch out of some other (possibly compli- cated) routine to set the output.
• Once the instruction is written to the output compare unit, however, the CPU can ignore it and continue on with the main program.
An output compare typically requires the following steps to be implemented:
1. Enable an appropriate timer. Sometimes this is built into the unit.
2. Specify a time, usually as some number of “ticks” from the present time.
3. Specify an event to occur when the time interval has elapsed: often toggling some pin on a port. Sometimes this pin is fixed, sometimes it can be specified.
Address Bus mcr Data Bus
The output compare unit will start the timer, set the output after the interval is complete, the unusually set some status flag after it has completed the task. The whole point of an output compare unit is that the above processes occur by the hardware unit, not by direct instruction from the processor.
A model output compare unit is shown schematically in Figure 2, the memory mapped structure is shown in Figure 3. This model operates as follows:
• The timer counts up.
• Control register bits 8, 9, and 10 select one of 8 output pins.
Figure 2: A simplified schematic of an output compare unit (that “sort of works” — probably a few details are missing). Only a single output pin is shown, but consider the tristate buffer by the pin to allow any one of 8 pins to be selected. The count interval is written to the data register, a single status bit (at the bottom) is set when the current count on the 16-bit timer goes above the interval, this also triggers the clock for the D flipflop, allowing the control register value in bit 0 to be written to the output pin.
Control Register
b7 b10 ..b8
16-bit Timer EN
CLR Q[15..0]
D[15..0] Q[15..0]
Data Register
Output Enable Clear
151413121110 9 8 7 6 5 4 3 2 1 0 [base] + 0x04:Status Pin select
151413121110 9 8 7 6 5 4 3 2 1 0 [base] + 0x02:Control 1514131211109 8 7 6 5 4 3 2 1 0 [base]+0x00:Data
• Control register bit 7 clears the timer, control register bit 6 is used to start or stop the timer. Control register bit 0 is the value to be written to the output pin at the given time.
• The time interval is loaded into the data register.
• The time interval is compared to the current count, as soon as the count exceeds that interval, the value in control register bit 0 is written to the output pin and the status register bit 0 is set to one.
Please note that this is just a model that we may use in conceptual questions for this course, this does not necessarily correspond to an actual output compare unit on a real microcontroller.
Note: In various textbooks and technical documentation for micro- controllers, output compare units are often implemented to produce a pulse train of a particular frequency, and some- times even a particular duty cycle. 3 This is basically a clock output, and is an extension of the simple functionality de- scribed here.
Figure 3: Structure of the model output compare unit. Note the addresses are based on 16-bit registers, not the 32-bit registers used in an ARM.
3 This latter functionality, of changing the duty cycle, is sometimes instead described as pulse width modulation (PWM).
Input Capture Units
A second common peripheral that is based on a timer is an input capture unit. This is a hardware peripheral that is the mirror of an output compare unit: this peripheral will record the exact time a particular input is received.
• Essentially, the input capture unit responds to instructions like: “watch pin 7 of port B. Tell me exactly when it goes high.”
• Again, this can be done in software, but that requires the CPU to constantly be checking that input port. If the input result isn’t needed immediately (i.e., it just needs to be recorded
for future use), then the CPU probably has more important things to do.
• Once the instruction is written to the input compare unit, the CPU can ignore it and continue on with the main program.
An input compare typically requires the following steps to be imple- mented:
1. Set a pin to watch.
2. Set a state to watch for (high, low, toggle). 3. Start the timer.
When the appropriate state is present on the particular pin, the timer will stop and save the current count to some data register.
Often a status bit is also set to indicate the event happened. Input capture units often share components — particularly the timer — with output capture units. Again, the whole point of an input cap- ture unit is that the above processes occur by the hardware unit, not by direct instruction from the processor.
A model input capture unit is shown schematically in Figure 4 — I tried to draw the circuit so that the similarity to an output compare unit is reasonably clear. The memory mapped structure would
be the same as the output compare unit shown in Figure 3, except now the data register is for reading from, rather than writing to. This model operates as follows:
• The timer counts up.
• Control register bits 8, 9, and 10 select one of 8 input pins.
• Control register bit 7 clears the timer, control register bit 6 is used to start or stop the timer. Control register bit 0 is the value to be checked against the input pin.
• The input pin is assumed to be digital.
• The first time the input pin matches the specified value, the current count on the timer is stored in the data register.
Control Register
b0 D[15..0] b7 b10 ..b8 b6
Figure 4: A simplified schematic of an input capture unit (that “sort of works” — probably a few details are missing). Only a single input pin
str is shown, but consider the tristate buffer by the pin to allow any one of 8 pins to be selected. The
count interval is written to the data register the first time the input pin reaches the value in bit 0 of the control register.
16-bit Timer
Q[15..0] CLR
mdr Address Bus Data Bus
D[15..0] Q[15..0]
Data Register
DE10-Standard Interval Timer
There are two general-purpose interval timers on the DE10-Standard board that can be configured and used in software. These have the same basic functionality as the model timer described above, but a rather more complicated structure.
• These timers operate at 100 MHz, which is considerably slower than the ARM®Cortex-A9 CPU clock.
• These timers always count down to zero.
We can set the count down interval by writing the appropriate multiple of the timer clock cycles to the appropriate data register.
One or both of the interval timers may be used for the labs in this course whenever a timer is needed. These are memory mapped to the base addresses 0xFF202000 and 0xFF202020. For simplicity, the structure of these timers is based on 32-bit words. However, due to a bunch of reasons, none of the actual inputs or outputs from the timer exceed 16-bit half-words.
• The first word at the base address of the timer is the status register. This uses only two (2) bits!
◦ Bit 0 is a flag that indicates whether or not the timer has reached a timeout — i.e., counted down to zero.
◦ Bit 1 is a flag that indicates whether or not the timer is running.
··· 1716151413121110 9 8 7 6 5 4 3 2 1 0 [base] + 0x14:HighCounter ··· 1716151413121110 9 8 7 6 5 4 3 2 1 0 [base] + 0x10:LowCounter ··· 1716151413121110 9 8 7 6 5 4 3 2 1 0 [base] + 0x0C:HighPeriod
··· 1716151413121110 9 8 7 6 5 4 3 2 1 0 [base] + 0x08:LowPeriod Start
Stop ··· 5 4 3 2 1 0 [base] + 0x04:Control Continue · · · 3 2 1 0 [base] + 0x00: Status
Enable Interrupts Timeout
This status register can be read to determine the current state of the timer. This register can also be partially written to: if the timeout flag was previously set, writing anything to this register will clear it.
• The second word after the base address of the timer is the control register. This uses a whopping four (4) bits.
◦ Bit 0 is a flag that enables the timer to send interrupts to the CPU. We will discuss interrupts in a later lesson. 4
◦ Bit 1 is a flag that tells the timer to count continuously, “wrapping around” back to the period value whenever
the present interval is reached.
◦ Bit 2 is a flag that tells the timer to start counting.
◦ Bit 3 is a flag that tells the timer to stop counting.
Figure 5: Structure of the interval timers on
the DE10-Standard board. The base addresses are 0xFF202000 and 0xFF202020. Note that although the timer is structured in words (32 bits), for legacy reasons at most only half-words (16 bits) are used for each part.
4 Set this bit to 1 in order to generate hardware interrupts, but unless interrupts are also enabled in the CPU nothing will happen.
This register can obviously be written to, as this is how the timer is controlled. It can also be read from, if you forget what the controls were.
• The third and fourth words after the base address are the period registers. These are a type of data register, and are used to set the count interval. Although the count interval is a 32-bit value — and the registers themselves are 32-bits — for legacy reasons this is split into the least significant 16 bits of two registers.
• The final two words after the base address are the counter registers. These are also a type of data register, and are used to record the current count state. Again, for legacy reasons the 32-bit state is split into the least significant 16 bits of two registers.
The structure of the timer is pretty frustrating — why, for a 32-bit timer, on a 32-bit architecture, is it necessary to split the timer inter- val across two half-word registers? Presumably these timers were first developed for 16-bit CPUs, and for “reasons” needs to keep it that way. 5
• My griping aside, reading a writing to the timer isn’t a huge problem as long as you remember how to use the barrel shifter to switch two half-words for word.
To continue complaining about this timer, I find operating it also very confusing.
5 Incidentally, this timer silliness is an issue with the DE10-Standard development board, not the ARM®Cortex-A9 microcontroller, as the timer is an on-board peripheral, not an on-chip peripheral. So direct your complaints to Terasic, not ARM.
• I can’t think of a reason why the control register has one bit for “start” and another bit for “stop”.
• Setting the start bit to 1 will start the timer counting down.
• It seems that setting both the start and stop bit to 1 will also start the timer — it seems the “start bit” takes priority.
• If the timer is running, it will continue to run if the the entire control register is cleared to zero — it seems the “running bit” in the status register takes priority.
• You can’t write directly to the status register, so it seems the only way to turn off the timer (other than letting it count down to zero if the “continue bit” is not set) is to set the “stop bit” to 1 and the “start bit” to 0 in the control register.
Finally, one last complexity! If you want to read the current state of the timer, do not read the period registers. The current count is stored in these registers, but attempting to read them directly will use one or more clock cycles and will make the actual timed interval less accurate.
• Instead, write some value — any value, as it is ignored — to either of the counter registers.
• This will cause the timer to mirror the current count to the counter registers.
• After that, you can read from the counter registers normally. 18
In this simulator, the timer is not completely accurate but it is still pretty close. Note that if you start the timer to run continuously 6 it will do so — even if you stop, or pause the assembly program. This usually isn’t a problem, but can lead to unexpected results if you are trying to time a precise interval and also stepping through your code line-by-line to debug it.
6 i.e. write 0x06 to the control register to set both the “start bit” and the “continue bit”
DE10-Standard HPS Timers
There are four additional general-purpose timers on the DE10- Standard board that are considered part of the “hard processor sys- tem” (HPS). These can be configured and used in software. These have the same basic functionality as the model timer described above, and a simpler structure compared to the interval timers previ- ously discussed.
• Two of these timers operate at 100 MHz, the remaining two operate at 25 MHz.
• These timers always count down to zero.
We can set the count down interval by writing the appr
程序代写 CS代考 加微信: powcoder QQ: 1823890830 Email: powcoder@163.com