tài liệu đầy đủ và có bài tập mô tả lập trình trên nền MPLAP, liên kết hitech c, c++, ccs,... mô phỏng trên proteus,. có mạch mô phỏng. gồm 5 chương hỗ trợ viết chương trình đơn giản, kèm file rack bên dưới
Trang 1CHƯƠNG CHƯƠNG 5 5
MODUL ðỊNH THỜI
(TIMER)
1 TỔNG QUAN BỘ ĐỊNH THỜI
- Bộ định thời được dùng để định thời gian để kích
hoạt sự kiện, Đếm số lượng sự kiện, tạo xung
- PIC16F887 có 3 bộ định thời:
Timer 0 : bộ định thì 8 bit
Timer 1 : bộ định thì 16 bit
Timer 2 : bộ định thì 8 bit
Trang 2TỔNG QUAN BỘ ĐỊNH THỜI
3
Kích thước
thanh ghi
8 bit (TMR0)
16 bit (TMR1H:TMR1L)
8-bit (TMR2) Nguồn xung
Nguồn xung
(Bên ngoài) Chân T0CKI
Chân T1CKI hoặc
bộ dao ñộng Timer 1 (T1OSC)
Không có
Tỉ lệ xung
clock khả
dụng
(ðộ phân giải)
Prescaler 8 bit (1:2 →→1:256)
Prescaler 3 bit (1:1, 1:2, 1:4, 1:8)
Prescaler (1:1, 1:4, 1:8) Postscaler (1:1 →→1:16)
Sự kiện ngắt
và vị trí cờ
ngắt
Khi bị tràn FFh →→00h (TMR0IF của INTCON)
Khi bị tràn FFFFh →→0000h (TMR1IF của PIR1)
TMR2 bằng với PR2 (TMR2IF của PIR2)
Có thể “ñánh
thức" PIC từ
chế ñộ “ngủ”
2 Module 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ừ FFh00h
Trang 3SƠ ĐỒ KHỐI TIMER 0
5
TMR0
T0CKI pin
Fosc/4
Prescaler Watchdog Timer
ðồng bộ
WDT out
OPTION register
RBPU INTEDG T0CS T0SE PSA PS2 PS1 PS0
Chọn nguồn xung clock cho Timer 0
8
DATA BUS
Clock 1
0
SƠ ĐỒ KHỐI TIMER 0
6
TMR0
T0CKI pin
Fosc/4
Prescaler Watchdog Timer
ðồng bộ
WDT out
OPTION register
RBPU INTEDG T0CS T0SE PSA PS2 PS1 PS0
Chọn cạnh kích của nguồn xung ngoài
1 = Tăng TMR0 tại cạnh lên (L →H)
0 = Tăng TMR0 tại cạnh xuống (H →L)
8
DATA BUS
Clock
Trang 4SƠ ĐỒ KHỐI TIMER 0
7
TMR0
T0CKI pin
Fosc/4
Prescaler Watchdog Timer
ðồng bộ
WDT out
OPTION register
RBPU INTEDG T0CS T0SE PSA PS2 PS1 PS0
Chỉ ñịnh Prescaler
1 = Prescaler dùng cho WDT
0 = Prescaler dùng cho Timer 0
8
DATA BUS
Clock
1
0
0
1
SƠ ĐỒ KHỐI TIMER 0
8
T0CKI pin
Fosc/4
Prescaler Watchdog Timer
ðồng bộ
WDT out
OPTION register
RBPU INTEDG T0CS T0SE PSA PS2 PS1 PS0
Các bit chọn tỉ lệ cho Prescaler
PS2 PS1 PS0
Tỉ lệ chia
8
DATA BUS
Clock
Trang 5SƠ ĐỒ KHỐI TIMER 0
9
TMR0
T0CKI pin
Fosc/4
Prescaler Watchdog Timer
ðồng bộ
WDT out
8
DATA BUS
Nếu nguồn xung clock cấp cho Timer 0 ñược lấy từ
chân T0CKI thì nó sẽ ñược ñồng bộ hóa với nguồn
xung clock bên trong
SƠ ĐỒ KHỐI TIMER 0
10
TMR0
T0CKI pin
Fosc/4
Prescaler Watchdog Timer
ðồng bộ
WDT out
8
DATA BUS
T0IF
TMR0 có thể đọc hoặc ghi
T0IF trong INTCON sẽ được đặt (T0IF = 1) khi Timer 0 bị
tràn (TMR0 = FFh → 00h).
INTCON register
Trang 6SƠ ĐỒ KHỐI TIMER 0
11
B1: Tính toán các giá trị cần đưa vào code:
delay
OSC
1
f
tdelay: thời gian cần định thời (us)
fOSC: tần số dao động thạch anh
Pre:hệ số chia tần trước prescaler(Pre=1,2,4 ,256
[TMR0]: giá trị cần ghi vào thanh ghi TMR0
0 [TMR0]≤ ≤255
B3: Xóa cờ báo tràn( cờ ngắt) TMR0IF
B2: Ghi vào thanh ghi TMR0 giá trị đã tính toán
B4: Chọn chế độ hoạt động của Timer 0 (chọn chế độ Timer, gán
prescaler )
B5: Xác định thời điểm Timer 0 bị tràn bằng cách:
• 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)
2.1 Dùng timer0 để định thời
Trang 7• BƯỚC 1: Xóa giá trị trong thanh ghi TMR0
(hoặc đặt giá trị ban đầu của bộ đếm)
• BƯỚC 2: Xóa cờ báo tràn (cờ ngắt) TMR0IF
• BƯỚC 3: Chọn chế độ hoạt động của Counter 0
- Chế độ đếm sự kiện (Counter)
- Kích hoạt hoặc vô hiệu hóa ngắt (tùy chọn)
- Gán Prescaler cho Timer và chọn giá trị tỉ lệ của Prescaler (tùy
chọn)
- Chọn loại cạnh kích của nguồn xung đếm bên ngoài
• BƯỚC 4: Đọc về và xử lý số xung đếm được trong thanh ghi TMR0
Dựa vào cờ báo tràn TMR0IF để xử lý các trường hợp số xung đếm
vượt quá 255
13
2.2 Dùng timer 0 để đếm sự kiện
Giải:
Tính các giá trị thanh ghi
࢚ࡰࡱࡸࢅ= − ࢀࡹࡾ × ×
ࢌࡻࡿ× ࡼ࢘ࢋ
Ta có:
tdelay= 100us, pre = 2, fosc = 4MHz TMR0 = 206
14
VÍ DỤ 1 : Viết chương trình con tạo trễ tdelay=100μs dùng
Timer 0, fOSC =4MHZ, chọn prescaler =2.
Trang 8VÍ DỤ 1 : Viết chương trình con tạo trễ tdelay=100μs dùng
Timer 0, fOSC =4MHZ, chọn prescaler =2.
Void DELAY100us(void)
{
TMR0 = 206; //Bước 1:giá trị cần ghi vào thanh ghi TMR0
TMR0IF = 0; // Bước 2: Xóa cờ báo tràn
T0CS = 0; // Chế độ định thời
TMR0IE = 0;PEIE = 0;GIE = 0; //cấm ngắt
PSA = 0; PS2 = 0; PS1 = 0; PS0 = 0; // chọn prescaler =2
While(TMR0IF==0); // Kiểm tra cờ TMR0IF
}
Ví dụ 2: lập trình 3 led chớp tắt với f = 1Hz, dùng timer0 để tạo delay
Trang 9Led chớp tắt với f = 1Hz chọn Ton = Toff = 500ms = 500 000us
- Tạo delay 100us (như VD1):
Tính các giá trị thanh ghi
࢚ ࡰࡱࡸࢅ = − ࢀࡹࡾ × ×
ࢌࡻࡿ× ࡼ࢘ࢋ
Ta có:
tdelay= 100us, pre = 2, fosc = 4MHz TMR0 = 206
- Cho lặp 5000 lần delay500ms = 100x5000 = 500 000us
17
Ví dụ 2: lập trình 3 led chớp tắt với f = 1Hz, dùng timer0 để tạo delay
#include <htc.h>
#include <math.h>
CONFIG (FOSC_HS & WDTE_OFF & PWRTE_ON & MCLRE_ON & CP_OFF & CPD_OFF &
BOREN_OFF & IESO_OFF & FCMEN_OFF & LVP_OFF & DEBUG_ON);
#define _XTAL_FREQ 4000000
void delay100us(unsigned int n)
{
unsigned int i;
for (i=1;i<=n;i++)
{
TMR0 = 206;
TMR0IF = 0;
T0CS = 0;
TMR0IE = 0;PEIE = 0;GIE = 0;
// chon prescaler =2
PSA = 0; PS2 = 0; PS1 = 0; PS0 = 0;
while(TMR0IF==0);
}
}
void main()
{
ANSEL = 0X00;
ANSELH = 0X00;
TRISE = 0X00;
while(1) { PORTE = 0X00;
delay100us(5000); //delay500ms PORTE = 0X07;
delay100us(5000);
} }
Trang 10Ví dụ 3: viết chương trình đếm số lần nhấn–nhả nút SW7
(0 → 255) và hiển thị giá trị này trên 8 LED đơn SW0 được nối
với ngõ vào của Counter 0 (T0CKI)
19
#include <htc.h>
#include <math.h>
CONFIG (FOSC_HS & WDTE_OFF & PWRTE_ON & MCLRE_ON & CP_OFF & CPD_OFF &
BOREN_OFF & IESO_OFF & FCMEN_OFF & LVP_OFF & DEBUG_ON);
#define _XTAL_FREQ 4000000
void main (void)
{
ANSEL = 0;
ANSELH = 0;
TRISD = 0X00;
TRISA4 = 1;
TMR0 = 0;
TMR0IF = 0;
T0CS = 1; // che do counter T0SE = 0;
PSA = 1;
PS2 = 0;
PS1 = 0;
PS0 = 0;
while(1)
{ PORTD = TMR0;
} }
Trang 113 Module 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ừ FFFFh0000h
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 TIMER 1
22
T1CKI
T1 OSC T1OSO
T1OSI
Timer1 Control Register (T1CON)
Cho phép bộ dao ñộng LP
1 = Chọn T1OSC
F OSC /4
T1CKPS1 T1CKPS0 Tỉ lệ
Kích hoạt Timer 1
1 = Cho phép Timer 1
0 = Cấm Timer 1
T1GINV TMR1GE T1CKPS1 T1CKPS0 T1OSCEN T1SYNC TMR1CS TMR1ON
Cho phép TMR1ON
Chọn nguồn xung clock
1 = Bên ngoài (cạnh lên tại T1CKI)
0 = Bên trong (F OSC /4)
Trang 12TMR1GE T1GINV
SƠ ĐỒ KHỐI TIMER 1
23
T1CKI
T1 OSC T1OSO
T1OSI
Timer1 Control Register (T1CON)
F OSC /4
T1GINV TMR1GE T1CKPS1 T1CKPS0 T1OSCEN T1SYNC TMR1CS TMR1ON
Cho phép
TMR1ON T1G
ðảo mức kích cổng Timer 1
1 = Timer 1 ñếm khi cổng có mức CAO
0 = Timer 1 ñếm khi cổng có mức THẤP
Cho phép kích cổng Timer 1
1 = Timer 1 bật nếu cổng kích hoạt
0 = Timer 1 luôn luôn ñếm (cấm kích cổng)
Ngõ ra
COMPARATOR 2
Nếu TMR1ON = 0 thì
bỏ qua bit TMR1GE
ðược xác ñịnh bởi
T1GSS trong thanh
ghi CM2CON1
ðồng bộ xung clock bên ngoài Timer 1 với xung clock bên trong (F OSC /4)
1 = Không ñồng bộ
0 = ðồng bộ
SƠ ĐỒ KHỐI TIMER 1
24
Trang 13• Bộ dao động của Timer 1:
• Được kết nối thông qua chân RC0 và RC1
• Mạch điện bổ sung (xem hình) được thiết kế chủ yếu cho các hoạt
động ở tần số thấp
• Không phụ thuộc vào xung clock bên trong nên có thể hoạt động
ngay cả trong chế độ "ngủ"
• Sau khi được kích hoạt thì người sử dụng phải chờ khoảng vài ms để
bộ
dao động hoạt động ổn định
25
OSCILLATOR FREQUENCY C1 C2
LP
32 kHz 33 pF 33 pF
100 kHz 15 pF 15 pF
200 kHz 15 pF 15 pF
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 T1OSI và T1OSO)
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]
delay
OSC
1
f
delay
OSC(T1)
1
f
0≤[TMR1]≤65536
3.1 Dùng timer 1 để định thời
Trang 14B2: 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)
3.1 Dùng timer 1 để định thời
• BƯỚC 1: Xóa giá trị trong thanh ghi TMR1 (hoặc đặt giá trị ban đầu
của bộ đếm)
• BƯỚC 2: Xóa cờ báo tràn (cờ ngắt) TMR1IF
• BƯỚC 3: Chọn chế độ hoạt động của Counter 1
oChế độ đếm sự kiện (Counter)
oKích hoạt hoặc vô hiệu hóa ngắt (tùy chọn)
oChọn giá trị tỉ lệ của Prescaler
oChọn tính năng đồng bộ hoặc không đồng bộ xung
• BƯỚC 4: Cho phép Counter 1 bắt đầu hoạt động
• BƯỚC 5: Đọc về và xử lý số xung đếm được trong thanh ghi TMR1
(TMR1H:TMR1L)
Dựa vào cờ báo tràn TMR1IF để xử lý các trường hợp số xung đếm
vượt quá 65535
28
3.2 Dùng timer 1 để đếm
Trang 15Ví dụ 1: Dựa vào sơ đồ, viết chương trình tạo sóng vuông có
f=10Hz tại chân RE0 Sử dụng modul Timer 1, với fosc= 4MHz.
29
Tính giá trị thanh ghi
Tạo xung có f = 10Hz T = 0,1s =100mschọn Ton=Toff=50ms
Dùng timer1 tạo delay 50ms
Ta có fosc= 4MHz, chọn Pre =4, tdelay= 50ms=50000us
TMR1 = 53036
TMR1H = TMR1/256 = 207 (thương)
TMR1L = TMR1%256 = 44 (dư)
30
delay
OSC
1
f
Trang 16#include <htc.h>
#include <math.h>
CONFIG (FOSC_HS & WDTE_OFF & PWRTE_ON & MCLRE_ON & CP_OFF & CPD_OFF &
BOREN_OFF & IESO_OFF & FCMEN_OFF & LVP_OFF & DEBUG_ON);
#define _XTAL_FREQ 4000000
void main (void)
{
ANSEL = 0;
ANSELH = 0;
TRISE = 0X00;
PORTE = 0X00;
while (1)
{
RE0 = 1;
delay_50ms();
RE0 = 0;
delay_50ms();
}
}
void delay_50ms(void) {
TMR1H = 207;
TMR1L = 44;
TMR1IF = 0;
TMR1CS = 0; //xung ck ben trong GIE = PEIE = TMR0IE = 0; cam ngat T1CKPS1 = 1; T1CKPS0 = 0; //pre= 4 T1SYNC = 0;
TMR1ON = 1;
while (TMR1IF == 0);
}
4 module 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
Trang 17Sơ đồ khối củaTimer2
Prescaler
1:1, 1:4, 1:16
COMPARATOR
TOUTPS3 TOUTPS2 TOUTPS1 TOUTPS0 TMR2ON T2CKPS1 T2CKPS0
Postscaler 1:1 1:16
Fosc/4
Timer2 ON
1 = Timer2 enabled
T2CKPS1 T2CKPS2 Scale
TMR2
TMR2 OUTPUT
PR2
Timer2 Control Register (T2CON)
Sơ đồ khối củaTimer2
Prescaler
1:1, 1:4, 1:16
COMPARATOR
TOUTPS3 TOUTPS2 TOUTPS1 TOUTPS0 TMR2ON T2CKPS1 T2CKPS0
Postscaler 1:1 1:16
Fosc/4
Timer2 ON
1 = Timer2 enabled
T2CKPS1 T2CKPS0 Scale
TMR2
TMR2 OUTPUT
PR2
TOUTPS3 TOUTPS2 TOUTPS1 TOUTPS0 SCALE
1 0 0 1 1:10
1 0 1 0 1:11
1 0 1 1 1:12
1 1 0 0 1:13
1 1 0 1 1:14
1 1 1 0 1:15
1 1 1 1 1:16
Timer2 Control Register (T2CON)
Trang 181:1, 1:4, 1:16
COMPARATOR
TOUTPS3 TOUTPS2 TOUTPS1 TOUTPS0 TMR2ON T2CKPS1 T2CKPS0
Postscaler 1:1 1:16
Fosc/4
TMR2 OUTPUT
1 1 1 1 0 1 1 0
1 PIR1
TMR2IF Timer2 Control Register (T2CON)
TMR2
PR2
Sơ đồ khối củaTimer2
Load Period
Register
Start Timer2 Counting
Flag set on first match with postscaler = 1:1
1 1 1 1 1 0 0 0
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
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
delay
OSC
1
f
=
0 [PR2],[TMR2]≤ ≤255
Các bước để định thời gian Timer thời gian Timer 2 2
Trang 19B4: 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)
Các bước để định thời gian Timer 2 thời gian Timer 2