Using the Input Capture Functions on the S12

(Enhanced Capture Timer)

ME 4370/5370

Introduction:

(From Cady and Sibigtroth, 2000). The Input Capture (IC) and Output Compare (OC) functions are part of the S12 Enhanced Capture timer (ECT) system. In addition to general I/O, Port T can be used as 8 input capture, 8 output compare, 4 pulse accumulators, or some combination. The input capture function generates an interrupt (and sets a corresponding flag) on a rising or falling edge of an input signal (on a PORT T configured as input) and captures the current value of TCNT on this event in the associated timer compare register. Examples of uses of the IC function include counting events and timing events, decoding waveforms, etc. The output compare generates an interrupt (and sets a flag) when the free-running counter (TCNT) is equal to a 16 bit value stored in the associated timer compare register. In addition to generating the interrupt, the state of the associated output pin can be controlled to go low, high or toggle. Examples of uses of the OC function include generating a wave form with desired frequency and duty cycle or making precise timing applications. Finally, the pulse accumulator will index a counter according to input edges. This discussion will consider the input capture and output compare functions on the HC12

Input Capture:

When a pin on Port T is programmed as an input capture pin, the value of the free-running counter (TCNT) is captured and stored into the corresponding Timer Compare register (TCn) in response to an input signal into a Port T pin. The input capture can trigger on one of the following; 1) a rising edge on PTn, 2) a falling edge on PTn, or 3) a rising or falling edge on PTn. One example use of the input capture function is to measure the period of an incoming wave train. Another example is to accurately measure the time of an event, such as in time-of-flight measurements for an ultrasonic range-finder. Timer channel bits are configured as input captures by setting the desired port pins to 0 in the TIOS register. The edge select for each input capture channel are based on two bits in the TCTL3 and TCTL4 registers. Bits EDGnB and EDGnA control whether input capture n (ICn) is triggered on a rising, falling or both rising and falling edge. The input capture has several associated registers, each is listed below with its corresponding function.

The remainder of this document proceeds as follows:

1)  Summary of important registers for Input Capture/Output Compare

2)  Details of registers for Input Capture Output Compare

3)  Software Checklist for using Input Capture

4)  Example program (in assembly) for using Input Capture

1. Summary of important registers for Input Capture/Output Compare

Timer Count Register, TCNT: This 16-bit register contains the value of the free-running counter.

Timer System Control Register 1, TSCR1: This register controls the timer. In particular, bit 7 called TEN must be set to 1 to enable the timer.

Timer System Control Register 2, TSCR2: This register controls the timer. In particular, bits 0-2 select a prescale from the Eclock.

Timer Input Capture/Output Compare Select, TIOS: The 8 pins, IOS0-IOS7 designate channels on Port T as input captures (value of 0, the default) or output compares (value of 1).

Timer Input Enable Register (TIE) The 8 pins determine whether the associated interrupts are enabled or not.

TC0 –TC7, Timer Compare Registers: These 8, 16-bit registers hold either a) the value of TCNT at a time when a selected edge is detected at the input capture pin or b) the value for comparison with the TCNT register when using the output compare.

Timer Interrupt Flag 1,2, TFLG1, TFLG2 register contains the timer interrupt flags, C0F-C7F. These flags are set when either: a) a selected edge is detected at the input capture pin when using the input capture or b) the value the TCNT and TCn register contents are equal when using the output compare. TFLG2 contains the timer overflow flag.

Timer Control register 1 and 2, TCTL1, TCTL2: These registers control the state change on PortT pins when configured as outputs.

Timer Control register 3 and 4, TCTL3, TCTL4: These registers control the edge-detection ability of the selected input capture pin. These are set as combinations of the EDGnB and EDGnA bits (refer to following figures).


2. Details of registers for Input Capture Output Compare

Timer Input Capture/ Output Compare Select (TIOS)

IOSn: 1 -> Corresponding channel is an output compare

0 -> Corresponding channel is an input capture

Timer Count Register (TCNT)

The 16 bit timer counter

Timer System Control Register 1 (TSCR1)

TEN = Timer enable (1 enabled, 0 disabled)

Timer Control Registers 1 and 2

Use when the channel is configured as an output compare, set OMn/OLn according to the following table:

Timer Control Registers 3 and 4

Use when the channel is to be configured as an input capture, set EDGnB,A according to the following table:

Timer Interrupt Enable Register (TIE)

C7I:C0I are timer interrupt enables. 0=> the corresponding bit in TFLG1 is disabled from generating interrupts, 1=> the corresponding bit in TFLG1 will generate an interrupt.

Timer System Control Register 2 (TSCR2)

TOI = Timer overflow interrupt enable (1 enables interrupt when timer overflow flag is set)

PR2, PR1, PR0 = Timer prescaler select bits prescale the module clock to achieve the main timer counter according to the following table

Timer Interrupt Flag 1 (TFLG1)

These bits are set when an interrupt condition has occurred (input for input capture, a successful compare for output compare). To clear a bit in the flag register, write a one to the bit.

Timer Interrupt Flag 2 (TFLG2)

TOF bit is set when TCNT overflows

Timer Input Capture/Output Compare Registers 0-7 (TC0-7)

When channel n is set as an input, TCn contains the value of TCNT captured upon rising or falling input edge (Read time of input edge)

When channel n is set as an output compare, TCn contains the time which is compared to TCNT to trigger an output condition (Write the desired compare time)


3. Input Capture Software Checklist:

1. Initialize the interrupt vectors for each timer channel to be used (as appropriate)

2. Turn the timer system on, by writing a 1 to bit 7 in TSCR (enable the timer).

3. Configure the timer channels as input captures (as desired). Reset bits in the TIOS register (to zero) to enable timer pins as input captures.

4. Configure the TCTL3 and TCTL4 register bits, EDGnB and EDGnA to select the type of edge to cause the input capture trigger.

5. Reset the corresponding Input Capture/Output Compare Channel Flags (CnF) in TFLG1 (Reset by writing a 1 to the flags).

6. Enable the required interrupts in TIE by setting these bits high.

7. Unmask global S12 interrupts in the CCR (clear the I bit in the CCR)with the CLI command.

8. Wait for the input capture to trigger through polling or interrupts (CnF is set) TFLG1.

9. After the input capture event occurs, read the data in TCn register and use according to your application.

10. Reset the CnF bit (interrupt flag bit) in TFLG1.


4. Input Capture Programming Example:w

#include <hidef.h> /* common defines and macros */

#include <mc9s12dp256.h> /* derivative information */

#include <stdio.h>

#include "lcd.h"

#include "pll.h"

#pragma LINK_INFO DERIVATIVE "mc9s12dp256b"

#define CPR 10000

/***************************************************************

* Function prototypes

****************************************************************/

__interrupt void RealTimeInterrupt( void ); //not used

__interrupt void TC1Interrupt( void );

volatile long int encoder=0; //keeps track of ticks on encoder

void main( void )

{

//Initialize Variables here

char counts[17] = " "; //initialize ecounts string for lcd

char deg[17] = " "; //initialize ecounts string for lcd

float degrees;

int duty =0;

int dutyinc = 1;

int invPTH;

int print_ctr;

char str[16];

//Set Data Direction Registries and use _init functions here

DDRT = 0xf0; //set PORT T as input

DDRA = 0; //set port A as input

DDRB = 0xff; // output

DDRP = 0xff;

DDRH = 0; // input

LCD_init(); /* Enable the LCD display */

PLL_init();

//Initialize Timer Capture

TSCR1 = 0x80; //enable timer

TSCR2 = 0x07; //prescale by 128 so each clock cycle is 128/24MHz = 5.333 us.

TIOS = 0; //set timer channels to input capture

TCTL4 = 0x04; //capture on channel 1 on rising edges only

TIE = 0x02; //enable timer interrupt channel 1

EnableInterrupts; //enable global interrupts

//Initialize PWM

PWMCLK = 0b00000001; //select clock SA as clock source

PWMPOL = 0b00000001; //waveform of pwm0 starts high

PWMCTL = 0b00000000; //8 bit pwm

PWMPRCLK = 0b00000011; //set pwm prescaler to 1 (1/24MHz=x)

PWMSCLA = 11; //set pwm prescaler to 2^11 (x us*2*11 = us )

PWMPER0 = 255; //set period to 117.33*256= 30.04ms

PWMDTY0 = duty; //set duty cycle to 43/259%

PWME |= 0b00000001; //enable pwm channel 0

//Enable PLL circuit

PLL_init();

//Enable LCD

LCD_init();

PORTB = 0b00000001; // 1Y - high, 2Y - low, this controls direction, 0b00000010 -> opposite dir

while(1) //wait forever

{

degrees = (360.0 / CPR)*encoder; //calculate degrees shaft has turned

sprintf(counts, "Counts = %7ld", encoder); //int to string

writeLine(counts, 0); //print encoder data to lcd

sprintf(deg, "Degrees = %6d", (int)degrees); //int to string

writeLine(deg, 1); //print encoder data to lcd

//sprintf(str,"Duty Cycle = %-4d",duty) ; //print duty cycle

//writeLine(str,0);

PWMDTY0=50;

}

}

__interrupt void RealTimeInterrupt( void ) //not used

{

CRGFLG = 0x80; /* clear rti flag */

}

__interrupt void TC1Interrupt( void ) //fires every rising edge

{

TFLG1 = 0x02; /* clear TC1 flag */

if (PORTA & 0b00000001) //increment if channel b on encoder is high

{

encoder++;

}

else //decrement since channel b on encoder is low

{

encoder--;

}

}

7