Title: Using Timers for RealTime Programming
1Lecture 5
- Using Timers for Real-Time Programming
2Recap
Covered in Detail
Covered with a few things missing
3Timers
Max Value
pulse
Counter
zero
clk
- Timers are on-chip logic structures intended
mainly for generating the clock/timing signals
for various peripherals, including serial ports,
pulse-width-modulators, quadrature decoders, and
interrupts.
4Why Do We Need Timers?
- Timers provide a tool for creating a
(surprisingly) flexible, high-speed, real-time
interface with the real world. - A prevalence of timers is generally a feature of
microcontrollers (and DSPs) that differentiate
them from general purpose microprocessors (i.e.,
desktop processors). - When using event driven programming, some events
are asynchronous to our system, and the embedded
system reacts to them - For example, a button press on the Denon Home
Theatre In a Box our embedded system
controlling this would merely react to the button
press - We would determine our latency requirements and
program our system accordingly - However, many events that we face when performing
embedded programming need to be (tightly)
synchronized to a clock - Dont want the complexity of keeping track of
elapsed time with a while(1) loop
5Timer Example AGC
- For example, consider Automatic Gain Control on a
receiver - If the input power reaches the AGC set point,
introduce attenuation - If the input power is an attenuation step below
the set point after a timer period, remove
attenuation - Set a timer to interrupt with the appropriate
period to check if AGC should be removed uP
then does no processing except for handling the
interrupt
Attenuation
AGC Decay Time Constant
AGC Set Point
Measured Input Power
Time
input
uP
Avg Power Measure
RCVR Frontend
Peak Power Measure
int
ATTN
Rest of RCVR
set point
6Timers for Event-Driven Operation
- Many events that we face when performing embedded
programming need to be synchronized to a clock - A/D conversion
- Operating a motor
- Serial ports
- Timers allow us to perform event-driven
operations on a on an accurate time-scale without
tying up our processor (allow for hard RT systems
i.e. deterministic performance) - Timers give us greater time resolution than we
could accomplish (easily at least) using
sequential programming techniques
7Timer Example Serial Port
If synchronous serial port being used, must
provide this clock, else must provide a clock 16
times faster to sample
8Timer for A/D Conversion
Startconversion
Startconversion
Startconversion
Startconversion
fs 1/t
A poorly timed convert signal would introduce
phase noise
9Basic Timer Structure
- Timer A
- Simple
- Generate baud clocks for serial ports
- Interruptible
- Chainable
- Also handle Input Capture, PWM, and Quadrature
Decode
mux
- Timer B
- Interruptible
- Free-running (used to manually time events)
- Clock parallel ports
- More precise synthesis and measurement of events
10Peripheral Clock
- Peripheral clock can be set to same speed as
processor or various multiples of it - Allows for lower power processing while still
preserving timing resolution - May want to run faster if uP is slave to another
device (need extra clock cycles to synchronize) - Note that peripherals cannot be clocked slower
than processor
11Timer A Structure
- Timers A1 and A2A10 are 8-bit countdown
registers - The reload register can contain any number in the
range from 0 to 255. The counter divides by
(n1). - For example, if the reload register contains 127,
then 128 pulses (or clocks) enter on the left
before a pulse exits on the right - If the reload register contains zero, then each
pulse (or clock) on the left results in a pulse
on the right, that is, there is division by one.
12Timer A Phase
- It is possible that an application would require
multiple timers to be phase-locked (i.e., produce
pulses at the same time) - Since the timer counters are all free-running and
can not be reset, this must be accomplished in
the following manner - Set the counter reload value to 0x0
- Wait until the longest possible countdown has
completed (this condition will be met when all
counters with 0x0 value report an interrupt on a
Timer A interrupt) - Reload the counters that need to be phase locked
with the new value both timers will now be
phase-locked
13Timer A Registers
14Timer A Interrupts
- For seven of the counters (A1-A7), the terminal
count condition is reported in a status register
and can be programmed to generate an interrupt - There is one interrupt vector for Timer A and a
common interrupt priority - TACSR has a bit for each timer that indicates if
the output pulse for that timer has taken place
since the last read of the status register. - When the status register is read, these bits are
cleared. No bit will be lost. Either it will be
read by the status register read or it will be
set after the status register read is complete. - If a bit is on and the corresponding interrupt is
enabled, an interrupt will occur when priorities
allow. - A separate interrupt is not guaranteed for each
bit with an enabled interrupt - It is possible that one bit will cause an
interrupt, and then one or more additional bits
will be set before the status register is read. - The proper rule to follow is for the interrupt
routine to handle all bits that it sees set.
15Timer A Interrupt Example (1)
void main() unsigned int cnt,
state //directive to setup interrupt at
compile time SetVectIntern(0x0A,
timera_interrupt) config_leds() config_timera
()
PCLK29.4 MHz
14.7 MHz
57.4 kHz
224.3 Hz
.0449 Hz
Timer A1 256
Timer A2 256
interrupt 5001
PCLK 2
Outputevery 22.3 s
16Timer A Interrupt Example (2)
void config_timera() asm Timer A Control
Register ld a,0x05 bit2, Tmr A2 clocked by
A1 ioi ld (TACR),a bit0, ints are priority
1 Timer A Prescale Register ld a,0x1 bit
0, Timer A is periph clock / 2 ioi ld (TAPR),
a Timer A Time Constant 1 Register ld a,0xFF
load max value (divide by 256) ioi ld (TAT1R),
a Timer A Time Constant 2 Register ld a,0xFF
load max value (divide by 256) ioi ld (TAT2R),
a Timer A Control/Status Register
ld a,0x5 bit2, Tmr A2 int enabled ioi ld
(TACSR),a bit0, TmrA clock enabled endasm
17Timer A Interrupt Example (3)
interrupt void timera_interrupt() asm ioi ld
a, (TACSR) read the status register endasm
intCnt if (intCnt gt 5000 ) intCnt
0 asm ld a,(PGDRShadow) use shadow register
to keep other bit values bit DS1,a
read the current value of the
LED jp z,turnOff1 if 0, jump to turnOff, if 1
fall through to On turnOn1 ld a,(PGDRShadow) u
se shadow register to keep other bit
values res DS1,a clear bit 7 only ioi ld
(PGDR),a write data to port g ld (PGDRShadow),
a update shadow register jp done1 turnOff1 l
d a,(PGDRShadow) use shadow register to keep
other bit values set DS1,a set bit 7
only ioi ld (PGDR),a write data to port
g ld (PGDRShadow),a update shadow
register done1 endasm
18I/O Clocked on Timer A
- With Rabbit, I/O can be clocked using a timer
pulse as the clock - This allows for the precise generation of
arbitrary output pulses - An interrupt based on the timer can set up the
next output value, which is then clocked on the
next timer pulse
19Timer A Serial Ports
- Topic of their ownwill talk about in later
lecture. - Min and Max baud rate
20Timer Related Function PWM
LUT pwm f(speed sensor, psi, temp, feedback,)
uP
PWM signal
BrakePedal
MasterCylinder
Brake
valve
PWMWaveform
50
25
75
95
21Timer Related Functions PWM
PWM0
PWM1
10 bit Counter
PWM2
PWM3
22Spread PWM
23Timer Related Functions PWM
- A new PWM interrupt can be set up to be requested
on every PWM cycle, every other cycle, every
fourth cycle, or every eighth cycle. - Options are available to suppress the PWM output
for seven-of-eight, three-of-four and one-of-two
iterations of the PWM counter - The one-of-eight option works nicely with R/C
servos, which require a 1 ms to 2 ms pulse width
and a 20 ms period - This option gives the full resolution for the
pulse width while still meeting the period
requirements
NOT OUR VERSION
24Optical Incremental Encoder
Knob Interface The optically encoded knobs put
out two out of phase pulse trains which differ in
relative phase depending on the direction in
which the switch is turned.
25Optical Incremental Encoder
- Incremental rotary encoder provides information
about the instantaneous position of a rotating
shaft - It does this by producing one square wave cycle
per increment of shaft movement - This increment is referred to as the resolution
of the encoder and is built directly into the
internal hardware of the device - A resolution of 360 means that 360 square wave
cycles will be produced in one complete rotation
of the shaft - By counting the number of cycles, one can tell
the position of the shaft, relative to its
starting position. In our example, 90 cycles
means that the shaft is now at a position 90
degrees from where it started - By adding a quadrature signal, we can measure the
direction of the rotation, by reading which
signal (A or B) we measured first) - Often a Zero signal is added so that the zero
position can be known - Commercial (i.e., volume dial) and industrial
(conveyor belt control, motor feedback) uses
26Optical Incremental Encoder
Index slot, often called Z slot
Light source from above illuminates
- Two photodiodes underneath produce a voltage when
illuminated - The two photodiodes are mounted with a ¼ the
pitch of the slots in between then, thus forming
the 90 phase difference between the two detected
signals
Better picture on Page 49 of text.
27Quadrature Decoding (1)
Page 49 of text describes in terms of gray code
Signal A
Signal B
- Write an interrupt that sums up the counter value
on every interrupt - Periodically (when you want to know that state of
the dial) request the summed value and read the
current value of the quadrature counter
Up-Down Counter
Q. How could we use the Z or Index signal?
28Quadrature Decoding (2)
- Additional Information
- Quadrature Decoders are clocked off of Timer A10
- Both the I and the Q inputs go through a digital
filter that rejects pulses shorter than two clock
periods wide - Clock rate must be high enough so that I and Q
input are sampled in different clock cycles - Presume 2 rps, 40 divisions 1/(804) 4.2 ms, 4
times over-sampling would be 1.05 ms or 960 Hz
29Quad Decoder Configuration
- In R3000.lib
- nodebug void qd_init(int iplevel)
-
- SetVectIntern(0x19, qd_isr)
- qd_zero(1)
- qd_zero(2)
- WrPortI(TAT10R, TAT10RShadow, QD_DIVISOR)
- //set quad inputs to lower nibble of port F
- WrPortI(QDCR, QDCRShadow, 0x88 iplevel)
30quad_isr and qd_read()
- quad_isr sums qd_count every time the quadrature
decoder interrupt is thrown
nodebug long qd_read(int channel) auto long
temp_reading if(channel 1) while(1)
qd_isrflag 0 temp_reading qd_count0
RdPortI(QDC1R) if(qd_isrflag
0) return temp_reading else
while(1) qd_isrflag
0 temp_reading qd_count1
RdPortI(QDC2R) if(qd_isrflag
0) return temp_reading
31HC12 Timers
- Enhanced capture timer (ECT)
- 16-bit main counter with 7-bit prescaler
- 8 programmable input capture or output compare
channels 4 of the 8 input captures with buffer - Input capture filters and buffers, three
successive captures on four channels, or two
captures on four channels with a capture/compare
selectable on the remaining four - Four 8-bit or two 16-bit pulse accumulators
- 16-bit modulus down-counter with 4-bit prescaler
- Four user-selectable delay counters for signal
filtering - 4 PWM channels with programmable period and duty
cycle - 8-bit 4-channel or 16-bit 2-channel
- Separate control for each pulse width and duty
cycle - Center- or left-aligned outputs
- Programmable clock select logic with a wide range
of Frequencies - Serial interfaces
- Two asynchronous serial communications interfaces
(SCI) - Synchronous serial peripheral interface (SPI)
NEXT CLASS
32HC12 PWM
33Basic Timer Structure
- Timer A
- Simple
- Generate baud clocks for serial ports
- Interruptible
- Chainable
- Also handle Input Capture, PWM, and Quadrature
Decode
mux
- Timer B
- More precise synthesis and measurement of events
34Input Capture
- The input capture peripheral is used to time
input signals from various input ports - Baud rate detection
- measure width of pulses to negotiate baud rate
- Measure speed of quadrature decoder
- Measure time between pulses to determine
rotational speed - Use simply as four additional external interrupts
35Input Capture HW
Latch register
Overflow latch
16-bit counter
Clk (Timer A8)
enable
Enable/LatchLogic
Start Detect(rising, falling, either)
mux
interrupt
Stop Detect(rising, falling, either)
mux
36Major Modes of Operation
- The counter starts counting at the Start
condition and stops counting at the Stop
condition - I.e., for pulse width measurement on a single pin
or time delay between two signals - The counter runs continuously and the Start and
Stop conditions merely latch the current count - Useful for time-stamping inputs to the counter
(may need to keep track of overflow note there
is not an overflow interrupt) - The counter runs continuously until the Stop
condition occurs - measures the time from the software-defined
counter Start until the Stop condition occurs on
an input - Note that once the counter stops because of the
Stop condition, it will not resume counting until
re-enabled by software
37Input Capture Registers
38Input Capture Example
- void main()
-
- unsigned long time_start
- unsigned int num_clocks, condition
- config_leds()
- config_timera()
- config_input_capture()
- while (1)
-
- asm
- ld a, 0x80
- ioi ld (PGDR),a
- endasm
- WrPortI(PGDR, PGDRShadow, 0x00)
- //pause
- time_start SEC_TIMER
Capture this
39Input Capture Example (2)
- WrPortI(ICCSR, NULL, 0x0C) //bit 4, note no
interrupts - //bit 3, reset IC2 counter/rollover latch
- //bit 2, reset IC1 counter/rollover latch
- asm
- ld a, 0x80
- ioi ld (PGDR),a
- ld a, 0x00
- ioi ld (PGDR),a
- endasm
- //pause
- time_start SEC_TIMER
- while (SEC_TIMER - time_start lt 1)
- //turn off both lights
- WrPortI(PGDR, PGDRShadow, 0xFF)
- //report for assembly
- num_clocks RdPortI(ICM1R) ltlt 8
RdPortI(ICL1R)
Capture this
40Input Capture Example (3)
- void config_input_capture()
-
- WrPortI(ICT1R, NULL, 0x5A) //bit 6, count from
start to stop - //bit 4, latch count on stop
- //bit 3, start on falling edge
- //bit 1, stop at input falling edge
- WrPortI(ICS1R, NULL, 0x01) //0x01 upper nibble,
start with port C, bit1 - // lower nibble, stop with port C, bit3
- WrPortI(ICCR, NULL, 0x01) //bit 0, set
priority 1 interrupt - WrPortI(ICCSR, NULL, 0x0C) //bit 4, note no
interrupts - //bit 3, reset IC2 counter/rollover latch
- //bit 2, reset IC1 counter/rollover latch
41Input Capture Example
31 (31/2 15.5)
15 (15/2 7.5)
42RST
43Timer A Prescale
- void config_timera()
-
- asm
- Timer A Control Register
- ld a,0x00
- ioi ld (TACR),a
- Timer A Prescale Register
- ld a,0x01 bit 0, Timer A is periph clock / 2
- ioi ld (TAPR), a Timer A Time Constant 2
Register - ld a,0x00 load min value (no divide)
- ioi ld (TAT8R), a Timer A Control/Status
Register - ld a,0x1 bit0, TmrA clock enabled
- ioi ld (TACSR),a
- endasm
This affects the debug interface!!!
44Timer A Prescale
- From the BIOS
-
- Read the time constant for 19200 baud
calculated by the BIOS... - ld a, (bios_divider19200)
- ld b, a
- ifdef USE_TIMERA_PRESCALE
- enable timer A prescale if desired
- xor a
- ioi ld (TAPR), a
- sla b if prescale
enabled, multiply constant by two - endif
45Timer A Prescale
- // Timer A prescale information (Rabbit 3000
only) - //define USE_TIMERA_PRESCALE // The Rabbit
3000 has the ability to - // run the
peripheral clock at the - // same
frequency as the CPU clock - // instead of
the standard CPU/2. - // Uncomment
this macro to enable - // this feature.
Or
46Timer B Structure
47Timer B Registers
- To Read Timer B
- Read the lower 8 bits (read TBCLR register).
- Read the upper 2 bits (read TBCMR register)
- Read the lower 8 bits again (read TBCLR register)
- If bit 7 changed from 1 to 0 between the first
and second read of the lower 8 bits, there has
been a carry to the upper 2 bits. In this case,
read the upper 2 bits again and decrement those 2
bits to get the correct upper 2 bits. Use the
first read of the lower 8 bits. - This procedure assumes that the time between
reads can be guaranteed to be less than 256
counts. This can be guaranteed in most systems by
disabling the priority 1 interrupts, which will
normally be disabled in any case in an interrupt
routine.
48Timer B Uses
- By setting the speed of the counter clock,
precise, arbitrary, waveforms can be generated - Need to set the value on the output port
- Minimum pulse width 5 us
- 19 Clocks for interrupt (from manual)
- (1/29.4e6)19 .64 us
- Give yourself 15 instructions at 10 clocks each
- (1/29e6)1510 5.1 us
- Resolution
- Determined by clock width possible to have PCLK
at full clock speed (Timer A1 w/o division) - (1/29.4e6) 34 ns
- Can measure SW events by reading the TIMER B
Count Register - By setting the match register to 0, Timer B can
behave like Timer A
49Timer B Uses
- If desired the capture counter can be
synchronized with Timer B outputs used to
synchronously load parallel port output registers - This makes it possible to generate an output
signal precisely synchronized with an input
signal - The count offset can be measured by outputting a
pulse at a precise time using Timer B to set the
output time and capturing the same pulse - Once the phase relationship is known between the
counters it is then possible to output pulses a
precise time delay after an input pulse is
captured, provided that the time delay is great
enough for the interrupt routine to processes the
capture event and set up the output pulse
synchronized by Timer B - The minimum time delay needed is probably less
than 10 microseconds if the software is done
carefully the clock speed is reasonably high.