You are on page 1of 32

TIMER / COUNTER

4/26/2019 7:56 AM NGUYEN HUY HOANG 1


TỔNG QUAN
 Chức năng chính:
• Định thời
• Đếm sự kiện
• Tạo xung PWM
 Atmega 128 có 4 bộ timer:
• Timer 1, 3: 16 bit.
• Timer 0, 2: 8 bit.

4/26/2019 7:56 AM NGUYEN HUY HOANG


TỔNG QUAN
Các định nghĩa:

• BOTTOM: Bộ đếm đạt tới giá trị BOTTOM khi nó có giá trị 0000h
• MAX: Bộ đếm đạt tới giá trị MAX khi nó bằng FFh (Timer 8 bit), FFFFh (Timer 16 bit)
• TOP: Giá trị TOP do người lập trình tự định nghĩa bằng việc ghi giá trị vào một thanh
ghi nào đó của Timer/Counter (sẽ đề cập sau). Khi bộ đếm đạt giá trị TOP thì thực hiện
một tác vụ gì đó.

4/26/2019 7:56 AM NGUYEN HUY HOANG


1. TCCR1 – Timer Counter Control Register:

• Các bit WGM (Waveform Generation Mode): Chọn chế độ hoạt


động của bộ Timer
CÁC MODE HOẠT ĐỘNG CỦA TIMER 0 – 8 bit

4/26/2019 7:56 AM NGUYEN HUY HOANG


1. TCCR1 – Timer Counter Control Register:

Các bit CS (Clock Source) dùng để chọn nguồn xung clock cho bộ Timer
4/26/2019 7:56 AM NGUYEN HUY HOANG
2. TCNT1 – Timer Counter Register 1:

Đây là thanh ghi đếm 16 bit của bộ định thời 1 .Giá trị thanh ghi này tăng

hoặc giảm 1 đơn vị sau mỗi chu kì clock.

4/26/2019 7:56 AM NGUYEN HUY HOANG


3. OCR1A / B / C – Output Compare Register

• Thanh ghi lưu giá trị để so sánh với giá trị trong thanh ghi TCNT1
• Thường dùng trong các chế độ cần so sánh (PWM, CTC)
4. ICR1– Input Capture Register

• Thanh ghi lưu giá trị để so sánh với giá trị trong thanh ghi TCNT1
• Thường dùng trong các chế độ cần so sánh (PWM, CTC).
• Dùng để cập nhật giá trị bộ đếm (TCNT) khi có sự kiện ở chân ICP1
4. TIMSK– Timer Counter Interrupt Mask Register

• Bit 5 – TICIE1: Cho phép ngắt khi xảy ra “Input Capture”

• Bit 4 – OCIE1A: Cho phép ngắt khi giá trị OCRA1 = TCNT1

• Bit 3 – OCIE1B: Cho phép ngắt khi OCRB1 = TCNT1

• Bit 2 – TOIE1: Cho phép ngắt tràn


5. ETIMSK– Extended Timer Counter Interrupt Mask Register

• Bit 0 – OCIE1C: Cho phép ngắt khi giá trị OCRC1 = TCNT1
6. TIFR–Timer Counter Interrupt Flag Register

• Bit 5 – ICF1: Timer/Counter1, Input Capture Flag

• Bit 4 – OCF1A: Timer/Counter1, Output Compare A Match Flag. Khi match thì OCF1A = 1

• Bit 3 – OCF1B: Timer/Counter1, Output Compare B Match Flag. Khi match thì OCF1B = 1

• Bit 2 – TOV1: Timer/Counter1, Overflow Flag: Khi tràn thì TOV1 = 1


7. ETIFR– Extended Timer Counter Interrupt Flag Register

• Bit 0 – OCF1C: Timer/Counter1, Output Compare B Match Flag. Khi match thì OCF1C = 1
ĐỊNH THỜI BẰNG TIMER

Có thể dùng Normal Mode hoặc CTC Mode

Normal Mode:

BOTTOM TCNT1 - init TOP

0x0000 xxxx 65535


???? 0xFFFF
ĐỊNH THỜI BẰNG TIMER
Ví dụ: định thời 1 giây, F_CPU = 7372800 Hz

1. Chia tần 1024: 7372800/1024 = 7200 Hz

Resolution = 1/7200 = 139 us

Max time = Resolution * 65536 = 9.1 s

2. Tính TCNT1_init: TCNT1 = 65536 – 1/Resolution = 58336


BOTTOM TCNT1 - init TOP

0x0000 58336 65535


0xFFFF

1s
void TMR_vInit(void)
{
/* Start timer 1 with clock prescaler CLK/1024 */
/* Resolution is 139 us */
/* Maximum time is 9.1 s */

TCCR1A = (0<<COM1A1)|(0<<COM1A0)|(0<<COM1B1)|(0<<COM1B0)
|(0<<COM1C1)|(0<<COM1C0)|(0<<WGM11) |(0<<WGM10);

TCCR1B = (0<<ICNC1) |(0<<ICES1) |(0<<WGM13) |(0<<WGM12)


|(1<<CS12) |(0<<CS11) |(1<<CS10);
}
void TMR_vInit(void)
{
/* Start timer 1 with clock prescaler CLK/1024 */
/* Resolution is 139 us */
/* Maximum time is 9.1 s */
TCCR1A = (0<<COM1A1)|(0<<COM1A0)|(0<<COM1B1)|(0<<COM1B0)
|(0<<COM1C1)|(0<<COM1C0)|(0<<WGM11) |(0<<WGM10);

TCCR1B = (0<<ICNC1) |(0<<ICES1) |(0<<WGM13) |(0<<WGM12)


|(1<<CS12) |(0<<CS11) |(1<<CS10);

TCNT1 = (uint16_t) (0x10000 - ((F_CPU/1024)* x)/1000);


TIMSK |= (1<<TOIE1);

sei();
}

4/26/2019 7:56 AM NGUYEN HUY HOANG


void TMR_vStart(uint16_t u16DelayMs)
{
// Calculate and set delay
TCNT1 = (uint16_t) (0x10000 - ((F_CPU/1024)*u16DelayMs)/1000);

// Clear timer overflow flag by writing a logical 1, other flags are unchanged
TIFR = (1<<TOV1);
// NOTE: This line is more efficient than using "TIFR |= (1<<TOV1);“
// Nếu không dùng ngắt thì phải clear bit TOV1 như thế này.
}
bool TMR_bHasExpired(void) void TMR_vDelay(uint16_t u16DelayMs)
{ // See if timer overflow flag is set {
if(TIFR&(1<<TOV1)) TMR_vStart(u16DelayMs);
{
while(!TMR_bHasExpired())
return TRUE;
{
}
;
else
}
{
}
return FALSE;
}
}
ĐỊNH THỜI BẰNG TIMER
CTC Mode:

BOTTOM TOP – OCR1A TOP

0x0000 xxxx 65535


???? 0xFFFF
ĐỊNH THỜI BẰNG TIMER
Ví dụ: định thời 1 giây, F_CPU = 7372800 Hz
Dùng cờ
1. Chia tần 1024: 7372800/1024 = 7200 Hz
OCF1A thay
Resolution = 1/7200 = 139 us
cho TOV1
Max time = Resolution * 65536 = 9.1 s

2. Tính OCR1A: OCR1A = 1/Resolution - 1 = 7200 - 1


BOTTOM TOP – OCR1A TOP

0x0000 7200 - 1 65535


0xFFFF
1s
ĐẾM SỰ KIỆN BẰNG TIMER COUNTER

Có thể dùng Normal Mode hoặc CTC Mode:

Lưu ý chọn nguồn clock:


PWM

4/26/2019 7:56 AM NGUYEN HUY HOANG


FAST PWM

https://garretlab.web.fc2.com/en/arduino/inside/arduino/wiring_analog.c/analogWrite.html

4/26/2019 7:56 AM NGUYEN HUY HOANG


FAST PWM

4/26/2019 7:56 AM NGUYEN HUY HOANG


void PWM_vInit(void)
{ /*
Start Timer 1 with clock prescaler CLK/8 and Fast PWM mode 14.
Output on PB6 (OC1B). Resolution is 1.09 us.
f = clock frequency /
Frequency is 900 Hz.
(Prescaler* TOP)
*/
TCCR1A = (0<<COM1A1)|(0<<COM1A0)|(1<<COM1B1)|(0<<COM1B0)
F = 7372800/(8*1023)
|(0<<COM1C1)|(0<<COM1C0)|(1<<WGM11) |(0<<WGM10);
= 900 Hz
TCCR1B = (0<<ICNC1) |(0<<ICES1) |(1<<WGM13) |(1<<WGM12)
|(0<<CS12) |(1<<CS11) |(0<<CS10);
// Reset counter
TCNT1 = 0;
// Set TOP value by ICR1
ICR1 = PWM_MAX_DUTY_CYCLE;
// Set duty cycle to 0%
OCR1B = 0;
}

4/26/2019 7:56 AM NGUYEN HUY HOANG


void PWM_vSetDutyCycle(uint16_t u16DutyCycle)
{
// Clip parameter to maximum value
if (u16DutyCycle > PWM_MAX_DUTY_CYCLE)
{
u16DutyCycle = PWM_MAX_DUTY_CYCLE;
}

OCR1B = u16DutyCycle;
}

PWM_vSetDutyCycle((PWM_MAX_DUTY_CYCLE*(50.0/100)));

4/26/2019 7:56 AM NGUYEN HUY HOANG


PHASE CORRECT PWM

https://garretlab.web.fc2.com/en/arduino/inside/arduino/wiring_analog.c/analogWrite.html

4/26/2019 7:56 AM NGUYEN HUY HOANG


PHASE CORRECT PWM

4/26/2019 7:56 AM NGUYEN HUY HOANG


void PWM_vInit(void)
{
/*
Start Timer 1 with clock prescaler CLK/8 and phase correct
10-bit PWM mode. Output on PB6 (OC1B). Resolution is 1.09 us.
Frequency is 450 Hz.
*/
TCCR1A = (0<<COM1A1)|(0<<COM1A0)|(1<<COM1B1)|(0<<COM1B0)
|(0<<COM1C1)|(0<<COM1C0)|(1<<WGM11) |(1<<WGM10);

TCCR1B = (0<<ICNC1) |(0<<ICES1) |(0<<WGM13) |(0<<WGM12)


|(0<<CS12) |(1<<CS11) |(0<<CS10);

// Reset counter f = clock frequency /


TCNT1 = 0; (Prescaler* TOP*2)

// Set duty cycle to 0% F = 7372800/(8*1023*2)


OCR1B = 0; = 450 Hz
}

4/26/2019 7:56 AM NGUYEN HUY HOANG

You might also like