1. KHẢO SÁT TIMER1 CỦA PIC 16F887
Là bộ định thời/đếm 16 bit gồm 2 thanh ghi 8 bit (TMR1H và TMR1L) – có thể đọc và ghi. Hai thanh ghi này tăng từ 0000h đến FFFFh và quay trở lại 0000h. Khi bị tràn thì Timer1 sẽ phát sinh ngắt, cờ báo ngắt TMR1IF (PIR1<0>) lên mức 1. Timer1 có bit cho phép/cấm là TMR1IE (PIE1<0>).
Cấu trúc của Timer1:
Khảo sát thanh ghi điều khiển Timer1:
Bit 7
Bit 6
Bit 5-4 T1CKPS1:T1CKPS0: các bit lựa chọn bộ chia - Timer1 input Clock Prescale Select bits
Khi TMR1CS = 1:
Bit này bị bỏ qua. Timer1 dùng xung clock bên trong khi TMR1CS = 0.
Bit 1 TMR1CS: bit lựa chọn nguồn xung clock của timer1
Nếu bit TMR1CS bằng 0 thì T1 hoạt động định thời đếm xung nội có tần số bằng FOSC/4. Bit điều khiển đồng bộ T1 SYNC không bị ảnh hưởng do xung clock bên trong luôn đồng bộ.
b. Timer1 ở chế độ đếm xung ngoại
Nếu bit TMR1CS bằng 1 thì T1 hoạt động đếm xung ngoại. Xung ngoại có 2 nguồn xung phụ
thuộc vào bit T1OSCEN:
Nếu bit T1OSCEN bằng 1 thì T1 đếm xung ngoại từ mạch dao động của T1 - xem hình 6-9.
Nếu bit T1OSCEN bằng 0 thì T1 đếm xung ngoại đưa đến ngõ vào T1CKI - xem hình 6-10.
Hình trên thì ngõ vào đang ở mức 1, counter sẽ đếm khi có xung cạnh lên.
Hình dưới thì ngõ vào đang ở mức thấp, xung cạnh lên thứ nhất thì mạch vẫn chưa đếm, xung xuống mức thấp và khi có cạnh lên thứ 2 thì counter bắt đầu đếm.
c. Hoạt động của Timer1 ở chế độ Counter đồng bộ
Khi bit TMR1CS bằng 1 thì T1 hoạt động ở chế độ Counter:
d. Hoạt động của Timer1 ở chế độ Counter bất đồng bộ
Nếu bit T1SYNC bằng 1 thì xung ngõ vào từ bên ngoài không được đồng bộ. Bộ đếm tiếp tục tăng bất đồng bộ với xung bên trong. Bộ đếm vẫn đếm khi CPU ở trong chế độ ngủ và khi tràn sẽ phát sinh ngắt và đánh thức CPU. Ngắt T1 có thể ngăn được.
e. Đọc và ghi Timer1 trong chế độ đếm không đồng bộ
Timer T1 cho phép đọc giá trị các thanh ghi TMR1H hoặc TMR1L khi timer đang đếm xung bất đồng bộ bên ngoài. Khi ghi thì nên ngừng timer lại rồi mới ghi giá trị mong muốn vào các thanh ghi. Nếu ghi mà timer đang đếm vẫn được nhưng có thể tạo ra một giá trị đếm không dự đoán được hay không chính xác.
- Đây là ảnh mô phỏng protues.
- Đây code chương trình.
Là bộ định thời/đếm 16 bit gồm 2 thanh ghi 8 bit (TMR1H và TMR1L) – có thể đọc và ghi. Hai thanh ghi này tăng từ 0000h đến FFFFh và quay trở lại 0000h. Khi bị tràn thì Timer1 sẽ phát sinh ngắt, cờ báo ngắt TMR1IF (PIR1<0>) lên mức 1. Timer1 có bit cho phép/cấm là TMR1IE (PIE1<0>).
Cấu trúc của Timer1:
Khảo sát thanh ghi điều khiển Timer1:
Bit 7
Bit 6
Bit 5-4 T1CKPS1:T1CKPS0: các bit lựa chọn bộ chia - Timer1 input Clock Prescale Select bits
- 11=1:8 giá trị chia.
- 10=1:4 giá trị chia.
- 01=1:2 giá trị chia.
- 00=1:1 giá trị chia.
- 1= bộ dao động được phép.
- 0= Tắt bộ dao động.
Khi TMR1CS = 1:
- 1= không thể đồng bộ ngõ vào clock ở từ bên ngoài.
- 0= đồng bộ ngõ vào clock ở từ bên ngoài.
Bit này bị bỏ qua. Timer1 dùng xung clock bên trong khi TMR1CS = 0.
Bit 1 TMR1CS: bit lựa chọn nguồn xung clock của timer1
- 1= Chọn nguồn xung clock từ bên ngoài ở chân RC0/T1OSO/T1CKI (cạnh lên).
- 0= Chọn xung nội bên trong (FOSC/4).
- 1= Cho phép Timer1 đếm.
- 0= Timer1 ngừng đếm.
Nếu bit TMR1CS bằng 0 thì T1 hoạt động định thời đếm xung nội có tần số bằng FOSC/4. Bit điều khiển đồng bộ T1 SYNC không bị ảnh hưởng do xung clock bên trong luôn đồng bộ.
b. Timer1 ở chế độ đếm xung ngoại
Nếu bit TMR1CS bằng 1 thì T1 hoạt động đếm xung ngoại. Xung ngoại có 2 nguồn xung phụ
thuộc vào bit T1OSCEN:
Nếu bit T1OSCEN bằng 1 thì T1 đếm xung ngoại từ mạch dao động của T1 - xem hình 6-9.
Nếu bit T1OSCEN bằng 0 thì T1 đếm xung ngoại đưa đến ngõ vào T1CKI - xem hình 6-10.
Hình 6-9: T1 hoạt động đếm xung ngoại từ mạch dao động T1
Timer1 tăng giá trị khi có xung cạnh lên. Counter chỉ tăng giá trị đếm sau khi nhận 1 xung cạnh xuống được minh hoạ hình 6-11.Hình trên thì ngõ vào đang ở mức 1, counter sẽ đếm khi có xung cạnh lên.
Hình dưới thì ngõ vào đang ở mức thấp, xung cạnh lên thứ nhất thì mạch vẫn chưa đếm, xung xuống mức thấp và khi có cạnh lên thứ 2 thì counter bắt đầu đếm.
c. Hoạt động của Timer1 ở chế độ Counter đồng bộ
Khi bit TMR1CS bằng 1 thì T1 hoạt động ở chế độ Counter:
- Nếu bit T1OSCEN bằng 1 thì đếm xung từ mạch dao động của T1.
- Nếu bit T1OSCEN bằng 1 thì đếm xung cạnh lên đưa đến ngõ vào RC0/T1OSO/T1CKI.
d. Hoạt động của Timer1 ở chế độ Counter bất đồng bộ
Nếu bit T1SYNC bằng 1 thì xung ngõ vào từ bên ngoài không được đồng bộ. Bộ đếm tiếp tục tăng bất đồng bộ với xung bên trong. Bộ đếm vẫn đếm khi CPU ở trong chế độ ngủ và khi tràn sẽ phát sinh ngắt và đánh thức CPU. Ngắt T1 có thể ngăn được.
e. Đọc và ghi Timer1 trong chế độ đếm không đồng bộ
Timer T1 cho phép đọc giá trị các thanh ghi TMR1H hoặc TMR1L khi timer đang đếm xung bất đồng bộ bên ngoài. Khi ghi thì nên ngừng timer lại rồi mới ghi giá trị mong muốn vào các thanh ghi. Nếu ghi mà timer đang đếm vẫn được nhưng có thể tạo ra một giá trị đếm không dự đoán được hay không chính xác.
- Đây là ảnh mô phỏng protues.
- Đây code chương trình.
#include <stdio.h>
#include <stdlib.h>
#define _XTAL_FREQ 8000000
#include <xc.h>
// CONFIG1
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator: High-speed crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF // RE3/MCLR pin function select bit (RE3/MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF // Brown Out Reset Selection bits (BOR disabled)
#pragma config IESO = OFF // Internal External Switchover bit (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
#pragma config LVP = OFF // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)
// CONFIG2
#pragma config BOR4V = BOR40V // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF // Flash Program Memory Self Write Enable bits (Write protection off)
unsigned int Count = 0;
void main(void) {
TRISCbits.TRISC0 = 0;
TMR1 = 15535;
T1CONbits.TMR1CS = 0;
T1CONbits.T1CKPS1 = 1;
T1CONbits.T1CKPS0 = 0;
T1CONbits.T1SYNC = 1;
T1CONbits.TMR1ON = 1;
while (1)
{
if(PIR1bits.TMR1IF == 1)
{
PIR1bits.TMR1IF = 0;
TMR1 = 15535;
Count++;
if(Count==5)
{
Count =0;
PORTCbits.RC0 ^= 1; //toggle the LED
}
}
}
}
#include <stdlib.h>
#define _XTAL_FREQ 8000000
#include <xc.h>
// CONFIG1
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator: High-speed crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF // RE3/MCLR pin function select bit (RE3/MCLR pin function is digital input, MCLR internally tied to VDD)
#pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF // Brown Out Reset Selection bits (BOR disabled)
#pragma config IESO = OFF // Internal External Switchover bit (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
#pragma config LVP = OFF // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)
// CONFIG2
#pragma config BOR4V = BOR40V // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF // Flash Program Memory Self Write Enable bits (Write protection off)
unsigned int Count = 0;
void main(void) {
TRISCbits.TRISC0 = 0;
TMR1 = 15535;
T1CONbits.TMR1CS = 0;
T1CONbits.T1CKPS1 = 1;
T1CONbits.T1CKPS0 = 0;
T1CONbits.T1SYNC = 1;
T1CONbits.TMR1ON = 1;
while (1)
{
if(PIR1bits.TMR1IF == 1)
{
PIR1bits.TMR1IF = 0;
TMR1 = 15535;
Count++;
if(Count==5)
{
Count =0;
PORTCbits.RC0 ^= 1; //toggle the LED
}
}
}
}
EmoticonEmoticon