0% found this document useful (0 votes)
10 views

C9 Timers2

Uploaded by

bayav.nimetolla
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
10 views

C9 Timers2

Uploaded by

bayav.nimetolla
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 20

Embedded Systems

Chapter 9 - Timers in AVR Microcontrollers

Dr. Adnan Ismail Al-Sulaifanie

Department of Electrical and Computer Engineering


University of Duhok, Iraq

Outline

ä Necessity of timers in a microcontroller-based system.

ä Principle and applications of timers.

ä AVR timers and related registers.

ä AVR timers operation modes.

ä Interval timer configuration and programming.

ä Event counter configuration and programming.

References

1. Mazidi, The AVR Microcontroller and Embedded Systems Using Assembly and C,
chapter 10

1
1 Timers and Counters

ä Timers are essential components in microcontrollers that allow the manipulation of time
intervals and the generation of precise timing events.

ä In AVR microcontrollers, timers play a critical role in various applications, including gener-
ating delays, PWM signals, and interfacing with external devices.

ä Many timing applications require the generation of accurate time delay between certain
events or counting of external events outside microprocessor, such as as counting number
of pulses.

ä There are two approaches to generate a time delay: software (loop), and hardware (timers)

ä The subroutine that generates a time delay do nothing for a specified time period. It keeps
the microcontroller busy during delay time. Also, it is difficult to generate precise time
delay.

ä Using programmable hardware timer circuits have two advantages:

1. Provide more accurate time delay.


2. Using timer + interrupt relieves the microcontroller from the burden of generating time
delays

ä The basic applications of timers are:

1. Generate precise timing delay.


2. Generating controlled output signal. The frequency and duty cycle of the output signal
can be adjusted by the programmer.
3. Measure external signal parameters such as frequency, duty cycle, and pulse width

2 AVR Timers

ä AVR microcontrollers have 2 - 6 timers depending on family member.

ä ATmega328 have 3 timers while ATmega2560 have 6.

ä The most common timers found in AVR microcontrollers are:

1. Timer/Counter 0 (TC0) and Timer/Counter 2 (TC2) are 8 bit.


2. Other timers are 16 bit (TC1, TC3, TC4, TC5)

2.1 AVR Timer Architecture

ä Architecture of 8 bit AVR timer

2
ä Architecture of 16 bit AVR timer

ä Timer components: clock source, counter register, compare register, overflow flag, match
compare flag, output compare pin, and interrupt flag.

3
2.2 Timer 0 Registers

Timer 0 Registers:

1. TCNT0 - timer/counter register

2. TCCR0A, TCCR0B - control register.

3. OCR0A, OCR0B - output compare register.

4. TIFR0 - interrupt flag register.

5. TIMSK0 - interrupt mask register.

Reg. D7 D6 D5 D4 D3 D2 D1 D0
TCCR0A COM0A1 COM0A0 COM0B1 COM0B0 - - WGM01 WGM00
TCCR0B FOC0A FOC0B – – WGM02 CS02 CS01 CS00
TIFR0 – – – – – OCF0B OCF0A TOV0
TIMSK0 – – – – – OCIE0B OCIE0A TOIE0

ä TCNT0 -

ã TCNT0 is a counter register that incremented on each clock.


ã The Timer/Counter overflow flag (TIFR0.TOV0) is set according to the mode of operation
selected by the WGM02:0 bits.
ã TOV0 can be used for generating a CPU interrupt.
ã The TCNT0 value can be accessed by the CPU. Its value can be initialized by programmer
to set the time delay.

ä Output Compare Register (OCR0) -

ã The 8-bit comparator continuously compares TCNT0 with OCR0.


ã Whenever TCNT0 = OCR0, OCF0 will set.
ã If the corresponding interrupt is enabled, the output compare flag (OCF0) generates
an output compare interrupt.
ã OCF0 flag is automatically cleared when the interrupt is executed. Also, the flag can
be cleared by software by writing a logical one to its I/O bit location.

ä Time Interrupt Flag Register (TIFR0) - TIFR contains the flags of different timers.

Reg. D7 D6 D5 D4 D3 D2 D1 D0
TIFR0 – – – – – OCF0B OCF0A TOV0

Bit Value Description

4
TOV0 Timer0 Overflow Flag bit
1 if TCNT0 changes from 0xFF to 0x00
OCF0A Timer0 Output Compare flag bit
1 if TCNT0 = OCR0A
OCF0B Timer0 Output Compare B match flag
1 if TCNT0 = OCR0B

ä Interrupt enable (TIMSK0) -

ã Use timer interrupt mask register (TIMSK0).


ã TIMSK0 register is used to enable/disable interrupt requests from timer 0.
ã TIMSK0 is located inside extended I/O memory, therefore, LDS/STS instructions are
used to access it.

Reg. D7 D6 D5 D4 D3 D2 D1 D0
TIMSK0 – – – – – OCIE0B OCIE0A TOIE0

ä Clock source (CS02-CS00) -

ã The clock source can be internal or external (system clock, external clock, external
signal)
ã Prescalar divides the cpu-clock before it reaches the timer.
ã AVR timers have different clock sources and prescaling as shown below:
ã The clock source and prescaling are selected by setting CS2-CS0 in TCCR0B register.
CS2 - CS0 are used to set prescalar.

CS02 - CS00 Clock source (T0,T1) Clock source (T2)


000 stopped stopped
001 CLK/1 (No Prescaling) CLK/1 (No Prescaling)
010 CLK/8 CLK/8
011 CLK/64 CLK/32
100 CLK/256 CLK/64
101 CLK/1024 CLK/128
110 Ext. clock (falling edge) CLK/256
111 Ext. clock (rising edge) CLK/1024

Example 1 - The following instructions set the prescaler values in the TCCR0B to a clock
division factor of 1024.
LDI R16, (1<<CS02)|(1<<CS00) ; This equivalent to LDI R16, 0x05
OUT TCCR0B, R16 ; Timer clock = system clock/1024
If we do not need to change the content of other bits in TCCR0B, use the following code:
IN R16, TCCR0B ; R16 = TCCR0B
SBR R16, 0x05 ; Set b2 and b0 in R16
OUT TCCR0B, R16 ; Timer clock = system clock/1024

5
ä Operation modes (WGM02 - WGM00) -

ã AVR timers support four operation modes.


ã The mode is selected through WGM01-WGM00 bits in TCCR0A register .

WGM02-0 Mode TOP


000 normal 0xFF
001 Phase correct PWM 0xFF
010 CTC OCRnA
011 Fast PWM 0xFF
100 Reserved
101 Phase correct PWM OCRnX
110 Reserved
111 Fast PWM OCRnX

6
ä Control OC0X (COM0A1-COM0A0 , COM0B1-COM0B0) -
These bit are used to change the OC0A/OC0B pin in non-PWM mode.

none-PWM fast-PWM phase correct -PWM


COM0A1:0 WGM002 OC0A OC0A OC0A
00 X disconnected disconnected disconnected
01 0 toggle disconnected disconnected
1 toggle toggle toggle
10 X clear clear on match clear on up match
set on bottom set on down match
11 X set set on match set on up match
clear on bottom clear on down match

7
Standard I/O registers (00 - 1F)- IN, OUT, SBI, CBI, SBIS, SBIC

PINB, DDRB, PORTB, PINC, DDRC, PORTC, PIND, DDRD, PORTD, TIFR0, TIFR1, TIFR2

Standard I/O registers (20 - 5F)- IN, OUT

TCCR0A, TCCR0B, TCNT0, OCR0A, OCR0B, SPL, SPH, SREG

Extended I/O registers (60 - FF)- LD/LDS/LDD , ST/STS/STD

TIMSK0, TIMSK1, TIMSK2, TCCR1A, TCCR1B, TCCR1C, TCNT1L, TCNT1H, ICR1L, ICR1H, OCR1AL,
OCR1AH, OCR1BL, OCR1BH, TCCR2A, TCCR2B, TCNT2, OCR2A, OCR2B, ASSR,

8
ä I/O Registers within the address range 0x00 - 0x1F are directly bit-accessible using the SBI
and CBI instructions. In these registers, the value of single bits can be checked by using
the SBIS and SBIC instructions.

ä Some of the Status Flags are cleared by writing a logical one to them.

ä The CBI and SBI instructions work with registers 0x00 to 0x1F only.

ä When using the I/O specific commands IN and OUT, the I/O addresses 0x00 - 0x3F must
be used. When addressing I/O Registers as data space using LD and ST instructions, 0x20
must be added to these addresses.

ä For the Extended I/O space from 0x60 - 0xFF in SRAM, only the ST/STS/STD and LD/LDS/LDD
instructions can be used.

3 Operation Modes

3.1 Normal Mode

ä WGM02:0 = 0

ä The counting direction is always up (incrementing), and no counter clear is performed.


Count range = 0x00 – 0xFF

ä The TOV0 = 1 exactly when the TCNT is changed from 0xFF to 0x00.

ä An overflow interrupt is generated if the interrupt is enabled (TIMSK0.TOIE0 = 1)

ä This mode is used to generate precise delay or generates a periodic signal.

Example 2 - list the available methods to monitor timer events and respond to them.

1. Polling - the main program can frequently check the status of these flags (TOV0, OCF0A,
OCF0B) to see if one of these events occurred. This requires some program overhead,
which will cost additional processing time. The advantage of this solution is the very short
response time when tight loops are used.

LOOP: SBIS TIFR0, TOV0 ; Skip next instruction if TOV0 = 1


RJMP LOOP
....

9
2. Interrupt - the AVR can be configured to execute interrupts if an interrupt flag (TOV0,
OCF0A, OCF0B) is set. Normal program execution will be interrupted (almost) immediately
and the processor will execute the code of the ISR. The advantage compared to polling of
interrupt flags is zero overhead in the main loop. This saves processing time.

LDI R16, 1<< TOIE0


STS TIMSK0, R16 ; Enable timer0 overflow interrupt
SEI ; Enable global interrupts
....
ISRT0: ...
...
RETI

3. Changing the level of output signal automatically by the hardware - the output
pin (OC0A or OC0B) can be configured to be set, cleared, or toggled automatically on a
compare match based on the content of COM0A1:0. In contrast to the two other solutions
this happens in parallel to normal code execution and requires no processing time.

LDI R16, 32
OUT OCR0A, R16 ; OCR0A = 32
LDI R16, (1<<COM0A0)|(1<<WGM01)|(1<<WGM00)
OUT TCCR0A, R16 ; fast PWM, toggle OC0A when TCNT0 = OCR0A
LDI R16, 1<<CS00
STS TCCR0B, R16 ; prescaler = 1, start timer 0
....

To enable OCOA pin toggling, the PD6 = OC0A has to be set to make it an output pin.

Example 3 - Find the value for TCCR0A and TCCR0B if we want to program Timer0 in Normal
mode, no prescaler.

TCCR0A COM0A1 COM0A0 COM0B1 COM0B0 – – WGM01 WGM00


0 0 0 0 0 0 0 0
TCCR0B FOC0A FOC0B – – WGM02 CS02 CS01 CS00
0 0 0 0 0 0 0 1

CLR R20
OUT TCCR0A, R20
LDI R20, 0x01
OUT TCCR0B, R20

We use OUT instruction because the TCCR0A and TCCR0B reside at standard I/O mem-
ory addresses.

Example 4 - Assume the system clock is 1 MHz, and it is divided by a prescaler = 1024, Write
an ALP to blink the LED. What is the blinking frequency.

Reg. D7 D6 D5 D4 D3 D2 D1 D0

10
TIFR0 – – – – – OCF0B OCF0A TOV0
0 0 0 0 0 0 0 ?
TIMSK0 – – – – – OCIE0B OCIE0A TOIE0
0 0 0 0 0 0 0 1
TCCR0A COM0A1 COM0A0 COM0B1 COM0B0 - - WGM01 WGM00
0 0 0 0 0 0 0 0
TCCR0B FOC0A FOC0B – – WGM02 CS02 CS01 CS00
0 0 0 1 0 1

.ORG 0x0000 starting address of main program


RJMP MAIN
.ORG 0x0020 starting address of Timer 0 overflow interrupt
RJMP ISRTOV0

MAIN: LDI R16, HIGH(RAMEND)


OUT SPH, R16
LDI R16, LOW(RAMEND)
OUT SPL, R16 ; set up stack
SBI DDRB, 5
LDI R16, (1 << TOV0)
OUT TIFR0, R16 ; Clear all flags in TIFR0
LDI R16, 1<<TOIE0 ; or use LDI R16, 0x01
STS TIMSK0, R16 ; Enable Timer/Counter0 Overflow Interrupt
SEI
LDI R16, (1<<CS02)|(1<<CS00) ; R16 = 0x05
OUT TCCR0B, R16 ; start timer 0 in mode 0 and with prescaler = 1024
HERE: RJMP HERE

ISRTOV0: SBI PINB, 5 ; toggle PB5


RETI

Example 5 - Use Timer 0 in normal mode to create a simple blinking LED program. Calculate
the delay.

Reg. D7 D6 D5 D4 D3 D2 D1 D0
TIFR0 – – – – – OCF0B OCF0A TOV0
0 0 0 0 0 0 0 ?
TIMSK0 – – – – – OCIE0B OCIE0A TOIE0
0 0 0 0 0 0 0 1
TCCR0A COM0A1 COM0A0 COM0B1 COM0B0 - - WGM01 WGM00
0 0 0 0 0 0 0 0
TCCR0B FOC0A FOC0B – – WGM02 CS02 CS01 CS00
0 0 0 1 0 1

11
.ORG 0x0000 ; location for reset
RJMP MAIN
.ORG 0x0020 ; ISR location for Timer0 overflow
JMP ISRT0
MAIN: LDI R20, HIGH(RAMEND)
OUT SPH, R20
LDI R20, LOW(RAMEND)
OUT SPL, R20 ; set up stack
SBI DDRB, 5 ; PB5 = output
LDI R16, (1 << TOV0)
OUT TIFR0, R16 ; Clear all flags in TIFR0
LDI R20, (1 << TOIE0) ; or use LDI R20, 0x01
STS TIMSK0, R20 ; enable Timer0 overflow interrupt
SEI ; set I (enable interrupts globally)
LDI R20, 0x05
OUT TCCR0B, R20 ; start Timer0, normal mode, prescaler = 1024
HERE: JMP HERE ; keeping CPU busy waiting for interrupt

ISRT0: SBI PINB, 5 ; toggle PB5


RETI ; return from interrupt

3.2 Clear Timer on Compare Match (CTC)

ä WGM02:0 = 2

ä The OCR0A defines the TOP value for the counter (TOP = OCR0A)
Count range = 0x00 – OCR0A

Whenever the TCNT0 = OCR0A ⇒ TCNT0 = 0x00


OCF0A = 1

ä An interrupt can be generated when TCNT0 = OCR0A using the OCF0A flag.
LDI R16, 1<< OCIE0A ; or use LDI R16, 0x02
STS TIMSK0, R16 ; enable OCF0A interrupt, TIMSK0.OCIE0A = 1

ä The CTC mode is used to generate a precise time delay or a digital waveform. It allows
greater control of the output frequency.

ä The waveform frequency is defined by the following equation:


fi
fo = P =∈ {1, 8, 64, 256, or1024}
2 ∗ P ∗ (OCR0A + 1)

12
Example 6 - write an ALP using Timer0 in CTC mode to toggle PB5 every 40 µs.

Assume system-clock = 1 MHz and prescaler = 1

fs 106
ft = = = 1 µs
P 1
1 1
Tt = = = 1 µs
ft 106

delay = counts * Tt = 40 µs
delay 40 µs
count = = = 40
Tt 1 µs

OCR0A = count - 1 = 39

1. Use polling method

Reg. D7 D6 D5 D4 D3 D2 D1 D0
TIMSK0 – – – – – OCIE0B OCIE0A TOIE0
0 0 0 0 0 0 0 0
TIFR0 – – – – – OCF0B OCF0A TOV0
0 0 0 0 0 0 ? 0
TCCR0A COM0A1 COM0A0 COM0B1 COM0B0 - - WGM01 WGM00
0 0 0 0 0 0 1 0
TCCR0B FOC0A FOC0B – – WGM02 CS02 CS01 CS00
0 0 0 0 0 1

.ORG 0x0000
SBI DDRB, 5 ; PB5 is output
LDI R20, 0x27
OUT OCR0A, R20 ; OCR0A = 39
LDI R20, 0x02
OUT TCCR0A, R20 ; CTC mode
LDI R20, 0x01
OUT TCCR0B, R20 ; start Timer0, CTC mode, prescaler = 001 = CLK/1
LOOP: SBIS TIFR0, OCF0A ; skip next instruction if OCF0A = 1
RJMP HERE
SBI TIFR0, OCF0A ; Clear OCF0A

13
SBI PINB, 5 ; toggle PB5
RJMP LOOP ; go to HERE to check flag

How you can optimize the previous program?

2. Use interrupt method

Reg. D7 D6 D5 D4 D3 D2 D1 D0
TIMSK0 – – – – – OCIE0B OCIE0A TOIE0
0 0 0 0 0 0 1 0
TIFR0 – – – – – OCF0B OCF0A TOV0
0 0 0 0 0 0 ? 0
TCCR0A COM0A1 COM0A0 COM0B1 COM0B0 - - WGM01 WGM00
0 0 0 0 0 0 1 0
TCCR0B FOC0A FOC0B – – WGM02 CS02 CS01 CS00
0 0 0 0 0 1

.ORG 0x0000 ; location for reset


RJMP MAIN
.ORG 0x0020 ; ISR location for Timer0 overflow interrupt
JMP ISRT0
MAIN: LDI R20, HIGH(RAMEND)
OUT SPH, R20
LDI R20, LOW(RAMEND)
OUT SPL, R20 ; set up stack
SBI DDRB, 5 ; PB5 is output
LDI R20, 0x27
OUT OCR0A, R20 ; OCR0A = 39
LDI R20, 0x02
OUT TCCR0A, R20 ; CTC mode
LDI R16, (1 << OCF0A)
OUT TIFR0, R16 ; Clear all flags in TIFR0
LDI R16, (1 << OCIE0A) ; or LDI R16, 0x02

STS TIMSK0, R16 ; enable interrupt, TIMSK0.OCIE0A = 1


SEI ; set I (enable interrupts globally)
LDI R20, 0x01
OUT TCCR0B, R20 ; start Timer0, CTC mode, prescaler = 001 = CLK/1
HERE: JMP HERE ; keeping CPU busy waiting for interrupt

ISRT0: SBI PINB, 5 ; toggle PB5


RETI ; return from interrupt

Example 7 - Write an ALP using Timer0 in CTC mode to toggle PB5 every 100 µs (XTAL = 16
MHz)

14
P=8
fs 16 ∗ 106
ft = = = 2 MHz
P 8
1 1
Tt = = = 0.5 µs
ft 2 ∗ 106

delay = counts * Tt = 100 µs


delay 100 µs
count = = = 200
Tt 0.5 µs

OCR0A = count - 1 = 199 = 0xC7

1. Use polling method

Reg. D7 D6 D5 D4 D3 D2 D1 D0
TIMSK0 – – – – – OCIE0B OCIE0A TOIE0
0 0 0 0 0 0 0 0
TIFR0 – – – – – OCF0B OCF0A TOV0
0 0 0 0 0 0 0 ?
TCCR0A COM0A1 COM0A0 COM0B1 COM0B0 - - WGM01 WGM00
0 0 0 0 0 0 1 0
TCCR0B FOC0A FOC0B – – WGM02 CS02 CS01 CS00
0 0 0 0 0 0 1 0

.ORG 0x0000
SBI DDRB, 5 ; PB5 is output
LDI R20, 0xC7
OUT OCR0A, R20 ; OCR0A = 39
LDI R20, 1 << WGM01 ; or LDI R20, 0x02
OUT TCCR0A, R20 ; WGM = 010, CTC mode
LDI R20, 1 << CS01
OUT TCCR0B, R2O ; TCCR0B = 0x02, start Timer0, prescaler = 010 = CLK/8
HERE: SBIS TIFR0, OCF0A ; skip next instruction if OCF0A = 1
RJMP HERE
SBI TIFR0, OCF0A ; Clear OCF0A
SBI PINB, 5 ; toggle PB5
RJMP HERE

2. Use interrupt method

Reg. D7 D6 D5 D4 D3 D2 D1 D0
TIMSK0 – – – – – OCIE0B OCIE0A TOIE0
0 0 0 0 0 0 1 0
TIFR0 – – – – – OCF0B OCF0A TOV0
0 0 0 0 0 0 ? 0
TCCR0A COM0A1 COM0A0 COM0B1 COM0B0 - - WGM01 WGM00
0 0 0 0 0 0 1 0

15
TCCR0B FOC0A FOC0B – – WGM02 CS02 CS01 CS00
0 0 0 0 0 0 1 0

.ORG 0x0000 ; location for reset


RJMP MAIN
.ORG 0x001C ; ISR location for Timer0 compare match
JMP ISRCTC ; jump to ISR
MAIN: LDI R20, HIGH(RAMEND)
OUT SPH, R20
LDI R20, LOW(RAMEND)
OUT SPL, R20 ; set up stack
SBI DDRB, 5 ; PB5 is output
LDI R16, (1 << OCF0A)
OUT TIFR0, R16 ; Clear all flags in TIFR0
LDI R20, (1 << OCIE0A) ; or LDI R20, 0x02
STS TIMSK0, R20 ; enable compare match interrupt, TIMSK0.OCIE0A = 1
SEI ; SREG.I = 1 enable interrupts globally)
LDI R20, 199
OUT OCR0A, R20 ; OCR0A = 199
LDI R20, 1 << WGM01
OUT TCCR0A, R20 ; WGM0x = 010, CTC mode
LDI R20, 1 << CS01
OUT TCCR0B, R2O ; start Timer0, prescaler = 010 = CLK/8
HERE: RJMP HERE ; keeping CPU busy waiting for interrupt

ISRCTC: SBI PINB, 5 ; toggle PB5


RETI ; return from interrupt

Example 8 - Write a subroutine to generate 16 ms delay. Use Timer0, CTC mode. Assuming
XTAL = 16 MHz.
fs 16 ∗ 106
ft = = = 15625
P 1024
counts counts
Time delay = = 16 ms = counts = 250
ft 15625

OCR0A = counts - 1 = 249 = 0xF9

Since a subroutine delay is required, a polling method should be used.

Reg. D7 D6 D5 D4 D3 D2 D1 D0
TIMSK0 – – – – – OCIE0B OCIE0A TOIE0
0 0 0 0 0 0 0 0
TIFR0 – – – – – OCF0B OCF0A TOV0
0 0 0 0 0 0 0 0

16
TCCR0A COM0A1 COM0A0 COM0B1 COM0B0 - - WGM01 WGM00
0 0 0 0 0 0 1 0
TCCR0B FOC0A FOC0B – – WGM02 CS02 CS01 CS00
0 0 0 0 0 1 0 1

D16ms: LDI R20, 0xF9


OUT OCR0A, R20 ; OCR0A = 249
LDI R20, 1 << WGM01 ; or use LDI R20, 0X02
OUT TCCR0A, R20 ; Timer0, CTC mode
LOOP: LDI R20, 0x05
OUT TCCR0B, R20 ; start Timer0 in CTC, prescaler = 101 = CLK/1024
CHECK: SBIS TIFR0, OCF0A ; skip next instruction if OCF0A = 1
RJMP CHECK
SBI TIFR0, OCF0A ; clear OCF0A flag
RET

Homework - demonstrate if it is possible to modify the previous program to introduce a 1s


delay and provide an explanation.

Example 9 - determine the frequency and duty cycle of output signal generated by the fol-
lowing ALP. Assume the system clock = 16 MHz.

LDI R20, HIGH(RAMEND)


OUT SPH, R20
LDI R20, LOW(RAMEND)
OUT SPL, R20 ; set up stack

SBI DDRB, 5 ; PB5 = output


LDI R20, 0x5F
OUT OCR0A, R20 ; OCR0A = 0x5F = 95
BEGIN: LDI R20, 0x02
OUT TCCR0A, R20 ; Timer0, CTC mode
LDI R20, 0x05
OUT TCCR0B, R20 ; start timer0, prescaler = 1024
LOOP: SBIS TIFR0, OCF0A ; if OCF0A is set skip next instruction
RJMP AGAIN
SBI TIFR0, OCF0A ; clear OCF0A flag
SBI PINB, 5 ; toggle PB5
RJMP LOOP

fs 16 ∗ 106
ft = = = 15625 Hz
P 1024
OCR0A + 1 96
Td = = = 6.144 ms
ft 15625
1
fo = = 81.38 Hz
2 ∗ Td

17
Or
ft 15625
fo = = = 81.38 Hz
2 ∗ (1 + OCR0A) 192

Duty cycle = 50%

Homework - what should be modified in previous program to generate 50 Hz signal.

3.3 Fast PWM Mode

ä WGM02:0 = 3, 7

ä The difference between two modes is in the value of TOP.

WGM BOTTOM TOP


3 0x00 0xFF
7 0x00 OCR0A

ä The TCNT0 register counts from 0x00 to 0xFF and back down to 0x00 continually (single-
slop operation).

ä The output pin OC0A is used to generate PWM waveform.

ä Whenever the TCNT0 = OCR0A register, the OC0A is changed according to the values of
COM0A1-COM0A0 bits.

fast-PWM
COM0A1:0 WGM002 OC0A
00 X disconnected
01 0 disconnected
1 toggle
10 X clear on match
set on bottom
11 X set on match
clear on bottom

ä In non-inverting mode, OC0A is cleared when TCNT0 = OCR0A, and set at when TCNT0 =
BOTTOM. In inverting mode, OC0A is set on compare match and cleared at BOTTOM.

non-inverting inverting
OC0A OC0A
TCNT = OCR0A 0 1
TCNT0 = 0x00 1 0

ä The OC0A value will only be visible on the port pin if the pin is defined as output.
SBI DDRD, 6 ; OC0A is multiplexed with PD6 in UNO board

18
ä The frequency of the output signal is calculated by:
fs
fo = P ∈ {1, 8, 64, 256, or 1024}
P ∗ 256
ä The extreme values for the OCR0A register represents special cases:

OCR0A Description
0x00 output will be a narrow spike for each MAX+1 timer clock cycle
0xFF constantly high or low output (set by the COM0A1:0)

ä The toggle option can be used to generate an output signal with fixed frequency and variable
duty cycle. This option is not available for the OC0B pin.
A frequency (with 50% duty cycle) waveform output in fast PWM mode can be achieved by
setting OC0x to toggle mode (COM001:0 = 01).

ä TOV0 = 1 when TCNT0 = TOP. If the interrupt is enabled, the ISR can be used to update
OCR0A.

ä This mode provides higher frequency PWM waveform than phase correct PWM. It is called
the Fast PWM because its maximum frequency is twice that of the Phase Correct PWM mode.

Example 10 - Assuming XTAL = 16 MHz, calculate the frequency of the wave generated by
the following program:

SBI DDRD, 6 ; PD6 = OC0A as output


LDI R20, 200
OUT OCR0A, R22 ; OCR0 = 200
LDI R22, 0x83
OUT TCCR0A, R22 ; COM0A1:0 = non-inverting, fast-PWM
LDI R22, 0x05

19
OUT TCCR0B, R22 ; start Timer 0, prescaler = 101 = CLK/1024
HERE: RJMP HERE

Reg. D7 D6 D5 D4 D3 D2 D1 D0
TIMSK0 – – – – – OCIE0B OCIE0A TOIE0
0 0 0 0 0 0 0 0
TIFR0 – – – – – OCF0B OCF0A TOV0
0 0 0 0 0 0 0 0
TCCR0A COM0A1 COM0A0 COM0B1 COM0B0 - - WGM01 WGM00
1 0 0 0 0 0 1 1
TCCR0B FOC0A FOC0B – – WGM02 CS02 CS01 CS00
0 0 0 0 0 1 0 1

fs 16000000
fo = = = 61 Hz
P ∗ 256 1024 ∗ 256
Th = 201

Tl = 55
Th 201
duty cycle = = = 0.785
T 256
OCR0A + 1 201
or simply it is = = 0.785
T OP 256
If the OC0A is connected to a LED, nothing is observed due to high frequency output.

Homework - In the previous example, calculate the output frequency in each of the following
cases:

# XTAL (MHz) OCR0A P


1 16 50 1024
2 4 95 1024
3 8 150 8
4 F N P

20

You might also like