Professional Documents
Culture Documents
Xung nhịp được đưa vào bộ đếm TMR0 thông qua các công tắc chọn lựa chuyển mạch số
T0CS_bit, PSA_bit, PS<2:0>, T0SE. Tùy theo yêu cầu định thời và độ chính xác định thời mà
có các lập trìn phù hợp
4.2.2. Các bit và thanh ghi liên quan đến TIMER0
Các bit chuyển mạch sử dụng trong Timer0 gồm:
- T0SE_bit (Timer0 Select Edge): bit chọn cạnh tác động lên khi bằng 0 và tác động cạnh
xuống khi bằng 1, bit này chỉ có tác dụng khi chọn nguồn xung nhịp bên ngoài
- T0CS_bit (Timer0 Clock Source): bit chọn nguồn xung nhịp từ dao dộng cơ bản Fosc/4
nếu bằng 0 hay xung nhịp bên ngoài nếu bằng 1
- PSA_bit (Prescaler Assignment): bit cho phép truy cập bộ chia trước nếu bằng 0 và ngược
lại
- PS<2:0> (Prescaler Rate Select): 3 bit này để chọn lựa bộ chia trước theo bảng.
4.2.3. Hoạt động định thời và bộ chia trước
Trường hợp chọn bộ chia trước khi thời gian định thời có số lần đếm vượt quá 255. Nếu
chọn bộ chia trước, khoảng cách giữa 2 lần đếm của Timer sẽ tăng lên tỉ lệ với bộ chia nên độ
chính xác định thời trên 1 lần đếm sẽ giảm tương ứng.
Như đã nêu ở phần định nghĩa, hoạt động định thời thực chất là hoạt động đếm số xung nhịp
nhận được dùng bộ đếm (counter) kết hợp khoảng thời gian giữa 2 lần đếm liên tiếp đã biết
trước
Do là hoạt động định thời nên chỉ cần chọn xung nhịp bên trong là đủ
Gọi thời gian giữa 2 lần đếm liên tiếp (chu kỳ đếm) là Tc, số lần đếm của Timer là N thì
thời gian trì hoãn do Timer tạo ra là T = NxTc
Ví dụ 1: Muốn tạo thời gian trì hoãn 22000ns thì tính như sau:
Tc = 1/(Fosc/4) = 200ns với thạch anh 20MHz
N = T/Tc = 22000/200 = 110 lần đếm
Ví dụ 2: Muốn tạo thời gian trì hoãn 220000ns thì tính như sau:
Tc = 1/(Fosc/4) = 200ns với thạch anh 20MHz
N = T/Tc = 220000/200 = 1100 lần đếm
Số lần đếm tính được vượt quá 255 nên 1100 không thể chứa được trong thanh ghi 8 bit. Để
định thời được phải sử dụng bộ chia trước (prescale)
Gọi tỉ lệ chia trước là p. Chọn p sao cho p là nhỏ nhất (theo bảng và thỏa TMR0 <=255
p = N/256 = 1100/256 = 4.3
Chọn p = 8, lúc này chu kỳ đếm Tc = p x Tc = 8 x 200ns = 1600ns
Tính lại N = T/Tc = 220000/1600 = 137.5 làm tròn xuống 137
Tại sao không chọn p = 4 gần với giá trị trong bảng hơn? Thử tính lại N với p = 4
Tc = p x Tc = 800ns
N = T/Tc = 220000/800 = 275 > 255
Kết quả N vẫn không thể chứa trong TMR0. Do đó chọn giá trị gần nhất lớn hơn
Còn N = 137.5 làm tròn xuống còn 137. Trong hệ thống số ngoài thời gian định thời còn có
thời gian để thực thi các lệnh, thời gian nảy từ chương trình chính sang chương trình ngắt. Nếu
làm tròn 138 cộng với thời gian thực thi lệnh
Tổng thời gian trì hoãn sẽ là: 138xTc + T(lệnh) = 220800 + T(lệnh)
Sai số sẽ là: [220800 + T(lệnh)] – 220000 = 800ns + T(lệnh) > 800ns
Còn nếu lấy 137 cộng với thời gian thực thi lệnh, tổng thời gian trì hoãn sẽ là 137xTc +
T(lệnh) = 219200 + T(lệnh)
Sai số sẽ là: 220000 - [219200 + T(lệnh)] = 800ns - T(lệnh) < 800ns
4.2.4. Hoạt động đếm của TIMER0
Ngoài chức năng định thời, Timer0 còn được thiết kế để tạo bộ đếm xung từ bên ngoài. Nếu
xung từ bên ngoài có chu kỳ không đổi thì cũng có thể lập trình được chức năng định thời. Tuy
nhiên thông thường xung từ bên ngoài dùng để đếm số lần có tác động cạnh lên hoặc xuống
(tùy theo T0SE_bit)
Chức năng đếm lập trình sẽ đơn giản hơn định thời. Lập trình đưa trực tiếp xung bên ngoài
vào TMR0 mà không qua bộ chia trước. Đọc giá trị TMR0 sẽ biết được có bao nhiêu cạnh từ
bên ngoài đưa vào
4.2.5. Ngắt TIMER0
Do bộ đinh thời hoạt động độc lập với CPU nên cần 1 báo hiệu để phát hiện bộ định thời đã
đủ thời gian định thời. Báo hiệu đó là ngắt
Ngắt Timer0 chỉ xảy ra khi TMR0 bằng 255 và trở về 0 hay còn gọi là ngắt tràn Timer0.
Khi ngắt cờ ngắt T0IF_bit tự động được set, nếu có cho phép ngắt tương ứng CPU sẽ trỏ đến
địa chỉ chương trình ngắt và thực hiện chương trình ngắt (xem lại phần ngắt và ngắt ngoài)
Quay lại ví dụ 1 ở trên, làm sao để biết được bộ định thời đã đếm được 110 lần đếm nếu
dùng hỏi vòng là không thể chính xác do chương trình hỏi vòng còn thực hiện các nhiệm vụ
khác nữa. Do đó ngắt là cách để nhận biết bộ định thời đã hoạt động xong
Ngắt Timer0 chỉ khi TMR0 từ 255 về 0 nên cần phải nạp giá trị ban đầu cho TMR0 sao cho
sau số lần đếm 110 lần thì xảy ra ngắt, TMR0 được nạp là TMR0 = 256 – số lần đếm = 256 -
110
Cấu hình ngắt định thời Timer0:
- Cho phép ngắt toàn cục
- Cài đặt các bit chuyển mạch T0CS_bit, PSA_bit, PS<2:0>, T0SE
- Nạp giá trị TMR0 ban đầu
- Xóa cờ ngắt T0IF_bit và cho phép ngắt Timer0 bằng cách set T0IE_bit
Chương trình ngắt:
- Kiểm tra cờ ngắt để xác định loại ngắt
- Xóa cờ ngắt
- Nạp lại giá trị TMR0 ban đầu nếu tiếp tục thực hiện định thời mới. Nếu không tiếp tục
định thời, ta có thể vô hiệu hóa cho phép ngắt Timer0
- Thực hiện nội dung ngắt
Ví dụ 3: Cấu hình ngắt và chương trình ngắt Timer0
void interrupt() iv 0x04 {
if ((T0IF_bit==1)&&( T0IE_bit==1)){
T0IF_bit=0; // Xóa cờ ngắt
TMR0=155; // nạp lại TMR0
RE0_bit=!RE0_bit;// thực hiện nội dung ngắt
}
}
void main() {
GIE_bit=1;
T0CS_bit=0
PSA_bit=1
PS2_bit=0;PS1_bit=0;PS0_bit=0;
TMR0=155;
T0IF_bit=0;T0IE_bit=1;
while(1){}
}
4.3. Bộ định thời, bộ đếm TIMER1
4.3.1. Cấu trúc và hoạt động của TIMER1
Timer 1 là bộ định thời/bộ đếm 16 bit, kết quả của bộ đếm 16 bit được lưu trong 2 thanh ghi
8 bit là TMR1H và TMR1L
Vì TMR1L và TMR1H là thanh ghi 8 bit nên khi TMR1L đếm đến 255 nếu có thêm 1 xung
nhịp thì sẽ về 0, đồng thời TMR1H sẽ tăng thêm 1 đơn vị. Tương tự khi TMR1H đếm đến 255
mà có thêm một lần TMR1L từ 255 về 0 thì TMR1H sẽ về 0
Khi cả 2 thanh ghi TMR1L và TMR1H từ 255 về 0 thì sẽ xảy ra ngắt tràn Timer1
Tóm lại: xem 2 thanh ghi TMR1H và TMR1L ghép lại như một thanh ghi 16 bit và được
đếm đến 255 * 256 + 255 = 65535 và trở về 0 thì sẽ xảy ra ngắt tràn Timer1
Xung nhịp được đưa trực tiếp vào bộ chia trước, sau đó vào TMR2. Giá trị TMR2 được so
sánh với PR2 (đã đặt trước), nếu TMR2 đếm đến bằng PR2 thì sẽ tự động xóa TMR2 và xuất
ngõ ra TMR2 (dùng cho chức năng PWM). Bộ chia sau postscaler sẽ quyết định số lần TMR2
bị xóa để xảy ngắt (Timer2 ngắt là ngắt so sánh chứ không phải là ngắt tràn như Timer0 và
Timer1)
Timer1 ngoài chức năng định thời còn hổ trợ chức năng PWM, CCP, Capture trên 2 chân
CCP1 và CCP2. Timer2 sẽ được quay lại phân tích kỹ hơn ở phần PWM.
4.4.2. Các bit và thanh ghi liên quan đến TIMER2
- T2CKPS<1:0> (Timer2 Clock Prescale Select): bit tạo bộ chia trước