Download as pdf or txt
Download as pdf or txt
You are on page 1of 61

CHƯƠNG 5

BỘ ĐỊNH THỜI
Kiểm tra chương ngắt

1. Nêu tên các thanh ghi liên quan đến ngắt, chức
năng các bit trong thanh ghi INTCON?
2. Nêu các chân ngắt ngoài và các chân ngắt PORTB
của PIC16F887, có gì khác với PIC 16F877A?
3. Vẽ sơ đồ mạch nguyên lý, vẽ lưu đồ giải thuật và
viết chương trình điều khiển 8 LED nối với PORTD
theo yêu cầu: Khi có ngắt ngoài PORTD = 0xF0;
Biết ban đầu 8 LED tắt; Fosc = 4MHz
Nội dung chương 5
1. Timer
2. Đặc điểm, Sơ đồ khối của Timer 0
3. Các bước để định thời gian Timer 0
4. Các bước để đếm sự kiện Counter 0
5. Bài tập Timer 0
6. Đặc điểm, Sơ đồ khối của Timer 1
7. Các bước để định thời gian Timer 1
8. Các bước để đếm sự kiện Counter 1
9. Bài tập Timer 1
10. Đặc điểm, Sơ đồ khối của Timer 2
11. Các bước để định thời gian Timer 2
12. Bài tập Timer 2
Timers
 Timer được sử dụng cho nhiều chức
năng:
 Định thì để tạo sự kiện
 Đếm sự kiện
 Tạo dạng sóng v..v
 PIC16F877 có 3 timers
– Timer0
– Timer1
– Timer2
So sánh các Timer
TIMER0 TIMER1 TIMER2
Kích thước 8-bits (TMR0) 16-bits 8-bits (TMR2)
thanh ghi (TMR1H:TMR1L)
Nguồn CLOCK Fosc/4 Fosc/4 Fosc/4
(bên trong)
Nguồn CLOCK T0CKI pin T1CKI pin or None
(bên ngoài) Timer 1 oscillator
(T1OSC)
CLOCK SCALING Prescaler 8-bits Prescaler 3-bits Prescaler
AVAILABLE (1:21:256) (÷1,÷2,÷4,÷8) (1:1,1:4,1:8)
(Resolution) Postscaler
(1:11:16)
Sự kiện ngắt và On overflow On overflow TMR2 matches
cờ ngắt FFh00h FFFFh0000h PR2
(TMR0IF in INTCON) (TMR1IF in PIR1) (TMR2IF in PIR2)
Đánh thức PIC từ NO YES NO
SLEEP
Đặc điểm của Timer 0
 Là Timer/Counter 8 bit
 Có thể đọc và ghi
 Có bộ chia trước 8 bit có thể lập trình bằng
phần mềm
 Có thể lựa chọn nguồn xung clock bên
trong hoặc bên ngoài
 Cho phép lựa chọn tác động cạnh cho xung
clock bên ngoài
 Xảy ra hiện tượng ngắt khi tràn từ
FFh00h
Sơ đồ khối Timer 0
DATA BUS
Fosc/4 8

synchronize
T0CKI
pin
scaled clock TMR0

TMR0
prescaler PS2 PS1 PS0 RATE
Watchdog Timer
WDT out
0 0 0 1:2

OPTION register 0 0 1 1:4

0 1 0 1:8
RBPU INTEDG TOCS TOSE PSA PS2 PS1 PS0
0 1 1 1:16

Prescaler Rate Select Bits 1 0 0 1:32

1 0 1 1:64
Prescaler Assignment
TMR0 Clock 1= prescaler assigned to WDT 1 1 0 1:128
Source Select 0= prescaler assigned to Timer 0
1 = TOCK1, 0 = Fosc/4 1 1 1 1:256
Source Edge Select
1 = increment TMR0 on high-to-low transition
0 = increment TMR0 on low-to-high transition
Sơ đồ khối Timer 0
DATA BUS
Fosc/4 8

synchronize
T0CKI
pin
scaled clock TMR0

prescaler
Watchdog Timer INTCON register
TMR0IF

• Xung clock bên ngoài (TOCKI) được sử dụng, nó sẽ


được đồng bộ hóa với xung clock bên trong

•Timer 0 có thể đọc/ ghi

•Cờ ngắt Timer 0 sẽ được set khi có hiện tượng tràn TMR0
(FF00)
Hoạt động
Các bước để định thời gian Timer 0
B1: Tính toán các giá trị cần đưa vào code:
Xác định được:
 tdelay: thời gian cần định thời (us) TMR0 =
 fOSC: tần số dao động thạch anh TMR0IF =
 Pre:hệ số chia tần trước prescaler(Pre=1,2,4...,256
PSA =
PS2 =
 [TMR0]: giá trị cần ghi vào thanh ghi TMR0
PS1 =
PS0 =
B2: Ghi vào TMR0 giá trị đã tính toán
T0SE =
B3: Xóa cờ báo tràn( cờ ngắt) TMR0IF T0CS =
B4: Chọn chế độ hoạt động của Timer 0
Nếu dùng ngắt:
• (chọn chế độ Timer, gán prescaler..)
GIE =
B5: Xác định thời điểm Timer 0 tràn bằng cách:
TMR0IE =
• Kiểm tra cờ TMR0IF( nếu dùng thăm dò)
• Xử lý ISR của Timer 0 (nếu dùng ngắt)
Ví dụ
Fosc=4MHz Tcy = 1us
 TD = dem* Tdelay = dem * [256-TMR0] *4*(1/fosc)* PresT0
 = dem* [256-TMR0] *4*(Tosc)* PresT0
 = dem* [256-TMR0] *Tcy* PresT0
Tdelay min = 1 *Tcy* 2 = 2us
max = 256 *Tcy* 256= 65,536ms

a. TD = 100ms = dem * tdelay = 2 * 50ms


 dem = 2; TMR0=61; TMR0IF =0
PresT0 =1:256) PS2=1; PS1=1; PS0=1;
PSA=0 T0SE = 0 T0CS=0
b. TD = 500ms = dem * tdelay = 50 * 10ms
 dem = 50 ; TMR0=; TMR0IF =0
PresT0 =1:X) PS2=x; PS1=x; PS0=x;
PSA=0 T0SE = 0 T0CS=0
 [TMR0] = 256 – [ tdelay/Tcy*PresT0]
 = 256 – [1000us/1us*256) =

 [0] <= 256 – [ tdelay/Tcy*PresT0]


 PresT0 >= [ tdelay/ 256*Tcy]
= 1000us/ 256*1us >=4

TMR0 0……….………………. …..255


Các bước để đếm sự kiện Counter 0

 B1: Xóa giá trị trong thanh ghi TMR0 =0


 B2: Xóa cờ báo tràn( cờ ngắt) TMR0IF=0
 B3: Chọn chế độ hoạt động của Counter 0
• Chọn chế độ đếm sự kiện (Counter) T0CS =1
• Kích hoạt hoặc không cho phép ngắt GIE=0, TMR0IE=0
• Gán giá trị prescaler cho Timer 0 PSA =
• Chọn loại kích của nguồn xung bên ngoài T0SE=

 B4: Đọc giá trị về và xử lý xung đếm trong thanh ghi TMR0.

Lưu ý:
 Ví dụ mô phỏng
Lập trình khởi tạo cho timer0 để tạo thời gian trễ
t=[256-0] *1us*16=4096us=4,1ms=0.0041s
fosc= 4MHz
Xác định:
Giá trị ban đầu TMR0=0;
Hệ số chia trước 1:16 (ps2=0; ps1=1; ps0=1)
Khởi tạo giá trị cho Timer0 (hitech-C)
Timer0
;Xóa giá trị đếm cho Timer0
TMR0 incrementing
;Xóa TMR0
0
1 0
1 0
1 0
1 0
1 0 0 0
1 1 1
TMR0=0x00;
INTCON
;Xóa cờ ngắt Timer0 TMR0IF
TMR0IF=0; 0
1
;Thiết lập thanh ghi OPTION_REG ; Flag on overflow TMR0IF
;với xung clock bên trong với bộ
;chia tần 1:16 This interrupt flag will set on
BANKSEL OPTION_REG Timer0 overflow even if
MOVLW b’00000011’ interrupts are disabled
OPTION_REG=0x03 OPTION_REG
;Kiểm tra cờ tràn TMR0IF nếu tràn 0 0 0 0 0 0 1 1
;thì tiếp tục
TOCS PSA
PS<2:0>
while(!TMR0IF) {}
Selects Timer 0 Prescaler
Prescaler
Clock Source Assignment
<continue> (WDT or TMR0)
value = 1:16
(External or Internal)
Ví dụ 1:
Dựa vào sơ đồ viết lưu đồ giải thuật và viết chương
trình tạo sóng xung vuông có tần số 500Hz tại chân
RE1 và 2Hz tại chân RE2 dùng Timer 0 để định thời.
Ta có: Td1 = 1/500Hz = 2ms  tdelayT0 = 1ms
Td2 = 1/2Hz = 500ms = 250 Td1
Sơ đồ giải
thuật: Begin
Đặt chế độ Timer0
Pre=4
Cấu hình các Timer0
PORT digital

Cấu hình các PORT E: TMR0IF


output =1?

PORTE=0 RE1=!RE1
LOOP1

COUNT=250 COUNT- -
LOOP2

TMR0=6 COUNT
=0?

TMRIF=0
RE2=!RE2
Code C: void main()
{
#include <xc.h> ANSEL=0x00;
#define _XTAL_FREQ 4000000 TRISE = 0b001; // E1& E2 la out
PORTE = 0;
unsigned char count; loop:
count=250;
while(count--)
{
TMR0=6;
T0CS=0;
TMR0IF=0;
PSA=0;
PS2=0;
PS1=0;
PS0=1;
while(!TMR0IF){}
RE1=!RE1;
}
RE2=!RE2;
goto loop;
}
Ví dụ 2: Dựa vào sơ đồ viết lưu đồ giải thuật và viết
chương trình điều khiển đếm số lần nhấn nút SW0
được nối với ngõ vào của counter 0 (T0CKI) và hiển
thị giá trị này trên 8 led đơn dùng counter 0.
Sơ đồ giải thuật:
Begin
Đặt chế độ Timer0:
Cấu hình các Mode: Counter
PORT digital Prescaler:1:2
PrescalerWDT
Cấu hình các PORT C:
output
Đọc giá trị từ bộ
đếm & xuất giá trị
Cấu hình chân nối lên LED
RA4: input

Đặt giá trị ban đầu cho


bộ đếm(TMR0=0)

Xóa cờ báo tràn


Timer0
Code Mplabx-XC8

 SV tự viết
Bài tập Timer0

Bài 1: Viết chương trình delay 4ms dùng Timer 0


biết fOSC=4Mhz

Bài 2: Chỉ dùng Timer 0 viết chương trình delay có


thời gian lớn nhất biết fOSC=4Mhz.

Bài 3: Cho sơ đồ giống như ví dụ 2. Viết chương


trình khi nhấn nút SW0 thì số đếm giảm từ 2000
hiển thị trên 8 led đơn.
Chữa bài 1.2,3
Bài kiểm tra21/09/2023 lớp
DHDTMT17ATT
a. Viết chương trình có tên TD_ms() theo yêu cầu sau:
 Biết tdelay=25ms; fosc=8MHz; Phải sử dụng module timer
0 để định thời gian.
b. sử dụng chương trình trên làm chương trình delay, hãy
viết chương trình điều khiển 8 led nối với portC của PIC
16f887 và các nút nhấn sw1 và sw2 và sw3 (theo kết nốicho
trước), thực hiện theo yêu cầu sau:
– Khi nhấn/nhả sw1( nối với RB0) 8 led sáng đuổi từ
MSB  LSB.
– Khi nhấn/nhả sw2( nối với RE0) 8 led sáng dần từ LSB
 MSB.
– Khi nhấn/nhả sw3( nối với RA4) 8 led tắt.
Biết Fosc=8MHz ; thời gian chuyển giữa các trạng thái
là Td = 100ms.
Kiểm tra 20/09/2023

a. Viết chương trình có tên TD_ms() theo yêu cầu


sau:
 Biết tdelay=25ms; fosc=8MHz; Phải sử dụng
module timer 0 để định thời gian.
b. sử dụng chương trình trên làm chương trình
delay, hãy viết chương trình điều khiển 8 led nối
với PORTC thực hiện yêu cầu sau với sw1 và sw2
và sw3 (tự thiết kế mạch):
- Khi nhấn nhả swi.
với td=100ms
 t_delay = 25 ms = 25000 us.
 f_xtal = 8 MHz  t_xung=0.5 us.
 Số lượng xung cần đếm:
n_xung=50000.
 Chọn tỉ lệ chia tần trước presT0 là 8
[với giá trị này, số xung cần đếm sẽ là
50000/8= 6250]
 + Chọn số đếm cho TMR0 là 250
 + Số lần đếm cờ báo tràn (TMR0IF)
nIF = 25
 Thanh ghi OPTION có: PS<2:0>=
010; PSA=0; T0SE=0; T0CS=0;
 TMR0 = 256-250
 TMR0IF=0;
void Delay_25ms (void)
{
OPTION = 0B00000010;
TMR0 = 6;
unsigned char nIF=0;
while (nIF<25)
{
while (TMRIF==0);
TMR0IF=0;
TMR0 = 6;
nIF ++;
}
}
Đặc điểm của Timer 1
 Là Timer/Counter 16 bit gồm 2 thanh ghi
TMR1H và TMR1L có thể đọc và ghi
 Timer1 có thể hoạt động ở chế độ định thời
hay đếm được lựa bởi bit TMR1CS.
 Trong chế độ định thời T1 tăng giá trị ở mỗi
chu kỳ lệnh, chế độ đếm bộ đếm tăng mỗi khi
có cạnh clock ngõ vào bên ngoài
 Có bộ prescale chia tần 3 bit
 Xảy ra hiện tượng ngắt khi tràn từ
FFFFh0000h
 Có khả năng “đánh thức” vi điều khiển từ chế
độ “ngủ” nhờ có thêm bộ dao động bên ngoài.
Sơ đồ khối Timer1
T1OSI
T1
T1OS0 OSC
synchronize
prescaler

Fosc/4

T1CKI
TMR1H TMR1L
pin
Enable

Timer1 Control Register (T1CON) TMR1ON


T1GINV TMR1GE T1CKPS1 T1CKPS0 T1OSCEN T1SYNC TMR1CS TMR1ON

T1CKPS1 T1CKPS0 scale


1 1 1:8 Timer1 On
LP Oscillator Enable 1 = Enable Timer1
1 0 1:4
1 = T1OSC selected Chọn nguồn xung clock
0 1 1:2 0 = T1CKI can be used 1 = External (T1CKI)
0 0 1:1 0 = Internal (FOSC/4)
Sơ đồ khối Timer1
T1OSI
T1
T1OS0 OSC
synchronize
prescaler

Fosc/4

T1CKI TMR1H TMR1L


pin
Enable
Thanh ghi điều khiển (T1CON) TMR1ON

T1GINV TMR1GE T1CKPS1 T1CKPS0 T1OSCEN T1SYNC TMR1CS TMR1ON

Timer1 Gate Enable and Timer1 External Clock Input Synchronization


Timer1 Gate Invert are 1 = do not synchronize external clock input
available on some devices 0 = synchronize external clock input with
internal clock (Fosc/4)
Các bước để định thời gian Timer 1
 B1: Tính toán các giá trị cần đưa vào code:
Đối với dao động nội:

Đối với nguồn xung clock bên ngoài lấy từ bộ dao động Timer1
(thạch anh gắn trên 2 chân T1OS1 và T1OS0)

Trong đó:
tdelay: thời gian cần định thời (us)
fOSC: tần số dao động thạch anh
fOSC(T1): tần số dao động Timer1
Pre:hệ số chia tần trước prescaler(Pre=1,2,4,8)
[TMR1]: giá trị cần ghi vào thanh ghi TMR1

TMR1H: Byte cao của [TMR1]


TMR1L: Byte thấp của [TMR1]
TMR1 =15536D = 3CB0H-> TMR1H =3CH =00111100B ;
TMR1L=B0H = 10110000B;
Các bước để định thời gian Timer 1

 B2: Ghi vào thanh ghi TMR1( gồm TMR1H:TMR1L) được xác định ở
trên
 B3: Xóa cờ báo tràn (cờ ngắt) TMR1IF
 B4: Chọn chế độ hoạt động của Timer1
• Chế độ định thời gian (Timer)
• Kích hoạt hoặc vô hiệu hóa các ngắt
• Chọn giá trị prescale
 B5: Cho phép Timer1 bắt đầu hoạt động
 B6: Xác định thời điểm Timer1 bị tràn bằng cách:
• Kiểm tra cờ TMR1IF( nếu dùng thăm dò)
• Xử lý ISR của Timer 1 (nếu dùng ngắt)
Các bước để đếm sự kiện Counter 1

 B1: Xóa giá trị trong thanh ghiTMR1


 B2: Xóa cờ báo tràn (cờ ngắt) TMR1IF
 B3: Chọn chế độ hoạt động của Counter 1
• Chế độ đếm sự kiện (Counter 1)
• Kích hoạt hoặc vô hiệu hóa các ngắt(tùy chọn)
• Chọn giá trị tỉ lệ của prescale
• Chọn tính năng đồng bộ hoặc không đồng bộ xung
 B4: Cho phép Counter 1 bắt đầu hoạt động
 B5: Đọc về và xử lý số đếm xung đếm được trong thanh ghi
TMR1(TMR1H:TMR1L)
 Ví dụ mô phỏng
Lập trình khởi tạo cho timer1 để tạo thời
gian trễ td=
fosc= 4MHz
Xác định:
Giá trị ban đầu TMR1H= ..;
TMR1L= ..;

Hệ số chia trước 1:8


Thiết lập ngắt Timer1 (C)
TMR1H TMR1L
Main Code
1 0
0
Start 1 01 01 01 01 0 1 0
1 0
1 0
1 0
1 0 1
1 0 0
1 1 0
0 1
;Xóa cờ ngắt Timer1 TMR1IF

TMR1IF=0; PIR1
1
0
;Cho phép ngắt Timer1
TMR1IF
TMR1IE=1; PIE1
1
;Cho phép ngắt toàn cục và ngắt ngoại vi TMR1IE
PEIE=1;
GIE=1; INTCON
1 1
GIE PEIE
Khởi tạo Timer1 (C)
TMR1H
;Xóa thanh ghi TMR1 0 0 0 0 0 0 0 0
TMR1H=0x00;
TMR1L
TMR1L=0x00 0 0OVERFLOW!!
0 0 INCREMENTING
TMR1H:TMR1L 0 0 0 0

;Xóa cờ ngắt TMR1IF trong thanh ghi PIR1

TMR1IF=0; PIR1 (Peripheral Interrupt Request)


;Setup T1CON register for internal clock
;with 1:8 prescaler, Timer1 is stopped
0 0 0 0 0 0 0 01
;and T1 osc is disabled
TMR1IF
T1CON=0xC0;
T1CON (Timer1 Control)
;Bật Timer 1
TMR1ON=1; 0 0 1 1 0 0 0 1
0

;Kiểm tra cờ ngắt Timer 1 Input clock


while(!TMR1IF) {} prescale bits Timer1 TMR1ON
(T1CKPS<1:0>) oscillator Clock source
enable bit select bit
(T1OSCEN) (TMR1CS)
Viết CT Delay_2s sử dụng Timer1
 Tính toán:  Với Timer1:
t_delay = 2s = 2000000 + Chọn tỉ lệ chia tần
us; f_xtal = 8 MHz  trước prescale là 8
t_xung=0.5 us + Chọn dung lượng
Số lượng xung cần đếm Timer1 là 50000
đếm: n_xung=4000000 + Số lần đếm cờ báo tràn
Timer1 là 10
void Delay_2s (void)
{
T1CON=0B00110000;
TMR1H=(65536-50000)/256;
TMR1L=(65536-50000)%256;
unsigned char nIF=0;
TMR1IF=0; TMR1ON=1;
while (nIF <10)
{
TMR1IF=0;
TMR1H=(65536-50000)/256;
TMR1L=(65536-50000)%256;
nIF ++;
}
TMR1ON=0;
}
Ví dụ 3: Dựa vào sơ đồ viết chương trình điều
khiển tạo sóng xung vuông có chu kỳ 100ms tại
chân RE1 và 500ms tại chân RE2
Sơ đồ giải thuật
dùng “thăm dò” : Begin
RE1=!RE1
Cấu hình các
PORT digital,
PORTE: output count - -

Cấu hình các PORT E:


output N count
LOOP =0?
count=5
Y
RE2=!RE2
TMR1IF=0
TMR1=15536

T1CON=b’00000001’

TMR1IF N
=1?
Y
Code Hitech: while(!TMR1IF){}

#include<pic.h> RE1=RE1^1;
unsigned char count; }
void main (void) RE2=!RE2;
{
ADCON1=0x06; }
TRISE=0b001;
PORTE=0; }
while(1)
{
count=5;
while(count--)
{
TMR1IF = 0;
TMR1H =0X3C;
TMR1L = 0XB0;

T1CKPS0 = 0;
T1CKPS1 = 0;
TMR1CS = 0;
TMR1ON = 1;
Dùng ngắt: Code void main (void)
Hitech C:
{
#include<pic.h> ADCON1=0x06;
unsigned char count = 0x00; TRISE=0b001;
void interrupt Timer1_ISR(void) PORTE=0;
{
TMR1IF = 0; TMR1ON = 0;
TMR1L = 0XB0; TMR1H = 0X3C;
TMR1H = 0X3C; TMR1L = 0XB0;
RE1 = RE1 ^ 1;
count++; T1CKPS0 = 0;
if (count == 5) T1CKPS1 = 0;
{ TMR1CS = 0;
RE2 = RE2 ^ 1;
count = 0; TMR1IE = 1;
} TMR1IF = 0;
} PEIE = 1;
GIE = 1;
TMR1ON = 1;
while(1);
}
Ví dụ 4: Dựa vào sơ đồ viết chương trình điều
khiển tạo sóng xung vuông có chu kỳ 2s tại chân
RE1.
Sơ đồ giải thuật Begin
dùng “thăm dò” :

Cấu hình các


PORT digital

Cấu hình PORT E:


output
LOOP
TMR1IF=0
TMR1=0x8000

T1CON=b’00001111’

TMR1IF N
=1?
Y
RE1=!RE1
Code Hitech C:
#include<pic.h> while(!TMR1IF){}
#define _XTAL_FREQ 4000000 PORTE ^= 2;
void main() }
{ }
ADCON1=0x06;
TRISE=0b000;
PORTE=0;
while(1)
{
TMR1IF=0;
TMR1H=0x80;
TMR1L=0x00;

TMR1CS=1;
T1OSCEN=1;
T1SYNC=1;
T1CKPS0=0;
T1CKPS1=0;
TMR1ON=1;
Dùng ngắt: Code Hitech C:
void main()
#include<htc.h> {
….. ADCON1=0x06;
#define _XTAL_FREQ 4000000 TRISE=0b000;
PORTE=0;
void interrupt isr(void)
{ TMR1H=0x80;
if(TMR1IF && TMR1IE) TMR1L=0x00;
{
TMR1IF = 0; TMR1IF=0;
TMR1L = 0; TMR1CS=1;
TMR1H = 0x80; T1OSCEN=1;
PORTE ^= 2; T1SYNC=1;
} T1CKPS0=0;
} T1CKPS1=0;
TMR1ON=1;
TMR1IE=1;
PEIE=1;
GIE=1;
while(1);
}
Bài tập Timer1

Bài 1: Viết chương trình delay 100ms dùng


Timer1 biết fOSC=4Mhz

Bài 2: Chỉ dùng Timer1 viết chương trình


delay có thời gian lớn nhất biết fOSC=4Mhz

Bài 3: Viết chương trình delay 10s dùng


Timer 1 sử dụng bộ dao động bên ngoài gắn
trên 2 chân RC1/T1OSI, RC2/T1OSO có
f =32768 Hz
Đặc điểm của Timer 2
 Là Timer 8 bit có bộ prescale và postscale
 Được sử dụng như bộ tạo xung có PWM
cho chế độ hoạt động PWM của khối CCP
 Thanh ghi TMR2 có thể đọc ghi và xóa khi
bị reset
 Có bộ chia tần số trước prescale với bit
điều khiển T2CKPS1:T2CKPS2
 Ngõ ra TMR2 đi qua bộ postscale 4 bit để
tạo ra yêu cầu ngắt TMR2 được chốt trong
cờ TMR2IF(PIR1<1>)
 Tạo tín hiệu ngắt khi giá trị TMR2 bằng PR2
 Chỉ sử dụng nguồn xung clock bên trong
Sơ đồ khối củaTimer2

TMR2
OUTPUT
TMR2
Prescaler
Fosc/4
1:1, 1:4, 1:16

Postscaler
COMPARATOR 1:1  1:16

PR2

Timer2 Control Register (T2CON)


TOUTPS3 TOUTPS2 TOUTPS1 TOUTPS0 TMR2ON T2CKPS1 T2CKPS0
T2CKPS T2CKPS Scale
1 0
Timer2 ON 0 0 1:1
1 = Timer2 enabled 0 1 1:4
1 X 1:16
TOUTPS3
Sơ đồ khối củaTimer2
TOUTPS2 TOUTPS1 TOUTPS0 SCALE
0 0 0 0 1:1
0 0 0 1 1:2
0 0 1 0 1:3 TMR2
0 0 1 1 1:4 OUTPUT
0 1 0
TMR21:5
0
0 Prescaler
1 0 1 1:6
01:1, 1:4,
1 1:16 1 0 1:7
Fosc/4 0 1 1 1 1:8
1 0 0 0 1:9
Postscaler
1
1
0
0
0
1
1
0
COMPARATOR
1:10
1:11 1:1  1:16
1 0 1 1 1:12
1 1 0 PR2 1:13
0
1 1 0 1 1:14
1 1 1 0 1:15
1 1 1 1 1:16

Timer2 Control Register (T2CON)


TOUTPS3 TOUTPS2 TOUTPS1 TOUTPS0 TMR2ON T2CKPS1 T2CKPS0

T2CKPS1 T2CKPS0 Scale


0 0 1:1 Timer2 ON
0 1 1:4 1 = Timer2 enabled
1 X 1:16
Sơ đồ khối củaTimer2
Start Timer2
Counting TMR2
OUTPUT
TMR2
Prescaler
1 1 1 1 0
1 1
0 0
1 1
0
Fosc/4
1:1, 1:4, 1:16

Postscaler
COMPARATOR 1:1  1:16

PR2
Load Period PIR1
Register 1 1 1 1 1 0 0 0
1
TMR2IF
Timer2 Control Register (T2CON)
TOUTPS3 TOUTPS2 TOUTPS1 TOUTPS0 TMR2ON T2CKPS1 T2CKPS0
Flag set on first
match with
postscaler = 1:1
Khi sử dụng Timer2 cần chú ý:
 Khi mới cấp nguồn thì PR2=0xFF
 Prescaler và Postscaler sẽ bị xóa khi:
• Ghi dữ liệu vào TMR2
• Ghi dữ liệu vào T2CON
• Bất cứ sự kiện reset nào((WDT,POR,BOR)
 Khi reset vi điều khiển thì Prescaler và Postscaler sẽ
bị xóa
 TMR2 bị xóa khi ghi giá trị vào T2CON
 TMR2 sẽ tăng giá trị từ 00h đến khi bằng PR2 sau đó
TMR2 sẽ được reset về 0 vào chu kỳ tăng kế tiếp
 Sự kiện ngắt khi TMR2=PR2 không thể làm “đánh
thức” vi điều khiển khỏi chế độ “ngủ“.
 Timer 2 ít dùng để định thời gian. Nó thường dùng cho
CCP để tạo xung PWM
Các bước để định thời gian Timer 2
B1: Tính toán các giá trị cần đưa vào code:
Đối với dao động nội:

Trong đó:
tdelay: thời gian cần định thời (us)
fOSC: tần số dao động thạch anh(Mhz)
Pre: hệ số chia tần trước Prescaler(Pre=1,4,16)
Post: hệ số chia tần sau Postscaler(Post=1,2,...,16)

[TMR2]: giá trị cần ghi vào thanh ghi TMR2


[PR2]: giá trị cần ghi vào thanh ghi PR2
Các bước để định thời gian Timer 2
B2: Ghi vào thanh ghi PR2 giá trị đã tính toán
B3: Xóa cờ báo tràn (cờ ngắt) TMR2IF
B4: Chọn chế độ hoạt động của Timer 2
 Kích hoạt hoặc vô hiệu hóa các ngắt
 Chọn giá trị Pre
 Chọn giá trị Post
B5: Cho phép Timer 2 bắt đầu hoạt động
B6: Xác định thời điểm Timer 2 bị tràn bằng
cách:
 Kiểm tra cờ TMR2IF (dùng thăm dò)
 Xử lý ISR của Timer 2 (nếu dùng ngắt)
Khởi tạo Timer2 (C) Timer2
Incrementing
TMR2 (Timer2 Counter)
;Disable the Timer2 interrupts in the PIE1
;Cấm ngắt Timer2 trong thanh ghi PIE1 0
1 0
1 0
1 0
1 0
1 0 1 0
1 0 1
;Xóa cờ ngắt TMR2IF trong thanh ghi PIR1
PR2 (Period Register Timer2)
TMR2IE=0;
1 0 0 0 0 0 0 0
TMR2IF=0; PIE1 (Peripheral Interrupt Enable)
;Setup thanh ghi T2CON Postscaler = 1:15,
;Prescaler = 1:16, Timer2 off 0
TMR2IE
T2CON=0x72; PIR1 (Peripheral Interrupt Request)
;Xóa thanh ghi TMR2
1
0
TMR2=0; TMR2IF
;Khởi tạo giá trị PR2 Flag is set
T2CON (Timer2 Control)
PR2=0x80
;Timer2 bắt đầu đếm lên 0 1 1 1 0 0
1 1 0
TMR2ON=1;
TMR2ON
;Kiểm tra cờ ngắt TMR2IF Postscaler = 1:15
while (!TMR2IF) (TOUTPS<3:0>) Prescaler = 1:16
{}
(T2CKPS<1:0>)
Ví dụ 5: Dựa vào sơ đồ viết chương trình điều
khiển tạo sóng xung vuông có tần số 10Hz và
100Hz tại chân RE1 và RE2.
Sơ đồ giải thuật Begin
dùng ngắt : ISR:

Cấu hình các TMR2IF=0


PORT digital

Cấu hình PORT E: RE1=!RE1


output, PORTE=0
count++
TMR2IF=0
PR2=249, count=0
count N
T2CON=b’00100001’ =10?
(Pre=1:4,Post=1:5) Y
count=0
TMR2IE=1
PEIE=1 RE2=!RE2
GIE=1

RETFIE
Dùng ngắt: Code Hitech C:
#include<pic.h> void main (void)
#define _XTAL_FREQ 4000000 {
unsigned char count = 0x00; ADCON1=0x06;
TRISE=0b001;
void interrupt Timer2_ISR(void) PORTE=0;
{
TMR2IF = 0; PR2=249;
TMR2IF=0;
RE1 = RE1 ^ 1; TOUTPS3=0;
count++; TOUTPS2=1;
if (count == 10) TOUTPS1=0;
{ TOUTPS0=0;
RE2 = RE2 ^ 1; T2CKPS1=0;
count = 0; T2CKPS0=1;
}
} TMR2ON = 1;
TMR2IE=1;
PEIE=1;
GIE=1;
while(1);
}
Bài tập Timer2

Bài 1: Viết chương trình delay 1ms dùng


Timer2 biết fOSC=4Mhz

Bài 2: Chỉ dùng Timer2 viết chương trình


delay có thời gian lớn nhất biết fOSC=4Mhz
Bài tập tổng hợp
Bài tập tổng hợp

Bài 1: Viết chương trình delay 1s dùng Timer0, Timer1,


Timer2 biết fOSC=4Mhz

Bài 2: Viết chương trình tạo xung 10Hz trên chân RB7

Bài 3: Viết chương trình tạo xung có tần số 20Hz trên chân
RB0, chu kỳ nhiệm vụ D=40%.

Bài 4: Viết chương trình đếm sự kiện tại chân T0CKI kết
quả được hiển thị số đếm trên 8 led nối với PORT B biết
xung clock tác động từ mức cao xuống thấp.

You might also like