2011/03/23

仕事ー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; 
}

No comments:

Post a Comment