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

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

  • Upload
    others

  • View
    26

  • Download
    0

Embed Size (px)

Citation preview

AVR Timer/Counter

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

1

Overview

Introduction

Basic Component

Operation

ATmega168 Timer

Overview

Related Registers

Operation

Programming Language

C Language

C Language with Arduino

2

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

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

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

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

3

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

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

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

4

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

5

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

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

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

6

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

7

ตวัอยา่ง Prescaler

Multiplexer

8

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

9

AVR processor architecture

10

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

External counter input

PD4/ T0 Timer/Counter 0 external counter input

PD5/ T1 / Timer/Counter 1 external counter input

12

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

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

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

15

วงจรนบั

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

16

Output Compare Registers

วงจรนบั

The 8-bit Timer Control Register

17

The 16-bit Timer

18

รีจิสเตอร์ส ำหรับควบคุม 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

รีจิสเตอร์ส ำหรับควบคุม 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

นิยาม

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

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

21

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

22

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

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

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

23

Timing Diagram

ไมมี่ Prescale

มี Prescale 1/8

24

การท างานของ 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

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

26

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

27

Prescaler for Timer/Counter0 and Timer/Counter1

28

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

29

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

30

Timer/Counter Interrupt Mask Register TIMSKn

31

ตวัอยา่งโปรแกรม 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

ตวัอยา่งโปรแกรม 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

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

จากตวัอยา่ง จะไดส้ญัญาณส่ีเหล่ียม ออกทางพอรท ์ 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

ตวัอยา่งโปรแกรม 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

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

{

}

}

ISR(TIMER1_OVF_vect)

{

PORTB = ~PORTB; //Complement PortB

TCNT1 = 60000; //Preload Counter

}

36

การค านวณคาบเวลา 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

การท างานแบบ 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

ตวัอยา่งโปรแกรม 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

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

{

}

}

ISR(SIG_OUTPUT_COMPARE0A)

{

PORTB = ~PORTB;

}

40

การค านวณคาบเวลา 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

Phase correct PWM mode

42

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

External counter Output

44

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 สัญญาณจะกลบัเฟสกนั

ตวัอยา่งโปรแกรม สร้าง 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

การค านวณคาบเวลา 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

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

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

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

49

ตวัอยา่งให ้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

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

if(a==0) {

digitalWrite(8, LOW);

a = 1;

}else{

digitalWrite(8, HIGH);

a = 0;

}

}

Loop ()

{

}

51

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%

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

53

โปรแกรมเม่ือเขียนบน 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

โปรแกรมเม่ือเขียนบน 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;

}

โปรแกรมเม่ือเขียนบน 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;

}

โปรแกรมสร้าง 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

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

58

อา้งองิ

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

59