Académique Documents
Professionnel Documents
Culture Documents
13-13
n is 0 - 7 for each of the timer channels. Any of the channels can be input capture or output compare.
13-14
'TSCR2' PR2 PR1 PR0 'TSCR2' TOI 00 PACLK PACLK/256 PACLK/65536 01 TCNT Clock 10 MUX 11 CLK1 CLK2 'PACTL' 'TIE' CnI 'TFLG1' 16-Bit Comparator CnF 'CFORC' FOCn 'TCNT' 16-BIT Counter 'TFLG2' TOF 'CCR' I
Output Compare Interrupt Request Port Pin PTn Output Bit Control
'TCTL1 or TCTL2' 'TIOS' 7 6 5 4 3 2 1 0 Set IOSn BIT TO 1 FOR Output Compare OMn OLn
13-15
TC0 Base + $0050, $0051 -- Timer Input Capture/Output Compare Register 0 TC1 Base + $0052, $0053 -- Timer Input Capture/Output Compare Register 1 TC2 Base + $0054, $0055 -- Timer Input Capture/Output Compare Register 2 TC3 Base + $0056, $0057 -- Timer Input Capture/Output Compare Register 3 TC4 Base + $0058, $0059 -- Timer Input Capture/Output Compare Register 4 TC5 Base + $005A, $005B -- Timer Input Capture/Output Compare Register 5 TC6 Base + $005C, $005D -- Timer Input Capture/Output Compare Register 6 TC7 Base + $005E, $005F -- Timer Input Capture/Output Compare Register 7
Bit 15 TC15 Reset: 0 Bit 7 TC7 Reset: 14 TC14 0 6 TC6 13 TC13 0 5 TC5 12 TC12 0 4 TC4 11 TC11 0 3 TC3 10 TC10 0 2 TC2 9 TC9 0 1 TC1 8 TC8 0 0 TC0
0 0 0 0 0 0 0 0 Read: Anytime. Write: Anytime for output compare operations. Writes have no effect in pulse accumulator mode.
13-16
13-17
Example 13-8 1 msec Delay Program in C /******************************************************************* * This program shows how to use the output compare * channel 1 to generate time delays. It outputs a * 500 Hz squarewave on Port T, bit-0 *******************************************************************/ #include <mc9s12c32.h> /* derivative information */ #define MS_1 8000 /* Number clocks per ms */ /*******************************************************************/ void main(void) { /*******************************************************************/ /* Initialize the I/O */ DDRT_DDRT0 = 1; /* Make PT-0 output */ TSCR1_TEN = 1; /* Enable the timer */ TIOS_IOS1 = 1; /* Enable Output Compare 1 */ /* set the output bit high */ PTT_PTT0 = 1; /* Grab the value of the TCNT register and * Add the clocks for 1 msec delay */ TC1 = TCNT + MS_1; /* DO */ for(;;) { /* Reset the OC flag */ TFLG1 = TFLG1_C1F_MASK; /* Wait until it is set */ while (TFLG1_C1F == 0) {} /* Timed out so toggle the bit */ if (PTT_PTT0 == 1) PTT_PTT0 = 0; else PTT_PTT0 = 1; /* Set up the next output compare time */ TC1 += MS_1; } /* FOREVER */ }
13-18
Example 13-7 shows an output compare time delay that can have at most an 8.192 ms delay an 8 MHz bus clock is used. Figure 13-3 shows that the TSCR2 register has three prescaler bits PR2:PR1:PR0. These can be changed to select a prescaler of 1, 2, 4, 8, 16, 32, 64 or 128. Example 13-9 shows a program to generate a 10 ms delay. Lines 24 and 25 set the prescaler bits to 010 to divide by four. Now, each clock pulse is at 0.5 s and a 10 ms delay is represented by 20,000 counts. If you use this technique to generate longer time delays, remember that any changes you make will affect all timing being done by the timer system in other parts of the program.
Example 13-9 Changing the Timer Prescaler Metrowerks HC12-Assembler (c) COPYRIGHT METROWERKS 1987-2003 Rel.Loc ---------1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22000000 23 24000003 25000006 26 27000009 28 2900000D 30 31000010 32 33 34 35000013 36 37 38000017 39 40000019 4100001C Obj. code Source line --------- ----------; This is a test program showing how to ; use the Output Compare to generate time ; delays longer than 8.192 ms by change ; the TCNT register prescaler. ; It outputs a 10-msec-wide pulse ; Port T, Bit 0. ;******************************** ; Define the entry point for the main program XDEF Entry, main XREF __SEG_END_SSTACK INCLUDE timer.inc ; Timer defns INCLUDE base.inc ; Reg base defn INCLUDE bits.inc ; Bit defns INCLUDE portt.inc ;******************************** ; Constants 0000 4E20 MS_10: EQU 20000 ; # Clocks for 10 ms ; Code Section MyCode: SECTION Entry: main: CFxx xx lds #__SEG_END_SSTACK ; Set the prescaler to divide by 4 4C4D 02 bset TSCR2,PR1 ; PR1 4D4D 05 bclr TSCR2,PR2|PR0 ; PR2, PR0 ; Initialize the I/O 1C02 4201 bset DDRT,BIT0 ; Make PT-0 output ; Enable the timer 4C46 80 bset TSCR1,TEN ; Enable Output Compare Channel 1 4C40 02 bset TIOS,IOS1 main_loop: ; DO ; Set the output bit high 1C02 4001 bset PTT,BIT0 ; Delay ten msec ; Grab the value of the TCNT register DC44 ldd TCNT ; Add the number of clocks for 10 msec delay C34E 20 addd #MS_10 5C52 std TC1 ; Set up the next compare
13-19
C code to change the prescaler bits is: /* . . . */ /* PR2:PR1:PR0 = "010" = divide by 4 */ TSCR2_PR2 = 0; TSCR2_PR1 = 1; TSCR2_PR0 = 0; /* . . . */
CnI Timer Interrupt Flags 0 = The corresponding bit in TFLG1 is disabled from generating interrupts (default). 1 = The corresponding bit in TFLG1 may generate an interrupt.
Delays longer than 8.192 ms can be generated by changing the prescaler as shown in Example 13-9 or by waiting for more output comparisons to be made. Example 13-10 and Example 13-11 shows how to generate a one second delay using the output compare flag to generate an interrupt. The delay is achieved by waiting for 250 complete four millisecond delay times generated by the output compare. This is done by reading the TNCT register in line 34 and then generating an interrupt every 4 ms after that. After 250 interrupts, the LED will toggle. A counter for this is initialized in line 32. After the C2F flag is cleared and interrupts enabled and unmasked ( lines 38 - 43), the processor waits for the interrupt to occur (line 46). When it does, the counter is checked to see if it is zero. After the counter reaches zero, it is reinitialized to NTIMES and the LED is
13-20
toggled. The interrupt service routine decrements the counter in line 64. With a bus clock of 8 MHz, each time an interrupt occurs MS_4 (32,000 bus clock cycles) is added to the TC2 register in lines 66 - 69. Finally the flag is cleared in lines 71 and 72.
Example 13-10 1 sec Delay Using Output Compare Interrupts Metrowerks HC12-Assembler (c) COPYRIGHT METROWERKS 1987-2003 Rel.Loc ---------1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22000000 23 24000003 25000006 26 27000009 28 2900000C 30 31 3200000F 000013 33 34000014 35000016 36 37 38000018 3900001A 40 4100001C 42 4300001F 44 45 46000021 47000022 48000025 Obj. code Source line --------- ----------; This is a test program showing a ; one sec delay using output compare ; and interrupts. It flashes LED1 on the ; Student Learning Kit with a CSM-12C32 CPU. ;******************************** ; Define the entry point for the main program XDEF Entry, main,OC2_isr XREF __SEG_END_SSTACK INCLUDE timer.inc ; Timer defns INCLUDE base.inc ; Reg base defn INCLUDE bits.inc ; Bit defns INCLUDE porta.inc ; Port A defns ;******************************** ; Constants 0000 7D00 MS_4: EQU 32000 ; # Clocks for 4 ms 0000 00FA NTIMES: EQU 250 ; Number interrupts 0000 0001 LED1: EQU BIT0 ; LED1 on Port A - 0 ; Code Section MyCode: SECTION Entry: main: CFxx xx lds #__SEG_END_SSTACK ; Initialize the I/O 4C02 01 bset DDRA,LED1 ; Make PA-0 output 4C00 01 bset PTA,LED1; Initial LED display ; Enable the timer 4C46 80 bset TSCR1,TEN ; Enable Output Compare Channel 2 4C40 04 bset TIOS,IOS2 ; Generate a 1 sec delay ; Need NTIMES interrupts 180B FAxx movb #NTIMES,counter xx ; Grab the value of the TCNT register DC44 ldd TCNT 5C54 std TC2 ; Now have 8 msec to set up the system ; Set up the interrupts 8604 ldaa #C2F 5A4E staa TFLG1 ; Clear C2F ; Enable OC2 interrupts 4C4C 04 bset TIE,C2I ; Unmask global interrupts 10EF cli ; Wait until the counter is zero spin: 3E wai ; Wait for interrupt F7xx xx tst counter 26FA bne spin
13-21
Example 13-11 One second delay in C /******************************************************************* * This test program shows a one second delay using output * compare and interrupts. It flashes LED1 on the Student * Learning Kit with a CSM-12C32 CPU *******************************************************************/ #include <mc9s12c32.h> /* derivative information */ #define NTIMES 250 /* Number of interrupts for a second */ #define MS_4 32000 /* Number of clocks for 4 ms */ /*******************************************************************/ void interrupt 10 OC2_isr (void); int counter; /* Global counter for interrupts */ /*******************************************************************/ void main(void) { /*******************************************************************/ /* Initialize I/O */ DDRA_BIT0 = 1; /* Make Port A-0 output */ PORTA_BIT0 = 0; /* Turn the LED1 on */ TSCR1_TEN = 1; /* Enable the timer */ TIOS_IOS2 = 1; /* Enable output compare channel 2 */ /* Initialize the interrupt counter */ counter = NTIMES; /* Set up TC2 */ TC2 = TCNT; /* Now have ~ 8 ms to set up the system without an * interrupt */
13-22
} /******************************************************************* * The interrupt service routine decrements the counter * sets up TC2 for the next interrupt and resets the flag. *******************************************************************/ void interrupt 10 OC2_isr ( void ){ /*******************************************************************/ /* Decrement the counter */ --counter; /* Set up TC2 */ TC2 += MS_4; /* Clear the flag */ TFLG1 = TFLG1_C2F_MASK; /* Clear C2F flag */ } Example 13-12 In Example 13-10 the programmer calculates the count for the next interrupt by adding 32,000 clock cycles to the current value of the TC2 register (lines 68 - 71) . Why didn't the programmer first read the TCNT register and then add 32,000 to find the time for the next interrupt? Solution: Interrupts are required every 4 msec in this example. If the TCNT registger is used every time to calculate the time for the next interrupt, the time interval will be longer than 4 msec because the TCNT register increments with every clock cycle.
Output Compare Interrupt Vectors Each of the eight timer channels can generate interrupts and each has it's own interrupt vector as given in Table 13-3.
13-23
Table 13-3 Output Compare Interrupt Vectors Vector Address $FFE0:FFE1 $FFE2:FFE3 $FFE4:FFE5 $FFE6:FFE7 $FFE8:FFE9 $FFEA:FFEB $FFEC:FFED $FFEE:FFEF Interrupt Source Timer Channel 7 Timer Channel 6 Timer Channel 5 Timer Channel 4 Timer Channel 3 Timer Channel 2 Timer Channel 1 Timer Channel 0 Local Enable Bit C7I C6I C5I C4I C3I C2I C1I C0I See Register TIE TIE TIE TIE TIE TIE TIE TIE HPRIO Value to Promote $E0 $E2 $E4 $E6 $E8 $EA $EC $EE
Priority 15 14 13 12 11 10 9 8
Chapter 13 M68HCS12 Timer TCTL1 Base + $0048 -- Timer Control Register 1 TCTL2 Base + $0049 Timer Control Register 2
Bit 7 TCTL1 Reset: OM7 0 Bit 7 OM3 6 OL7 0 6 OL3 5 OM6 0 5 OM2 4 OL6 0 4 OL2 0 3 OM5 0 3 OM1 0 2 OL5 0 2 OL1 0
13-24
1 OM4 0 1 OM0 0
0 OL4 0 0 OL0 0
TCTL2 Reset:
OMn:OLn Output Compare Bit Control OMn = Output Mode. OLn = Output Level. These pairs of bits specify the output action to be taken as a result of a successful output compare. When either OMn or OLn is one, the pin associated with OCn becomes an output tied to OCn regardless of the state of the associated DDRT bit. Table 13-4 Compare Result Output Action OMn 0 0 1 1 OLn 0 1 0 1 Bit-n Action Timer disconnected from output pin logic. Toggle OCn output line. Clear OCn output line to zero. Set OCn output line to one.
Example 13-13 Output Compare Bit Operation Metrowerks HC12-Assembler (c) COPYRIGHT METROWERKS 1987-2003 Rel.Loc ---------1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18000000 19 20 21000003 Obj. code Source line --------- ----------; This is a test program showing a ; 250 Hz square wave using output compare ; bit control and interrupts ;******************************** ; Define the entry point for the main program XDEF Entry, main,OC2_isr XREF __SEG_END_SSTACK INCLUDE timer.inc ; Timer defns INCLUDE base.inc ; Reg base defn INCLUDE bits.inc ; Bit defns ;******************************** ; Constants 0000 3E80 HALF_P: EQU 16000 ; 1/2 period ; Code Section MyCode: SECTION Entry: main: CFxx xx lds #__SEG_END_SSTACK ; Initialize the I/O ; Enable the timer 4C46 80 bset TSCR1,TEN
13-25
Example 13-14 Write a short section of code to cause Port T, bit -5 to clear the bit when an output comparison is made. Solution: Port T, bit-5 is connected to Output Compare 5. Therefore, use the code ; Set OM5, OL5 in TCTL1 to 1 0 bset TCTL1, %00001000 bclr TCTL1, %00000100
13-26
Exampl e 13-15 Output Compare Bit Operation in C /******************************************************************* * This program outputs a 250 Hz square wave on * Port T, bit-0 using timer channel 0 interrupts and the * output compare bit operations. *******************************************************************/ #include <mc9s12c32.h> /* derivative information */ #define HALF_P 16000 /* Number clocks per 1/2 period */ /******************************************************************/ void interrupt 8 OC0_isr (void); /******************************************************************/ void main(void) { /******************************************************************/ /* Initialize I/O */ TSCR1_TEN = 1; /* Enable the timer */ TIOS_IOS0 = 1; /* Enable output compare channel 0 */ /* Set up TC0 */ TC0 = TCNT; /* Now have ~ 8 ms to set up the system without an * interrupt */ TFLG1 = TFLG1_C0F_MASK;/* Clear C0F flag */ TIE_C0I = 1; /* Enable the interrupt */ /* Set up the output compare action to toggle * Port T, bit-0. (DDRT does not need to be set.) */ TCTL2_OM0 = 0; TCTL2_OL0 = 1; EnableInterrupts; /* DO */ for(;;) { asm (wai); /* Wait for interrupt */ } /* FOREVER */ } /******************************************************************* * The interrupt service routine simply sets up the TC0 * for the next interrupt time. *******************************************************************/ void interrupt 8 OC0_isr ( void ){ /******************************************************************/ /* Set up TC0 */ TC0 += HALF_P; /* Clear the flag */ TFLG1 = TFLG1_C0F_MASK; /* Clear C2F flag */ }
Chapter 13 M68HCS12 Timer TTOV Base + $0047 Timer Toggle on Overflow Register
Bit 7 Read: Write: Reset: 0 0 0 Read: Anytime. Write: Anytime. 0 0 0 TOV7 6 TOV6 5 TOV5 4 TOV4 3 TOV3 2 TOV2
13-27
1 TOV1 0
0 TOV0 0
TOVn Toggle on Overflow 0 = Toggle output compare pin on overflow disabled (default). 1 = Toggle output compare pin on overflow enabled. When this bit is set and the associated output compare channel overflows, the output compare pin is toggled. This is the same as setting OMn:OLn = 10.
13-28
OC7
OC5
OC6
OC7
OC7
OC5
OC6
OC7
OC4 (a)
OC4
OC7
OC7
OC7
OC7
Figure 13-4 (a) Output Compare 7 Controlling Four Bits Each with (a) Shorter Comparison Times; (b) Equal Comparison Times
Example 13-16 Control Five Bits wi th One Output Compare Show an assembly language program to output the waveforms shown in Figure 13-4(a) where the output high times are 2, 1, 0.5, and 0.25 ms.
13-29
Obj. code Source line --------- ----------; This is an example shows how to control ; four bits simultaneously using the ; output compare channel 7. ;******************************** ; Define the entry point for the main program XDEF Entry, main XREF __SEG_END_SSTACK INCLUDE timer.inc ; Timer defns INCLUDE base.inc ; Reg base defn INCLUDE bits.inc ; Bit defns ;******************************** ; Constants 0000 00F0 D_BITS: EQU %11110000 ; Initial pattern 0000 00F0 O_BITS: EQU %11110000 ; The bits to output 0000 3E80 DELAY1: EQU 16000 ; 2 ms - Ch 7 0000 1F40 DELAY2: EQU 8000 ; 1 ms - Ch 6 0000 0FA0 DELAY3: EQU 4000 ; 0.5 ms - Ch 5 0000 07D0 DELAY4: EQU 2000 ; 0.25 ms - Ch 4 ;******************************** ; Code Section MyCode: SECTION Entry: main: CFxx xx lds #__SEG_END_SSTACK ; Initialize the I/O ; Enable Output Compare Ch 7-4 4C40 F0 bset TIOS,O_BITS ; Initialize the mask register 86F0 ldaa #O_BITS 5A42 staa OC7M ; Initialize the data register 86F0 ldaa #D_BITS 5A43 staa OC7D ; Enable the timer 4C46 80 bset TSCR1,TEN ; Wait until the C7F is set main_loop: ; DO ; Wait until output compare 7 hits spin: 4F4E 80FC brclr TFLG1,C7F,spin ; The data in OC7D is output to bits 7 - 4 ; Now set up for the next interval on ; each channel DC5E ldd TC7 C307 D0 addd #DELAY4 ; 0.25 ms 5C58 std TC4 DC5E ldd TC7 C30F A0 addd #DELAY3 ; 0.5 ms 5C5A std TC5 DC5E ldd TC7 C31F 40 addd #DELAY2 ; 1.0 ms 5C5C std TC6 DC5E ldd TC7
13-30
20D4
Explanation of Example 13-16 Example 13-16 illustrates how to control four bits simultaneously using one output compare. PT-7 PT-4, defined by O_BITS in line 14 are to be toggled. The initial data state for these bits is %1111xxxx as defined in line 13 by D_BITS. Output compare channels 7 - 4 are initialized for use in lines 27 35. All four channels must be activated as output compare channels (IOSn = 1). The mask register, OC7M, is set up in line 30 and the initial data is stored in OC7D in line 33. A spin loop is entered at line 41 to wait for the output compare to be made on channel 7. When it does, the data in OC7D is transferred to the output pins automatically. Lines 45 - 56 set up each channel for the next output compare time and reset the C7F flag. Lines 61 - 63 then complement the data bits in the OC7D data register. Because each of the channel six to four have a an output comparison time shorter than channel seven, their values will be switched to the value of the bit in OC7D when their comparisons are made.
Example 13-17 Control Five Bits with One Output Compare in C Show an C program to output the waveforms shown in Figure 13-4(a) where the output high times are 2, 1, 0.5, and 0.25 ms. Solution: /******************************************************************* * This example shows how to control four bits simultaneously * using the output compare channel 7 with each channel * switching at the same time. *******************************************************************/ #include <mc9s12c32.h> /* derivative information */ #define DELAY1 16000 /* Number clocks for 2 ms */ #define DELAY2 8000 /* 1 ms */ #define DELAY3 4000 /* 0.5 ms */ #define DELAY4 2000 /* 0.25 ms */ #define O_BITS 0xF0 /* Bits to be output */ #define D_BITS 0xF0 /* Initial data value to output */ /*******************************************************************/ void main(void) { /*******************************************************************/ /* Initialize I/O */ TIOS = O_BITS; /* Enable output compare bits 7 - 4 */ OC7M = O_BITS; /* Initialize the mask register */ OC7D = D_BITS; /* Initialize the data register */
13-31
- 4 */ bit change */
*/
Example 13-18 Control Five Bits with One Output Compare in C (Equal Comparison Values) Show an C program to output the waveforms shown in Figure 13-4(b) where the output high times are 2 ms. Solution: /******************************************************************* * This example shows how to control four bits simultaneously * using the output compare channel 7 with each channel * switching at the same time. *******************************************************************/ #include <mc9s12c32.h> /* derivative information */ #define DELAY1 16000 /* Number clocks for 2 ms */ #define O_BITS 0xF0 /* Bits to be output */ #define D_BITS 0xA0 /* Initial data value to output */ /*******************************************************************/ void main(void) { /*******************************************************************/ /* Initialize I/O */ TIOS = O_BITS; /* Enable output compare bits 7 - 4 */ OC7M = O_BITS; /* Initialize the mask register */ OC7D = D_BITS; /* Initialize the data register */ TSCR1_TEN = 1; /* Enable the timer */ /* DO */ for(;;) { /* Wait until output compare 7 hits */ while (TFLG1_C7F == 0) {} /* The data in OC7D is output to bits 7 - 4 */ /* Now set up each channel for the next bit change */ TC4 = TC7; TC5 = TC7; TC6 = TC7; /* Reset the output compare flag */ TFLG1 = TFLG1_C7F_MASK; /* Toggle the bits in the data register */ OC7D = OC7D ^ O_BITS; //O_BITS; }
13-32
13-33
Explanation of Example 13-19 To create a very short pulse we first set up output compare channel seven to successfully compare at some time in the future ( line 28 ) and then set output compare channel six to compare two sec later by initializing TC6 in line 31. OC7M and OC7D are set to output a one on Port T-6 when output compare seven is made (lines 36 - 39 ) and output compare six to reset the bit ( lines 42 - 43). The two spin loops at line 46 and line 49 wait until OC7 and then OC6 are made.
Example 13-20 Example 13-19 shows a program to output a 2-sec pulse on Port T, bit-6. What is the period of this pulse? Solution: The output compare registers are not changed after their initialization. Therefore the period of the pulse is 8.192 msec.
13-34
The input capture hardware is shown in Figure 13-5. Again, the 16bit free-running TCNT register is the heart of the system, and the same eight, 16-bit Timer Input Capture/Output Compare registers, TC7 - TC0, used for the output capture function, latch the value of the free-running counter in response to a program-selected, external signal coming from Port T. For example, the period of a pulse train can be found by capturing the TCNT at the start of the period, signified by a rising or falling edge, and storing it. The next rising or falling edge will capture the count at the end of the period. The difference in the two counts, taking into account timer overflows, will be the period in bus clock cycles. The length of the positive pulse can be measured by capturing the time at the rising edge and then again at the falling edge. Two bits for each Input Capture channel, EDGnB and EDGnA in Timer Control Registers 3 and 4, control when the signal on Port T causes the capture event to occur. You may select rising, falling or both edges to be active. The input capture interrupts operate just like output compare interrupts. The interrupt enable bits in TIE must be set. Then, when the flag in TFLG1 is set by the selected input capture edge, the interrupt request is forwarded to the CPU. Example 13-21 shows a subroutine that measures the period of a wave form, so long as it is less than 8.192 ms. Input capture one is to be used; it is enabled in line 25, and a rising edge is selected in lines 28 and 29. The IC1 flag is reset in lines 31 and 32. The