î¨nÅ â¹nµ¥´ µâš¸Ãâ¹Â³Ã oÅ´ (Timer Clock Source)
î¨nÅ â¹nµ¥´ µâš¸Ãâ¹Â³Ã oÅ´ (Timer Clock Source)
î¨nÅ â¹nµ¥´ µâš¸Ãâ¹Â³Ã oÅ´ (Timer Clock Source)
You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
Overview<br />
AVR <strong>Timer</strong>/Counter<br />
รศ.ณรงค บวบทอง<br />
Introduction<br />
Basic Component<br />
Operation<br />
ATmega168 <strong>Timer</strong><br />
Overview<br />
Related Registers<br />
Operation<br />
Programming Language<br />
C Language<br />
C Language with Arduino<br />
1<br />
2<br />
หลักการเบื้องตน<br />
<strong>Timer</strong> การวัดคาบเวลา หรือการจับเวลา<br />
Counter การนับจํานวนสัญญาณ ถาสัญญาณนั้นมีคาบเวลาคงที่ การนับก็<br />
จะเปนการนับจํานวนเวลา นั่นคือ <strong>Timer</strong><br />
สวนประกอบเบื้องของ <strong>Timer</strong>/Counter ในระบบ Microcontroller:<br />
แหลงจายสัญญาณที่จะใชนับ<br />
วงจรนับ<br />
รีจิสเตอรควบคุม<br />
Optional prescaler ของสัญญาณที่จะใชนับ<br />
ทั้ง <strong>Timer</strong> และ Counter บางครั้งก็เรียกรวมๆกันวา <strong>Timer</strong><br />
3<br />
แหลงจายสัญญาณที่จะใชนับ (<strong>Timer</strong> <strong>Clock</strong> <strong>Source</strong>)<br />
แหลงจายสัญญาณมาจาก :<br />
ภายใน Internal<br />
ภายนอก External<br />
ปกติแลว Microcontroller จะใชสัญญาณนาฬิกาเพื่อการทํางานของระบบ สัญญาณ<br />
นาฬิกานี้ อาจจะมาจากภายนอกชิพ เชน ใช XTAL หรือเปนวงจรสรางสัญญาณ<br />
ภายในชิพเองก็ได สัญญาณนาฬิกาของระบบนี้ ยังใชเปนสัญญาณนาฬิกาของวงจร<br />
ตางๆดวย เชน<br />
CPU clock (clkcpu)<br />
I/O clock (clkI/O)<br />
ADC clock (clkADC)<br />
<strong>Timer</strong>/Counter clock<br />
4
วงจรนับ (<strong>Timer</strong>/Counter Registers)<br />
วงจรนับ ใชสําหรับการนับสัญญาณ และการจับเวลา<br />
ขนาดของวงจรนับ<br />
8 บิต<br />
16 บิต บางครั้งใชวงจรนับขนาด 8 บิต 2 ตัวมาทําเปนวงจรนับขนาด 16 บิต<br />
รีจิสเตอรควบคุม (<strong>Timer</strong> Control Registers)<br />
ทําหนาที่ควบคุมการทํางาน เชน<br />
รูปแบบการทํางาน (Operating mode) เชน Normal, PWM,<br />
compare/capture<br />
สรางสัญญาณอินเตอรรัพท<br />
เลือกแหลงจายสัญญาณ<br />
เลือกรูปแบบการทริก (Trigger)<br />
รีจิสเตอรควบคุมนี้อาจมีหลายตัว<br />
5<br />
6<br />
<strong>Timer</strong> Prescaler<br />
Controller บางตัวมีความยืดหยุนสูง สามารถเลือกใชสัญญาณนาฬิกาที่<br />
ความถี่ตางๆกันได ซึ่งความถี่เหลานี้ไดมาจากวงจร prescaler.<br />
วงจร Prescaler อาจเปนวงจร คูณหรือวงจรหารความถี่ก็ได การคูณ<br />
หรือหารความถี่นี้ก็เพื่อใหไดความถีสัญญาณที่ตองการ โดยปกติจะ<br />
เปนวงจรหารความถี่ตัวอยางเชน ถาสัญญาณนาฬิกาของระบบมี<br />
Prescaler เปน 64 ก็หมายความวาความถี่สัญญาณที่ไดจะเปน fsys/64<br />
ตัวอยาง Prescaler<br />
Multiplexer<br />
7<br />
8
การทํางานเบื้องตนของ <strong>Timer</strong>/Counter<br />
วงจรนับ เริ่มการนับจากคาตั้งตน (ปกติเปน 0)<br />
เมื่อมีสัญญาณเขามา วงจรนับจะเพิ่มคา (หรือลดคา) ทีละ 1<br />
เมื่อนับมาถึงคาที่กําหนดใว จะเกิดสัญญาณ Overflow ในสัญญาณลูกถัดไป<br />
วงจรนับ เริ่มการนับจากคาตั้งตนใหม<br />
AVR processor architecture<br />
9<br />
10<br />
ATmega168 <strong>Timer</strong>/Counter<br />
ATmega168 มี <strong>Timer</strong> 3 ตัว<br />
<strong>Timer</strong>/Counter 0 : 8 bit with PWM<br />
<strong>Timer</strong>/Counter 1 : 16 bit with PWM<br />
<strong>Timer</strong>/Counter 2 : 8 bit with PWM and Asynchronous Operation<br />
External counter input<br />
PD4/ T0 <strong>Timer</strong>/Counter 0 external counter input<br />
PD5/ T1 / <strong>Timer</strong>/Counter 1 external counter input<br />
11<br />
12
External counter Output<br />
PD6/OC0A <strong>Timer</strong>/Counter 0 output compare match A output<br />
PD5/OC0B <strong>Timer</strong>/Counter 0 output compare match B output<br />
PB1/OC1A <strong>Timer</strong>/Counter 1 output compare match A output<br />
PB2/OC1B <strong>Timer</strong>/Counter 1 output compare match B output<br />
PB3/OC2A <strong>Timer</strong>/Counter 2 output compare match A output<br />
PD3/OC2B <strong>Timer</strong>/Counter 2 output compare match B output<br />
The 8-bit <strong>Timer</strong> block diagram<br />
<strong>Timer</strong>/Counter 0/2<br />
external counter<br />
input<br />
<strong>Timer</strong>/Counter 0/2<br />
output compare<br />
match A output<br />
<strong>Timer</strong>/Counter 0/2<br />
output compare<br />
match B output<br />
13<br />
14<br />
วงจรนับ<br />
ขนาด 8 บิต<br />
วงจรเปรียบเทียบ Output compare unit<br />
Output Compare<br />
Registers<br />
วงจรนับ<br />
วงจรนับ<br />
15<br />
16
The 8-bit <strong>Timer</strong> Control Register<br />
The 16-bit <strong>Timer</strong><br />
17<br />
18<br />
รีจิสเตอรสําหรับควบคุม <strong>Timer</strong> 8 บิต<br />
รีจิสเตอรสําหรับควบคุม <strong>Timer</strong> 16 บิต<br />
Counter0 Counter2 Description<br />
TCCR0A TCCR2A <strong>Timer</strong>/Counter Control Register A<br />
TCCR0B TCCR2B <strong>Timer</strong>/Counter Control Register B<br />
TCNT0 TCNT2 <strong>Timer</strong>/Counter Register<br />
OCR0A OCR2A Output Compare Register A<br />
OCR0B OCR2B Output Compare Register B<br />
TIMSK0 TIMSK2 <strong>Timer</strong>/Counter Interrupt Mask Register<br />
TIFR0 TIFR2 <strong>Timer</strong>/Counter Interrupt Flag Register<br />
Counter1<br />
TCCR1A<br />
TCCR1B<br />
TCCR1C<br />
TCNT1H<br />
TCNT1L<br />
OCR1AH<br />
OCR1AL<br />
OCR1BH<br />
OCR1BL<br />
ICR1H<br />
ICR1L<br />
TIMSK1<br />
TIFR1<br />
Description<br />
<strong>Timer</strong>/Counter 1 Control Register A<br />
<strong>Timer</strong>/Counter 1 Control Register B<br />
<strong>Timer</strong>/Counter 1 Control Register C<br />
<strong>Timer</strong>/Counter 1 High Register<br />
<strong>Timer</strong>/Counter 1 Low Register<br />
Output Compare Register 1 A High<br />
Output Compare Register 1 A Low<br />
Output Compare Register 1 B High<br />
Output Compare Register 1 B Low<br />
Input Capture Register 1 High<br />
Input Capture Register 1 Low<br />
<strong>Timer</strong>/Counter Interrupt Mask Register<br />
<strong>Timer</strong>/Counter Interrupt Flag Register<br />
19<br />
20
นิยาม<br />
MAX คาสูงสุดที่ Counter นับได กรณีเปนแบบ 8 บิต นับได 255 ถาเปน<br />
16 บิตจะนับได 65535<br />
BOTTOM คาต่ําสุดที่นับได ปกติคือ 0<br />
TOP คาสูงสุดที่กําหนดให Counter นับ<br />
การทํางานของ <strong>Timer</strong>/Counter<br />
Normal<br />
CTC (Clear <strong>Timer</strong> on Compare Match)<br />
Fast PWM (Single Slope PWM)<br />
Phase Correct PWM (Double Slope PWM)<br />
21<br />
22<br />
การทํางานแบบ Normal<br />
นับจากคาที่ตั้งใวใน Counter ไปจนถึงคา MAX จะเกิดการ Overflow ซึ่ง<br />
ใชไปอินเตอรรัพท CPU ได<br />
วิธีกาหนดการทํางาน<br />
กําหนดให WGM ในรีจิสเตอร TCCRnA และ TCCRnB เทากับ 000<br />
กําหนดคา Prescale CSn2 – CSn0 ในรีจิสเตอร TCCRnB<br />
กําหนดคาเริ่มตนสําหรับการนับ ในรีจิสเตอร TCNTn<br />
กําหนดสถานการณอินเตอรรัพทของ <strong>Timer</strong> บิต TOIEn ในรีจิสเตอร TIMSKn<br />
กําหนดบิต Global ใน SREG<br />
Timing Diagram<br />
ไมมี Prescale<br />
มี Prescale 1/8<br />
23<br />
24
การทํางานของ <strong>Timer</strong> 0 : TCCR0A and TCCR0B<br />
การทํางานของ <strong>Timer</strong> 1 : TCCR1A และ TCCR1B<br />
Mode WGM02 WGM01 WGM00 Description<br />
0 0 0 0 Normal<br />
1 0 0 1 PWM, Phase Correct<br />
2 0 1 0 Clear <strong>Timer</strong> on Compare (CTC)<br />
3 0 1 1 Fast PWM<br />
4 1 0 0 Reserved<br />
5 1 0 1 PWM, Phase Correct<br />
6 1 1 0 Reserved<br />
7 1 1 1 Fast PWM<br />
25<br />
26<br />
การทํางานของ <strong>Timer</strong> 1<br />
Prescaler for <strong>Timer</strong>/Counter0 and <strong>Timer</strong>/Counter1<br />
27<br />
28
TCCRnB ใชกําหนดคา Prescaler<br />
รีจิสเตอรสําหรับนับ <strong>Timer</strong>/Counter Register<br />
<strong>Timer</strong> 0 : TCNT0<br />
<strong>Timer</strong>1 : TCnT1 = TCNT1H (8-bit) + TCNT1L (8-bit)<br />
<strong>Timer</strong>2 : TCNT2<br />
<br />
29<br />
30<br />
<strong>Timer</strong>/Counter Interrupt Mask Register TIMSKn<br />
ตัวอยางโปรแกรม <strong>Timer</strong> 0 mode 0 (Normal)<br />
#include <br />
#include <br />
ISR(TIMER0_OVF_vect)<br />
{<br />
PORTB = ~PORTB;<br />
TCNT0 = 55;<br />
}<br />
//Complement PortB<br />
//Preload Counter<br />
31<br />
32
ตัวอยางโปรแกรม <strong>Timer</strong> 0 mode 0 (Normal)<br />
// ***********************************************************<br />
// Main program<br />
//<br />
int main(void) {<br />
DDRB = 0b11111111; // All outputs<br />
TCCR0A = 0;<br />
// initialize timer1<br />
TCCR0B = 0; // mode 0<br />
TCCR0B |= (1
การคํานวณคาบเวลา Interrupt<br />
fclk = 16MHz<br />
Prescale = 1<br />
ความถี่ที่ใชในการนับ = fclk/prescale = 16MHz/1 = 16MHz<br />
การนับแตละครั้งใชเวลา = 1/16MHz = 0.0625 uS<br />
Preload Counter = 60000<br />
คา MAX ของ <strong>Timer</strong> 1 = 65536<br />
ดังนั้นตองนับ = MAX – Preload = 65536 – 60000 = 5536 จึงจะ Overflow<br />
คาบเวลาการอินเตอรรัพท = 5536 * 0.0625 uS = 346 uSec<br />
การทํางานแบบ Clear timer on compare match (CTC) mode<br />
รีจิสเตอร TCNT เริ่มนับจากนับจาก 0 ไปจนเทากับคา TOP ที่ตั้งใวใน<br />
OCRA จะเกิดการ Overflow ซึ่งใชไปอินเตอรรัพท CPU ได และ <strong>Timer</strong><br />
จะ Clear คา ใน TCNT ใหเปน 0 ใหม<br />
วิธีกาหนดการทํางาน<br />
กําหนดให WGM ในรีจิสเตอร TCCRnA และ TCCRnB เทากับ 010<br />
กําหนดคา Prescale CSn2 – CSn0 ในรีจิสเตอร TCCRnB<br />
กําหนดคา TOP สําหรับการนับ ในรีจิสเตอร OCRnA<br />
กําหนดสถานการณอินเตอรรัพทของ <strong>Timer</strong> บิต OCIEnA ในรีจิสเตอร TIMSKn<br />
กําหนดบิต Global ใน SREG<br />
37<br />
38<br />
ตัวอยางโปรแกรม <strong>Timer</strong> 0 mode 2 (CTC)<br />
#include <br />
#include <br />
ตัวอยางโปรแกรม <strong>Timer</strong> 0 mode 2 (CTC)<br />
while(1)<br />
{<br />
int main (void)<br />
{<br />
DDRB = 0b11111111;<br />
TIMSK0 = _BV(OCIE0A);<br />
TCCR0A = _BV(WGM01);<br />
TCCR0B = _BV(CS02) | _BV(CS00);<br />
OCR0A = 40;<br />
PORTB = 0xff;<br />
sei();<br />
// All outputs<br />
// Enable Interrupt<br />
// Mode = CTC<br />
// <strong>Clock</strong>/1024<br />
// Set Top value<br />
}<br />
}<br />
ISR(SIG_OUTPUT_COMPARE0A)<br />
{<br />
PORTB = ~PORTB;<br />
}<br />
39<br />
40
การคํานวณคาบเวลา Interrupt<br />
Phase correct PWM mode<br />
fclk = 16MHz<br />
Prescale = 1024<br />
ความถี่ที่ใชในการนับ = fclk/prescale = 16MHz/1024 = 15.625 KHz<br />
การนับแตละครั้งใชเวลา T = 1/15.625 KHz = 0.064 uS<br />
คา TOP ที่ตั้งของ <strong>Timer</strong> 0 = OCR0A = 40<br />
คาบเวลาการอินเตอรรัพท = TOP*T = 40* 0.064 uS = 2.56 mSec<br />
41<br />
42<br />
Phase correct PWM mode<br />
External counter Output<br />
การทํางานโหมดนี้ เริ่มตน Counter TCNT จะนับ<br />
ขึ้น เมื่อนับถึงคาสูงสุด MAX ของ Counter (เชน<br />
<strong>Timer</strong> 0 = 255) วงจรนับจะเปลี่ยนทิศทางการนับ<br />
กลายเปนนับลง และเมื่อนับถึงคาต่ําสุด<br />
BOTTOM วงจรนับก็จะเปลี่ยนทิศทางการนับอีก<br />
ครั้ง การนับจะเปนเชนนี้ตลอดไป<br />
สัญญาณเอาทพุท จะออกทางขา Ocnx เชน <strong>Timer</strong><br />
0 ชอง A จะออกที่ขา PD6 โดยสัญญาณจะถูก<br />
กําหนดดวยคา COM0A1 COM0A0 (<strong>Timer</strong> 0<br />
ชอง A) และ COM0B1 COM0B0 COM0A0<br />
(<strong>Timer</strong> 0 ชอง B) ในรีจิสเตอร TCCR0A<br />
43<br />
44
Compare output mode, phase correct PWM mode<br />
ตัวอยางโปรแกรม สราง PWM ออกที่ PD6 Duty cycle 25%<br />
#include <br />
#include <br />
ตัวอยาง ถาให COM0A1-COM0A0 = 10<br />
เมื่อ Counter นับขึ้น สัญญาณ OC0A เปน 1 และจะกลายเปน 0 เมื่อ คา Counter<br />
เทากับคาที่ตั้งใวใน OCR0A<br />
เมื่อนับถึงคาสูงสุด Counter เปลี่ยนเปนนับลง ขณะนี้ สัญญาณ OC0A ยังเปน 0<br />
อยู แตมื่อนับมาเทากับคา OCR0A จะเปลี่ยนเปน ลอจิก 1 อีกครั้ง<br />
ถาให COM0A1-COM0A0 = 11 สัญญาณจะกลับเฟสกัน<br />
45<br />
int main (void)<br />
{<br />
DDRD = 0b11111111; // All outputs<br />
TCCR0A = 0b10000001; // Mode = PWM<br />
TCCR0B = 0b00000011; // <strong>Clock</strong>/64, Normal phase<br />
OCR0A = 51; // Duty cycle 20%<br />
PORTD = 0xff; //PWM Output on PD6 = OC0A<br />
while(1)<br />
{<br />
}<br />
}<br />
46<br />
การคํานวณคาบเวลา<br />
fclk = 16MHz<br />
Prescale = 64<br />
ความถี่ที่ใชในการนับ = fclk/prescale = 16MHz/64 = 250 KHz<br />
การนับแตละครั้งใชเวลา T = 1/250 KHz = 4 uS<br />
คาคาบเวลาของสัญญาณ PWM = 4uS*255*2 = 2040 uS<br />
คาความถี่ของสัญญาณ PWM = 1/2040 uS = 490 Hz<br />
คา TOP ที่ตั้งของ <strong>Timer</strong> 0 = OCR0A = 51<br />
ความกวางของพัลส = 4uS*51*2 = 408 uS<br />
Duty Cycle = คาคาบเวลาของสัญญาณ PWM / ความกวางของพัลส = 408uS/2040uS = 20%<br />
หมายเหตุ 2 มาจากการที่ Counter นับขึ้นและนับลง<br />
47