13. Time is of the Essence 379
A more robust software system would also enable the Timer 1 overflow interrupt. if this occurs it indicates that the subsequent captured data will be invalid – although time-outs can be counted and thus extend the validity of the captured time. However, in our system it is more likely to be used to set o an alarm!
Timer 2 is an 8-bit counter which has both pre and postscalers. Unlike the two previous timers, output is not taken from the counter chain but from the Timer 2 Comparator. This compares the state of Timer 2 with that in the Period Register PR2. On equality an output pulse is generated which resets Timer 2 at the next clock pulse. This reset signal also sets the Timer 2 Interrupt Flag TMR2IF in PIR1[1]. The number of equality events to set TMR2IF and optionally create an interrupt, is a function of the postscaler. Any integer number between 1 and 16 events can be set up using the TOUTPS[3:0] (Timer 2 OUTput Post Scaler) in the Timer 2 CONtrol register at T2CON[5:2]. T2CON at File 12h also controls the prescaler, giving four divide ratios for the internal clock, and can also be used to disable the timer. The reset state of T2CON is all zeros, disabling the timer and giving a pre/post scaler ratio of 1:1.
The advantage of this architecture is that time-out can be fine tuned by setting the Period Register to an appropriate value, independently of a CCP module. The period until TMR2IF is set is given as:
4/Fosc × Prescale × (PR2 + 1) × Postscale
For our example, consider the need for an interrupt 100 times per second to scan a 7-segment display (see Program 11.8 on page 302) and that the main crystal is 4 MHz. Choosing a prescale ratio of 4:1 gives a clocking period for Timer 2 of 4 µs. If the Period Register is set to 249 then the Timer 2 comparator output period is 250 × 4 = 1 ms. Thus setting
Fosc /4 |
T2CON |
|
|
|
|
|
|
2 |
|
|
|
Timer 2 output |
|
|
TMR2ON |
|
|
|
(to SCI |
port |
baud clock) |
|
|
|
File 11h |
|
|
|
|
Prescaler |
|
Timer 2 |
R |
|
|
|
|
|
|
|
|
|
|
|
÷1, ÷4, ÷16 |
|
|
|
|
|
|
File 0Ch |
|
|
|
TMR2 |
|
|
|
|
|
|
|
|
|
1 |
|
|
|
|
|
|
|
|
TMR2IF |
|
|
|
TMR2 Comparator |
|
|
Postscaler |
PIR1 |
|
|
|
= |
|
|
1 |
|
0 |
|
÷1 to ÷16 |
|
|
|
|
|
|
T2CKS1 |
T2CKS0 |
|
|
|
|
|
|
T2CON |
File 12h |
|
PR2 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Period Register |
5 |
4 |
3 |
2 |
|
|
|
TOUTPS3 TOUTPS2 TOUTPS1 TOUTPS0 |
|
|
|
File 92h |
|
T2CON |
|
|
Fig. 13.8 A simplified equivalent circuit for Timer 2.
380 The Quintessential PIC Microcontroller
the postscaler to 1:10 (1001) will give a 10 ms (100 Hz) interrupt rate. By varying the postscaler from 1 to 16 (TOUTPS[3:0] = 0000 to 1111) respectively we can have an interrupt rate from 1 to 16 ms. For fine adjustments a unit change in PR2 alters the rate by 4 × postscaler × µs.
Set up code for this example is:
movlw |
b’01001101’ |
; Postscale 1:10 (1001), Timer2 on (1) |
movwf |
T2CON |
; Prescale 1:4 (01) |
bsf |
STATUS,RP0 |
; Change |
to Bank1 |
movlw |
d’249’ |
; Set up |
period register to 249 |
movwf |
PR2 |
|
|
bsf |
PIE1,TMR2IE |
; Enable |
Timer2 interrupts |
bcf |
STATUS,RP0 |
; Change |
back to Bank0 |
bsf |
INTCON,PEIE |
; Enable |
all Timer/CCP interrupts |
bsf |
INTCON,GIE |
; Global |
enable |
|
|
|
|
One of the more common applications of MCU-based systems is the control of power circuits, such as heating, lighting and electric motor speed control. One approach to this problem would be to use a digital to analog converter, such as that discussed in Fig. 12.16 on page 328, driving a power amplifier. Linear control is expensive and ine cient due to the large current:voltage products that must be handled by the power amplifier. A rather more e cient and more cost e ective approach rapidly switches the load on and o at a reasonably fast rate. A power switch, such as a thyristor, dissipates relatively little power, as when the switch is o no current flows and when the switch is on the voltage across the switch is low – ideally zero.
An example of such a waveform is shown in Fig. 13.9. The average amplitude is simply A × N%, where N is the duty cycle percentage of the repeat period. If we vary N from 0 to 100% then the average power will vary in a like fashion – all without the benefit of analog circuitry. This digital to analog conversion technique is known as pulse width modulation (PWM).
The thermal or mechanical inertia of most high-power loads is such that even with a relatively low repetition rate (typically no lower than 100 Hz) the ‘bumps’ will be smoothed. Low switching rates are more efficient, as each switching action dissipates energy. If PWM is used for more conventional digital to analog conversion, such as for audio, then a
Fig. 13.9 Pulse width modulation.
13. Time is of the Essence 381
low-pass filter may be utilized to reduce the high-frequency harmonics. In such cases a sampling rate of at least ten times the maximum analog signal should be used to space out the harmonics (see Fig. 14.3 on page 396) and reduce the necessary filtering burden.
It is relatively easy to generate a PWM waveform solely in software by simply counting and setting a port pin when the count rolls over to zero and resetting the pin when it equals the datum representing the duty cycle. Thus if the duty cycle datum was 9Fh and the period count was module-256 (00–FFh) then the average power would be 62.5% (58 ).
CCP modules have a PWM mode in conjunction with Timer 2, as shown in Fig. 13.10. Here Timer 2 runs with a period determined by the main crystal, prescaler and Period Register 2 as previously described. When the Timer 2 comparator causes the count to reset, it also sets the PWM latch. This gives the PWM repeat period.
A second CCP equality comparator matches the 10-bit duty cycle number which is set up by the program in CCPR1L and the two bits DC1B[1:0] (Duty Cycle 1 Bits) in CCP1CON[5:4]. Taken together this gives a 10-bit duty-cycle datum DC1B[9:0]. This datum is loaded into the CCPR1H and a slave 2-bit latch each time Timer 2 rolls over. CCPR1H is not directly writable to in this mode. Thus we have the following sequence of operations repeated indefinitely:
|
|
CCPR1L |
|
5 |
|
4 |
CCP1CON |
|
|
|
DC1B1 DC1B0 |
File 17h |
|
|
|
|
|
|
|
Duty cycle |
|
|
|
|
|
|
|
registers |
|
|
|
|
|
|
|
|
Slave |
CCPR1H |
C |
Latch |
C |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PWM latch |
|
|
|
|
|
|
|
RC2/CCP1 |
|
|
10-bit PWM Comparator |
= |
|
R |
|
|
|
|
|
|
|
S |
|
|
|
|
Timer 2 |
Prescaler |
|
|
Timer 2 |
1RC1 |
1R |
C1 |
|
Fosc /4 |
|
|
|
|
T2CKPS[1:0] |
Period |
|
8-bit TMR2 Comparator = |
|
|
|
|
registers |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
CCP1M[3:0] = 11XX |
Period Register
Fig. 13.10 Timer 2 and the PWM CCP mode.
382 The Quintessential PIC Microcontroller
1.Timer 2 increments.
2.When Timer 2:Prescaler equals DC1B[9:0] the PWM latch resets and pin CCP1 goes low.
3. The |
next clock pulse after Timer 2 reaches the datum in PR2 it is reset. |
The |
PWM latch is set, CCP1 goes high and the 10-bit slave duty cycle regis- |
ter/latch us updated. 4. Goto item 1.
From the above description we see that:
•The PWM period is set by the Timer 2/PR2 time-out.
•The duty cycle is set by the 10-bit datum in CCPR1L:CCP1CON[5:4].
•The duty cycle datum can be glitchlessly changed by the software at any time by updating the slave registers and will take e ect in the PWM period following this update.
•The RC2/CCP1 pin direction should be set to output.
Where the Timer 2 prescale is set to 1:1 the lower two bits used on the timer side are the quadrature clock phases described in Fig. 4.4 on page 87. This gives a period resolution equal to the crystal period. In all cases the datum in CCPR1L must be smaller than that in PR2, otherwise the PWM latch will never reset!
If PR2 is FFh then the resolution of the system is a full ten bits. Smaller values of Timer 2 period data will reduce this resolution. For example, if PR2 = 3Fh then the resolution is reduced to eight bits – six in PR2 and two in the prescaler.
For our example let us assume a crystal frequency of 20 MHz, a prescale ratio of 1:16 and a PR2 value of FFh. In this case the PWM frequency is 204 × 161 ×256 = 1.22 kHz. A prescale ratio of 1:1 would increase the period frequency to 19.53 kHz. Reducing the value in PR2 would also increase the repetition frequency. The programmer need only place the duty cycle datum in CCPR1L and CCP1CON[5:4] (the latter can be left at its reset value of zero if the datum is to be treated as 8-bit) and a PWM signal will automatically be generated with no software overhead. Set up code for this instance would be:
bsf |
STATUS,RP0 |
; Change to Bank0 |
movlw |
FFh |
; Set up Timer2 Period register |
movwf |
PR2 |
; to FFh |
bcf |
TRISC,2 |
; Make RC2/CCP1 an output |
bcf |
STATUS,RP0 |
; Change back to Bank1 |
movlw |
b’00001100’ |
; CCP1 module PCM mode (1100) |
movwf |
CCP1CON |
|
movlw |
b’00000110’ |
; Timer2 prescale 16:1 (10), |
movwf |
T2CON |
; Timer2 on (1) |
|
|
|
The Timer 2 postscaler does not a ect the PWM generation but still sets the TMR2IF in the normal way. The CCP1IF is not altered in this mode.
13. Time is of the Essence 383
If a second CCP module is used, an extra PWM output at pin RC1/CCP2 is available with a separate duty cycle but an identical period, as Timer 2 is a shared resource.
Examples
Example 13.1
Show how you could use Timer 0 to generate a PWM version of a digital byte in file register DATUM using pin RA0 as the output. Assuming an 8 MHz crystal, calculate the PWM duration.
Solution
Timer 0 will give a time-out related to a number loaded into the timer at the beginning of the period. If we load in the the 2’s complement of the byte (the negative value) then the duration will be proportional to this value – the larger it is the longer the timer has to count before overflowing. Conversely loading in the value of DATUM will give a time-out duration inversely proportional to the value. By alternately loading the 2’s complement of DATUM and making the pin high followed by DATUM itself making the pin low will give us a total period approximately the same as a total Timer 0 time-out as if counting through all 256 states.
The coding of Program 13.5 sets up Timer 0 to count 2 MHz internal clock cycles with no prescale. Thus the total PWM rate is 2562 or 7.8125 KHz. When Timer 0 overflows it generates an interrupt. The ISR checks the state of PORTAA[0] and if 0 changes its state and then calculates the 2’s complement of the data byte (invert plus one). However, there is a 2-cycle delay in Timer 0 responding when its state is changed due to the clock synchronizer circuit and so another two is added to compensate for this extra delay. If the port pin was already 1 then it is zeroed and the datum itself plus the compensatory two is written into Timer 0.
Adding the compensation will cause problems at either extremes of the mark:space ratio. Why is this so and what action could you take to ameliorate it?
Example 13.2
A certain tachometer is to register engine speed in the range 0–12,000 rpm (revolutions per second). The engine generates one pulse per revolution and it is intended that a PIC16C74 be used to count the number of pulses each second and calculate the equivalent rpm. Using two of the three available timers can you design a suitable hardware-software configuration?
384 The Quintessential PIC Microcontroller
Program 13.5 Pulse-Width Modulation using Timer 0.
MAIN |
bsf |
STATUS,RP0 |
; Change into Bank 1 |
|
clrf |
OPTION_REG |
; Internal clock, 1;1 prescale |
|
bcf |
TRISA,0 |
; Make RA0 the PWM output |
|
bcf |
STATUS,RP0 |
; Change back to Bank 0 |
|
bsf |
INTCON,T0IE |
; Enable Timer 0 interrupt |
|
bsf |
INTCON,GIE |
; Enable all interrupts |
;<<<< More background code >>>>
;*************************************************************
; * The ISR to generate a PWM waveform at RA0 |
* |
;* Digital byte is in DATUM. PORTA[0] holds current PWM state*
;*************************************************************
;First save context in usual way
ISR |
movwf |
_work |
; |
Put |
away W |
|
swapf |
STATUS,w |
; |
and |
the Status register |
|
movwf |
_status |
|
|
|
;************************************************************
;The core code
|
btfss |
INTCON,T0IF |
; Has Timer0 overflowed? |
|
goto |
ISR_EXIT |
; IF no THEN false alarm |
|
bcf |
INTCON,T0IF |
; Reset interrupt flag |
|
movf |
DATUM,w |
; Get datum |
|
btfsc |
PORTA,0 |
; Is current output low? |
|
goto |
MAKE_LO |
; IF not THEN bring it low |
MAKE_HI |
bsf |
PORTA,0 |
|
|
xorlw |
b’11111111’ |
; ELSE compute 2’s complement |
|
addlw |
1 |
; Invert +1 |
|
goto |
SET_UP |
; and set Timer0 up |
MAKE_LO |
bcf |
PORTA,0 |
; Bring pin low |
SET_UP |
addlw |
2 |
; Compensation for synch delay |
|
movwf |
TMR0 |
; Initialize Timer |
; ************************************************************
ISR_EXIT swapf |
_status,w |
; Untwist |
the original Status reg |
movwf |
STATUS |
|
|
|
|
swapf |
_work,f |
; Get |
the |
original W reg back |
swapf |
_work,w |
; |
leaving |
STATUS unchanged |
retfie |
|
; |
and |
return from interrupt |
|
|
|
|
|
|