Time is of the Essence Part 2 (PIC Microcontroller)

With the initialization code in situ all that remains is to implement the Interrupt Service Routine (ISR) that will be automaticlly entered after each batch of 24 cans. When this occurs, Timer 0 will set T0IF and the PIC will jump to the Interrupt vector at 004h. In our initialization code we have placed a goto ISR at this point and so named the routine in Program 13.1.

Program 13.1 The bean counter Interrupt Service Routine.

Program 13.1 The bean counter Interrupt Service Routine.

The ISR itself is sandwiched between the normal context switching wrapper described in Program 7.2.The core simply implements the following task list in no particular order:

• Toggle RB1 to signal the packing machine.

• Reset Timer 0 to -24.

• Increment the double-byte score count.

• Reset the Timer 0 Interrupt flag T0IE.

In Program 13.1 T0IE is tested on entry and if not set the ISR is exited. If there are other sources of interrupt then the switch would be to another part of the ISR, as shown in the listing.


For an alternative approach using hardware interrupts see Program 7.2.

Our second example illustrates the use of Timer 0 as a clock to measure time between events. The events in question are R-points peaks in the ECG waveform illustrated in Fig. 7.1. Here a peak detector interrupts the MCU, which keeps a 2-byte count from a 10 kHz external oscillator. In this manner the period between events can be determined on each event in increments of 100 is, which we call here jiffies. For our example we will modify the specification to eliminate this oscillator and use Timer 0 to keep a 1 ms 2-byte Jiffy tally.

For this task we need to use the main PIC oscillator as the clock source together with the prescaler that so that Timer 0 overflows once per millisecond (103 is). If we choose a 4.096 MHz crystal we have:

tmp9285_thumb

which gives a required prescale ratio of 1:4.

With these requirements in mind we have for our initialization background software:

tmp9286_thumb

As well as enabling the Timer 0 interrupt, INTE is set to enable hardware interrupts from the INT pin which is going to signal an ECG peak. Neither the double-byte Jiffy count nor Timer 0 need be cleared as the first reading of the series will always be erroneous – as the patient’s heartbeat is not synchronized to the PIC reset! However, file register NEW which is set to non zero each time an ECG peak is detected is cleared.

Program 13.2 Measuring the ECG waveform period to a resolution of 1 ms.

Program 13.2 Measuring the ECG waveform period to a resolution of 1 ms.

The core of the ISR shown in Program 13.2 implements the following task list when an interrupt is received:

1. IF Timer 0 interrupt.

• Increment 2-byte Jiffy count.

• Reset Timer 0 interrupt flag.

• Return from interrupt.

2. ELSE a hardware interrupt form peak picker.

• Copy jiffy count into general-purpose file registers.

• ZeroTimer0.

• Set New flag.

• Reset hardware interrupt flag.

• Return from interrupt.

Both bytes in COUNT:COUNT+1 are copied into the two data file registers DATUM:DATUM+1 when a hardware interrupt is received and the Jiffy count/Timer 0 is then zeroed ready for the next event. When the background program polls file register NEW and finds a non-zero datum then it knows that a fresh count is ready for collection. It then, for instance, could send it to a serial EEPROM as in Example 12.3 or down a serial link to a PC for subsequent processing and display.

Most mid- and high-range PICs have at least two additional timer/counters and associated circuitry with the following properties.

Timer 1

This 16-bit counter has its own dedicated oscillator and programmable prescaler. Its state can be sampled by an external event and it can control the state of a pin when it reaches a pedefined value.

Timer 2

This 8-bit counter has both programmable pre and postscaler facilities. Its count length can be set by the programmer and it may be used to generate a pulse-width modulated output with no on-going software overhead.

Capture/Compare/PWM

Both timers can be used in conjunction with additional logic called Capture/Compare/Pulse Width Modulation (CCP) to implement the Timer1 sample instant (Capture), the Timer 1 roll-over value (Compare) and the automatic PWM generation from Timer 2.

Timer 1 comprises a primary 16-bit counter implemented as a pair of file registers at File 0Eh for the low byte TMR1L and File 0Fh for the high byte TMR1H. The Timer 1 Control register TMR1CON at File 10h configures Timer 1 as shown in Fig. 13.5.

Timer 1 has the option (T1OSCEN in T1CON[3] = 1) of using a separate oscillator from the main PIC oscillator. This avoids having to pick the main crystal to suit the timer, as we did in our Timer 0 bean counter example. Some older PIC devices, such as the PIC16C74A, require the RC0/T1CKI pin to be set as input for the oscillator to function. Newer devices, such as the PIC16C74B, do not need this configuration. The Timer 1 oscillator has a maximum frequency of 200 kHz but is typically used with a 32.768 kHz watch crystal. Where this is the case, Timer 1 will overflow in 2 seconds with a prescale ratio of 1:1 (T1CKPS[1:0] = 00) and a maximum of 16 s for a prescale ratio of 1:8 (T1CKPS[1:0] = 11). When overflow takes place, the Timer 1 Interrupt Flag in the Peripheral Interrupt Register 1 PIR1[0] is set. If the corresponding TMR1IE mask in the Peripheral Interrupt Enable 1 register PIE1[0] then an interrupt will occur. All interrupt flags and mask bits for Timer 1, Timer 2 and their related CCP modules are located in PIR1, PIR2, PIE1 and PIE2 as shown in Fig 14.10(b). To enable all these interrupts the PEIE (PEripheral Interrupt Enable) bit in INTCON[6] must be set as well as the overall GIE global mask bit in INTCON[7]. The latter should be 0 if the only action required is to awaken the PIC from its Sleep state, but PEIE must still be set.

Functional equivalent circuit for Timer 1

Fig. 13.5 Functional equivalent circuit for Timer 1

The Timer 1 oscillator adds approximately 20 ia current drain which is a consideration that is especially important if it is intended to use Timer 1 to awaken the processor. Where power consumption is at a premium then a low-power external oscillator should be considered. In this situation with T1OSCEN = 0 the external oscillator should drive the T1CKI pin. Limitations on the upper frequency of such an input are similar to that discussed for Timer 0. Alternatively the internal PIC clock can be used if TMR1CS is zeroed (the reset condition), but of course this stops when the processor is in its Sleep state.

Output from the programmable prescaler is by default synchronized to the internal clock giving a 2-cycle delay. However, unlike Timer 0 this synchronization shift register can be bypassed withtmp9289_thumbset to 1.

This needs to be done to allow Timer 1 to operate in the Sleep mode as Fosc is disabled in this situation. Apart from this casetmp9290_thumbshould be 0 as the lack of synchronization can lead to an unpredictable outcome if data is written into the two Timer 1 primary registers. If the Timer 1 state is to be updated, then the count should be stopped by clearing TMR1ON during this process; for instance:

tmp9291_thumb

Altering the state of Timer 1 will always clear the prescale counter.

Timer 1 can be read at any time whatever the state of T1SYNCH. However, as only one byte can be read at a time6 it is possible that the timer may have overflowed from lower to higher byte in between the two reads; for example:

tmp9292_thumb

Erroneously reads the state as 81FFh instead of 80FFh. This is even more likely to occur if another peripheral device interrupts between reads. A predictable reading can be obtained by either stopping Timer 1 before taking the readings or by reading the high byte first and then checking after the low byte has been read that the high byte has not changed.

The T1CON register is zeroed on Power-on and Manual reset – see topic B. This means that Timer 1 defaults to off with an internal clock source and prescale value of 1:1.

For our example assume that we have a low-power temperature logger that is to read the sensor and transmit its value back to base once every 15 minutes. It is proposed that Timer 1 be used to action this process and that the Timer 1 oscillator with a 32.768kHz watch crystal is to give the timebase.

Timer 1 has a maximum overflow rate of 16 seconds, but if set to 4 seconds we will have a whole number of 15 interrupts per second. If we keep a Jiffy count then a total of 15 x 15 = 225 will give 15 minutes. Thus our set up and main skeleton software would be something like that shown in Program 13.3. Here Timer 1 is set up to use the external 6In the PIC18CXXX family reading one of the bytes of Timer 1/3 automatically makes a copy of the other byte in a temporary register, effectively giving a single 16-bit time sample.

Program 13.3 Generating a 15 minute data logger timebase.

Program 13.3 Generating a 15 minute data logger timebase.

The ISR simply adds one onto the Jiffy count. This is tested for 225 in the background program after sleep and if equal it is zeroed, the temperature taken and transmitted to base.

Timer 1 can be reset to zero by any Compare/Compare/PWM CCP module. Some PIC devices have two CCP modules sharing the same timer, such as the PIC16C74, and in such cases the second module CCP2 is virtually identical to CCP1 and can share the same timer. With this in mind we will look just at CCP1 for convenience, pointing out any differences at the relevant point. All CCP operations require Timer 1 to be configured in its synchronous mode; that is SYNCH = 0.

Each CCP module has an associated control register. For CCP1 this is CCP1CON at File 1Dh in which the lower four bits CCP1M[3:0] set the module mode. A setting of 0000, the reset value, disables the CCP module, resets the CCP output latch and clears the Capture mode prescaler. Modes 1000 – 1011 listed in Fig. 13.6 give four Compare modes. Here an equality comparator detects when the 16-bit Timer 1 datum equals the setting in the 16-bit CCPR1H:L (CCP Register 1) at File 15:16h respectively. When an equality match occurs the CCP1IF interrupt flag in PIR1[2] will be set and this can cause an interrupt if the corresponding CCP1IE mask bit in PIE1[2] is set.

Next post:

Previous post: