Timer and interrupt of PIC

Timer

Trong Pic16f877a có 3 timer :

+ Timer0 : 8 bit

+ Timer1 : 16 bit

+ Timer2 : 8 bit

Timer dùng cho nhiều ứng dụng : định thời, capture, pwm, ...

1.Timer0

Thanh ghi tác động:

Các lệnh:

setup_TIMER_0(mode);

setup_COUNTERS (rtcc_state, ps_state); // hay setup_WDT()

set_TIMER0(value); // hay set_RTCC(value) :xác định giá trị ban đầu (8bit) cho Timer0

get_TIMER0(); // hay get_RTCC() :trả về số nguyên (8bit) của Timer0

Trong đó mode là một hoặc hai constant (nếu dùng hai thì chèn dấu "|"ở giữa) được định nghĩa trong file 16F877A.h gồm :

RTCC_INTERNAL : chọn xung clock nội

RTCC_EXT_L_TO_H : chọn bit cạnh lên trên chân RA4

RTCC_EXT_H_TO_L : chọn bit cạnh xuống trên chân RA4

RTCC_DIV_2 :chia prescaler 1:2

RTCC_DIV_4 1:4

RTCC_DIV_8 1:8

RTCC_DIV_16 1:16

RTCC_DIV_32 1:32

RTCC_DIV_64 1:64

RTCC_DIV_128 1:128

RTCC_DIV_256 1:256

rtcc_state là một trong những constant sau:

RTCC_INTERNAL

RTCC_EXT_L_TO_H

RTCC_EXT_H_TO_L

ps_state là một trong những constant sau:

RTCC_DIV_2

RTCC_DIV_4

RTCC_DIV_8

RTCC_DIV_16

RTCC_DIV_32

RTCC_DIV_64

RTCC_DIV_128

RTCC_DIV_256

WDT_18MS

WDT_36MS

WDT_72MS

WDT_144MS

WDT_288MS

WDT_576MS

WDT_1152MS

WDT_2304MS

Mình cũng chưa hiểu ý nghĩa của hàm WDT_..., ko biết có phải khai báo như trên thì sau khoảng thời gian ms bao nhiêu đó đặt sau WDT_ thì sẽ reset lại Pic ?????

2.Timer1

Thanh ghi tác động:

Các lệnh:

Code:

setup_TIMER_1(mode);

set_TIMER1(value); // xác định giá trị ban đầu (16bit) cho Timer1

get_TIMER1(); // trả về số nguyên (16bit) của Timer1

mode gồm (có thể kết hợp bằng dấu "|"):

T1_DISABLED : tắt Timer1

T1_INTERNAL : xung clock nội (Fosc/4)

T1_EXTERNAL : xung clock ngoài trên chân RC0

T1_EXTERNAL_SYNC : xung clock ngoài đồng bộ

T1_CLK_OUT

T1_DIV_BY_1

T1_DIV_BY_2

T1_DIV_BY_4

T1_DIV_BY_8

3.Timer2

Thanh ghi tác động:

Các lệnh:

Code:

setup_TIMER_2(mode, period, postscale);

set_TIMER2(value); // xác định giá trị ban đầu (8bit) cho Timer2

get_TIMER2(); // trả về số nguyên 8bit

Với mode gồm (co the ket hop bang dau "|"):

T2_DISABLED

T2_DIV_BY_1

T2_DIV_BY_4

T2_DIV_BY_16

period là số nguyên từ 0-255, xác định giá trị xung reset

postscale là số nguyên 1-16, xác định reset bao nhiêu lần trước khi ngắt.

===================================================

INTERRUPT

Các lệnh dùng cho ngắt:

Code:

enable_interrupts(level); //cho phép ngắt kiểu level

disable_interrupts(level); //cấm ngắt kiểu level

ext_int_edge(edge); // chọn cách lấy xung loại edge

level bao gồm:

GLOBAL : ngắt toàn cục

INT_RTCC : tràn TMR0

INT_RB : có thay đổi trạng thái một trong các chân RB4 đến RB7

INT_EXT : ngắt ngoài

INT_AD : chuyển đổi AD đã hoàn tất

INT_TBE : bộ đệm chuyển RS232 trống

INT_RDA : data nhận từ RS232 sẵn sàng

INT_TIMER1 : tràn TMR1

INT_TIMER2 : tràn TMR2

INT_CCP1 : có capture hay compare trên CCP1

INT_CCP2 : có capture hay compare trên CCP2

INT_SSP : có hoạt động SPI hay I2C

INT_PSP : có data vào cổng parallel slave

INT_BUSCOL : xung đột bus

INT_EEPROM : ghi vào eeprom hoàn tất

INT_TIMER0 : tràn TMR0

INT_COMP : kiểm tra bằng nhau comparator

edge bao gồm:

L_TO_H : cạnh lên

H_TO_L : cạnh xuống

Sau khai báo trên để vào đoạn chương trình ngắt, khai báo:

#INT_.........

Ví dụ vào thực thi ngắt ngoài, ta có đoạn code:

Code:

#INT_EXT

void ngat_ngoai()

{

//Chương trình ngắt tại đây

}

Ngắt Timer0

Đây là chương trình dùng ngắt Timer0 định thì 1s.

Đầu tiên led ở chân RB0 sáng, sau 1s sẽ dịch sang trái, nghĩa là led 1 trên chân RB1 sáng , lần lượt như vậy cho các led trên portB và lặp lại mãi mãi.

Code:

#include <16F877A.h>

#fuses NOWDT,PUT,XT,NOPROTECT

#use delay(clock=4000000)

#byte PORTB = 0x06

int16 count;

int8 a;

//Chuong trinh ngat TMR0

#int_timer0

void interrupt_timer0()

{

set_timer0(6);

++count;

if(count == 2000) // 2000*500us = 500000us = 1s

{

count=0;

rotate_left(&a,1);

}

}

//Chuong trinh chinh

void main(void)

{

set_tris_b(0);

enable_interrupts(int_timer0);

setup_timer_0(RTCC_INTERNAL|RTCC_DIV_2);

enable_interrupts(global);

set_timer0(6);// T_dinhthi = 2*(256 - 6)*1us = 500us

a = 0x01;

while(true)

{

PORTB = a;

}

}

Bạn đang đọc truyện trên: AzTruyen.Top

Tags: