Top Banner
1 EET484 Microcontroller Lecture 8 (Adapted from Prof. Huang’s lecture notes) 8. Timer Functions 1. The Timer System of the C8051F040 The C8051F040 implements Timer 0, 1, and 2 of the original 8051 and adds two timers (Timer 3 and 4) that are identical to Timer 2. The 8051F040 provides three popular timer functions, i.e., o Capture: edge-triggered; requires capture register; can measure the pulse width, period or duty cycle of a signal. o Compare: implemented by comparing the timer value in every clock cycle with the value stored in the compare register; when equal, sets pin. o PWM: to generate periodic square waveforms with a given frequency and duty cycle; can change the average DC voltage by adjusting duty cycle. The 8051F040 also adds a six-channel programmable counter array (PCA). The capabilities of the C8051F040 timers and PCA are illustrated in Table 8.1. Table 8.1 Capability of the C8051F040 timer system Timer subsystem Capabilities Timer 0 Mode 0: 13-bit counter/timer Mode 1: 16-bit counter/timer Mode 2: 8-bit auto-reload counter/timer Mode 3: two separate 8-bit counters Timer 1 Mode 0-2: identical to those in Timer 0 Mode 3: holds its contents Timer 2, 3, and 4 16-bit counter/timer with auto-reload 16-bit counter/timer with capture Toggle clock out PCA Edge-triggered capture Software timer High-speed output Frequency output 8-bit PWM 16-bit PWM Signal pins related to timer functions are listed in Table 8.2. These signal pins are assigned to port pins by programming the crossbar decoder.
19
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
  • 1

    EET484 Microcontroller Lecture 8

    (Adapted from Prof. Huangs lecture notes)

    8. Timer Functions

    1. The Timer System of the C8051F040 The C8051F040 implements Timer 0, 1, and 2 of the original 8051 and adds two

    timers (Timer 3 and 4) that are identical to Timer 2.

    The 8051F040 provides three popular timer functions, i.e., o Capture: edge-triggered; requires capture register; can measure the pulse

    width, period or duty cycle of a signal.

    o Compare: implemented by comparing the timer value in every clock cycle with the value stored in the compare register; when equal, sets pin.

    o PWM: to generate periodic square waveforms with a given frequency and duty cycle; can change the average DC voltage by adjusting duty cycle.

    The 8051F040 also adds a six-channel programmable counter array (PCA). The capabilities of the C8051F040 timers and PCA are illustrated in Table 8.1.

    Table 8.1 Capability of the C8051F040 timer system

    Timer subsystem

    Capabilities

    Timer 0

    Mode 0: 13-bit counter/timerMode 1: 16-bit counter/timerMode 2: 8-bit auto-reload counter/timerMode 3: two separate 8-bit counters

    Timer 1 Mode 0-2: identical to those in Timer 0Mode 3: holds its contents

    Timer 2, 3, and 4

    16-bit counter/timer with auto-reload16-bit counter/timer with captureToggle clock out

    PCA

    Edge-triggered captureSoftware timerHigh-speed outputFrequency output8-bit PWM16-bit PWM

    Signal pins related to timer functions are listed in Table 8.2. These signal pins are assigned to port pins by programming the crossbar decoder.

  • 2

    Table 8.2 The functions of timer pins of the C8051F040

    Pin name

    T0

    T1

    T2

    T2EX

    T3

    T3EX

    T4

    T4EX

    ECI

    CEX0

    CEX1

    CEX2

    CEX3

    CEX4

    CEX5

    ECI1

    Description

    Timer 0 external inputTimer 1 external inputTimer 2 external inputTimer/counter 2 capture/reload trigger and direction controlTimer 3 external inputTimer/counter 3 capture/reload trigger and direction controlTimer 4 external inputTimer/counter 3 capture/reload trigger and direction controlExternal count input to PCA0External I/O for compare/capture module 0External I/O for compare/capture module 1External I/O for compare/capture module 2External I/O for compare/capture module 3External I/O for compare/capture module 4External I/O for compare/capture module 5External count input to PCA1

    2. Timer 0 and Timer 1

    Each timer is implemented as a 16-bit register accessed as two separate bytes (TH0:TL0 and TH1:TL1).

    TCON enables/disables these two timers and indicates their status. The TMOD register selects the operation mode of Timer 0 and Timer 1. The CKCON register selects the clock source of Timer 0 and Timer 1. The Timer 0 and Timer 1 should be stopped when changing the operation mode or

    reload a new value to the timer.

    Mode 0: 13-bit timer or counter (use T0 as clock source)

    Setting the GATE0 bit allows the INT0 pin to control the running of Timer 0.

    Setting TR0 enables but does not reset the timer.

    0

    1

    0

    1

    Crossbar

    Prescaled clock

    SYSCLK

    C/T0

    T0M

    T0

    INT0

    TR

    0GATE0

    TL0

    5 bits)

    TH0

    (8 bits)TF0

    Figure 8.1a Timer 0 mode 0 block diagram (C8051F040)

    Mode 1: 16-bit timer or counter

    The counters/timers are enabled and configured in the same manner as in Mode 0. The block diagrams of Mode 1 for Timers 0 and 1 are identical to Figure 8.1a

    except TL0 is 8 bits.

  • 3

    Mode 2: 8-bit timer or counter with auto-reload

    The TLx is the counter whereas THx holds the reload value. Whenever TLx overflows (from 0xFF to 0x00), the TFx flag is set and the value

    in THx is loaded into the TLx register.

    0

    1

    0

    1

    Crossbar

    Prescaled clock

    SYSCLK

    C/T0

    T0M

    T0

    INT0

    TR0GATE0

    TL0(8 bits)

    TH0(8 bits)

    TF0

    Figure 8.2a Timer 0 mode 2 block diagram (C8051F040)

    Reload

    Mode 3: two 8-bit timers or counters

    Only available in Timer 0 Configured as two separate 8-bit counters/timers held in TL0 and TH0 TL0 can use either the system clock or an external input signal as its clock source. TL0 is controlled using the Timer 0 control/status bits in TCON and TMOD.

    TH0 is restricted to timer function clocked by system clock or prescaled clock. TH0 is enabled using TR1 of Timer 1 and sets the TF1 flag on overflow.

  • 4

    TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0

    7 6 5 4 3 2 1 0

    TF1: Timer 1 overflow flag

    0 = No Timer 1 overflow

    1 = Timer 1 has overflowed

    This flag is automatically cleared when the CPU vectors to Timer 1

    interrupt service routine.

    TR1: Timer 1 run control

    0 = Timer 1 disabled

    1 = Timer 1 enabled

    TF0: Timer 0 overflow flag

    0 = No Timer 0 overflow

    1 = Timer 0 has overflowed

    This flag is automatically cleared when the CPU vectors to Timer 0

    interrupt service routine.

    TR0: Timer 0 run control

    0 = Timer 0 disabled

    1 = Timer 0 enabled

    IE1: External interrupt 1 flag

    This flag is set when an edge/level of type defined by IT1 is

    detected. It is automatically cleared when the CPU is vectored to

    the external interrupt 1 service routine. It can also be cleared by

    software.

    IT1: Interrupt 1 type select

    0 = /INT1 is level triggered, active low

    1 = /INT1 is falling-edge triggered

    IE0: External interrupt 0 flag

    This flag is set when an edge/level of type defined by IT0 is

    detected. It is automatically cleared when the CPU is vectored to

    the external interrupt 1 service routine. It can also be cleared by

    software.

    IT0: Interrupt 0 type select

    0 = /INT0 is level triggered, active low

    1 = /INT0 is falling-edge triggered

    Figure 3.17 Timer control register (TCON)

    Value after Reset: 00h

    rw rw rw rw rw rw rw rw

  • 5

    GATE1 C/T1 T1M1 T1M0 GATE0 C/T0 T0M1 T0M0

    7 6 5 4 3 2 1 0

    GATE1: Timer 1 gate control 0 = Timer 1 is enabled when TR1 = 1 irrespective of /INT1 logic level 1 = Timer 1 is enabled only when TR1 = 1 and /INT1 = logic 1C/T1: Counter/Timer 1 select 0 = Timer function: Timer 1 is incremented by clock defined by T1M bit 1 = Counter function: Timer 1 is incremented by high-to-low transitions on external input pin (T1)T1M1-T1M0: Timer 1 mode select 00 = Mode 0: 13-bit counter/timer 01 = Mode 1: 16-bit counter/timer 10 = Mode 2: 8-bit counter/timer with auto-reload 11 = Mode 3: Timer 1 inactive.GATE0: Timer 0 gate control 0 = Timer 0 is enabled when TR0 = 1 irrespective of /INT0 logic level 1 = Timer 0 is enabled only when TR0 = 1 and /INT0 = logic 1C/T0: Counter/Timer select 0 = Timer function: Timer 0 is incremented by clock defined by T0M bit 1 = Counter function: Timer 0 is incremented by high-to-low transitions on external input pin (T0)T0M1-T0M0: Timer 0 mode select 00 = Mode 0: 13-bit counter/timer 01 = Mode 1: 16-bit counter/timer 10 = Mode 2: 8-bit counter/timer with auto-reload 11 = Mode 3: Two 8-bit counter/timers.

    Figure 3.18 Timer mode register (TMOD)

    Value afterReset: 00h

    rw rw rw rw rw rw rw rw

    -- -- -- T1M T0M -- SCA1 SCA0

    7 6 5 4 3 2 1 0

    T1M: Timer 1 clock select (this bit is ignored when C/T1 is set to 1) 0 = Timer 1 uses the clock defined by the prescale bits SCA1-SCA0 1 = Timer 1 uses the system clock as clock sourceT0M: Timer 0 clock select (this bit is ignored when C/T0 is set to 1) 0 = Timer 0 uses the clock defined by the prescale bits SCA1-SCA0 1 = Timer 0 uses system clockSCA1-SCA0: Timer 0/1 prescale bits 00 = system clock divided by 12 01 = system clock divided by 4 10 = system clock divided by 48 11 = external clock divided by 8

    Figure 3.19 Timer mode register (CKCON)

    Value afterReset: 00h

    rw rw rw rw rw rw rw rw

    Figure 3.19. Clock control register (CKCON)

  • 6

    3. Applications of Timer 0 and Timer 1 3.1 Pulse Width Measurement

    Connect the unknown signal to INT0 (or INT1) Enable INT0 (or INT1) pin falling edge interrupt Clear TF0 (or TF1) flag

    The procedure is as follows:

    1. Connect the unknown signal to the INT1 pin. Invert the signal if it is a negative-

    going pulse.

    2. Configure Timer 1 to operate in mode 1 and select SYSCLK 12 as the clock input to the timer.

    3. Initialize the Timer 1 overflow count to 0, and also initialize the INT1 interrupt

    count to 1.

    4. Write a Timer 1 overflow interrupt service routine that increments the overflow count by 1 and returns.

    5. Write an INT1 interrupt service routine, which decrements its interrupt count by 1.

    6. Select falling edge interrupt from INT1 pin. Enable Timer 1 overflow interrupt.

    7. Clear the TF1 flag to 0 and also enable Timer 1 to run.

    8. Wait until the INT1 interrupt count is decremented to 0. Then the pulse width of the

    unknown signal is given by the following expression:

    Pulse Width = (timer overflow count 216 + timer count) machine cycles

    Example1. Write a program to measure the pulse width of the signal connected to the

    INT1 pin, assuming that the C8051F040 is controlled by an oscillator running at 24 MHz. include

    void int1ISR(void);

    void T1ISR(void);

    char intCnt; // variable to wait for INT1 falling edge interrupt

    unsigned long pw;

    unsigned long int T1OvCnt;

    void sysinit(void);

    void main(void) {

    sysinit();

    SFRPAGE = TIMER01_PAGE;

    TL1 = 0; // count up from 0

    TH1 = 0; // T1OvCnt = 0;

    intCnt = 1; // there is only one falling edge in a pulse width

    TMOD = 0x90; // gated, timer mode, mode 1 operation

    CKCON = 0; // Timer clock source is SYSCLK / 12

    IT1 = 1; // choose falling edge interrupt for INT1

    IE |= 0x8C; // enable INT1 and Timer 1 overflow interrupts

    TF1 = 0;

    TR1 = 1; // start Timer 1

    while (intCnt); // wait until the falling edge of INT1 arrives

    TR1 = 0; // stop the timer

  • 7

    pw = 65536*T1OvCnt + 256*(unsigned long)TH1 + (unsigned long)TL1;

    while(1);

    }

    void sysinit(void)

    {

    int n;

    SFRPAGE = CONFIG_PAGE;

    WDTCN = 0xDE; // disable watchdog timer

    WDTCN = 0xAD; // "

    OSCXCN = 0x67; // start external oscillator; 24 MHz Crystal

    // system clock is 24 MHz

    for (n = 0; n < 255; n++); // delay about 1 ms

    while ((OSCXCN & 0x80) == 0); // wait for oscillator to stabilize

    CLKSEL |= 0x01; // switch to external oscillator

    XBR2 = 0x5D; // enable crossbar and assign I/O pins to all

    XBR0 = 0xF7; // peripheral signals,

    XBR1 = 0xFF; // "

    XBR3 = 0x8F; // "

    SFRPAGE = SPI0_PAGE;

    SPI0CN = 0x01; // enable 3-wire SPI (make sure SPI uses 3 pins

    }

    void int1ISR(void) interrupt 2

    {

    intCnt--;

    }

    void T1ISR(void) interrupt 3

    {

    T1OvCnt++;

    }

    3.2 Frequency Measurement

    The frequency of an unknown signal can be measured by using Timer 0 (or 1) to create a

    delay of one second and use Timer 1 (or 0) to count the number of rising (or falling)

    edges arrived during this interval.

    Connect unknown signal to T1 pin Use Timer 0 to create one-second delay At the end of one second, the count value in Timer 0 is the frequency of the signal.

    Example2. Write a program to measure the frequency of a signal by using Timer 0 or

    Timer 1 to create a delay of one second and use Timer 1 to count the number of rising or

    falling edges arrived at during this interval. #include

    void sysinit(void);

    void t1_ISR (void);

    unsigned char t1ovCnt;

    void main (void)

    {

    char i;

    long int freq;

  • 8

    sysinit();

    SFRPAGE = TIMER01_PAGE;

    TMOD = 0x51; // configure Timer 1, Timer 0 to counter and timer mode 1

    CKCON = 0x02; // use SYSCLK/48 as the clock source of Timer 0

    TH1 = 0x00; // Timer 1 count up from 0

    TL1 = 0x00;

    IE = 0x88; // enable Timer 1 interrupt

    ET0 = 0; // disable Timer 0 interrupt

    for (i = 0; i < 10; i++){

    TF0 = 0;

    TR0 = 0; // stop Timer 0

    TH0 = 0x3C; // let Timer 0 count up from 15536 so it overflows in 100 ms

    TL0 = 0xB0; // *

    TR0 = 1; // start Timer 0

    while(!TF0); // wait for 100 ms

    }

    freq = (long)t1ovCnt * 65536 + 256 * (long)TH1 + (long)TL1;

    }

    void t1_ISR (void) interrupt 3

    {

    TF1 = 0;

    t1ovCnt++;

    }

    // ---------------------------------------------------------------------------------------------------------

    // include the sysinit() function here.

    // --------------------------------------------------------------------------------------------------------

  • 9

    4. Timer 2, Timer 3, and Timer 4 These Timers have identical capabilities. These timers can operate as a timer or an event counter. They also provide auto-

    reload, capture, and toggle output modes with the capability of counting up or

    counting down.

    The operation modes of these timers are configured by programming the TMRnCN and TMRnCF registers.

    The contents of TMRnCN and TMRnCF are shown in Figure 8.3 and 8.4.

    TFn EXFn EXENn TRn C/Tn CP/RLn-- --

    7 6 5 4 3 2 1 0TMRnCNreset:00h

    TF2 EXF2 EXEN2 TR2 C/T2 CP/RL2RCLK TCLKT2CONreset:00h

    TFn (n = 2, 3, or 4): Timer n overflow/underflow flag

    0 = no overflow or underflow occurred.

    1 = Timer n overflow or underflow (timer/counter count from 0x0000 to 0xFFFF) ocurred

    EXFn (n = 2, 3, or 4): Timer 2, 3, or 4 external flag

    This flag is set when either a capture or reload is caused by a high-to-low transition on

    the TnEX pin and EXENn is logic one. This flag must be cleared by software.

    RCLK: Receive clock bit

    0 = use Timer 1 overflow as receive clock for serial port in mode 1 or 3

    1 = use Timer 2 overflow as receive clock for serial port in mode 1 or 3

    TCLK: Transmit clock bit

    0 = use Timer 1 overflow as transmit clock for serial port in mode 1 or 3

    1 = use Timer 2 overflow as transmit clock for serial port in mode 1 or 3

    EXENn (n = 2, 3, or 4): Timer n external enable

    0 = transitions on the TnEX pin are ignored

    1 = transitions on the TnEX pin cause capture, reload, or control the direction of timer

    count (up or down) as follows:

    Capture mode: 1-to-0 transition on TnEX pin causes RCAPnH:RCAPnL to capture

    count value.

    Auto-reload mode:

    DCEN = 0: 1-to-0 transition of TnEX pin causes reload of timer and sets ExFn flag.

    DCEN = 1: TnEX logic level controls direction of timer (up or down)

    TRn (n = 2, 3, or 4): Timer n run control

    0 = timer n disabled

    1 = timer n enabled

    C/Tn (n = 2, 3, or 4): Counter/timer select

    0 = timer function

    1 = counter function: timer incremented by the falling edge of Tn pin

    CP/RLn (n = 2, 3, or 4): Capture/reload select

    0 = timer is in reload mode

    1 = timer is in capture mode

    Figure 8.3 Contents of the TMRnCN and T2CON register

  • 10

    -- -- TnM0 TOGn TnOE DCEN-- TnM1

    7 6 5 4 3 2 1 0TMRnCFreset:00h

    -- -- -- -- T2OE DCEN-- --T2MODreset:00h

    TnM1-TnM0 (n = 2, 3, or 4): Timer clock mode select bits

    00: select SYSCLK/12 as the Timer n clock source

    01: select SYSCLK as the Timer n clock source

    10: select External Clock/8 as the Timer n clock source

    11: select SYSCLK/2 as Timer n clock source

    TOGn (n = 2, 3, or 4): Toggle output state bit

    When timer is used to toggle a port pin, this bit can be used to read the state of the output,

    or can be written to in order to force the state of the output

    TnOE (n = 2, 3, or 4): Timer output enable bit

    0 = output of toggle mode not available at timer's assigned port pin

    1 = output of toggle mode available at timer's assigned port pin

    DCEN: Decrement enable bit

    0 = Timer will count up, regardless of the state of TnEX

    1 = Timer will count up or down depending on the state of TnEX as follows:

    if TnEX = 0, the timer counts down

    if TnEX = 1, the timer counts up

    Figure 8.4 Contents of the TMRnCF and T2MOD register

    4.1 Configuring Timer 2, 3, and 4 to Count Down

    Set the DCEN bit of the TMRnCF register, and set the EXENn bit of the TMRnCN register.

    The count direction is determined by the logic level of the TnEX (n = 2, 3, or 4) pin. The TnEX pin must be assigned to the I/O pin.

    When TnEX = 1, the timer counts up. Otherwise, timer counts down. When DCEN bit is set, other functions of the TnEX input (capture and auto-

    reload) are not available

    Thus, to count down: EXENn = 1, DCEN = 1 and TnEx = 0,

    4.2 Timer 2, 3, and 4 Capture Mode

    This mode is entered when the CP/RLn, TRn, and EXENn bits of the TMRnCN register are set to 1.

    The falling edge of the TnEX pin causes the 16-bit timer value TMRnH:TMRnL to be copied into the capture register RCAPnH:RCAPnL.

    When a capture occurs, the EXFn flag will be set and may cause an interrupt to the MCU.

    Thus, to enable Capture mode, CP/RLn = 1, TRn = 1, EXENn = 1, DCEN=0. When

    a capture occurs, the EXFn flag is set.

  • 11

    2

    2

    8

    SYSCLK

    MU

    X

    external clock

    crossbarTn

    01

    TRn

    crossbar

    EXENn

    TnEX

    TnM1:TnM0

    TCLK TMRnL TMRnH

    DCEN

    RCAPnLRCAPn

    H

    TFn

    EXFn

    Timer ninterrupt

    Figure 8.6 Timer 2, 3, or 4 in capture mode block diagram (C8051F040)

    C/T

    0xFF 0xFFtoggleTOGn Tn

    2

    2

    8

    SYSCLK

    MU

    X

    external clock

    (XTAL1)

    crossbarTn

    01

    TRn

    crossbar

    EXENn

    TnEX

    TnM1:TnM0

    TCLK TMRnL TMRnH

    DCEN

    RCAPnL RCAPnH

    TFn

    EXFn

    Timer ninterrupt

    Figure 8.7c Timer 2, 3, or 4 in auto-reload mode updown counter diagram (C8051F040)

    0xFF 0xFF

    C/T

    overflow

    Togglecircuit

    TOGn

    to Tn

    4.3 Timer 2, 3, or 4 Auto Reload Mode

    This mode is selected when the CP/RLn of the TMRnCN register is 0. Case A:

    The DCEN bit is set to 1 to allow the user to select count up or count down mode by pulling the TnEX pin to high or low.

    When counting up and the timer overflows, the values in the reload/capture register pair (RCAPnH:RCAPnL) will be reload into the timer and counting

    resumes.

  • 12

    When counting down and the time value matches that in RCAPnH:RCAPnL, the timer will be loaded with 0xFFFF and counting continues.

    In auto-reload mode, the EXFn flag toggles upon every overflow and underflow and does not cause an interrupt.

    Case B:

    When the DCEN bit is 0 and EXENn is set to 1, a falling edge of the TnEX pin cause a timer reload (in addition to the auto-reload caused by timer overflow).

    Thus, there are three cases:

    Auto reload at counting up mode:

    CP/RLn=0, EXENn=1, DCEN = 1, TnEX = 1. Or

    CP/RLn=0, EXENn=0, DCEN = 0, TnEX = dont care. Auto reload at counting down mode: CP/RLn=0, EXENn=1, DCEN = 1, TnEX = 0.

    Auto reload at a falling edge of TnEX pin: CP/RLn=0, EXENn=1, DCEN = 0, TnEX

    transit from 1 to 0

    4.4 Toggle Clock Out Mode

    Timer 2, 3, or 4 has the capability to toggle the state of their associated output port pins (T2, T3, or T4) to produce a 50% duty cycle waveform output.

    This mode is entered by clearing the C/Tn bit and CP/RLn bits, setting the TnOE bit, and loading a value into the RCAPnH:RCAPnL register pair..

    The timer pin toggles whenever the timer overflows (count up mode) or underflows (count down mode)

    When counting up, the auto-reload value comes from RCAPnH:RCAPnL, the overflow occurs when the timer register reaches 0xFFFF.

    When counting down, the auto-reload value is 0xFFFF, the underflow occurs when the value in the timer matches the value in RCAPnH:RCAPnL.

    The circuit is the same as that in Figure 8.7c. Thus, Need to set C/Tn = 0, CP/RLn=0, TnOE = 1,

    The frequency of the clock output fSQ is determined by the clock source fTCLK and value loaded into register pairs RCAPnH:RCAPnL, which is

    fSQ = fTCLK (2 (216

    RCAPnH:RCAPnL)) --- (8.3)

    Thus, given fSQ, the value to be loaded into the RCAPnH:RCAPnL is

    RCAPnH:RCAPnL = 216

    fTCLK (2 fSQ) --- (8.4)

    Using Timer 2 to Measure Signal Period

    Capture two falling edges Need to take Timer 2 overflow into account

    Let

    tovcnt = the Timer 2 overflow count

    diff = edge2 edge1 (because 2s complement addition is used to perform a subtract operation, this will give the correct magnitude if edge1

    is larger than edge 2)

    = edge2 + (216

    - edge1)

  • 13

    edge1 = the captured time of the first edge

    edge2 = the captured time of the second edge

    Then

    Case 1: edge2 edge1

    Period = tovcnt 216 + diff -- (8.5)

    Case 2: edge2 < edge1

    Period = (tovcnt 1) 216 + diff -- (8.6)

    Example 8.3 Write a C program to measure the period of a signal connected to T2EX

    pin assuming the internal oscillator is used as SYSLK (24.5 MHz). Solution:

    #include // compiled using the SDCC compiler

    unsigned char tov2Cnt; // timer 2 overflow count

    unsigned char periodH, periodL;

    unsigned long period;

    void t2ISR (void) interrupt 5

    {

    if (TF2) {

    tov2Cnt++;

    TF2 = 0;

    }

    }

    void sysInit (void)

    {

    SFRPAGE = 0x0F;

    WDTCN = 0xDE; // disable watchdog timer

    WDTCN = 0xAD;

    CLKSEL = 0; // select internal oscillator as SYSCLK

    OSCICN = 0x83; // XBR0 = 0xF7; // assign all peripheral function signals to port pins

    XBR1 = 0xFF; // "

    XBR2 = 0x5D; // "

    XBR3 = 0x8F; // "

    SFRPAGE = 0; // switch to SFR page 0

    SPI0CN = 0x01; // enable and configure SPI to 3-wire mode

    }

  • 14

    void main (void)

    {

    unsigned int t1, t2;

    sysInit();

    tov2Cnt = 0; // initialize timer 2 overflow count to 0

    TMR2CN = 0x0D; // enable T2EN, capture mode, timer mode

    IE = 0; // disable all interrupt

    while(!EXF2); // wait for the first falling edge on T2EX pin

    periodL = RCAP2L; // save the first edge

    periodH = RCAP2H; // "

    EXF2 = 0;

    TF2 = 0;

    IE = 0xA0; // enable Timer 2 interrupt

    while(!EXF2); // wait for the second falling edge on T2EX pin

    t1 = 256 * (unsigned int)periodH + (unsigned int)periodL;

    t2 = 256 * (unsigned int) RCAP2H + (unsigned int) RCAP2L;

    if (t2 < t1)

    tov2Cnt--;

    period = (unsigned long) tov2Cnt * 65536 + (unsigned long)t2 - (unsigned long)t1;

    while(1);

    }

    4.5 Waveform Generation using Timer 2

    Example 8.5 Write an instruction sequence to generate a 2 KHz (period=0.5ms - High

    time = Low time = 0.25ms, i.e., toggle frequency is 4KHz) square waveform using the

    Timer 2 of the C8051F040, which runs with the internal 24.5 MHz internal oscillator

    clock source.

    Solution: The reload value is 216

    24.5 106 (2 2000) = 65536 6125 = 0xE813.

    #include

    void sysinit (void);

    void main (void)

    {

    sysinit();

    TMR2H = 0xE8;

    TMR2L = 0x13;

    RCAP2H = 0xE8;

    RCAP2L = 0x13;

    TMR2CF = 0x0A; // select SYSCLK as timer clock, prescalar = 1, TnM1-TnM0=01

    // enable the output of toggle mode, T2OE = 1

    TMR2CN = 0x04; // enable Timer 2, TR2 = 1, all other 0

    while(1);

    }

  • 15

    void sysinit (void)

    {

    SFRPAGE = 0x0F;

    WDTCN = 0xDE;

    WDTCN = 0xAD;

    CLKSEL = 0;

    OSCICN = 0x83;

    XBR0 = 0xF7;

    XBR1 = 0xFF;

    XBR2 = 0x5D;

    XBR3 = 0x8F;

    P2MDOUT |= 0x80; // enable P2.8 output

    SFRPAGE = SPI0_PAGE;

    SPI0CN = 0x01; // enable 3-wire SPI mode

    }

    Generating Siren

    C8051F040

    T2

    3.3 F

    Speaker

    Figure 8.10 Circuit connection for a speaker

    Example 8.6 Use the circuit in Figure 8.10 to generate a two-tone siren.

    Solution: The procedure is as follows:

    Step 1 Connect an 8- speaker to the T2 pin. Step 2 Configure Timer 2 to operate in toggle output mode.

    Step 3 Stop Timer 2 and load the value 37695 (= 65536 (24,500,000 (440 2))) to RCAP2H:RCAP2L and TMR2H:TMR2L register pairs to generate the 440 Hz waveform.

    Step 4 Enable Timer 2 and wait for half of a second.

    Step 5 Load the value 51616 (= 65536 (24,500,000 (880 2))) to RCAP2H:RCAP2L and TMR2H:TMR2L register pairs to generate the 880 Hz waveform.

    Step 6

    Reenable Timer 2 and wait for half of a second.

    Step 7 Stop Timer 2 and go to Step 3.

    #include // compiled using SDCC

    void sysInit(void)

    {

  • 16

    SFRPAGE = 0x0F; // switch to SFR page 0

    WDTCN = 0xDE; // disable watchdog timer

    WDTCN = 0xAD;

    CLKSEL = 0; // select internal oscillator as SYSCLK

    OSCICN = 0x83; // "

    XBR0 = 0xF7; // assign all peripheral signals to port pins

    XBR1 = 0xFF; // XBR2 = 0x5D; // XBR3 = 0x8F; // P2MDOUT = 0x80; // enable T2 pin output

    SFRPAGE = 0; // switch to SFR page 0

    SPI0CN = 0x01; // enable SPI in 3-wire mode

    }

    void delayby100ms(unsigned char k)

    {

    unsigned char i,tempage;

    tempage = SFRPAGE;

    SFRPAGE = 0;

    TMOD = 0x11; // configure Timer 0 and 1 to mode 1

    CKCON = 0x02; // Timer 0 use system clock divided by 48 as clock source

    for (i = 0; i < k; i++){

    TH0 = 0x38; // place 14494 in TH0:TL0 so it overflows in 100 ms

    TL0 = 0x9E;

    TF0 = 0;

    TR0 = 1; // enable Timer 0

    while(!TF0); // wait for 100 ms

    TR0 = 0; // stop Timer 0

    }

    SFRPAGE = tempage; // restore original SFRPAGE

    }

    void main (void)

    {

    sysInit(); // configure SYSCLK and all peripheral pin assignments

    TMR2CF = 0x0A; // select SYSCLK as timer 2 clock, enable T2 output

    TMR2CN = 0; // stop TMR2 but select auto-reload timer mode

    while (1) {

    TMR2H = 0x93; // generate 440Hz tone

    TMR2L = 0x3F; // RCAP2H = 0x93; // RCAP2L = 0x3F; // TR2 = 1; // enable Timer 2 in auto reload mode

    delayby100ms(5); // wait for 0.5 seconds

    TR2 = 0;

    TMR2H = 0xC9; // generate 880 Hz tone

    TMR2L = 0xA0; // RCAP2H = 0xC9; // RCAP2L = 0xA0;

    TR2 = 1; delayby100ms(5);

    TR2 = 0;

    }

  • 17

    }

    Using Timer 2 to Play a Song

    A note in the score consists of two components: pitch (frequency) and tempo (duration).

    The duration of a quarter note is 400 ms. Place the frequencies and durations of all the notes of a music score in a table. For every note, the user program uses the toggle output mode of Timer 2 to

    generate the digital waveform with the specified frequency and duration.

    #include

    #define G3H 0x0B // reload value of TMR2 for the G3 note

    #define G3L 0xDC // "

    #define B3H 0x3E // reload value of TMR2 for the B3 note

    #define B3L 0x39 // "

    #define C4H 0x49 // reload value of TMR2 for the C4 note

    #define C4L 0x1A // "

    #define C4SH 0x53 // reload value of TMR2 for the C4 sharp note

    #define C4SL 0x5D // "

    #define D4H 0x5D // reload value of TMR2 for the D4 note

    #define D4L 0x0D // "

    #define E4H 0x6E // reload value of TMR2 for the E4 note

    #define E4L 0xD5 // "

    #define F4H 0x76 // reload value of TMR2 for the F4 note

    #define F4L 0xFB // "

    #define F4SH 0x7E // reload value of TMR2 for the F4 sharp note

    #define F4SL 0xAB // "

    #define G4H 0x85 // reload value of TMR2 for the G4 note

    #define G4L 0xEE // "

    #define A4H 0x93 // reload value of TMR2 for the A4 note

    #define A4L 0x3F // "

    #define B4FH 0x99 // reload value of TMR2 for the B4 flat note

    #define B4FL 0x59 // "

    #define B4H 0x9F // reload value of TMR2 for the B4 note

    #define B4L 0x1C // "

    #define C5H 0xA4 // reload value of TMR2 for the C5 note

    #define C5L 0x8D // "

    #define D5H 0xAE // reload value of TMR2 for the D5 note

    #define D5L 0x87 // "

    #define E5H 0xB7 // reload value of TMR2 for the E5 note

    #define E5L 0x6B // "

    #define F5H 0xBB // reload value of TMR2 for the F5 note

    #define F5L 0x7D // "

    #define ZH 0xFF // stop sound (high frequency and inaudible note)

    #define ZL 0xF0 // #define notes 118

    void sysInit(void);

    void delayby10ms(unsigned char kk);

  • 18

    code unsigned char scoreH[118] =

    {D4H,B3H,G3H,B3H,D4H,G4H,B4H,A4H,G4H,B3H,C4SH,

    D4H,ZH,D4H,ZH,D4H,B4H,A4H,G4H,F4SH,E4H,F4SH,G4H,ZH,G4H,D4H,B3H,G3H,

    D4H,B3H,G3H,B3H,D4H,G4H,B4H,A4H,G4H,B3H,C4SH,D4H,ZH,D4H,ZH,D4H,

    B4H,A4H,G4H,F4SH,E4H,F4SH,G4H,ZH,G4H,D4H,B3H,G3H,B4H,ZH,B4H,

    B4H,C5H,D5H,ZH,D5H,C5H,B4H,A4H,B4H,C5H,ZH,C5H,ZH,C5H,B4H,A4H,G4H,

    F4SH,E4H,F4SH,G4H,B3H,C4SH,D4H,ZH,D4H,G4H,ZH,G4H,ZH,G4H,F4SH,

    E4H,ZH,E4H,ZH,E4H,A4H,C5H,B4H,A4H,G4H,ZH,G4H,F4SH,D4H,ZH,D4H,

    G4H,A4H,B4H,C5H,D5H,G4H,A4H,B4H,C5H,A4H,G4H};

    code unsigned char scoreL[118] = {D4L,B3L,G3L,B3L,D4L,G4L,B4L,A4L,G4L,B3L,C4SL,

    D4L,ZL,D4L,ZL,D4L,B4L,A4L,G4L,F4SL,E4L,F4SL,G4L,ZL,G4L,D4L,B3L,G3L,

    D4L,B3L,G3L,B3L,D4L,G4L,B4L,A4L,G4L,B3L,C4SL,D4L,ZL,D4L,ZL,D4L,

    B4L,A4L,G4L,F4SL,E4L,F4SL,G4L,ZL,G4L,D4L,B3L,G3L,B4L,ZL,B4L,

    B4L,C5L,D5L,ZL,D5L,C5L,B4L,A4L,B4L,C5L,ZL,C5L,ZL,C5L,B4L,A4L,G4L,

    F4SL,E4L,F4SL,G4L,B3L,C4SL,D4L,ZL,D4L,G4L,ZL,G4L,ZL,G4L,F4SL,

    E4L,ZL,E4L,ZL,E4L,A4L,C5L,B4L,A4L,G4L,ZL,G4L,F4SL,D4L,ZL,D4L,

    G4L,A4L,B4L,C5L,D5L,G4L,A4L,B4L,C5L,A4L,G4L};

    code unsigned char dur[118] = {30,10,40,40,40,80,30,10,40,40,40,

    80,3, 20,3, 20,60,20,40,80,20,20,40,3, 40,40,40,40,

    30,10,40,40,40,80,30,10,40,40,40,80,3, 20,3, 20,

    60,20,40,80,20,20,40,3, 40,40,40,40,20,3, 20,

    40,40,40,3, 80,20,20,40,40,40,3, 80,3, 40,60,20,40,

    80,20,20,40,40,40,80,3, 40,40,3, 40,3, 20,20,

    40,3, 40,3, 40,40,20,20,20,20,3, 40,40,20,3, 20,

    60,20,20,20,80,20,20,60,20,40,80};

    void main (void)

    {

    int j;

    sysInit(); // configure SYSCLK and assign peripheral functions to port pins

    TMR2CF = 0x0A; // select SYSCLK as timer 2 clock, enable T2 output

    TMR2CN = 0; // disable Timer 2

    j = 0;

    while (j < notes) {

    TMR2H = scoreH[j]; // play the jth note

    RCAP2H = scoreH[j];

    TMR2L = scoreL[j];

    RCAP2L = scoreL[j];

    TR2 = 1; // enable Timer 2

    delayby10ms(dur[j]);

    TR2 = 0; // disable Timer 2 to change reload value

    j++;

    }

    while(1); // stay here

    }

    void sysInit(void)

    {

    SFRPAGE = 0x0F;

    WDTCN = 0xDE; // disable watchdog timer

    WDTCN = 0xAD;

    CLKSEL = 0; // select internal oscillator as SYSCLK

  • 19

    OSCICN = 0x83; // "

    XBR0 = 0xF7; // assign port pins to all peripheral signals

    XBR1 = 0xFF;

    XBR2 = 0x5D;

    XBR3 = 0x8F;

    P2MDOUT |= 0x80; // enable T2 output (must be done)

    SFRPAGE = 0; // switch to SFR page 0

    SPI0CN = 0x01; // enable 3-wire SPI

    }

    void delayby10ms(unsigned char k)

    {

    unsigned char i, tempage;

    tempage = SFRPAGE;

    SFRPAGE = 0;

    TMOD = 0x11; // configure Timer 0 and 1 to mode 1

    CKCON = 0x00; // Timer 0 use system clock divided by 12 as clock source

    for (i = 0; i < k; i++){

    TR0 = 0; // stop Timer 0

    TH0 = 0xB0; // place 45119 in TH0:TL0 so it overflows in 10 ms

    TL0 = 0x3F;

    TF0 = 0;

    TR0 = 1; // enable Timer 0

    while(!TF0); // wait for 10 ms

    }

    SFRPAGE = tempage; // restore original SFRPAGE

    }