Chào các bạn! Vì nhiều lý do từ nay Truyen2U chính thức đổi tên là Truyen247.Pro. Mong các bạn tiếp tục ủng hộ truy cập tên miền mới này nhé! Mãi yêu... ♥

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: Truyen247.Pro

Tags: