3.3. PIC16 C Hardware Timers

• Counter/timers

• Capture and Compare

• Timer interrupt

The PIC 16F877 has three hardware timers built in: Timer0 (originally called RTCC, the real-time counter clock), Timer1, and Timer2. The principal mode of operation of these registers are as counters for external events or timers using the internal clock. Additional registers are used to provide Capture, Compare, and Pulse Width Modulation (PWM) modes. The CCS timer function set is shown in Table 3.5

Table 3.5. Timer Functions
ActionDescriptionExample
TIMERX SETUPSet up the timer modesetup_timer0(RTCC_INTERNAL|RTCC_DIV_8 );
TIMERX READRead a timer register (8 or 16 bits)count0=get_timer0();
TIMERX WRITEPreload a timer register (8 or 16 bits)set_timer0(126);
CCPX SETUPSelect PWM, capture, or compare modesetup_ccp1(ccp_pwm);
PWMX DUTYSet PWM duty cycleset_pwm1_duty(512);

.

Counter/Timer Operation

A counter/timer register consists of a set of bistable stages (flip-flops) connected in cascade (8, 16, or 32 bits). When used as a counter, a pulse train fed to its least significant bit (LSB) causes the output of that stage to toggle at half the input frequency. This is fed to the next significant bit, which toggles at half that rate, and so on. An 8-bit counter thus counts up from 0×00 to 0xFF (255) before rolling over to 0 again (overflow). The binary count records the number of clock pulses input at the LSB.

In the ‘877, Timer0 is an 8-bit register that can count pulses at RA4; for this purpose, the input is called T0CKI (Timer0 clock input). Timer1 is a 16-bit register that can count up to 0xFFFF (65,535) connected to RC0 (T1CKI). The count can be recorded at any chosen point in time; alternatively, an interrupt can be generated on overflow to notify the processor that the maximum count has been exceeded. If the register is preloaded with a suitable value, the interrupt occurs after a known count.

The counters are more frequently used as timers, with the input derived from the MCU clock oscillator. Since the clock period is accurately known, the count represents an accurate timed period. It can therefore be used to measure the period or frequency of an input signal or internal intervals or generate a regular interrupt. Many PIC MCUs incorporate one or more Capture, Compare, and PWM (CCP) modules that use the timer registers.

A timer/counter register may have a prescaler, which divides the input frequency by a factor of 2, 4, 8, and so forth using additional stages, or a postscaler, which does the same at the output. Timer0 has a prescaler that divides by up to 128; Timer1 has one that divides by 2, 4, or 8; and Timer2 has a prescaler and postscaler that divide by up to 16.

PWM Mode

In Pulse Width Modulation mode, a CCP module can be used to generate a timed output signal. This provides an output pulse waveform with an adjustable high (mark) period. The high output state, called the duty cycle, is expressed as a percentage of the overall period of the pulse wave. A duty cycle of 50% gives an equal mark and space ratio. Program PWM.C (Listing 3.4) shows the basic setup procedure.

Listing 3.4. Pulse Width Modulation Program Source code

// PWM.C MPB 11-4-07

// Demo PWM output, MCU clock=4 MHz

#include “16F877A.h”

void main()

{

setup_ccp1(ccp_pwm); // Select timer and mode

set_pwm1_duty(500); // Set on time

setup_timer_2(T2_DIV_BY_16,248,1); // Clock rate & output period

while(1){} // Wait until reset

The setup_ccp1() function selects the mode of operation of the CCP module. The function setup_timer_2() controls the overall period of the PWM wave and has three arguments. The first sets the timer prescale division ratio, 16 in this case. The prescaler is an additional counter stage that reduces the input clock rate by the selected ratio of 1, 4, or 16. The second argument gives the overall output period from 1 to 255 times the input clock period. The last value is the postscaler setting, from 1 to 16, which divides the output from the MSB before it is fed to the interrupt system, so that the interrupt period can be adjusted to be a multiple of the timer output. The duty cycle is set via the set_pwm1_duty() function call. The value given is in the range 1–1023, an initial value for a 10-bit counter. The value 500 gives a mark-space ratio of about 50%.

The PWM wave is generated continuously after the setup is completed. The values for duty cycle (500) and overall period (248) used in this example produce an output at CCP1 of 250 Hz (4 ms) and a mark-space ratio of 50% with a 4-MHz MCU clock. The overall period is derived as follows: Timer2 is driven from the instruction clock at 1 MHz (Fosc/4). After prescaling, the clock period is 16 μs and the timer counts up to 248, overflowing approximately every 16×248=3968 μs or about 4 ms (the Figure 248 is used rather that 250 to adjust for software overheads in the timer processing). The postscaler value is set to default ‘1,’ since the timer interrupt is not being used in this example.

The various setup options available for the timers and CCP modules are given in the 16F877 header file in Listing 2.19. Refer to the CCS User Manual for more details about using these options.

Compare Mode

PWM uses the compare operation illustrated in Figure 3.4 to generate a timed output in conjunction with Timer2. The 16-bit CCPR register is preloaded with a set value, which is continuously compared with the Timer1 count. When the count matches the CCPR value, the output pin toggles and a CCP interrupt is generated. If this operation is repeated, an interrupt and output change with a known period can be obtained.

Figure 3.4. Compare Hardware Block Diagram


Capture Mode

This mode uses the timer in the inverse manner to compare. The CCP pin is set to input and monitored for a change of state. When a rising or falling edge (selectable) is detected, the timer register is cleared to 0 and starts counting at the internal clock rate. When the next active edge is detected at the input, the timer register value is copied to the CCP register. The count therefore corresponds to the period of the input signal. With a 1-MHz instruction clock, the count is in microseconds. An interrupt can also be generated on each active edge. The general hardware configuration is shown in Figure 3.5 and a program to demonstrate this operation is shown in Listing 3.5.

Listing 3.5. Capture Mode Demo Program

// PERIOD.C MPB 11-4-07

// Demo of period measurement

#include “16F877A.h” //****************************

#int_ccp1 // Interrupt name

void isr_ccp1() // Interrupt function

{

set_timer1(0); // Clear Timer1

clear_interrupt(INT_CCP1); // Clear interrupt flag

}

void main() //************************************

{

setup_timer_1(T1_INTERNAL); // Internal clock

setup_ccp1(CCP_CAPTURE_RE); // Capture rising edge on RC2

enable_interrupts(GLOBAL); // Enable all interrupts

enable_interrupts(INT_CCP1); // Enable CCP1 interrupt

while(1){}

}

Figure 3.5. Capture Hardware Block Diagram


In the main block of Program PERIOD.C, Timer1 and the CCP mode are set up (RE=rising edge of signal to be captured). The required interrupt is enabled, and the program waits for the CCP1 interrupt, indicating that the next rising edge has arrived. The CCP1 interrupt service routine clears the timer and interrupt, ready for the next capture event. The captured value is copied automatically into a variable called CCP_1. The simulation of this program is shown in Figure 3.6. When the program is run with the 100-Hz signal input, a count of 9963 us is captured (error=0.4%). This shows that some allowance may be needed for the software overhead associated with the capture process and adjustment made to correct the result obtained.

Figure 3.6. Capture Mode Used to Measure Input Period


..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.254.28