Top Banner
AVR Timer/Counter รศ.ณรงค์ บวบทอง 1
59

AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

Jan 29, 2020

Download

Documents

dariahiddleston
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
Page 1: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

AVR Timer/Counter

รศ.ณรงค ์ บวบทอง

1

Page 2: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

Overview

Introduction

Basic Component

Operation

ATmega168 Timer

Overview

Related Registers

Operation

Programming Language

C Language

C Language with Arduino

2

Page 3: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

หลกัการเบือ้งตน้

Timer การวดัคาบเวลา หรือการจบัเวลาCounter การนบัจ านวนสญัญาณ ถา้สญัญาณนั้นมีคาบเวลาคงท่ี การนบัก็จะเป็นการนบัจ านวนเวลา นัน่คือ Timer

ส่วนประกอบเบ้ืองของ Timer/Counter ในระบบ Microcontroller: แหล่งจ่ายสัญญาณท่ีจะใชน้บั วงจรนบั รีจิสเตอร์ควบคุม Optional prescaler ของสัญญาณท่ีจะใชน้บั

ทั้ง Timer และ Counter บางคร้ังกเ็รียกรวมๆกนัวา่ Timer

3

Page 4: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

แหล่งจ่ายสญัญาณท่ีจะใชน้บั (Timer Clock Source)แหล่งจ่ายสัญญาณมาจาก : ภายใน Internal ภายนอก External

ปกติแลว้ Microcontroller จะใชส้ัญญาณนาฬิกาเพื่อการท างานของระบบ สัญญาณนาฬิกาน้ี อาจจะมาจากภายนอกชิพ เช่น ใช ้XTAL หรือเป็นวงจรสร้างสัญญาณภายในชิพเองกไ็ด ้ สัญญาณนาฬิกาของระบบน้ี ยงัใชเ้ป็นสัญญาณนาฬิกาของวงจรต่างๆดว้ย เช่น

CPU clock (clkcpu) I/O clock (clkI/O) ADC clock (clkADC) Timer/Counter clock

4

Page 5: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

วงจรนบั (Timer/Counter Registers) วงจรนบั ใชส้ าหรับการนบัสัญญาณ และการจบัเวลา ขนาดของวงจรนบั 8 บิต 16 บิต บางคร้ังใชว้งจรนบัขนาด 8 บิต 2 ตวัมาท าเป็นวงจรนบัขนาด 16 บิต

5

Page 6: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

รีจิสเตอร์ควบคุม (Timer Control Registers)ท าหนา้ท่ีควบคุมการท างาน เช่น รูปแบบการท างาน (Operating mode) เช่น Normal, PWM,

compare/capture สร้างสัญญาณอินเตอร์รัพท ์ เลือกแหล่งจ่ายสญัญาณ เลือกรูปแบบการทริก (Trigger)

รีจิสเตอร์ควบคุมน้ีอาจมีหลายตวั

6

Page 7: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

Timer PrescalerController บางตวัมีความยดืหยุน่สูง สามารถเลือกใชส้ญัญาณนาฬิกาท่ีความถ่ีต่างๆกนัได ้ ซ่ึงความถ่ีเหล่าน้ีไดม้าจากวงจร prescaler. วงจร Prescaler อาจเป็นวงจร คูณหรือวงจรหารความถ่ีกไ็ด ้ การคูณหรือหารความถ่ีน้ีกเ็พื่อใหไ้ดค้วามถีสัญญาณท่ีตอ้งการ โดยปกติจะเป็นวงจรหารความถ่ีตวัอยา่งเช่น ถา้สัญญาณนาฬิกาของระบบมี Prescaler เป็น 64 กห็มายความวา่ความถ่ีสัญญาณท่ีไดจ้ะเป็น fsys/64

7

Page 8: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

ตวัอยา่ง Prescaler

Multiplexer

8

Page 9: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

การท างานเบ้ืองตน้ของ Timer/Counter วงจรนบั เร่ิมการนบัจากค่าตั้งตน้ (ปกติเป็น 0) เม่ือมีสัญญาณเขา้มา วงจรนบัจะเพ่ิมค่า (หรือลดค่า) ทีละ 1 เม่ือนบัมาถึงค่าท่ีก าหนดใว ้ จะเกิดสัญญาณ Overflow ในสัญญาณลกูถดัไป วงจรนบั เร่ิมการนบัจากค่าตั้งตน้ใหม่

9

Page 10: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

AVR processor architecture

10

Page 11: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

ATmega168 Timer/CounterATmega168 มี Timer 3 ตวั Timer/Counter 0 : 8 bit with PWM Timer/Counter 1 : 16 bit with PWM Timer/Counter 2 : 8 bit with PWM and Asynchronous Operation

11

Page 12: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

External counter input

PD4/ T0 Timer/Counter 0 external counter input

PD5/ T1 / Timer/Counter 1 external counter input

12

Page 13: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

External counter Output

13

PD6/OC0A Timer/Counter 0 output compare match A output

PD5/OC0B Timer/Counter 0 output compare match B output

PB1/OC1A Timer/Counter 1 output compare match A output

PB2/OC1B Timer/Counter 1 output compare match B output

PB3/OC2A Timer/Counter 2 output compare match A output

PD3/OC2B Timer/Counter 2 output compare match B output

Page 14: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

The 8-bit Timer block diagram

14

Timer/Counter 0/2

output compare match B output

Timer/Counter 0/2

output compare match A output

Timer/Counter 0/2

external counter input

Page 15: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

วงจรนบั ขนาด 8 บิต

15

วงจรนบั

Page 16: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

วงจรเปรียบเทียบ Output compare unit

16

Output Compare Registers

วงจรนบั

Page 17: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

The 8-bit Timer Control Register

17

Page 18: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

The 16-bit Timer

18

Page 19: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

รีจิสเตอร์ส ำหรับควบคุม Timer 8 บิต

Counter0 Counter2 Description

TCCR0A TCCR2A Timer/Counter Control Register A

TCCR0B TCCR2B Timer/Counter Control Register B

TCNT0 TCNT2 Timer/Counter Register

OCR0A OCR2A Output Compare Register A

OCR0B OCR2B Output Compare Register B

TIMSK0 TIMSK2 Timer/Counter Interrupt Mask Register

TIFR0 TIFR2 Timer/Counter Interrupt Flag Register

19

Page 20: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

รีจิสเตอร์ส ำหรับควบคุม Timer 16 บิต

20

Counter1 Description

TCCR1A Timer/Counter 1 Control Register A

TCCR1B Timer/Counter 1 Control Register B

TCCR1C Timer/Counter 1 Control Register C

TCNT1H Timer/Counter 1 High Register

TCNT1L Timer/Counter 1 Low Register

OCR1AH Output Compare Register 1 A High

OCR1AL Output Compare Register 1 A Low

OCR1BH Output Compare Register 1 B High

OCR1BL Output Compare Register 1 B Low

ICR1H Input Capture Register 1 High

ICR1L Input Capture Register 1 Low

TIMSK1 Timer/Counter Interrupt Mask Register

TIFR1 Timer/Counter Interrupt Flag Register

Page 21: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

นิยาม

MAX ค่าสูงสุดท่ี Counter นบัได ้กรณีเป็นแบบ 8 บิต นบัได ้255 ถา้เป็น 16 บิตจะนบัได ้65535

BOTTOM ค่าต ่าสุดท่ีนบัได ้ปกติคือ 0 TOP ค่าสูงสุดท่ีก าหนดให ้Counter นบั

21

Page 22: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

การท างานของ Timer/Counter Normal CTC (Clear Timer on Compare Match) Fast PWM (Single Slope PWM) Phase Correct PWM (Double Slope PWM)

22

Page 23: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

การท างานแบบ Normal

นบัจากค่าท่ีตั้งใวใ้น Counter ไปจนถึงค่า MAX จะเกิดการ Overflow ซ่ึงใชไ้ปอินเตอร์รัพท ์CPU ได ้

วิธีกาหนดการท างาน ก าหนดให ้WGM ในรีจิสเตอร์ TCCRnA และ TCCRnB เท่ากบั 000 ก าหนดค่า Prescale CSn2 – CSn0 ในรีจิสเตอร์ TCCRnB ก าหนดค่าเร่ิมตน้ส าหรับการนบั ในรีจิสเตอร์ TCNTn ก าหนดสถานการณ์อินเตอร์รัพทข์อง Timer บิต TOIEn ในรีจิสเตอร์ TIMSKn ก าหนดบิต Global ใน SREG

23

Page 24: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

Timing Diagram

ไมมี่ Prescale

มี Prescale 1/8

24

Page 25: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

การท างานของ Timer 0 : TCCR0A and TCCR0B

Mode WGM02 WGM01 WGM00 Description

0 0 0 0 Normal

1 0 0 1 PWM, Phase Correct

2 0 1 0 Clear Timer on Compare (CTC)

3 0 1 1 Fast PWM

4 1 0 0 Reserved

5 1 0 1 PWM, Phase Correct

6 1 1 0 Reserved

7 1 1 1 Fast PWM

25

Page 26: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

การท างานของ Timer 1 : TCCR1A และ TCCR1B

26

Page 27: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

การท างานของ Timer 1

27

Page 28: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

Prescaler for Timer/Counter0 and Timer/Counter1

28

Page 29: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

TCCRnB ใชก้ าหนดค่า Prescaler

29

Page 30: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

รีจิสเตอร์ส าหรับนบั Timer/Counter Register Timer 0 : TCNT0 Timer1 : TCnT1 = TCNT1H (8-bit) + TCNT1L (8-bit) Timer2 : TCNT2

30

Page 31: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

Timer/Counter Interrupt Mask Register TIMSKn

31

Page 32: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

ตวัอยา่งโปรแกรม Timer 0 mode 0 (Normal)#include <avr/io.h>

#include <avr/interrupt.h>

ISR(TIMER0_OVF_vect)

{

PORTB = ~PORTB; //Complement PortB

TCNT0 = 55; //Preload Counter

}

32

Page 33: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

ตวัอยา่งโปรแกรม Timer 0 mode 0 (Normal)// ***********************************************************

// Main program

//

int main(void) {

DDRB = 0b11111111; // All outputs

TCCR0A = 0; // initialize timer1

TCCR0B = 0; // mode 0

TCCR0B |= (1 << CS02); // prescaler 256

TCNT0 = 55; // preload timer 60000

TIMSK0 |= (1 << TOIE0); // enable timer overflow interrupt

PORTB = 0xff; // Set port B =1111 1111

sei(); // Global Interrupt

while(1)

{

}

}

33

Page 34: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

การค านวณค่าความถ่ี

จากตวัอยา่ง จะไดส้ญัญาณส่ีเหล่ียม ออกทางพอรท ์ B ซ่ึงสามารถ์ค านวณหาค่าความถ่ีไดด้งัน้ี

34

HzF

Fin

escaler

n

TCNT

Max

MHzspeedClock

TCNTMaxn

escaler

speedClockFin

n

FinF

47.155402

62500

62500256

16000000

256Pr

402

550

256

16

2*)0(

Pr

Page 35: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

ตวัอยา่งโปรแกรม Timer 1 mode 0 (Normal)#include <avr/io.h>

#include <avr/interrupt.h>

int main (void)

{

DDRB = 0b11111111; // All outputs

TCCR1A = 0; // initialize timer1

TCCR1B = 0; //mode 0

TCCR1B |= (1 << CS10); // no prescaler

TCNT1 = 60000; // preload timer 60000

TIMSK1 |= (1 << TOIE1); // enable timer overflow interrupt

PORTB = 0xff; // Set port B =1111 1111

sei(); //Global Interrupt

35

Page 36: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

ตวัอยา่งโปรแกรม Timer1 mode 0 (Normal) (ต่อ)while(1)

{

}

}

ISR(TIMER1_OVF_vect)

{

PORTB = ~PORTB; //Complement PortB

TCNT1 = 60000; //Preload Counter

}

36

Page 37: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

การค านวณคาบเวลา Interrupt fclk = 16MHz Prescale = 1 ความถ่ีท่ีใชใ้นการนบั = fclk/prescale = 16MHz/1 = 16MHz การนบัแต่ละคร้ังใชเ้วลา = 1/16MHz = 0.0625 uS Preload Counter = 60000 ค่า MAX ของ Timer 1 = 65536 ดงันั้นตอ้งนบั = MAX – Preload = 65536 – 60000 = 5536 จึงจะ Overflow คาบเวลาการอินเตอร์รัพท ์= 5536 * 0.0625 uS = 346 uSec

37

Page 38: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

การท างานแบบ Clear timer on compare match (CTC) mode

รีจิสเตอร์ TCNT เร่ิมนบัจากนบัจาก 0 ไปจนเท่ากบัค่า TOP ท่ีตั้งใวใ้น OCRA จะเกิดการ Overflow ซ่ึงใชไ้ปอินเตอร์รัพท ์CPU ได ้ และ Timer จะ Clear ค่า ใน TCNT ใหเ้ป็น 0 ใหม่

วิธีกาหนดการท างาน ก าหนดให ้WGM ในรีจิสเตอร์ TCCRnA และ TCCRnB เท่ากบั 010 ก าหนดค่า Prescale CSn2 – CSn0 ในรีจิสเตอร์ TCCRnB ก าหนดค่า TOP ส าหรับการนบั ในรีจิสเตอร์ OCRnA ก าหนดสถานการณ์อินเตอร์รัพทข์อง Timer บิต OCIEnA ในรีจิสเตอร์ TIMSKn ก าหนดบิต Global ใน SREG

38

Page 39: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

ตวัอยา่งโปรแกรม Timer 0 mode 2 (CTC)#include <avr/io.h>

#include <avr/interrupt.h>

int main (void)

{

DDRB = 0b11111111; // All outputs

TIMSK0 = _BV(OCIE0A); // Enable Interrupt

TCCR0A = _BV(WGM01); // Mode = CTC

TCCR0B = _BV(CS02) | _BV(CS00); // Clock/1024

OCR0A = 40; // Set Top value

PORTB = 0xff;

sei();

39

Page 40: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

ตวัอยา่งโปรแกรม Timer 0 mode 2 (CTC)while(1)

{

}

}

ISR(SIG_OUTPUT_COMPARE0A)

{

PORTB = ~PORTB;

}

40

Page 41: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

การค านวณคาบเวลา Interrupt fclk = 16MHz Prescale = 1024 ความถ่ีท่ีใชใ้นการนบั = fclk/prescale = 16MHz/1024 = 15.625 KHz การนบัแต่ละคร้ังใชเ้วลา T = 1/15.625 KHz = 0.064 uS ค่า TOP ท่ีตั้งของ Timer 0 = OCR0A = 40 คาบเวลาการอินเตอร์รัพท ์= TOP*T = 40* 0.064 uS = 2.56 mSec

41

Page 42: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

Phase correct PWM mode

42

Page 43: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

Phase correct PWM mode การท างานโหมดน้ี เร่ิมตน้ Counter TCNT จะนบั

ข้ึน เม่ือนบัถึงค่าสูงสุด MAX ของ Counter (เช่น Timer 0 = 255) วงจรนบัจะเปล่ียนทิศทางการนบั กลายเป็นนบัลง และเม่ือนบัถึงค่าต ่าสุด BOTTOM วงจรนบักจ็ะเปล่ียนทิศทางการนบัอีกคร้ัง การนบัจะเป็นเช่นน้ีตลอดไป

สัญญาณเอาทพ์ทุ จะออกทางขา Ocnx เช่น Timer 0 ช่อง A จะออกท่ีขา PD6 โดยสญัญาณจะถกูก าหนดดว้ยค่า COM0A1 COM0A0 (Timer 0 ช่อง A) และ COM0B1 COM0B0 COM0A0 (Timer 0 ช่อง B) ในรีจิสเตอร์ TCCR0A

43

Page 44: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

External counter Output

44

Page 45: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

Compare output mode, phase correct PWM mode

45

ตวัอยา่ง ถา้ให ้COM0A1-COM0A0 = 10 เม่ือ Counter นบัข้ึน สัญญาณ OC0A เป็น 1 และจะกลายเป็น 0 เม่ือ ค่า Counter เท่ากบัค่าท่ีตั้งใวใ้น OCR0A เม่ือนบัถึงค่าสูงสุด Counter เปล่ียนเป็นนบัลง ขณะน้ี สัญญาณ OC0A ยงัเป็น 0 อยู ่แต่ม่ือนบัมาเท่ากบัค่า OCR0A จะเปล่ียนเป็น ลอจิก 1 อีกคร้ังถา้ให ้COM0A1-COM0A0 = 11 สัญญาณจะกลบัเฟสกนั

Page 46: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

ตวัอยา่งโปรแกรม สร้าง PWM ออกท่ี PD6 Duty cycle 25% #include <avr/io.h>

#include <avr/interrupt.h>

int main (void)

{

DDRD = 0b11111111; // All outputs

TCCR0A = 0b10000001; // Mode = PWM

TCCR0B = 0b00000011; // Clock/64, Normal phase

OCR0A = 51; // Duty cycle 20%

PORTD = 0xff; //PWM Output on PD6 = OC0A

while(1)

{

}

}

46

Page 47: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

การค านวณคาบเวลา fclk = 16MHz Prescale = 64 ความถ่ีท่ีใชใ้นการนบั = fclk/prescale = 16MHz/64 = 250 KHz การนบัแต่ละคร้ังใชเ้วลา T = 1/250 KHz = 4 uS ค่าคาบเวลาของสญัญาณ PWM = 4uS*255*2 = 2040 uS ค่าความถ่ีของสญัญาณ PWM = 1/2040 uS = 490 Hz ค่า TOP ท่ีตั้งของ Timer 0 = OCR0A = 51 ความกวา้งของพลัส์ = 4uS*51*2 = 408 uS Duty Cycle = ค่าคาบเวลาของสญัญาณ PWM / ความกวา้งของพลัส์ = 408uS/2040uS = 20%

หมายเหตุ 2 มาจากการท่ี Counter นบัข้ึนและนบัลง

47

Page 48: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

TimerONE ท าอะไรไดบ้า้ง

void initialize(long microseconds=1000000);

void start();

void stop();

void restart();

unsigned long read();

void setPeriod(long microseconds);

void pwm(char pin, int duty, long microseconds=-1);

void setPwmDuty(char pin, int duty);

void disablePwm(char pin);

void attachInterrupt(void (*isr)(), long microseconds=-1);

void detachInterrupt();

48

Page 49: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

หมายเหตุ โปรแกรมท่ีเก่ียวกบั Timer0 มกัจะจ าลองการท างานบน

VMLAB ไม่ได ้ ตอ้งใชเ้ขียน บน Arduino แทน

49

Page 50: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

ตวัอยา่งให ้Interrupt ทุกๆ 1000 uSec#include <TimerOne.h> //เรยีกใช ้ไลบรารี ่TimerOne

unsigned char a = 0;

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

void setup() {

pinMode(8, OUTPUT);

//ก าหนดระยะเวลาการอนิเตอรรั์พทข์อง timer 1 ใหเ้ป็นทกุๆ 1000 uS

Timer1.initialize(1000);

// ก าหนดต าแหน่งโปรแกรมรองรับการอนิเตอรรั์พท ์

Timer1.attachInterrupt( timerIsr );

}

50

Page 51: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

ตวัอยา่งให ้Interrupt ทุกๆ 1000 uSec (ต่อ) void timerIsr(){

if(a==0) {

digitalWrite(8, LOW);

a = 1;

}else{

digitalWrite(8, HIGH);

a = 0;

}

}

Loop ()

{

}

51

Page 52: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

Arduino PWM#include "TimerOne.h"

void setup(){

pinMode(10, OUTPUT);

Timer1.initialize(1000); // initialize timer1, and set a 1/2 second period

Timer1.pwm(9, 256); // setup pwm on pin 9, 25% duty cycle

Timer1.attachInterrupt(callback); // attaches callback() as a timer overflow interrupt

}

void callback(){

digitalWrite(10, digitalRead(10) ^ 1);

}

void loop(){

// your program here...

}

52

สญัญาณท่ีขา 10 T = 2 mSDuty = 50%

สญัญาณท่ีขา 9 T = 1 mSDuty = 25%

Page 53: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

การใช ้ Library Timer 1 บน Arduinoใน Arduino มี Library เก่ียวกบั Timer TimerOne TimerThreeดูไดจ้าก http://playground.arduino.cc/code/timer1

53

Page 54: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

โปรแกรมเม่ือเขียนบน Arduino#include <avr/io.h>

#include <avr/interrupt.h>

void setup() {

DDRD = 0b11111111; // All outputs

TCCR0A = 0b10000001; // Mode = PWM

TCCR0B = 0b00000011; // Clock/64, Normal phase

OCR0A = 51; // Duty cycle 20%

PORTD = 0xff; //PWM Output on PD6 = OC0A

}

void loop() {

}

54

Page 55: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

โปรแกรมเม่ือเขียนบน Arduino#include <avr/io.h>

#include <avr/interrupt.h>

void setup() {

DDRB = 0b11111111; // All outputs

// initialize timer1

TCCR1A = 0;

TCCR1B = 0;

TCNT1 = 60000; // preload timer

TCCR1B |= (1 << CS10); // no prescaler

// enable timer overflow interrupt

TIMSK1 |= (1 << TOIE1);

PORTB = 0xff;

sei();

}

55

void loop() {

}

ISR(TIMER1_OVF_vect)

//ISR(TIMER0_OVF_vect)

{

PORTB = ~PORTB;

TCNT1 = 60000;

}

Page 56: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

โปรแกรมเม่ือเขียนบน Arduino#include <avr/io.h>

#include <avr/interrupt.h>

void setup() {

DDRB = 0b11111111; // All outputs

TIMSK0 = _BV(OCIE0A); // Enable Interrupt

TCCR0A = _BV(WGM01); // Mode = CTC

TCCR0B = _BV(CS02) | _BV(CS00); // Clock/1024

OCR0A = 40; // Top Value

PORTB = 0xff;

sei();

}

56

void loop() {

}

ISR(SIG_OUTPUT_COMPARE0A)

{

PORTB = ~PORTB;

}

Page 57: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

โปรแกรมสร้าง PWM 2 ช่อง ท่ี OC0A กบั OC0B เม่ือเขียนบน Arduino#include <avr/io.h>

#include <avr/interrupt.h>

void setup() {

DDRD = 0b11111111; // All outputs

TCCR0A = 0b10100001; // Mode = PWM 2 channel

TCCR0B = 0b00000010; // Clock/8, Normal phase

OCR0A = 51; // Duty cycle 20% : ch A = PD6

OCR0B = 128; //Duty cycle 50% : ch B = PD5

PORTD = 0xff; //PWM Output on PD6 = OC0A

}

void loop() {

}

57

Page 58: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

แสดงรูปคล่ืนของ PWM ทั้ง 2 ช่อง

58

Page 59: AVR Timer/Counter · การทางานเบ้ืองตน้ของ Timer/Counter วงจรนบั เริ่มการนับจากค่าต้งัตน้

อา้งองิ

http://playground.arduino.cc/Code/Timer1

59