ECE 2510 Introduction to Microprocessors Chapter 8 Dr. Bradley J. Bazuin Associate Professor Department of Electrical and Computer Engineering College of Engineering and Applied Sciences Chapter 8 • Enhanced Capture Timer (ECT) – – – – • 16-bit main counter with 7-bit prescaler 8 programmable input capture or output compare channels Two 8-bit or one 16-bit pulse accumulators Document: S12ECT_16B8CV1 8 Pulse Width Modulated (PWM) channels – – – – – – ECE 2510 Programmable period and duty cycle 8-channel 8-bit or 4-channel 16-bit Separate control for each pulse width and duty cycle Programmable clock select logic with a wide range of frequencies Usable as interrupt inputs Document: S12PWM_8B8CV1 2 Memory Addresses ECE 2510 3 Adapt9S12DP256 I/O Pins ECE 2510 4 Overview of Timer Functions • Many applications require a dedicated timer system – – – – – – – – Time delay creation and measurement Period and pulse width measurement Frequency measurement Event counting Arrival time comparison Time of day tracking Periodic interrupt generation Waveform Generation • The TIM (and ECT also) shares the eight Port T pins (IOC0…IOC7). ECE 2510 5 Overview of Timer Functions • The applications mentioned will be very difficult to implement without a dedicated timer system • HCS12 implements a very flexible timer system to support the implementation of these applications – HCS12 microcontroller consists of a 16-bit timer counter. The timer can be started or stopped according to the wishes of the programmer • Three different timer functions can be implemented – Input-capture (timing based on input signal changes) – Output compare (timing based on internal register values, w/output) – Timer overflow (time-out waiting) ECE 2510 6 The HCS12 Timer System ECE 2510 7 Applications of Input Capture Function • Event arrival time recording • Period measurement: need to capture the main timer values corresponding to two consecutive rising or falling edges one period (a) Capture two rising edges one period (b) Capture two falling edges Figure 8.9 Period measurement by capturing two consecutive edges • Pulse width measurement: (need to capture the rising and falling edges) Pulse width ECE 2510 Rising edge Falling edge Figure 8.10 Pulse-width measurement using input capture Input Capture • • Interrupt generation: Each input capture function can be used as an edge-sensitive interrupt source. Event counting: count the number of signal edges arrived during a period e3 e4 e1 e 2 ei ej ... ... Start of interval End of interval Figure 8.11 Using an input-capture function for event counting • Time reference: input-capture used in conjunction with an output compare function Time t0 Time t0 + delay Time of reference (set up by signal edge) Time to activate output signal (set up by output compare) ECE 2510 Figure 8.12 A time reference application Duty Cycle Measurement T T duty cycle = T * 100% T Figure 8.13 Definition of duty cycle ECE 2510 10 Phase Difference Measurement T signal S1 T signal S2 phase difference = T T * 360o Figure 8.14 Phase difference definition for two signals ECE 2510 11 ECT and T Pin Related Registers • Timer Counter Registers – – – – – – – – – – – – – – ECE 2510 – TIOS TCFORC TOC7M TOC7D = = = = $40 $41 $42 $43 TCNT TSCR1 TTOV TCTL1 TCTL2 TCTL3 TCTL4 TIE TSCR2 TFLG1 TFLG2 = = = = = = = = = = = $44 (16-bit) $46 $47 $48 $49 $4A $4B $4C $4D $4E $4F • Timer Counter Registers – – – – – – – – TC0 TC1 TC2 TC3 TC4 TC5 TC6 TC7 = $50 (16-bit) = $52 (16-bit) = $54 (16-bit) = $56 (16-bit) = $58 (16-bit) = $5A (16-bit) = $5C (16-bit) = $5E (16-bit) – and others through $7F 12 The HCS12 Timer Elements Bus clock Prescaler Channel 0 Input Capture Output compare Timer overflow interrupt IOC0 Channel 1 16-bit counter Input Capture Output compare Input Capture Output compare TC0 interrupt IOC1 IOC2 • Input Capture Output compare Registers TC3 interrupt IOC3 Channel 4 Input Capture Output compare TC4 interrupt 16-bit modulus downcounter – Prescalar – Load Channel 3 TC1 interrupt 16-bit free-running main timer – Prescalaer Channel 2 TC2 interrupt • IOC4 • Control Registers • Interrupt Registers • Capture/Compare Registers Channel 5 TC5 interrupt Input Capture Output compare TC6 interrupt IOC5 Channel 6 TC7 interrupt Input Capture PA overflow interrupt PA input interrupt Output compare ECE 4510/5530 16-bit Pulse accumulator A IOC6 Channel 7 Input Capture Output compare IOC7 13 Figure 8.1 HCS12 Standard Timer (TIM) block diagram Timer Block Diagram (Latch Mode) ÷1,2,...,128 bus clock PTx Prescaler pin logic 16-bit free-running bus clock main timer Delay counter ÷1, 4, 8, 16 Prescaler 16-bit load register 16-bit modulus down counter comparator EDG x TCx capture/compare register one IC channel (IC0..IC3) Latch TCxH hold register ICLAT, LATQ, BUFEN (force latch) to other IC channels write $0000 to modulus counter LATQ (MDC latch enable) PTi comparator pin logic EDG i MUX ECE 4510/5530 EDG j j=8-i TCx capture/compare register one IC channel (IC4..IC7) Figure 8.35 Enhanced Input capture function block diagram in latch mode 14 Timer Block Diagram (Queue Mode) ÷1,2,...,128 bus clock PTx Prescaler pin logic 16-bit free-running bus clock maintimer Delay counter ÷1, 4, 8, 16 Prescaler 16-bit load register 16-bit modulus down counter comparator EDG x TCxcapture/compare register one IC channel (IC0..IC3) TCxH hold register to other IC channels comparator PTi pin logic EDG i MUX EDG j TCxcapture/compare register one IC channel (IC4..IC7) j= 8- i ECE 4510/5530 Figure 8.36 Enhanced Input capture function block diagram in Queue mode (channels IC0..IC3 block diagram) 15 Timer Counter Register (TCNT) • Required for input capture and output compare functions. An up counter. • Must be accessed in one 16bit operation in order to obtain the correct value The 16-bit main timer is an up counter. A full access for the counter register should take place in one clock cycle. A separate read (any mode)/write (test mode) for high byte and low byte will give a different result than accessing them as a word. Read anytime. • Three other registers related to the operation of TCNT: TSCR1, TSCR2, TFLG2. ECE 2510 Write has no meaning or effect in the normal mode; only writable in special modes (test_mode = 1). The period of the first “count” after a write to the TCNT registers may be a different size because the write is not synchronized with the prescaler clock. 16 Running the TCNT Counter • Timer Counter Register 1 (TSCR1) – Select the mode of operation for the module • STOP: Timer and modulus counter are off since clocks are stopped. • FREEZE: Timer and modulus counter keep on running, unless TSFRZ in TSCR($06) is set to one. • WAIT: Counters keep on running, unless TSWAI in TSCR ($06) is set to one. • NORMAL: Timer and modulus counter keep on running, unless TEN in TSCR($06) respectively MCEN in MCCTL ($26) are cleared. • Timer Counter Register 2 (TSCR2) – Timer prescale counting factor, timer overflow IE, and timer counter reset enable • Timer Interrupt Flag 2 Register (TFLG2) – Bit 7 (TOF) Set when 16-bit free-running timer overflows from $FFFF to $0000. This bit is cleared automatically by a write to the TFLG2 register with bit 7 set. (See also TCRE control bit ECE 2510 explanation.) 17 Timer System Control Register 1 (TSCR1) • Setting and clearing the bit 7 of value TSCR1 will start and stop the after reset counting of the TCNT. 6 7 TEN 0 5 4 TSWAI TSFRZ TFFCA 0 0 0 3 2 1 0 0 0 0 0 0 0 0 0 TEN -- timer enable bit 0 = disable timer; this can be used to save power consumption 1 = allows timer to function normally • Setting the bit 4 will enable fast timer flag clear function. If this bit is clear, then the user must write a one to a timer flag in order to clear it. TSWAI -- timer stops while in wait mode bit 0 = allows timer to continue running during wait mode 1 = disables timer when MCU is in wait mode TSFRZ -- timer and modulus counter stop while in freeze mode 0 = allows timer and modulus counter to continue running while in freeze mode 1 = disables timer and modulus counter when MCU is in freeze mode TFFCA -- timer fast flag clear all bit 0 = allows timer flag clearing to function normally 1 = For TFLG1, a read from an input capture or a write to the output compare channel causes the corresponding channel flag, CnF, to be cleared. For TFLG2, any access to the TCNT register clears the TOF flag. Any access to the PACN3 and PACN2 registers clears the PAOVF and PAIF flags in the PAFLG register. Any access to the PACN1 and PACN0 registers clears the PBOVF flag in the PBFLG register. Figure 8.2 Timer system control register 1 (TSCR1) ECE 2510 18 Timer System Control Register 2 (TSCR2) • • Bit 7 is the TCNT overflow interrupt enable bit. value after reset The clock input (E-CLK) to TCNT (E-Clock) can be prescaled by a factor selecting by bits 2 to 0 of TSCR2. 7 6 5 4 3 2 1 0 TOI 0 0 0 TCRE PR2 PR1 PR0 0 0 0 0 0 0 0 0 TOI -- timer overflow interrupt enable bit 0 = interrupt inhibited 1 = interrupt requested when TOF flag is set TCRE -- timer counter reset enable bit 0 = counter reset inhibited and counter free runs 1 = counter reset by a successful output compare 7 If TC7 = $0000 and TCRE = 1, TCNT stays at $0000 continuously. If TC7 = $FFFF and TCRE = 1, TOF will never be set when TCNT rolls over from $FFFF to $0000. Figure 8.3 Timer system control register 2 (TSCR2) • TCNT can be reset to 0 when TCNT equals TC7 by setting bit 3 of TSCR2. ECE 2510 Table 8.1 Timer counter prescale factor PR2 PR1 PR0 0 0 0 0 1 1 1 1 0 0 1 1 0 0 1 1 0 1 0 1 0 1 0 1 Prescale Factor 1 2 4 8 16 32 64 128 19 Timer Interrupt Flag 2 Register (TFLG2) • Only bit 7 (TOF) is implemented. – Bit 7 will be set whenever TCNT overflows. TFLG2 indicates when interrupt conditions have occurred. To clear a bit in the flag register, write the bit to one. Read anytime. Write used in clearing mechanism (set bits cause corresponding bits to be cleared). Any access to TCNT will clear TFLG2 register if the TFFCA bit in TSCR register is set. TOF — Timer Overflow Flag Set when 16-bit free-running timer overflows from $FFFF to $0000. This bit is cleared automatically by a write to the TFLG2 register with bit 7 set. (See also TCRE control bit explanation.) ECE 2510 20 Using TCNT Values • Once the counter is set up, the timer functions can be used to: • In - Input-Capture: – The TCNT value is captured when the desired external event occurs • Out - Output-Compare: – The output occurs when TCNT equals the preset register value ECE 2510 21 Timer Port Pins • Each port pin can be used as a general I/O pin when timer function is not selected. • Pin 7 can be used as input capture 7, output compare 7 action, and a pulse accumulator input. – The pulse accumulation function is unique to this pin. • When a timer port pin is used as a general I/O pin, its direction is configured by the DDRT register. ECE 2510 22 Input Capture Functions (1 of 2) • • Physical time is often represented by the contents of the main timer. The time when an event occurs can be recorded by latching the count of the main timer when a signal edge arrives as illustrated in Figure 8.4. – The occurrence of an event is represented by a signal edge (rising or falling edge). – The HCS12 has eight input capture channels. – Each channel has a 16-bit capture register, an input pin, edge-detection logic, and interrupt generation logic. • Input capture channels share most of the circuit with output compare functions. For this reason, they cannot be enabled simultaneously. Rising edge Falling edge or ECE 2510 Figure 8.4 Events represented by signal edges Input Capture Functions (2 of 2) • • The selection of input capture and output compare is done by programming the TIOS register. The contents of the TIOS register are shown in Figure 8.5. Setting a bit select the output compare function. Otherwise, the input capture function is selected. value after reset 7 6 5 4 3 2 1 0 IOS7 IOS6 IOS5 IOS4 IOS3 IOS2 IOS1 IOS0 0 0 0 0 0 0 0 0 IOS[7:0] -- Input capture or output compare channel configuration bits 0 = The corresponding channel acts as an input capture 1 = The corresponding channel acts as an output compare Figure 8.5 Timer input capture/output compare select register (TIOS) • • The following instruction will enable the output compare channels 7...4 and input capture channel 3…0: movb #$F0,TIOS ECE 2510 24 Timer Control Register 3 and 4 6 7 • The signal edge to be captured is selected by TCTL3 and TCTL4. 5 4 3 2 1 0 ED G 7 B ED G 7 A ED G 6 B ED G 6 A ED G 5 B ED G 5 A ED G 4 B ED G 4 A value afte r re se t 0 0 0 0 0 0 0 0 (a) Tim e r c o ntro l re gis te r 3 (TC TL3 ) 6 7 5 4 3 2 1 0 ED G 3 B ED G 3 A ED G 2 B ED G 2 A ED G 1 B ED G 1 A ED G 0 B ED G 0 A 0 • The edge to be captured is selected by two bits. The user can choose to capture the rising edge, falling edge, or both edges. ECE 2510 0 0 0 0 0 0 0 (b) Tim e r c o ntro l re gis te r 4 (TC TL4 ) ED G nB ED G nA -- Edge c o nfiguratio n 0 0 1 1 0 1 0 1 : : : : C apture C apture C apture C apture dis able d o n ris ing e dge s o nly o n falling e dge s o nly o n bo th e dge s Figure 8 .5 Tim e r c o ntro l re gis te r 3 and 4 25 Timer Interrupt Enable Register (TIE) • The arrival of a signal edge may optionally generate an interrupt to the CPU. • The enabling of the interrupt is controlled by the Timer Interrupt Enable Register. reset: 7 6 5 4 3 2 1 0 C7I C6I C5I C4I C3I C2I C1I C0I 0 0 0 0 0 0 0 0 C7I-C0I: input capture/output compare interrupt enable bits 0 = interrupt disabled 1 = interrupt enabled Figure 8.7 Timer interrupt enable register (TIE) ECE 2510 26 Timer Interrupt Flag 1 Register (TFLG1) • Whenever a signal edge arrives, the associated timer interrupt flag will be set to 1. • Read anytime. Write used in the clearing mechanism (set bits cause corresponding bits to be cleared). Writing a zero will not affect current status of the bit. reset: 7 6 5 4 3 2 1 0 C7F C6F C5F C4F C3F C2F C1F C0F 0 0 0 0 0 0 0 0 CnF: input capture/output compare interrupt flag bits 0 = interrupt condition has not occurred 1 = interrupt condition has occurred Figure 8.8 Timer interrupt flag register 1 (TFLG1) ECE 2510 27 How to Clear a Timer Flag Bit • In normal mode, write a 1 to the flag bit to be cleared. • Assembly – bset TFLG1, $01 – movb #$01,TFLG1 – ldaa TFLG1 eora #$01 staa TFLG1 • C language – TFLG1 |= bit0; • When the fast timer flag clear function is enabled (TFFCA bit in the TSCR register is set), a read from an input capture or a write into an output compare channel ($10–$1F) will cause the corresponding channel flag CnF to be cleared. ECE 2510 Example 8.2: Period Measurement (1 of 2) • Use the IC0 to measure the period of an unknown signal. The period is known to be shorter than 128 ms. Assume that the E clock frequency is 24 MHz. Use the number of clock cycles as the unit of the period. Solution: • Since the input-capture register is 16-bit, the longest period of the signal that can be measured with the prescaler to TCNT set to 1 is: – • 2^16 ÷ 24 MHz = 2.73 ms count roll-over To measure a period that is equal to 128 ms, we have two options: – Set the prescale factor to 1 and keep track of the number of times the timer counter overflows (LSB = 1/24MHz). – Set the prescale factor to 64 and do not keep track of the number of times the timer counter overflows (LSB = 64/24MHz). • We will set the prescale factor to TCNT to 64 (174.7 ms roll-over). The logic flow for measuring the signal period is shown in Figure 8.16. ECE 2510 Example 8.2: Period Measurement (2 of 2) Start Choose to capture the rising edge Set the timer counter prescale factor to 16 Enable the timer counter Clear the C0F flag no (a) Capture two rising edges one period C0F = 1? yes Saved the captured first edge Clear the C0F flag no one period (b) Capture two falling edges Figure 8.9 Period measurement by capturing two consecutive edges C0F = 1? yes Take the difference of the second and the first captured edges Stop ECE 2510 Figure 8.16 Logic flow of period measurement program 30 Example 8.2: Assembly Program for Period Measurement #include .org edge1: period: .text _main:: L1: L2: ECE 2510 "c:\miniide\hcs12.inc" $1000 .byte 2 .byte 2 movb bclr movb movb movb brclr ldd std brclr ldd subd std swi #$90,TSCR1 TIOS,IOS0 #$06,TSCR2 #$01,TCTL4 #C0F,TFLG1 TFLG1,C0F,L1 TC0 edge1 TFLG1,C0F,L2 TC0 edge1 period ; memory to hold the first edge ; memory to store the period ; enable timer counter and enable fast timer flags clear ; enable input-capture 0 ; disable TCNT overflow interrupt, set prescaler to 64 ; capture the rising edge of PT0 signal ; clear the C0F flag ; wait for the arrival of the first rising edge ; save the first edge and clear the C0F flag ; wait for the arrival of the second edge ; compute the period 31 Example 8.2: C Program for Period Measurement #include "c:\egnu091\include\hcs12.h" void main(void) { unsigned int edge1, period; TSCR1 = 0x90; /* enable timer counter, enable fast flag clear*/ TIOS &= ~IOS0; /* enable input-capture 0 / TSCR2 = 0x06; /* disable TCNT overflow interrupt, set prescaler to 64 */ TCTL4 = 0x01; /* capture the rising edge of the PT0 pin */ TFLG1 = C0F; /* clear the C0F flag */ while (!(TFLG1 & C0F)); /* wait for the arrival of the first rising edge */ edge1 = TC0; /* save the first captured edge and clear C0F flag */ while (!(TFLG1 & C0F)); /* wait for the arrival of the second rising edge */ period = TC0 - edge1; asm ("swi"); } ECE 2510 32 Example 8.3: Measure the Pulse Width • • Write a program to measure the pulse width of a signal connected to the PT0 pin. The E clock frequency is 24 MHz. Solution: – Set the prescale factor to TCNT to 32. Use clock cycle as the unit of measurement. (1 1/3 usec time steps) – The pulse width may be longer than 2^16 clock cycles. We need to keep track of the number of times that the TCNT timer overflows. Let • • • • ovcnt diff edge1 edge2 = TCNT counter overflow count = the difference of two consecutive edges = the captured time of the first edge = the captured time of the second edge – The pulse width can be calculated by the following equations: ECE 2510 Case 1: edge2 edge1 pulse width = ovcnt × 216 + diff Case 2: edge2 < edge 1 pulse width = (ovcnt – 1) × 216 + diff Pulse width Rising edge Falling edge Figure 8.10 Pulse-width measurement using input capture yes C0F = 1? yes C0F = 1? no overflow - 1 Retur n from V TO interr upt Execute the RTI instruction. Clear TOF flag. overflow overflow + 1. Figure 8.17 Logic flow for measuring pulse width of slow signals Stop Combine the results. overflow yes Is second edge smaller? Compute the difference of two edges. no Clear C0F flag. Save the first captured edge. pt u r r te in Timer overflow interrupt service routine Note: an interrupt is used Clear timer overflow flag. Enable main timer overflow interrupt. no ECE 2510 overflow 0 Set up to capture the rising edge. Disable all interrupts. Start Example 8.3 Flow Diagram 34 Example 8.3: Code (1 of 2) #include "c:\miniide\hcs12.inc" .org $1000 edge1: .byte 2 overflow: .byte 2 ; overflow and pulse-width form a 32-bit pulse_width: .byte 2 ; long word for the solution .text _main:: lds #$3C00 ; set up stack pointer movw #tov_isr,UserTimerOvf ; set up TCNT overflow interrupt vector movw #0, overflow movb #$90, TSCR1 ; enable TCNT and fast timer flag clear movb #$05, TSCR2 ; disable TCNT interrupt, set prescaler to 32 bclr TIOS, IOS0 ; select IC0 movb #$01, TCTL4 ; capture rising edge movb #C0F, TFLG1 ; clear C0F flag wait1: brclr TFLG1,C0F,wait1 ; wait for the first rising edge movw TC0,edge1 ; save the first edge & clear the C0F flag movb #TOF,TFLG2 ; clear TOF flag bset TSCR2,$80 ; enable TCNT overflow interrupt cli ; " movb #$02,TCTL4 ; capture the falling edge on PT0 pin wait2: brclr TFLG1,C0F,wait2 ; wait for the arrival of the falling edge ECE 2510 35 Example 8.3: Code (2 of 2) next ldd subd std bcc ldx dex stx swi TC0 edge1 pulse_width next overflow overflow tov_isr movb #TOF, TFLG2 ldx overflow inx stx overflow rti ECE 2510 ; is the second edge smaller? ; second edge is smaller, so decrement ; overflow count by 1 ; " ; clear TOF flag Example 8.3: C Program for Pulse Width Measurement (1 of 2) #include <hcs12.h> #include <vectors12.h> #define INTERRUPT __attribute__((interrupt)) unsigned diff, edge1, overflow; unsigned long pulse_width; void INTERRUPT tovisr(void); void main(void) { UserTimerOvf = (unsigned short)&tovisr; overflow = 0; TSCR1 = 0x90; /* enable timer and fast flag clear */ TSCR2 = 0x05; /* set prescaler to 32, no timer overflow interrupt */ TIOS &= ~IOS0; /* select input-capture 0 */ TCTL4 = 0x01; /* prepare to capture the rising edge */ TFLG1 = C0F; /* clear C0F flag */ while(!(TFLG1 & C0F)); /* wait for the arrival of the rising edge */ TFLG2 = TOF; /* clear TOF flag */ ECE 2510 Example 8.3: C Code (2 of 2) TSCR2 |= 0x80; /* enable TCNT overflow interrupt */ asm("cli"); edge1 = TC0; /* save the first edge */ TCTL4 = 0x02; /* prepare to capture the falling edge */ while (!(TFLG1 & C0F)); /* wait for the arrival of the falling edge */ diff = TC0 - edge1; if (TC0 < edge1) overflow -= 1; pulse_width = overflow * 65536u + diff; asm ("swi"); } void INTERRUPT tovisr(void) { TFLG2 = TOF; overflow = overflow + 1; } ECE 2510 /* clear TOF flag */ 38 Output Compare Function • The HCS12 has eight output compare functions. • Each output compare channel consists of – A 16-bit comparator – A 16-bit compare register TCx (also used as input capture register) – An output action pin (PTx, can be pulled high, pulled low, or toggled) – An interrupt request circuit – A forced-compare function (CFOCx) – Control logic ECE 2510 Operation of the Output-Compare • One of the applications of the output-compare function is to trigger an action at a specific time in the future. – Excellent for providing a timeout or time period • To use an output-compare function, the user – Makes a copy of the current contents of the TCNT register – Adds to this copy a value equal to the desired delay – Stores the sum into an output-compare register (TCx, x = 0..7) • A successful compare will set the corresponding flag bit in the TFLG1 register. • An interrupt may be optionally requested if the associated interrupt enable bit in the TIE register is set. ECE 2510 Control of the Output-Compare 6 5 7 • The actions that can be OM7 OL7 OM6 value activated on an output after reset 0 0 0 (a) TCTL1 register compare pin include – Pull up to high – Pull down to low – Toggle value after reset • The action is determined by the Timer Control Register 1 & 2 (TCTL1 & TCTL2): ECE 2510 4 3 2 1 0 OL6 OM5 OL5 OM4 OL4 0 0 0 0 0 7 6 5 4 3 2 1 0 OM3 OL3 OM2 OL2 OM1 OL1 OM0 OL0 0 0 0 0 0 0 0 0 (b) TCTL2 register read: anytime write: anytime OMn OLn : output level no action (timer disconnected from output pin) 0 0 toggle OCn pin 1 0 clear OCn pin to 0 0 1 set OCn pin to high 1 1 Figure 8.18 Timer control register 1 and 2 (TCTL1 & TCTL2) Example 8.4 Output-Compare • Example 8.4 Generate an active high 1 KHz digital waveform with 30 percent duty cycle from the PT0 pin. – Use the polling method to check the success of the output compare operation. The frequency of the E clock is 24 MHz. • Solution: An active high 1 KHz waveform with 30 percent duty cycle is shown in Figure 8.19. The logic flow of this problem is illustrated in Figure 8.20. – Setting the prescaler to the TCNT to 8, then the period of the clock signal to the TCNT will be 1/3 ms. The numbers of clock cycles that the signal is high and low are 900 and 2100, respectively. 300 s 700 s ECE 2510 42 Figure 8.19 1 KHz 30 percent duty cycle waveform Example 8.4 Flow Diagram Start Select pull high as pin action Clear C0F flag Start OC0 output compare with a delay of 700 s no C0F = 1? yes Select pull low as pin action Clear C0F flag Start OC0 output compare with a delay of 300 s no yes C0F = 1? ECE 2510 43 Figure 8.20 The program logic flow for digital waveform generation Example 8.4 Assembly Code #include "c:\miniide\hcs12.inc" hi_time = 900 lo_time = 2100 .text _main:: movb #$90,TSCR1 movb #$03,TSCR2 bset TIOS,OC0 movb #$03,TCTL2 ldd TCNT repeat: addd #lo_time std TC0 low: brclr TFLG1,C0F,low movb #$02,TCTL2 ldd TC0 addd #hi_time std TC0 high: brclr TFLG1,C0F,high movb #$03,TCTL2 ldd TC0 ECE 2510 bra repeat ; enable TCNT with fast timer flag clear ; disable TCNT interrupt, set prescaler to 8 ; enable OC0 ; select pull high as pin action ; start an OC0 operation with 700 us as delay ; " ; " ; wait until OC0 pin go high ; select pull low as pin action ; start an OC operation with 300 us as delay ; " ; " ; wait until OC0 pin go low ; select pull high as pin action Example 8.4 C Code #include "c:\egnu091\include\hcs12.h" #define hi_time 900 #define lo_time 2100 void main (void) { TSCR1 = 0x90; /* enable TCNT and fast timer flag clear */ TIOS |= OC0; /* enable OC0 function */ TSCR2 = 0x03; /* disable TCNT interrupt, set prescaler to 8 */ TCTL2 = 0x03; /* set OC0 action to be pull high */ TC0 = TCNT + lo_time; /* start an OC0 operation */ while(1) { while(!(TFLG1 & C0F)); /* wait for PT0 to go high */ TCTL2 = 0x02; /* set OC0 pin action to pull low */ TC0 += hi_time; /* start a new OC0 operation */ while(!(TFLG1 & C0F)); /* wait for PT0 pin to go low */ TCTL2 = 0x03; /* set OC0 pin action to pull high */ TC0 += lo_time; /* start a new OC0 operation */ } } ECE 2510 Example 8.5: 1 msec Time Delay • Write a function to generate a time delay which is a multiple of 1 ms. – Assume that the E clock frequency is 24 MHz. The number of milliseconds is passed in Y. Also write an instruction sequence to test this function. Solution: • One method to create 1 ms delay is as follows: – Set the prescaler to TCNT to 64 – Perform the number of output-compare operations (given in Y) with each operation creating a 1-ms time delay. – The number to be added to the copy of TCNT is 375. (375 64 24000000 = 1 ms) ECE 2510 46 Example 8.5: Y x 1 msec Time Delay Subroutine delayby1ms: again0: wait_lp0: ECE 2510 pshd movb movb bset ldd addd std brclr ldd dbne puld rts #$90,TSCR1 #$06,TSCR2 TIOS,OC0 TCNT ; enable TCNT & fast flags clear ; configure prescaler to 64 ; enable OC0 #375 TC0 TFLG1,OC0,wait_lp0 TC0 y,again0 ; start an output-compare operation ; with 1 ms time delay 47 Example 8.5: C Code void delayby1ms(int k) { int ix; TSCR1 = 0x90; /* enable TCNT and fast timer flag clear */ TSCR2 = 0x06; /* disable timer interrupt, set prescaler to 64 */ TIOS |= OC0; /* enable OC0 */ TC0 = TCNT + 375; for (ix = 0; ix < k; ix++) { while(!(TFLG1 & C0F)); TC0 += 375; } TIOS &= ~OC0; /* disable OC0 */ } See Textbook CD: Utilities/delay.c The above is from the old textbook CD ECE 2510 48 Textbook Delay Code • Delay.asm – – – – delayby50us delayby1ms delayby10ms delayby100ms ; multiple passed in Y reg ; multiple passed in Y reg ; multiple passed in Y reg ; multiple passed in Y reg • Delay.c – – – – – ECE 2510 void delayby10us(int k); void delayby50us(int k); /* time delay based on */ void delayby1ms(int k); /* 24 MHz crystal E-clock. */ void delayby10ms(int k); void delayby100ms(int k); 49 Example 8.6: Estimate Frequency • Use an input-capture and an output-compare functions to measure the frequency of the signal connected to the PT0 pin. • Solution: To measure the frequency, we will – Use one of the output-compare function to create a one-second time base. – Keep track of the number of rising (or falling) edges that arrived at the PT0 pin within one second. ECE 2510 Example 8.6: Estimate Frequency (1 of 2) #include CR LF .org oc_cnt frequency msg: "c:\MiniIDE\hcs12.inc" = $0D = $0A $1000 .blkb 1 .blkb 2 .byte CR,LF .ascii “The frequency is %d“ .byte CR,LF,0 .org $3E6E .word TC0_isr ; set up interrupt vector number ; for TC0 movb movb movb movb #$90,TSCR1 #$02,TSCR2 #$02,TIOS #100,oc_cnt movw movb movb bset cli #0,frequency #$01,TCTL4 #C0F,TFLG1 TIE,IC0 ; enable TCNT and fast timer flags clear ; set prescale factor to 4 ; enable OC1 and IC0 ; prepare to perform 100 OC1 operation, each ; creates 10 ms delay and total 1 second ; initialize frequency count to 0 ; prepare to capture the rising edges of PT0 ; clear the C0F flag ; enable IC0 interrupt ; " .text _main:: ECE 2510 Example 8.6: Code (2 of 2) ldd continue: addd std w_lp: brclr ldd dec bne sei ldd pshd ldd ldx jsr leas swi TC0_isr: ldd ldx inx stx ECE 2510 rti TCNT ; start an OC1 operation with 10 ms delay #60000 ; " TC1 ; " TFLG1,C1F, w_lp; wait for 10 ms TC1 oc_cnt continue ; set I, disabling all interrupts frequency #msg #00 [printf, X] 2,sp TC0 frequency frequency ; clear C0F flag ; increment frequency count by 1 ; " ; 52 Example 8.6: C Code (1 of 2) #include <hcs12.h> #include <vectors12.h> #include <convert.c> #include <stdio.c> #define INTERRUPT __attribute__((interrupt)) unsigned int frequency; void INTERRUPT TC0_isr(void); void main(void) { char arr[7]; char *msg = "Signal frequency is "; int i, oc_cnt; unsigned frequency; UserTimerCh0 = (unsigned short)&TC0_isr; TSCR1 = 0x90; /* enable TCNT and fast flag clear */ TSCR2 = 0x02; /* set prescale factor to 4 */ TIOS = 0x02; /* select OC1 and IC0 */ oc_cnt = 100; /* prepare to perform 100 OC1 operations */ frequency = 0; ECE 2510 Example 8.6: C Code (2 of 2) TCTL4 = 0x01; /* prepare to capture PT0 rising edge */ TFLG1 = C0F; /* clear C0F flag */ TIE |= IC0; /* enable IC0 interrupt */ asm("cli"); TC1 = TCNT + 60000; while (oc_cnt) { while(!(TFLG1 & C1F)); TC1 = TC1 + 60000; oc_cnt = oc_cnt - 1; } asm(“sei"); int2alpha(frequency, arr); puts(msg); puts(&arr[0]); asm("swi"); ECE 2510 } void INTERRUPT TC0_isr(void) { TFLG1 = C0F; /* clear C0F flag */ frequency ++; } Making Sound Using the Output-Compare Function • A sound can be generated by creating a digital waveform with appropriate frequency and using it to drive a speaker or a buzzer. • The simplest song is a two-tone siren. HCS12DP256 3.3 F PT5 Buzzer Figure 8.21 Circuit connection for a buzzer ECE 2510 55 Example 8.7: Algorithm for Generating a Siren • Step 1 – Enable an output compare channel to drive the buzzer (or speaker). • Step 2 – Start an output compare operation with a delay count equal to half the period of the siren and enable the OC interrupt. • Step 3 – Wait for the duration of the siren tone (say half a second). During the waiting period, interrupts will be requested many times by the output compare function. The interrupt service routine simply restart the output compare operation. • Step 4 – At the end of the siren tone duration, choose a different delay count for the output compare operation so that the siren sound may have a different frequency. • Step 5 – Wait for the same duration as in Step 3. During this period, many interrupts will be requested by the output compare operation. • Step 6 ECE 2510 – Go to Step 2. 56 Example 8.7 Siren Generation • Write a program to generate a two-tone siren that oscillates between 300 Hz and 1200 Hz. • Solution: – Set the prescaler to TCNT to 1:8. – The delay count for the low frequency tone is (24000000 8) 300 2 = 5000. – The delay count for the high frequency tone is (24000000 8) 1200 2 = 1250. ECE 2510 57 Example 8.7 Siren Generation (1 of 2) #include hi_freq lo_freq toggle .org delay: "c:\miniide\hcs12.inc" = 1250 = 5000 = $04 $1000 .blkw 1 ; delay count for 1200 Hz (with 1:8 prescaler) ; delay count for 300 Hz (with 1:8 prescaler) ; value to toggle the TC5 pin ; store the delay for output-compare operation .text _main:: ECE 2510 lds movw movb movb bset movb movw ldd addd std bset cli #$3C00 #oc5_isr,UserTimerCh5 ; initialize the interrupt vector entry #$90,TSCR1 ; enable TCNT, fast timer flag clear #$03,TSCR2 ; set main timer prescaler to 8 TIOS,OC5 ; enable OC5 #toggle,TCTL1 ; select toggle for OC5 pin action #hi_freq,delay ; use high frequency delay count first TCNT ; start the low frequency sound delay ; " TC5 ; " TIE,OC5 ; enable OC5 interrupt 58 Code (2 of 2) forever: ldy jsr movw ldy jsr movw bra oc5_isr: ldd addd std rti #5 delayby100ms #lo_freq, delay #5 delayby100ms #hi_freq, delay forever ; wait for half a second ; " ; switch to low frequency delay count TC5 delay TC5 ; half period of frequency ; switch to high frequency delay count #include c:\miniide\delay.asm” ECE 2510 59 C Program for Siren Generation (1 of 2) #include "c:\egnu091\include\hcs12.h" #include "c:\egnu091\include\delay.c" #include "c:\egnu091\include\v`ectors12.h" #define INTERRUPT __attribute__((interrupt)) #define HiFreq 1250 #define LoFreq 5000 int delay; /* delay count for OC5 operation */ void INTERRUPT oc5ISR(void); int main(void) { UserTimerCh5 = (unsigned short)&oc5ISR; TSCR1 = 0x90; /* enable TCNT and fast timer flag clear */ TSCR2 = 0x03; /* set prescaler to TCNT to 1:8 */ TIOS |= BIT5; /* enable OC5 */ TCTL1 = 0x04; /* select toggle for OC5 pin action */ delay = HiFreq; /* use high frequency delay count first */ TC5 = TCNT + delay; /* start an OC5 operation */ TIE |= BIT5; /* enable TC5 interrupt */ asm("cli"); ECE 2510 60 C Program for Siren Generation (2 of 2) while(1) { delayby100ms(5); delay = LoFreq; delayby100ms(5); delay = HiFreq; } return 0; /* wait for half a second */ /* switch to low frequency tone */ /* wait for half a second */ /* switch to high frequency tone */ } void INTERRUPT oc5ISR(void) { TC5 += delay; } ECE 2510 61 More Timing Capabilities • • • • • • • Play “The Star-Spangled Banner” More digital waveform generation Pulse accumulator operations N pulse event detector Alternate frequency measurement technique Gate time method for measuring a pulse duration Modulus down-counter to generate periodic interrupts ECE 2510 62