You are on page 1of 102

Chapter 8 HCS12 Timer Functions

Why are Timer Functions Important? y p


It is very difficult and impossible to implement the following applications without a timer function: g pp
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 g

The HCS12 Timer System (1 of 2) y


The HCS12 has a standard timer module (TIM) that consists of:
Eight channels of multiplexed input capture and output compare functions. 16-bit pulse accumulator A p 16-bit timer counter The TIM block diagram is shown in Figure 8.1.

The HCS12 devices in the automotive family have implemented an Enhanced Capture Timer module ( p (ECT). The ECT module contains: )
All the features contained in the TIM module One 16-bit buffer register for each of the input capture channels Four 8-bit pulse accumulator A 16-bit Modulus Down Counter with 4-bit prescaler p Four user selectable delay counters for increasing input noise immunity

The TIM (of course ECT also) shares the eight Port T pins (IOC0IOC7).

The HCS12 Timer System (2 of 2)


Bus clock Prescaler Channel 0 Input Capture Output compare Timer overflow interrupt Channel 1 16-bit counter Input Capture Output compare Channel 2 Input Capture TC0 interrupt TC1 interrupt TC2 i t interrupt t TC3 interrupt TC4 interrupt TC5 interrupt TC6 interrupt TC7 interrupt PA overflow interrupt i t t PA input interrupt Registers Output compare Channel 3 Input Capture Output compare Channel 4 Input Capture Output compare Channel 5 Input C Capture Output compare Channel 6 Input Capture Output compare 16-bit Pulse accumulator A Channel 7 Input Capture Output compare IOC7 IOC6 IOC5 IOC4 IOC3 IOC2 IOC1 IOC0

Figure 8.1 HCS12 Standard Timer (TIM) block diagram

Timer Counter Register ( g (TCNT) )


Required for input capture and output compare functions Must be accessed in one 16-bit operation in order to obtain the correct value Three other registers related to the operation of the TCNT: TSCR1, TSCR2, TFLG2.

Timer System Control Register 1 (TSCR1)


7 value after reset TEN 0 6 5 4 3 0 0 2 0 0 1 0 0 0 0 0 TSWAI TSFRZ TFFCA 0 0 0 TEN -- timer enable bit

The contents of TSCR1 are shown i Fi h in Figure 8 2 8.2. Setting and clearing the bit 7 of TSCR1 will start and stop the counting of the TCNT. TCNT 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.

0 = disable timer; this can be used to save power consumption 1 = allows timer to function normally ll i f i ll 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 g g y 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 i t A t th d i t l th PBOVF flag in the PBFLG register. Figure 8.2 Timer system control register 1 (TSCR1)

Timer System Control Register 2 (TSCR2) (1 of 2)


Bit 7 is the TCNT overflow interrupt enable bit bit. TCNT can be reset to 0 when TCNT equals TC7 by setting bit 3 of TSCR2. The clock input to TCNT can be prescaled by a factor selecting by bits 2 to 0 of TSCR2. Th contents of TSCR2 are shown i Fi The t t f h in Figure 8 2 8.2.

Timer System Control Register 2 ( y g (TSCR2) ) (2 of 2)


7 value after reset TOI 0 6 0 0 5 0 0 4 0 0 3 TCRE 0 2 PR2 0 1 PR1 0 0 PR0 0

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

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 t h b set when TCNT rolls over from $FFFF t $0000. ll f to $0000 Figure 8.3 Timer system control register 2 (TSCR2)

Timer Interrupt Flag 2 Register ( p g g (TFLG2) )


Only bit 7 (TOF) is implemented. Bit 7 will be set whenever TCNT overflows.

Input Capture Functions (1 of 2)


Physical time is often represented by the contents of the main timer timer. The occurrence of an event is represented by a signal edge (rising or falling edge). 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. g p p 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. f ti F thi th tb bl d i lt l
Rising edge or Falling edge

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.
7 6 5 4 3 2 1 0 value after reset IOS7 0 IOS6 0 IOS5 0 IOS4 0 IOS3 0 IOS2 0 IOS1 0 IOS0 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 g p p input capture channel 30: movb #$F0,TIOS

Timer Port Pins


Each port pin can be used as a general I/O pin when timer function is not selected. selected Pin 7 can be used as input capture 7, output compare 7 action and pulse accumulator input action, input. When a timer port pin is used as a general I/O pin, its direction is configured by the DDRT register.

Timer Control Register 3 and 4


7 6 5 4 3 2 1 0

value The signal edge to afte r re s e t be captured is selected by TCTL3 and TCTL4. The edge to be captured is selected by two bits. The user can choose to capture the rising edge, falling edge, or both edges.

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 0 0 0 0 0 0 0 0

(a) Tim e r c o ntro l re giste r 3 (TC TL3 ) 7 6 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 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 t C apture C apture C apture dis able d di bl 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

Timer Interrupt Enable Register ( p g (TIE) )


The arrival of a signal edge may optionally generate an interrupt to the CPU CPU. The enabling of the interrupt is controlled by the Timer Interrupt Enable Register. Register
7 C7I reset: 0 6 C6I 0 5 C5I 0 4 C4I 0 3 C3I 0 2 C2I 0 1 C1I 0 0 C0I 0

C7I-C0I: input capture/output compare interrupt enable bits 0 = interrupt disabled 1 = interrupt enabled Figure 8.7 Timer interrupt enable register (TIE)

Timer Interrupt Flag 1 Register ( p g g (TFLG1) )


Whenever a signal edge arrives, the associated timer interrupt flag will be set to 1 1.
7 C7F reset: 0 6 C6F 0 5 C5F 0 4 C4F 0 3 C3F 0 2 C2F 0 1 C1F 0 0 C0F 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)

How to Clear a Timer Flag Bit


In normal mode write a 1 to the flag bit to be cleared mode, cleared. Method 1
Use the BCLR instruction with a 0 at the bit position(s) corresponding to the flag(s) to be cleared. For example, BCLR TFLG1, $FE will clear the C0F flag. g

Method 2
Use the movb instruction with a 1 at the bit position (s) corresponding to the flag (s) to be cleared. For example, movb #$01,TFLG1

will clear the C0F flag.

When fast timer flag clear function is enabled, see Figure 8.1.

Applications of Input Capture Function


E Event arrival ti t i l time recording Period measurement: need to capture the main timer values corresponding to two consecutive rising or falling edges
one period p

( ) p (a) Capture two rising edges g g 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

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 edgesensitive interrupt source source. Event counting: count the number of signal edges arrived during a period
e1 e 2 e3 e4

...

ei

...

ej

Start of interval Figure 8.11 Using an input-capture function for event counting

End of interval

- Time reference: often used in conjunction with an output compare function


Time t0 Time t0 + delay

Time of reference (set up by signal edge) Figure 8.12 A time reference application

Time to activate output signal (set up by output compare)

Duty Cycle Measurement y y


T T duty cycle = T T Figure 8.13 Definition of duty cycle * 100%

Phase Difference Measurement


T

signal S1 T

signal S2 phase difference = T T * 360o

Figure 8.14 Phase difference definition for two signals

Period Measurement (1 of 2)
Example 8.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:
216 24 MHz = 216 x (1/24 MHz) = 2 73 ms 2.73 ms.
Note: Period=(1/24 MHz)

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. Set the prescale factor to 64 and do not keep track of the number of times the timer counter overflows.

We will set the prescale factor to TCNT to 64. The logic flow for measuring the signal period is shown in Figure 8 16 8.16.

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

C0F = 1? yes Saved the captured first edge Clear the C0F flag

no

C0F = 1? yes Take the difference of the second and the p g first captured edges Stop

Figure 8.16 Logic flow of period measurement program

Assembly Program for Period Measurement


#include "c:\miniide\hcs12 inc" c:\miniide\hcs12.inc org $1000 edge1 ds.b 2 period ds.b 2 org $1500 movb #$90,TSCR1 bclr TIOS,IOS0 movb #$06,TSCR2 movb #$01 TCTL4 #$01,TCTL4 movb #C0F,TFLG1 brclr TFLG1,C0F,* ldd TC0 std edge1 brclr TFLG1,C0F,* ldd TC0 subd edge1 std period swi end ; 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

C Program for Period Measurement g


#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 */ edge edge1 = TC0; C0; / sa e e s captured /* save the first cap u ed edge a d c ea C0 flag */ and clear C0F ag / while (!(TFLG1 & C0F)); /* wait for the arrival of the second rising edge */ period = TC0 - edge1; asm ("swi"); }

Example 8.3 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. The pulse width may be longer than 216 clock cycles. We need to keep track f th t k of the number of times that the TCNT ti b f ti th t th timer overflows. L t fl 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 f

The pulse width can be calculated by the following equations:


Case 1 edge2 edge1 g g pulse width = ovcnt 216 + diff Case 2 edge2 < edge 1 pulse width = (ovcnt 1) 216 + diff

Start over rflow 0 Set up to capture the rising edge. u r Disa all interrupts. able .

no C0F = 1? ? yes Clear timer overflow fla t ag. Enable main timer overf e flow interrupt.

Timer overflow interrupt w service rou utine


pt ru r te in V TO

Clear TO flag. OF overflow overflow + 1. o

Clea C0F flag. ar Save the first captured edge. e d

Execute the RT instruction. TI

no C0F = 1? ? yes

Retur n from

interr upt

Compu the difference of two edges. ute e

no

s Is second edge smaller? yes o overflow ove erflow - 1

Combine the re esults. Stop ogic suring pulse width of slow signals h Figure 8.17 Lo flow for meas

"c:\miniide\hcs12.inc" org $1000 edge1 ds.b 2 overflow ds.b 2 pulse_width ds.b 2 org $1500 movw #tov_isr,UserTimerOvf lds #$1500 movw #0,overflow movb #$90,TSCR1 movb #$05,TSCR2 bclr TIOS,IOS0 movb b #$01,TCTL4 #$01 TCTL4 movb #C0F,TFLG1 wait1 brclr TFLG1,C0F,wait1 movw TC0,edge1 movb #TOF,TFLG2 , bset TSCR2,$80 cli movb #$02,TCTL4 wait2 brclr TFLG1,C0F,wait2 ldd TC0 subd edge1

#include

; set up TCNT overflow interrupt vector ; set up stack pointer ; enable TCNT and fast timer flag clear ; disable TCNT interrupt, set prescaler to 32 ; select IC0 ; capture rising edge t i i d ; clear C0F flag ; wait for the first rising edge ; save the first edge & clear the C0F flag ; clear TOF flag g ; enable TCNT overflow interrupt ; " ; capture the falling edge on PT0 pin ; wait for the arrival of the falling edge

next tov_isr

std bcc ldx dex stx swi movb ldx inx stx rti end

pulse_width next overflow overflow

; is the second edge smaller? ; second edge is smaller, so decrement ; overflow count by 1 ; "

#TOF,TFLG2 overflow overflow fl

; clear TOF flag

C Program for Pulse Width Measurement


#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; U Ti O f ( i d h )& i overflow = 0; TSCR1 = 0x90; /* enable timer and fast flag clear */ TSCR2 = 0x05; /* set prescaler to 32, no timer overflow interrupt */ TIOS &= IOS0 & ~IOS0; /* select i l t input-capture 0 */ t t 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 TOF; /* clear TOF fl */ l flag

TSCR2 |= 0x80; /* enable TCNT overflow interrupt */ asm("cli"); (" li") 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; d 1 if (TC0 < edge1) overflow -= 1; pulse_width = overflow * 65536u + diff; asm (" i") ("swi"); } void INTERRUPT tovisr(void) { TFLG2 = TOF TOF; overflow = overflow + 1; }

/* clear TOF flag */

Output Compare Function p p


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 inout capture register) i t ) An output action pin (PTx, can be pulled high, pulled low, or toggled) An interrupt request circuit A forced-compare function (CFOCx) Control logic

Operation of the Output-Compare Function (1 of 4)


One of the applications of the output-compare function is to trigger an action at a specific time in the future. 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)

Operation of the Output-Compare Function (2 of 4)


The actions that can be activated on an output compare pin include
Pull up to high Pull down to low Toggle
7 value after reset OM7 0 6 OL7 0 5 OM6 0 4 OL6 0 3 OM5 0 2 OL5 0 1 OM4 0 0 OL4 0

The action is determined by the Timer Control Register 1 & 2 (TCTL1 & TCTL2):

(a) TCTL1 register 7 value after reset OM3 0 6 OL3 0 5 OM2 0 4 OL2 0 3 OM1 0 2 OL1 0 1 OM0 0 0 OL0 0

(b) TCTL2 register read: anytime write: anytime OMn OLn : output level 0 0 no action (timer disconnected from output pin) 0 1 toggle OCn pin 1 0 clear OCn pin to 0 1 1 set OCn pin to high Figure 8.18 Timer control register 1 and 2 (TCTL1 & TCTL2)

Operation of the Output-Compare Function (3 of 4)


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. Example 8 4 Generate an active high 1 KHz digital waveform with 8.4 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 S f is shown in Figure 8.19. The logic flow of this problem is illustrated in Figure 8.20.
Setting the p g prescaler to the TCNT to 8, then the p , 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 Figure 8.19 1 KHz 30 percent duty cycle waveform

Operation of the Output-Compare Function (4 of 4)


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?

Figure 8.20 The program logic flow for digital waveform generation

#include "c:\miniide\hcs12.inc" hi_time equ 900 lo_time equ l ti 2100 org $1500 movb #$90,TSCR1 movb #$03,TSCR2 bset b t TIOS,OC0 TIOS OC0 movb #$03,TCTL2 ldd TCNT repeat addd #lo_time std td TC0 low brclr TFLG1,C0F,low movb #$02,TCTL2 ldd TC0 addd ddd #hi_time #hi ti std TC0 high brclr TFLG1,C0F,high movb #$03,TCTL2 ldd TC0 bra repeat end

; enable TCNT with fast timer flag clear ; disable TCNT interrupt, set prescaler to 8 ; enable OC0 bl ; 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

C Program for Generating 1 KHz Digital Waveform g


#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 */ } }

Example 8.5 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 output compare operation creating a 1-ms time delay. The number to be added to the copy of TCNT is 375. (375 64 24000000 = 1 ms) delayby1ms pshd y y p movb movb bset ldd again0 addd std wait_lp0 brclr ldd dbne puld rts #$90,TSCR1 ; enable TCNT & fast flags clear #$06,TSCR2 ; configure prescaler to 64 TIOS,OC0 ; enable OC0 TCNT #375 ; start an output-compare operation TC0 ; with 1 ms time delay TFLG1,OC0,wait_lp0 TC0 y,again0

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 | OC0; /* enable OC0 */ bl TC0 = TCNT + 375; for (ix = 0; ix < k; ix++) { while(!(TFLG1 & C0F)); TC0 += 375 375; } TIOS &= ~OC0; /* disable OC0 */ }

Example 8.6 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 q y
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. #include "c:\MiniIDE\hcs12.inc" CR equ $0D $ LF equ $0A org $1000 oc_cnt rmb 1 frequency rmb 2 org $1500 movb #$90,TSCR1 ; enable TCNT and fast timer flags clear movb #$02,TSCR2 ; set prescale factor to 4 movb #$02,TIOS $ ; enable OC1 and IC0 movb #100,oc_cnt ; prepare to perform 100 OC1 operation, each ; creates 10 ms delay and total 1 second movw #0,frequency ; initialize frequency count to 0 movb #$01 TCTL4 b #$01,TCTL4 ; prepare to capture the rising edges of PT0 h i i d f movb #C0F,TFLG1 ; clear the C0F flag bset TIE,IC0 ; enable IC0 interrupt cli ; "

ldd continue addd std w_lp brclr ldd dec bne ldd pshd ldd jsr leas swi msg db TC0_isr TC0 isr ldd ldx inx stx rti org fdb end

TCNT #60000 TC1 TFLG1,C1F,w_lp TC1 oc_cnt continue frequency #msg [printf,PCR] [printf PCR] 2,sp

; start an OC1 operation with 10 ms delay ; " ; " ; wait for 10 ms

CR,LF,"The frequency is %d",CR,LF,0 TC0 ; clear C0F flag frequency ; increment frequency count by 1 ; " frequency ; $3E6E TC0_isr ; set up interrupt vector number ; for TC0

C Program for Frequency Measurement Using IC0


#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;

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; } int2alpha(frequency, arr); puts(msg); puts(&arr[0]); asm("swi"); } void INTERRUPT TC0_isr(void) { TFLG1 = C0F; /* clear C0F flag */ frequency ++; }

Making Sound Using the Output-Compare Function p p


A sound can be generated by creating a digital waveform with appropriate frequency and using it to drive a speaker or a buzzer. The circuit connection for a buzzer is shown in Figure 8.21. The simplest song is a two-tone siren.
HCS12DP256 3.3 F PT5 Buzzer

Figure 8.21 Circuit connection for a buzzer

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 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
Go to Step 2.

Example 8.7 Write a program to generate a two-tone siren that oscillates between 300 Hz and 1200 Hz. S l ti Solution:
Set the prescaler to TCNT to 1:8. The delay count for the low frequency tone is (24000000 8) 300 2 = 5000 5000. The delay count for the high frequency tone is (24000000 8) 1200 2 = 1250.
#include hi_freq lo_freq toggle delay "c:\miniide\hcs12.inc" equ 1250 ; delay count for 1200 Hz (with 1:8 prescaler) equ 5000 ; delay count for 300 Hz (with 1:8 prescaler) equ $04 ; value to toggle the TC5 pin org $1000 ds.w 1 ; store the delay for output-compare operation org $1500 lds #$1500 movw #oc5_isr,UserTimerCh5 ; initialize the interrupt vector entry movb #$90,TSCR1 ; enable TCNT, fast timer flag clear movb #$03,TSCR2 ; set main timer prescaler to 8

bset TIOS,OC5 movb #toggle,TCTL1 movw #hi freq delay #hi_freq,delay ldd TCNT addd delay std TC5 bset TIE,OC5 TIE OC5 cli forever ldy #5 jsr delayby100ms movw #lo freq delay #lo_freq,delay ldy #5 jsr delayby100ms movw #hi_freq,delay bra forever oc5_isr ldd TC5 addd delay std TC5 rti #include c:\miniide\delay.asm end

; enable OC5 ; select toggle for OC5 pin action ; use high frequency delay count first ; start the low frequency sound ; " ; " ; enable OC5 interrupt ; " ; wait for half a second ; " ; switch to low frequency delay count

; switch to high frequency delay count

C Program for Siren Generation (1 of 2)


#include "c:\egnu091\include\hcs12.h" 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 */ y; p TIE |= BIT5; /* enable TC5 interrupt */ asm("cli");

C Program for Siren Generation (2 of 2)


while(1) { delayby100ms(5); delay = LoFreq; delayby100ms(5); delay = HiFreq; } return 0; } void INTERRUPT oc5ISR(void) { TC5 += delay; } /* wait for half a second */ /* switch to low frequency tone */ /* wait for half a second */ /* switch to high frequency tone */

Playing Songs Using the OC Function


Place the frequencies and durations of all notes in a table table. For every note, use the output-compare function to generate the digital waveform with the specified frequency and duration. The next example plays the US national anthem.

#include G3 B3 C4 C4S D4 E4 F4 F4S G4 A4 B4F B4 C5 D5 E5 F5 notes toggle

"c:\miniide\hcs12.inc" equ 7653 ; delay count to generate G3 note (with 1:8 prescaler) equ 6074 ; delay count to generate B3 note (with 1:8 prescaler) equ 5733 ; delay count to generate C4 note (with 1:8 prescaler) equ 5412 ; delay count to generate C4S (sharp) note equ 5108 ; delay count to generate D4 note (with 1:8 prescaler) equ 4551 ; delay count to generate E4 note (with 1:8 prescaler) equ 4295 ; delay count to generate F4 note (with 1:8 prescaler) equ 4054 ; delay count to generate F4S note (with 1:8 prescaler) equ 3827 ; delay count to generate G4 note (with 1:8 prescaler) equ 3409 ; delay count to generate A4 note (with 1:8 prescaler) equ 3218 ; delay count to generate B4F note (with 1:8 prescaler) equ 3037 ; delay count to generate B4 note (with 1:8 prescaler) equ 2867 ; delay count to generate C5 note (with 1:8 prescaler) equ 2554 ; delay count to generate D5 note (with 1:8 prescaler) equ 2275 ; delay count to generate E5 note (with 1:8 prescaler) equ 2148 ; delay count to generate F5 note (with 1:8 prescaler) equ 101 equ $04 ; value to toggle the TC5 pin

org $1000 delay ds.w 1 ; store the delay for output-compare operation rep cnt ds.b p_ 1 ; repeat the song this many times p g y ip ds.b 1 ; remaining notes to be played org $1500 lds #$1500 ; establish the SRAM vector address for OC5 movw #oc5_isr,UserTimerCh5 movb #$90,TSCR1 ; enable TCNT, fast timer flag clear movb #$03,TSCR2 ; set main timer prescaler to 8 bset TIOS,OC5 ; enable OC5 movb #toggle,tctl1 ; select toggle for OC5 pin action ldx #score ; use as a pointer to score table ldy #duration ; points to duration table movb #1,rep_cnt ; play the song twice p_ p y g movb #notes,ip movw 2,x+,delay ; start with zeroth note ldd TCNT ; play the first note y ;" addd delay std TC5 ;" bset TIE,C5I ; enable OC5 interrupt cli ; "

forever

done

pshy ldy jsr puly iny iny ldd std dec bne dec beq ldx ldy movb movw ldd addd std bra swi

; save duration table pointer in stack 0,y ; get the duration of the current note delayby10ms ; " ; get the duration pointer from stack ; move the duration pointer ;" 2,x+ ; get the next note, move pointer delay ;" ip forever rep_cnt done ; if not finish playing, re-establish #score ; pointers and loop count #duration ;" #notes,ip ;" 0,x,delay ; get the first note delay count TCNT ; play the first note #delay ;" TC5 forever

ldd TC5 addd delay std TC5 rti ; ************************************************************************************ ; The following subroutine creates a time delay which is equal to [Y] times ; 10 ms. The timer prescaler is 1:8. ; ************************************************************************************ de ayby 0 s delayby10ms bset TIOS,OC0 ; enable OC0 ldd TCNT again1 addd #30000 ; start an output-compare operation std TC0 ; with 10 ms time delay y wait_lp1 brclr TFLG1,C0F,wait_lp1 ldd TC0 dbne y,again1 TIOS,OC0 , ; disable OC0 bclr rts

oc5_isr oc5 isr

dw D4,B3,G3,B3,D4,G4,B4,A4,G4,B3,C4S dw D4,D4,D4,B4,A4,G4,F4S,E4,F4S,G4,G4,D4,B3,G3 D4 D4 D4 B4 A4 G4 F4S E4 F4S G4 G4 D4 B3 G3 dw D4,B3,G3,B3,D4,G4,B4,A4,G4,B3,C4S,D4,D4,D4 dw B4,A4,G4,F4S,E4,F4S,G4,G4,D4,B3,G3,B4,B4 dw B4,C5,D5,D5,C5,B4,A4,B4,C5,C5,C5,B4,A4,G4 dw F4S,E4,F4S,G4,B3,C4S,D4,D4,G4,G4,G4,F4S F4S E4 F4S G4 B3 C4S D4 D4 G4 G4 G4 F4S dw E4,E4,E4,A4,C5,B4,A4,G4,G4,F4S,D4,D4 dw G4,A4,B4,C5,D5,G4,A4,B4,C5,A4,G4 ; ************************************************************************************** ; Each of the following entries multiplied by 10 ms gives the duration of a note note. ; ************************************************************************************** duration dw 30,10,40,40,40,80,30,10,40,40,40 dw 80,20,20,60,20,40,80,20,20,40,40,40,40,40 dw 30,10,40,40,40,80,30,10,40,40,40,80,20,20 30 10 40 40 40 80 30 10 40 40 40 80 20 20 dw 60,20,40,80,20,20,40,40,40,40,40,20,20 dw 40,40,40,80,20,20,40,40,40,80,40,60,20,40 dw 80,20,20,40,40,40,80,40,40,40,20,20 dw 40,40,40,40,20,20,20,20,40,40,20,20 40 40 40 40 20 20 20 20 40 40 20 20 dw 60,20,20,20,80,20,20,60,20,40,80 end

score

#include #include #define #define #d fi #define #define #define #define #d fi #define #define #define #define #d fi #define #define #define #define #d fi #define #define #define #define #d fi #define int

c:\egnu091\include\hcs12.h c:\egnu091\include\vectors12.h G3 7653 ; delay count to be added to TC5 B3 6074 ; t generate the given note to t th i t C4 5733 C4S 5412 D4 5108 E4 4551 F4 4295 F4S 4054 G4 3827 A4 3409 B4F 3218 B4 3037 C5 2867 D5 2554 E5 2275 F5 2148 notes 101 toggle t l 0x04 0 04 INTERRUPT __attribute__((interrupt)) delay;

void delayby10ms(int kk); void INTERRUPT oc5isr(void); unsigned int score [101] = {D4,B3,G3,B3,D4,G4,B4,A4,G4,B3,C4S, D4,D4,D4,B4,A4,G4,F4S,E4,F4S,G4,G4,D4,B3,G3, D4,B3,G3,B3,D4,G4,B4,A4,G4,B3,C4S,D4,D4,D4, D4 B3 G3 B3 D4 G4 B4 A4 G4 B3 C4S D4 D4 D4 B4,A4,G4,F4S,E4,F4S,G4,G4,D4,B3,G3,B4,B4, B4,C5,D5,D5,C5,B4,A4,B4,C5,C5,C5,B4,A4,G4, F4S,E4,F4S,G4,B3,C4S,D4,D4,G4,G4,G4,F4S, E4,E4,E4,A4,C5,B4,A4,G4,G4,F4S,D4,D4, E4 E4 E4 A4 C5 B4 A4 G4 G4 F4S D4 D4 G4,A4,B4,C5,D5,G4,A4,B4,C5,A4,G4}; unsigned int dur [101] = {30,10,40,40,40,80,30,10,40,40,40, 80,20,20,60,20,40,80,20,20,40,40,40,40,40, 30,10,40,40,40,80,30,10,40,40,40,80,20,20, 30 10 40 40 40 80 30 10 40 40 40 80 20 20 60,20,40,80,20,20,40,40,40,40,40,20,20, 40,40,40,80,20,20,40,40,40,80,40,60,20,40, 80,20,20,40,40,40,80,40,40,40,20,20, 40,40,40,40,20,20,20,20,40,40,20,20, 40 40 40 40 20 20 20 20 40 40 20 20 60,20,20,20,80,20,20,60,20,40,80};

main (void) { int j; UserTimerCh5 = (unsigned short)&oc5isr; TSCR1 = 0x90; /* enable TCNT, fast timer flag clear */ TSCR2 = 0x03; /* set TCNT prescaler to 8 */ TFLG1 = 0xFF; ; /* clear all TxF flags */ g TIE |= C5I; /* enable TC5 interrupt */ TIOS |= OC5; /* enable OC5 function */ TCTL1 = toggle; /* select toggle as OC5 pin action */ asm(" cli "); ( ); /* enable TC5 interrupt */ p j = 0; delay = score[0]; TC5 = TCNT + delay; /* play the first note */ while (j < notes) { ) /* play the song once */ p y g delay = score[j]; /* play the jth note */ delayby10ms(dur[j]); j++; } TIOS &= ~OC5; /* stop playing the song */ asm ("swi"); /* return to D-Bug12 monitor */ }

void delayby10ms(int kk) { int i; TIOS |= OC0; /* enable OC0 */ TC0 = TCNT + 30000; /* start one OC0 operation */ for (i = 0; i < kk; i++) { 0 kk while(!(TFLG1 & C0F)); TC0 += 30000; } TIOS &= ~OC0; OC0; } void INTERRUPT oc5isr(void) { TC5 += delay; }

Drawback of the Song Algorithm g g


Contiguous identical notes become one note C Cannot show crescendo and d t h d d decrescendo effect d ff t Cannot provide loudness control

Using OC7 to Control Multiple OC Functions


OC7 can control up to eight channels of OC functions functions. The register OC7M specifies which OC channels are controlled by OC7. The register OC7D specifies the value that any PTx pin to assume when the OC7 operation succeeds. For OC to OC when the OC OC0 OC6, OC7Mn ( = 0,,6) bit is set, a successful OC7 (n ) f OC compare overrides a successful OC0OC6 compare pin action during the same cycle.
7 reset
0

6
0

5
0

4
0

3
0

2
0

1
0

0
0

OC7M7 OC7M6 OC7M5 OC7M4 OC7M3 OC7M2 OC7M1 OC7M0

OC7Mn n = 0..7 0 = PTn pin is not affected by OC7 function 1 = A successful OC7 action will override a successful OC6-OC0 OC6 OC0 compare action during the same cycle and the OCn action taken will depend on the corresponding OC7D bit.
Figure 8.22 Output Compare 7 Mask Register (OC7M)
7 O C 7D7 6 O C 7D6 0 5 O C 7D5 0 4 O C 7D4 0 3 O C 7D3 0 2 O C 7D2 0 1 O C 7D1 0 0 O C 7D0 0

reset

Figure 8.23 O utput C om pare 7 D ata Register (O C 7D )

Example 8 9 What value should be written into OC7M 8.9 and OC7D if one wants pins PT2, PT3, and PT4 to assume the values of 1, 0, and 1, respectively when OC7 compare succeeds? Solution:
4, 3, and 2 of OC7M must be set to 1, and bits 4, 3, 2, of OC7D should b set t 1 0 and 1 respectively. h ld be t to 1, 0, d 1, ti l The following instruction sequence will achieve the desired effect:

movb #$1C OC7M b #$1C,OC7M movb #$14,OC7D

Forced Output-Compare (1 of 2)
There are applications in which the user wants an output compare in action to occur immediately instead of waiting for a match between the TCNT and the proper output compare register. p p g This situation arises in the spark plug timing control and some automotive engine control applications. To force an output compare operation, write ones to the corresponding bit in the CFORC register. At the next timer count after the write to the CFORC register, the forced channels will trigger their g , gg programmed pin actions to occur.
7 FOC7 reset: 0 6 FOC6 0 5 FOC5 0 4 FOC4 0 3 FOC3 0 2 FOC2 0 1 FOC1 0 0 FOC0 0

Figure 8.24 Contents of the CFORC register

Forced Output-Compare (2 of 2)
Example 8.12 Suppose that the contents of the TCTL1 and TCTL2 registers are $D6 and $6E respecti el The contents of the TFLG1 $6E, respectively. are $00. What would occur on pins PT7 to PT0 on the next clock cycle if the value $7F is written into the CFORC register? Solution:
The TCTL1 and TCTL2 configure the output-compare actions as shown in Table8.2. The TFLG1 register indicates that none of the started output-compare operations have succeeded y p yet. The actions indicated in Table 8.2 will be forced to occur immediately.
Table 8.2 Pin actions on PT7-PT0 pins Register TCTL1 Bit positions 7 5 3 1 7 5 3 1 6 4 2 0 6 4 2 0 Value 1 0 0 1 0 1 1 1 1 1 1 0 1 0 1 0 Action to be triggered set the PT7 pin to high h i hi h toggle the PT6 pin toggle the PT5 pin pull the PT4 pin to low toggle the PT3 pin pull the PT2 pin to low set the PT1 pin to high pull the PT0 pin to low

TCTL2

How to determine the DC voltage? g


v (t )
T 2

DC Voltage = average value = The light blue area = (2 x) (2 x) T T = ( x + 2) 2 2

1 v ( t ) dt TT

T T = the light green area =( x ( 2 )) 2 2 x = 0 V.

How to determine the DC voltage? g


v (t )
5T 8 3T 8

DC Voltage = average value = The light blue area = (2 x) (2 x)

1 v ( t ) dt TT

3T 5T = the light green area =( x ( 2 )) 8 8

3T 5T = ( x + 2) 8 8 3 ( 2 x ) = 5 ( x + 2 ) ( 3 5 ) x = 10 6

x = 0.5 V

Pulse Width Modulation (PWM)


Many applications require the generation of di i l waveform. M li i i h i f digital f Output compare function can be used to generate digital waveform but incur too much overhead. Pulse width modulation requires only the initial setup of period and duty cycle for generating the digital waveform. The MC9S12DP256 has an 8-channel PWM module. Each PWM channel has a period register, a duty cycle register, a control register, and a dedicated counter to support waveform g g pp generation. The clock input to PWM is programmable through a two-stage circuitry. There are four possible clock sources for the PWM module: clock A, clock SA, clock B, and clock SB. Clock SA is derived by dividing the clock A by an even number ranging from 2 to 512. Clock SB is derived by dividing the clock B by an even number ranging from 2 to 512. Clock A and clock B are derived by dividing the E clock by a power of 2 2. The power can range from 0 to 7.

PWM Module

PWM Channels Channel 7 Period and duty Counter

PWM7

Bus clock

Clock select
Control

PWM clock

Channel 6 Period and duty Counter

PWM6

Channel 5 Period and duty Counter

PWM5

Channel 4 Enable Period and duty Counter

PWM4

Polarity

Channel 3 Period and duty Counter

PWM3

Alignment

Channel 2 Period and duty Counter

PWM2

Channel 1 Period and duty Counter

PWM1

Channel 0 Period and duty y Counter

PWM0

Figure 8.38 HCS12 PWM block diagram

PWM Clock Generation


The SA clock takes clock A as one of its inputs and divides it further with a user-programmable value (f bl l (from 1 t 256) and th di id it b 2 to d then divides by 2.. Clock SA is derived by dividing clock A by the value of the PWMSCLA register and then dividing by 2. Clock SB is derived by dividing clock B by the value of the PWMSCLB register and th di idi b 2 i t d then dividing by 2. The clock source selection is controlled by the PWMCLK register.
7 0 reset: 0 6 PCKB2 0 5 PCKB1 0 4 PCKB0 0 3 0 0 2 PCKA2 0 1 PCKA1 0 0 PCKA0 0

Table 8.3 Clock B prescaler selects PCKB2 0 0 0 0 1 1 1 1 PCKB1 0 0 1 1 0 0 1 1 PCKB0 0 1 0 1 0 1 0 1 value of clock B E clock l k E clock/2 E clock/4 E clock/8 E clock/16 E clock/32 E clock/64 E clock/128

Table 8.4 Clock A prescaler selects PCKA2 PCKA1 PCKA0 0 0 0 0 1 1 1 1 0 0 1 1 0 0 1 1 0 1 0 1 0 1 0 1 value of clock A E clock l k E clock/2 E clock/4 E clock/8 E clock/16 E clock/32 E clock/64 E clock/128

Figure 8.41 PWM prescale clock select register (PWMPRCLK)

Clock Scale
When PWMSCLA = $00, the PWMSCLA value is considered a full-scale of 256.

Clock SA =

Clock A 2 PWMSCLA

When PWMSCLB = $00, the PWMSCLB value is considered a full-scale of 256.

Clock SB =

Clock B 2 PWMSCLB

7 PCLK7 reset: 0

6 PCLK6 0

5 PCLK5 0

4 PCLK4 0

3 PCLK3 0

2 PCLK2 0

1 PCLK1 0

0 PCLK0 0

PCLKx: PCLK PWM channel x clock select (x = 7 6 3 2) h l l k l t ( 7, 6, 3, 0 = clock B as the clock source 1 = clock SB as the clock source PCLKy: PWM channel y clock select (y = 5, 4, 1, 0) 0 = clock A as the clock source 1 = clock SA as the clock source

Figure 8.42 PWM clock select register (PWMCLK)

PWM Channel Timers


The main part of each PWM channel x consists of an 8-bit counter (PWMCNTx), an 8-bit period register (PWMPERx), and an 8-bit duty cycle register (PWMDTYx). The waveform output period is controlled by the match between the PWMPERx register and PWMCNTx register. The waveform output duty cycle is controlled by the match of the PWMDTYx register and the PWMCNTx register. The starting polarity of the output is selectable on a per channel basis by programming the PWMPOL register. A PWM channel must be enabled by setting the proper bit of the PWME register. y g g The overall operation of the PWM module is shown in Figure 8.44.

7 PPOL7 reset: 0

6 PPOL6 0

5 PPOL5 0

4 PPOL4 0

3 PPOL3 0

2 PPOL2 0

1 PPOL1 0

0 PPOL0 0

PPOLx: PWM channel x polarity 0 = PWM channel x output is low at the start of a period, then goes high when the duty count is reached. d h d 1 = PWM channel x output is high at the start of a period, then goes low when the duty count is reached.

Figure 8.43 PWM polarity register (PWMPOL)


7 PWME7 reset: 0 6 PWME6 0 5 PWME5 0 4 PWME4 0 3 PWME3 0 2 PWME2 0 1 PWME1 0 0 PWME0 0

PWMEx: PWM channel x enable 0 = PWM channel x disabled. 1 = PWM channel x enabled.

Figure 8.45 PWM enable register (PWME)

clock source 8-bit counter PWMCNTx From port PTP data register

GATE
(clock edge sync)

up/ down

reset

8-bit compare= p PWMDTYx

T R

Q M U Q X PPOLx

M U X

to pin driver

8-bit 8 bit compare= PWMPERx

Q Q

T R

CAEx

PWMEx

Figure 8.44 PWM channel block diagram

PWM Waveform Alignment


PWM output waveform can be left-aligned or center-aligned. t li d The choice of alignment is controlled by the PWMCAE register. register

Left-Aligned Output g p
The PWMCNTx counter is configured as a count-up counter.
PWMx frequency = Clock(A, B, SA, SB frequency) PWMPERx Polarity = 0 PWMx duty cycle = [(PWMPERx PWMDTYx) PWMPERx] 100% Polarity = 1 PWMx duty cycle = [PWMDTYx PWMPERx] 100%
PPOLx = 0

PPOLx = 1

PWMDTYx Period = PWMPERx Figure 8.47 PWM left-aligned output waveform g g p

Center-Aligned Mode g
PWM counter operates as an up/down counter and is set to count up whenever the counter is equal to $00. When th Wh the counter matches th d t register the output flip-flop t t h the duty i t th t t fli fl changes state causing the PWM output to also change state. A match between the PWM counter and the period register changes the counter direction from an up-count to a down-count down-count. When the PWM counter decrements and matches the duty register again, the output flip-flop changes state causing the PWM output to g also change state. When the PWM counter decrements to 0, the counter direction changes from a down-count back to an up-count and the period and duty registers are reloaded from their buffers.

In Center-Aligned Mode
PWMx frequency = Clock (A, B, SA, or SB) frequency (2 PWMPERx) Note: Period = 2 PWMPERx When polarity = 0, 0 PWMx duty cycle = [(PWMPERx PWMDTYx) PWMPERx] 100% When polarity = 1, PWMx duty cycle = [PWMDTYx PWMPERx] 100%

PPOLx = 0

PPOLx = 1

PWMDTYx

PWMDTYx

PWMPERx

PWMPERx

Period = PWMPERx * 2 Figure 8.48 PWM center aligned output waveform

PWM 16-bit Mode (1 of 2)


Two adjacent PWM channels can be concatenated into a 16-bit PWM channel. The Th concatenation of PWM channels are controlled by the PWMCTL t ti f h l t ll d b th register. The 16-bit PWM system is illustrated in Figure 8.49. When channel k and k+1 are concatenated channel k is the high concatenated, highorder channel, whereas channel k+1 is the lower channel. (k is even number). A 16-bit channel outputs from the lower-order channel pin y and is also enabled by the lower-order channel. Both left-aligned and center-aligned mode apply to the 16-bit mode.

PWM 16-bit Mode (2 of 2)

Clock source 7

high PWMCNT6

low PWMCNT7 PWM7 low PWMCNT5 PWM5

Period/Dutycompare Clock source 5 high PWMCNT4

Period/Dutycompare Clock Cl k source 3

high PWMCNT2

low PWMCNT3 PWM3 low PWMCNT1 PWM1

Period/Dutycompare Clock source 1 high PWMCNT0

Period/Dutycompare Figure 8.49 PWM16-bit mode

PWM Counters
Each channel has a dedicated 8-bit up-down counter that runs at the rate of the selected clock source. The Th counter is compared t th duty and period registers i each clock t i d to the d t d i d i t in h l k cycle. When the counter matches the duty register, the output flip-flop changes state, state causing the PWM waveform to change state state. When the counter matches the period register, the PWM depends on the selected polarity in the polarity register (starts with low or high level). In concatenated mode, writes to the 16-bit counter either the low- or high16 bit low high order byte of the counter will reset the 16-bit counter. In concatenated mode, reads of the 16-bit counter must be made by a 16-bit access to main data coherency.

Example 8.21 Write an instruction sequence to generate a 100 KHz waveform with 50% duty cycle from the PWM0 p ( % y y pin (PP0). Assume that the ) E clock frequency is 24 MHz. Solution: Use the following setting:
Select clock A as the clock source to PWM0 and set its prescaler to 2. Select left-aligned mode. left aligned Load the value 120 into the PWMPER0 register (= 24000000 100000 2) Load the value 60 into the PWMDTY0 register (= 120 50%)

#include c:\miniide\hcs12.inc bset PWME,PWME0 movb #1,PWMPOL movb #0,PWMCLK movb #1,PWMPRCLK movb #0,PWMCAE movb #$0C,PWMCTL movb #0,PWMCNT0 movb #120,PWMPER0 movb #60,PWMDTY0

; enable PWM channel 0 ; channel 0 output high at the start of the period ; select clock A as the clock source for PWM0 ; set clock A prescaler to 2 ; select left-aligned mode ; 8-bit mode, stop PWM in wait and freeze modes ; reset the PWM0 counter ; set period value ; set duty value

OR

bset movb movb movb movb movb movb movb movb movb

PWME,PWME0 #1,PWME #1,PWMPOL #0,PWMCLK #1,PWMPRCLK #0,PWMCAE #$0C,PWMCTL #0,PWMCNT0 #120,PWMPER0 #120 PWMPER0 #60,PWMDTY0

; enable PWM channel 0 ; enable PWM channel 0 ; channel 0 output high at the start of the period ; select clock A as the clock source for PWM0 ; set clock A prescaler to 2 ; select left-aligned mode ; 8-bit mode, stop PWM in wait and freeze modes ; reset the PWM0 counter ; set period value ; set duty value

Calculation
Example 8.21 Write an instruction sequence to generate a 100KHz waveform with 50% duty cycle from the PWM0 pin (PP0). Assume that the E clock frequency is 24 MHz. E clock is @ 24 MHz, and the prescaler = 2 Clock A is @ 12 MHz

Waveform frequency = 100 KHz, then half of the period =

1 1 = 5 106 = 5 s 5 10 2

5 106 # of co nt for Clock A for half of the period 5 s = count period, s = 5 106 12 106 = 60 1 12 106
[ PWMPER0 ] = 120 and [ PWMDTY0 ] = 60

Example 8.22a Write an instruction sequence to generate a square wave with 20 s period and 60% duty cycle from PWM0 and use center-aligned mode. Solution: Select clock A as the clock source and set its prescaler to 2. p Load the value 120 into PWMPER0 register (period = 2 PWMPER0) PWMPER0 = (20 24,000,000 1000,000) 2 2 = 120 PWMDTY0 = PWMPER0 60% = 72.
OR bset movb movb movb movb movb movb movb movb movb PWME,PWME0 #1,PWME #1,PWMPOL #0,PWMCLK #1,PWMPRCLK #1,PWMCAE #$0C,PWMCTL #0, PWMCNT0 #120,PWMPER0 #72,PWMDTY0 ; enable PWM channel 0 ; enable PWM channel 0 ; set PWM0 output to start with high level ; select clock A as the clock source ; set the PWM0 prescaler to clock A to 2 ; select PWM0 center-aligned mode ; select 8-bit mode, stop PWM in wait and freeze modes ; reset PWM0 counter ; set period value ; set duty value

OR

bset movb b movb movb movb movb movb movb movb movb

PWME,PWME0 #1,PWME #1 PWME #1,PWMPOL #0,PWMCLK #1,PWMPRCLK #1,PWMCAE #$0C,PWMCTL #$0C PWMCTL #0, PWMCNT0 #120,PWMPER0 #72,PWMDTY0

; enable PWM channel 0 ; enable PWM channel 0 bl h l ; set PWM0 output to start with high level ; select clock A as the clock source ; set the PWM0 prescaler to clock A to 2 ; select PWM0 center-aligned mode ; select 8-bit mode, stop PWM in wait and freeze modes 8 bit mode ; reset PWM0 counter ; set period value ; set duty value

Calculation
Example 8.22a Write an instruction sequence to generate a square wave with 20 s period and 60% duty cycle from PWM0 and use center-aligned mode.

E clock is @ 24 MHz and the prescaler = 2 MHz, The square wave has a 20 s period.

Clock A is @ 12 MHz

20 106 = 20 106 12 106 = 240 # of count for Clock A for the period, 20 s = 1 12 106

Note: For center aligned mode: 2 PWMPER0 = 240 center-aligned [ PWMPER0 ] = 120 and [ PWMDTY0 ] = 12060% = 72

Example 8.22b Write an instruction sequence to generate a square wave with 20 s period and 60% duty cycle from PWM2 and use center-aligned mode. Solution: Select clock B as the clock source and set its prescaler to 2. p Load the value 120 into PWMPER2 register (period = 2 PWMPER0) PWMPER2 = (20 24,000,000 1000,000) 4 2 = 60 PWMDTY2 = PWMPER0 60% = 36.
OR bset movb movb movb movb movb movb movb movb movb PWME,PWME2 ; enable PWM channel 2 #4,PWME ; enable PWM channel 2 #4,PWMPOL ; set PWM2 output to start with high level #0,PWMCLK #0 PWMCLK ; select clock B as the clock source #$20,PWMPRCLK ; set the PWM2 prescaler to clock B to 4 #4,PWMCAE ; select PWM2 center-aligned mode #$0C,PWMCTL ; select 8-bit mode, stop PWM in wait and freeze modes #0, PWMCNT2 ; reset PWM2 counter #60,PWMPER2 ; set period value #36,PWMDTY2 ; set duty value

OR

bset movb b movb movb movb movb movb movb movb movb

PWME,PWME2 #4,PWME #4 PWME #4,PWMPOL #0,PWMCLK #$20,PWMPRCLK #4,PWMCAE #$0C,PWMCTL #$0C PWMCTL #0, PWMCNT2 #60,PWMPER2 #36,PWMDTY2

; enable PWM channel 2 ; enable PWM channel 2 bl h l ; set PWM2 output to start with high level ; select clock B as the clock source ; set the PWM2 prescaler to clock B to 4 ; select PWM2 center-aligned mode ; select 8-bit mode, stop PWM in wait and freeze modes 8 bit mode ; reset PWM2 counter ; set period value ; set duty value

Calculation
Example 8.22b Write an instruction sequence to generate a square wave with 20 s period and 60% duty cycle from PWM2 and use center-aligned mode.

E clock is @ 24 MHz and the prescaler = 4 MHz, The square wave has a 20 s period.

Clock B is @ 6 MHz

20 106 = 20 106 6 106 = 120 # of count for Clock B within 20 s = 1 6 106

Note: For center aligned mode: 2 PWMPER2 = 120 center-aligned [ PWMPER2 ] = 60 and [ PWMDTY2 ] = 6060% = 36

Example 8.23 Write an instruction sequence to generate a 50 Hz g y y g digital waveform with 80% duty cycle using the 16-bit mode from the PWM1 output pin. Solution: Using the following setting: Select clock A as the clock source and set its prescaler to 16 16. Select left aligned mode and select polarity 1. Load the value 30000 into the PWMPER0:PWMPER1 register. Load the value 24000 into the PWMDTY0:PWMDTY1 register. g
bset movb movb movb movb movb movb movw movw PWME,PWME1 #2,PWMPOL #0,PWMCLK #4,PWMPRCLK #$1C,PWMCTL #0,PWMCAE #0,PWMCNT1 #30000,PWMPER0 #24000,PWMDTY0 ; enable PWM0:PWM1 ; set PWM0:PWM1 output to start with high level ; select clock A as the clock source ; set prescaler to 16 ; concat. PWM0:PWM1, stop PWM in wait and freeze modes ; select left align mode ; reset PWM1 counter ; set period value ; set duty value

bset movb b movb movb movb movb movb movw movw

PWME,PWME1 #2,PWMPOL #2 PWMPOL #0,PWMCLK #4,PWMPRCLK #$1C,PWMCTL #0,PWMCAE #0,PWMCNT1 #0 PWMCNT1 #30000,PWMPER0 #24000,PWMDTY0

; enable PWM0:PWM1 ; set PWM0:PWM1 output t start with high level t PWM0 PWM1 t t to t t ith hi h l l ; select clock A as the clock source ; set prescaler to 16 ; concat. PWM0:PWM1, stop PWM in wait and freeze modes ; select left align mode ; reset PWM1 counter ; set period value ; set duty value

Calculation
Example 8.23 Write an instruction sequence to generate a 50 Hz digital waveform with 80% duty cycle using the 16-bit mode from the PWM1 output pin. E clock is @ 24 MHz, and the prescaler = 16 Clock A is @ 1.5 MHz 1 = 0.02 = 20 ms Waveform frequency = 50 Hz, then the period = 50 # of count for the period, 20 ms =
0.02 = 0.02 1.5 106 = 0.03 106 = 30, 000 1 1.5 106

[ PWMPER0 ] = 30,000

and

[ PWMDTY0 ] = 30,00080% = 24,000

Example 24: Write an instruction sequence to generate a 20 Hz digital waveform with 50% duty cycle using the 16-bit mode from the PWM1 output pin Use left aligned mode pin. mode.
Solution: Using the following setting: Select SA as the clock source, set 50 as its down count value Set clock A prescale factor to 16. 16 Select center aligned mode and select polarity 1. Load the value 750 into the PWMPER0:PWMPER1 register. Load the value 375 into the PWMDTY0:PWMDTY1 register.
bset movb movb movb b movb movb movb movb b movw movw PWME,PWME1 #2,PWMPOL #2,PWMCLK #4,PWMPRCLK #4 PWMPRCLK #0,PWMCAE #$1C,PWMCTL #50,PWMSCLA #0,PWMCNT1 #0 PWMCNT1 #750,PWMPER0 #375,PWMDTY0 ; enable PWM0:PWM1 ; set PWM1 output high at the start of the period ; select SA as the clock source of PWM0, PWM1 ; set prescaler t clock A t 16 t l to l k to ; select left align mode ; set CON01, stop PWM in wait and freeze modes ; set SCLA down count value to 50 ; reset PWM1 and PWM0 counter t d t ; set period value ; set duty cycle value

bset movb b movb movb movb movb movb movb movw movw

PWME,PWME1 #2,PWMPOL #2 PWMPOL #2,PWMCLK #4,PWMPRCLK #0,PWMCAE #$1C,PWMCTL #50,PWMSCLA #50 PWMSCLA #0,PWMCNT1 #750,PWMPER0 #375,PWMDTY0

; enable PWM0:PWM1 ; set PWM1 output high at the start of the period t t t hi h t th t t f th i d ; select SA as the clock source of PWM0, PWM1 ; set prescaler to clock A to 16 ; select left align mode ; set CON01, stop PWM in wait and freeze modes ; set SCLA down count value to 50 ; reset PWM1 and PWM0 counter ; set period value ; set duty cycle value

Calculation
Example 24: Write an instruction sequence to generate a 20 Hz digital waveform with 50% duty cycle using the 16-bit mode from the PWM1 output pin. Use left aligned mode. The generated waveform is @ 20 Hz, then period = 1/20 = 0.05 sec. E clock is @ 24 MHz, assume the prescale factor is @ 16.

24 MHz 1 2 = 1 5 MHz Period E clock = 1.5 = 106 sec l k 16 1.5 MHz 3 0.05 # of counts within 0.05 sec. = = 1.5 0.05 106 = 75, 000 6 ( 2 3) 10 75, 000 = 2 50 750 [ PWMPER0 ] = 750
and [ PWMDTY0 ] = 750 50% = 375

Example 25: Write an instruction sequence to generate a 20 Hz digital waveform with 50% duty cycle using the 16-bit mode from the PWM3 output pin Use center aligned mode pin. mode.
Solution: Using the following setting: Select SB as the clock source and use 50 as its down count value. Set clock B prescale factor to 16. 16 Select center aligned mode and select polarity 1. Load the value 750 into the PWMPER0:PWMPER1 register. Load the value 375 into the PWMDTY0:PWMDTY1 register.
bset move movb movb movb movb movb movb movw movw PWME,PWME3 #8,PWMPOL #8,PWMCLK #$40,PWMPRCLK #$40 PWMPRCLK #8,PWMCAE #$2C,PWMCTL #50,PWMSCLB #0,PWMCNT3 #0 PWMCNT3 #750,PWMPER2 #375,PWMDTY2 ; enable PWM2:PWM3 ; set PWM3 output high at the start of the period ; select SB as the clock source of PWM3, PWM2 ; set prescaler to clock B to 16 ; select center aligned mode ; set CON23, stop PWM in wait and freeze modes ; set SCLB down count value to 50 ; reset PWM3 and PWM2 counter ; set period value ; set duty cycle value

bset move movb movb movb movb o b movb movb movw movw

PWME,PWME3 #8,PWMPOL #8 PWMPOL #8,PWMCLK #$40,PWMPRCLK #8,PWMCAE #$2C,PWMCTL #50, #50,PWMSCLB SC #0,PWMCNT3 #750,PWMPER2 #375,PWMDTY2

; enable PWM2:PWM3 ; set PWM3 output high at the start of the period ; select SB as the clock source of PWM3, PWM2 ; set prescaler to clock B to 16 ; select center aligned mode ; set CON23, stop PWM in wait and freeze modes ; set SCLB down count value to 50 SC do cou t a ue ; reset PWM3 and PWM2 counter ; set period value ; set duty cycle value

Calculation
Example 25: Write an instruction sequence to generate a 20 Hz digital waveform with 50% duty cycle using the 16-bit mode from the PWM3 output pin. Use center aligned mode.

The generated waveform is @ 20 Hz, then period = 1/20 = 0.05 sec. E clock is @ 24 MHz, assume the prescale factor is @ 16.
24 MHz 1 2 = 1 5 MH P i d E clock = 1.5 MHz Period = 106 sec 16 1.5 MHz 3 0.05 # of counts within 0.05 sec. = = 1.5 0.05 106 = 75, 000 6 ( 2 3) 10 75, 000 = 2 50 750

[ PWMPER0 ] = 750 and

[ PWMDTY0 ] = 750 50% = 375

Example 8.24 Use PWM to dim the light bulb. Assume that we use p g g the PWM0 output to control the brightness of a light bulb. Write a C program to dim the light to 10% brightness gradually in five seconds. The E clock frequency is 24 MHz. q y Solution:
Set duty cycle to 100% at the beginning. y y g g Dim the brightness by 10% in the first second and then 20% per second in the following four seconds. Load 100 into the PWMPER0 register at the beginning. D Decrement PWMPER0 b 1 every 100 ms d i th fi t second and t by during the first d d decrement PWMPER0 by 2 every 100 ms in the following four seconds.

#include c:\egnu091\include\hcs12.h #include c:\egnuo91\include\delay.c void main () { int dim_cnt; PWMCLK = 0; / /* select clock A as the clock source */ / PWMPOL = 1; /* make waveform to start with high level */ PWMCTL = 0x0C; /* select 8-bit mode */ PWMPRCLK = 2; /* set clock A prescaler to 4 */ PWMCAE = 0; /* select left-aligned mode */ PWMPER0 = 100; /* set period of PWM0 to 0.1 ms */ PWMDTY0 = 100; /* set duty cycle to 100% */ PWME = 0x01; /* enable PWM0 channel */ /* reduce duty cycle 1 % per 100 ms in the first second */ for (dim_cnt = 0; dim_cnt < 10 ; dim_cnt ++) { y y ( ); delayby100ms(1); PWMDTY0--; }

/* reduce duty cycle 2% per 100 ms in the next 4 seconds */ for (dim cnt = 0; dim cnt < 40; dim cnt ++) { (dim_cnt dim_cnt dim_cnt delayby100ms(1); PWMDTY0 -= 2; } asm ("swi"); }

You might also like