Người báo cáo: 

Nguyễn Trung Chính 

Tài liệu: 

TUT03.02 

Ngày: 

3/6/2006 

Trang: 

1/14 

Tutorial 03.02 
 

Gửi đến: 

picvietnam@googlegroups.com 

Nội dung: 

Bài 3: KĨ THUẬT BẢNG 

 

MICROSOFT WORD

 
Tóm tắt: 
Tutorial post lên picvietnam, topic “PIC16F877A TỪ DỄ TỚI KHÓ” thuộc luồng “CƠ BẢN VỀ 
VI ĐIỀU KHIỂN VÀ PIC” với nội dung: 
‐  Phân tích giải thuật kĩ thuật bảng và một số ứng dụng hiển thị với LED.  
 

1.

Đặt vấn đề 

Trước khi phân tích giải thuật của kĩ thuật bảng ta thực hiện một ứng dụng nhỏ, coi như 
vừa ôn lại bài cũ, vừa dặt ra các vấn đề cho bài mới. Ứng dụng này sử dụng mạch nguyên lí đã 
được xây dựng ở bài 1.  
Ứng dụng 1: Cho một LED chạy từ trái sang phải sau mỗi khoảng thời gian delay 100 ms. 
Ta đã xây dựng một mạch ứng dụng bao gồm các LED được gắn vào PORTB của vi điều 
khiển PIC thông qua các điện trở, và muốn LED nào sáng, cần xuất giá trị logic 1 ra chân 
tương ứng của PORTB. Để thuận tiện cho việc theo dõi, sơ đồ mạch sẽ đươc đưa lại trong hình 
dưới đây.  
HI

R2

D1

R3

D2

R4

D3

R5

D4

R6

D5

R7

D6

R8

D7

R9

D8

R1

2

2
3
4
5
6
7

1

SW1

0

8
9
10
11
12

HI

C1

0

13
14

30 pF
C2

0

4 MHz

15
16
17
18

30 pF
19
20

MCLR/VPP
RA0/AN0
RA1/AN1
RA2/AN2/VREF-/CVREF
RA3/AN3/VREF+
RA4/TOCKI/C1OUT
RA5/AN4/SS/C2OUT
RE0/RD/AN5
RE1/WR/AN6
RE2/CS/AN7
VDD
GND

PIC16F877A

OSC1/CLKIN
OSC2/CLKOUT
RC0/T1OSO/T1CKI
RC1/T1OSI/CCP2
RC2/CCP1
RC3/SCK/SCL

RB7/PGD
RB6/PGC
RB5
RB4
RB3/PGM
RB2
RB1
RBO/INT
VDD
GND
RD7/PSP7
RD6/PSP6
RD5/PSP5
RD4/PSP4

RC7/RX/DT
RC6/TX/CK
RC5/SDO
RC4/SDI/SDA
RD3/PSP3
RD2/PSP2

40
39
38
37
36
35
34
33
32
31
30
29
28
27

HI

1

0

26
25
24
23
22
21

RD0/PSP0
RD1/PSP1

0

Hình 1: Sơ đồ nguyên lí mạch ứng dụng. 

Người báo cáo: 

Nguyễn Trung Chính 

Tài liệu: 

TUT03.02 

Ngày: 

3/6/2006 

Trang: 

2/14 

Ta đã biết được cách thiết lập giá trị cho các chân I/O của vi điều khiển (bài 1), cách viết 
chương trình delay (bài 2), và muốn các LED dịch từ trái sang phải, ta sử dụng một trong hai 
lệnh sau: 
Lệnh RLF 
Cú pháp:  RLF  thanh_ghi,noi_den 
Tác dụng: dịch trái các bit trong thanh ghi “thanh_ghi” thông qua cờ carry C 
(thanh ghi chức năng STATUS). Kết quả sau khi dịch được lưu vào thanh ghi 
”thanh_ghi”nếu tham số “noi_den” mang gia trị 1 hoặc thanh ghi W nếu tham 
số “noi_den” mang giá trị 0. Có thể hình dung cách dịch của lệnh này theo 
hình dưới. 
 
Lệnh RRF 
 

Cú pháp:  RRF  thanh_ghi,noi_den 

Tác dụng: dịch phải các bit trong thanh ghi “thanh_ghi” thông qua cờ carry 
C (thanh ghi chức năng STATUS). Kết quả sau khi dịch được lưu vào thanh ghi 
”thanh_ghi”nếu tham số “noi_den” mang gia trị 1 hoặc thanh ghi W nếu tham 
số “noi_den” mang giá trị 0. Có thể hình dung cách dịch của lệnh này theo 
hình dưới. 
 
 
Đến đây xem như ta đã có đầy đủ các thông tin để  viết chương trình. Giải thuật cũng 
khá đơn giản, các bước tiến hành lần lượt như sau: 
‐  Đưa vào thanh ghi PORTB giá trị 10000000b (cho LED đầu tiên sáng). 
‐  Dịch phải giá trị trong thanh ghi PORTB (LED sáng cũng được dịch tương ứng). 
‐  Delay 100 ms. 
‐  Lặp lại bước 2. 
Và đây, chương trình của ứng dụng: 
Chương trình 3.1: 
;============================================================================= 
; WWW.PICVIETNAM.COM 
; Lap trinh: 

 

 

; Ngay bat dau:               

NGUYEN TRUNG CHINH 
23 thang 01 nam 2006 

Người báo cáo: 

Nguyễn Trung Chính 

Tài liệu: 

TUT03.02 

Ngày: 

3/6/2006 

Trang: 

3/14 

; Ngay hoan thanh:           

23 thang 01 nam 2006 

; Kiem tra chuong trinh:      

picvietnam@googlegroups.com 

; Ngay kiem tra:   

 

; Su dung vi dieu khien Microchip:  PIC16F877A 
title 

 

“chuongtrinh3‐1.asm” 

processor 

16f877a 

 

include 

<p16f877a.inc> 

 

 

 

__CONFIG  _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON &  _XT_OSC & 
_WRT_OFF & _LVP_OFF & _CPD_OFF 
; Cap nhat va bo sung: 
; Mo ta chuong trinh:   Chuong trinh dung de dieu khien một LED sang dịch sang phai sau  

 

 

 

moi khoang thoi gian 100 ms. 

 

 

 

 

; Mo ta phan cung: 

8 LED duoc gan vao PORTB thong qua cac dien tro, cac  

thanh phan di kem bao gom thach anh, mach reset va nguon 

 

 

 

;================================================================================  
;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
; Khoi tao cac bien 
;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
count1 

EQU  0x20   

; cac bien dung cho doan chuong trinh delay 

counta 

EQU  0x21   

 

countb 

EQU  0x22   

 

 

;============================================================================= 
; CHƯƠNG TRÌNH CHÍNH 
;============================================================================= 
ORG   

0x000   

GOTO  

start 

start 

 

 

 

 

 

 

; chương trình chính bắt đầu tại đây 

;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
; Khởi tạo PORT B 
;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 

Người báo cáo: 

Nguyễn Trung Chính 

Tài liệu: 

TUT03.02 

Ngày: 

3/6/2006 

Trang: 

4/14 

BCF     

STATUS,RP1 

BSF 

STATUS,RP0  

; chọn BANK1 

CLRF   

TRISB  

; PORT B <‐ outputs 

BCF   

STATUS,RP0  

; chọn BANK0 

MOVLW 

b’10000000’   

; bật LED đầu tiên sáng lên 

MOVWF 

PORTB 

; PORTB <‐ b‘10000000’ 

 

 

 

 

;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 

 

; Vòng lặp chính của chương trình 

 

;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
loop 

 

CALL  

delay100ms   

; gọi chương trình con delay100ms 

RRF   

PORTB,1 

; dịch phải thanh ghi PORTB 

 

; kết quả sau khi dịch lưu vào thanh ghi PORTB 
GOTO  

loop   

 

; vòng lặp vô hạn 

;================================================================================ 
; CHƯƠNG TRÌNH CON 
;================================================================================ 
delay100ms 

 

 

MOVLW 

d’100’ 

MOVWF 

count1 

d1   
MOVLW 

0xC7 

MOVWF 

counta 

MOVLW 

0x01 

MOVWF 

countb 

delay_0   

 

DECFSZ 

counta,1 

GOTO  

$+2 

DECFSZ 

countb,1 

GOTO  

delay_0 

 

 

; chương trình con delay 100 ms 

Người báo cáo: 

Nguyễn Trung Chính 

Tài liệu: 

TUT03.02 

Ngày: 

3/6/2006 

Trang: 

5/14 

DECFSZ 

count1,1 

GOTO  

d1 

 

 

 

RETURN 

 

 

 

; trở về chương trình chính 

END   

 

 

 

; kết thúc chương trình 

;================================================================================ 
Xong! Đến đây ta có thể cảm nhận được rằng dường như việc phát triển các ứng dụng 
đã trở nên dễ dàng hơn trước. Tương tự ta có thể điều khiển các LED dịch từ phải sang trái 
(thay lệnh RRF bằng lênh RLF).  
Bây giờ, giả sử yêu cầu của ứng dụng không phải là dịch trái hay dịch phải, mà là dịch 
theo một qui luật phức tạp nào đó hoặc chẳng cần qui luật dịch nào cả. Rõ ràng các lệnh 
RLF hay RRF không đủ khả năng giải quyết được vấn đề, hoặc nếu có thì giải thuật cho 
chương trình sẽ rất phức tạp vì phải tìm ra qui luật dịch LED mà yêu cầu đặt ra. Tuy nhiên 
mọi khó khăn dường như đều có cách giải quyết riêng của nó, và tập lệnh của PIC cung 
cấp cho ta một công cụ để giải quyết khó khăn trên: lệnh RETLW. Có thể  cho rằng đây là 
một lệnh rất quan trọng trong việc phát triển các ứng dụng và giải thuật cho vi điều khiển 
PIC. Kĩ thuật bảng cũng được xây dựng dựa trên lệnh này. Phần tiếp theo sẽ phân tích giải 
thuật của kĩ thuật này. 
 

2.

Kĩ thuật bảng 
2.1.

Các thông tin cơ sở để xây dựng kĩ thuật bảng 

2.1.1 Các lệnh hỗ trợ cho kĩ thuật bảng.  
Trong bài trước ta từng biết đến lệnh RETLW với vai trò như lệnh RETURN (trở về 
chương trình chính từ chương trình con), ta cũng đã biết được cách sử dụng lệnh này 
như thế nào. Để thuận tiện cho việc theo dõi, lệnh RETLW cũng sẽ được nhăc lại ở đây 
cùng với một số lệnh được sử dụng cho việc phát triển kĩ thuật bảng.  
Lệnh RETLW 
Cú pháp:  RETLW 

(0 ≤ k≤255) 

Tác dụng: trở về chương trình chính từ chương trình con với giá trị k được 
chứa trong thanh ghi W. 
Lệnh ADDLW 
Cú pháp:   ADDLW  

k  

(0 ≤ k≤255) 

Tác dụng: cộng giá trị k vào giá trị chứa trong thanh ghi W, kết quả chứa 
trong thanh ghi W. 
Lệnh  này  được  hỗ  trợ  bởi  các  bit  trạng  thái  C,  DC,  Z  trong  thanh  ghi 

Người báo cáo: 

Nguyễn Trung Chính 

Tài liệu: 

TUT03.02 

Ngày: 

3/6/2006 

Trang: 

6/14 

STATUS.  Chức  năng  các  lệnh  này  sẽ  được  bàn  đến  kĩ  hơn  khi  cần  phát  triển 
các ứng dụng liên quan đến các bit trạng thái này. 
Lệnh ADDWF 
Cú pháp:   

ADDWF 

thanh_ghi,noi_den   

Tác dụng: Cộng giá trị chứa trong thanh ghi W vào thanh ghi “thanh_ghi”. 
Kết quả được chứa trong thanh ghi “thanh_ghi” nếu tham số “noi_den” mang 
giá trị 1 hoặc thanh ghi W nếu tham số “noi_den” mang giá trị 0. 
Lệnh này cũng được hỗ trợ bởi các bit trạng thái C, DC, Z trong thanh ghi 
STATUS. 
Lệnh BTFSS 
Cú pháp:   
BTFSS   thanh_ghi,bit  
(0≤bit≤7) 
Lệnh 1 
Lệnh 2 
……….. 
Tác  dụng:  kiểm  tra  bit  được  chỉ  định  bởi  tham  số  “bit”  trong  thanh  ghi 
“thanh_ghi”. Nếu bit đó bằng 0, lệnh 1 được thực thi. Nếu bit đó khác 0, lệnh 1 
được bỏ qua và thay vào đó là lệnh NOP. 
Lệnh BTFSC 
Cú pháp:   

 

BTFSC   thanh_ghi,bit  
(0≤bit≤7) 
Lệnh 1 
Lệnh 2 
……………. 
Tác  dụng:  kiểm  tra  bit  được  chỉ  định  bởi  tham  số  “bit”  trong  thanh  ghi 
“thanh_ghi”.  Nếu bit đó bằng 1, lệnh 1 được thực thi. Nếu bit đó bằng 0, Lệnh 
tiếp theo được bỏ qua và thay vào đó bằng lệnh NOP. 
Leänh INCF
Cú pháp:  INCF    

thanh_ghi,noi_den   

 

Tác dụng: tang giá trị thanh ghi “thanh_ghi” len 1 đơn vị. Kết quả được lưu 
vào thanh ghi W nếu tham số “noi_den” bằng 0 hoặc thanh ghi “thanh_ghi” 
nếu tham số “noi_den” bằng 1. 
Lệnh này được hỗ trợ bởi bit Z trong thanh ghi STATUS. 

Người báo cáo: 

Nguyễn Trung Chính 

Tài liệu: 

TUT03.02 

Ngày: 

3/6/2006 

Trang: 

7/14 

Lệnh DECF 
Cú pháp: DECF   thanh_ghi,noi_den 
Tác dụng: giảm giá trị thanh ghi “thanh_ghi” 1 đơn vị. Kết quả được chứa 
trong thanh ghi W nếu “noi_den” bằng 0 hoặc thanh ghi “thanh_ghi” nếu 
“noi_den” bằng 1. 
Lệnh này được hỗ trợ bởi bit Z trong thanh ghi STATUS.
Lệnh MOVF 
Cú pháp:  MOVF  

thanh_ghi,noi_den 

Tác dụng: đưa giá trị trong thanh ghi “thanh_ghi” vào thanh ghi W nếu 
tham số “noi_den” bằng 0 hoặc thanh ghi “thanh_ghi” nếu tham số “noi_den” 
bằng 1.  
Việc đưa giá trị trong thanh ghi “thanh_ghi” vào thanh ghi “thanh_ghi” có 
vẻ vô nghĩa. Thông thường công việc này dùng để  thiết lập các giá trị cho bit Z 
(thanh ghi STATUS). Ta sẽ bàn đến kĩ hơn thao tác này khi xây dựng các ứng 
dụng liên quan đến nó. 
Lệnh XORLW 
Cú pháp:  XORLW   

k  

(0≤k≤255) 

Tác dụng: thực hiện phép toán XOR giữa giá trị k vả giá trị trong thanh ghi 
W. Kết quả được chứa trong thanh ghi W. Nếu kết quả phép toán bằng 0, bit Z 
(thanh ghi STATUS) sẽ mang giá trị 1. Nếu kết quả phép toán khác 0, bit Z sẽ 
mang giá trị 0. 
Xem bảng sau để biết được kết quả logic khi thực hiện phép toán XOR 
giữa hai tham số A và B: 

 

Kết quả 

Người báo cáo: 

Nguyễn Trung Chính 

Tài liệu: 

TUT03.02 

Ngày: 

3/6/2006 

Trang: 

8/14 

Lệnh XORWF 
Cú pháp:   XORWF   

thanh_ghi,noi_den 

Tác dụng: thực hiện phép toán XOR giữa các giá trị chứa trong thanh ghi W 
và thanh ghi  thanh_ghi . Kết quả được chứa trong thanh ghi W nếu tham số 
« noi_den » mang giá trị 0 hoặc thanh ghi « thanh_ghi » nếu tham số 
« noi_den » mang giá trị 1.  
Lệnh này cũng được hỗ trợ bởi bit Z trong thanh ghi STATUS. 
 

 

 

Ta có một số nhận xét về phép toán XOR như sau: 

 

‐  Khi hai biến A và B mang giá trị giống nhau, kết quả của phép toán là 0 

 

‐  Khi hai biến A và B mang giá trị khác nhau, kết của quả phép toán bằng 1 
Như vậy, giả sử A và B bằng nhau, thì kết quả phép toán (A XOR B) sẽ bằng 0, khi 
đó, trong trường hợp cấu tạo phần cứng của vi điều khiển PIC, bit Z sẽ mang mức logic 
1. Cần chú ý là tập lệnh PIC không có phép toán so sánh, nên lệnh XORLW và bit Z của 
thanh ghi STATUS được sử dụng để  xây dựng giải thuật thực hiện việc so sánh giữa 
hai số. 
 
2.1.2 Thanh ghi PC.  
Ta đã biết không như vi xử lí hay vi họ điều khiển 8051, do PIC được thiết kế theo 
lối kiến trúc Havard nên bộ nhớ chương trình và bộ nhớ dữ liệu được tách riêng. Và để 
thao tác được với bộ nhớ chương trình trong vi điều khiển PIC, thanh ghi PC được đưa 
vào để dùng cho việc truy xuất bộ nhớ chương trình. Đây là thanh ghi chứa địa chỉ các 
lệnh tiếp theo sẽ được thực thi trong bộ nhơ chương trình.  
Đối với vi điều khiển PIC16F877A, thanh ghi PC là thanh ghi 13 bit, bao gồm hai 
thanh ghi PCL (chứa 8 bit thấp) và thanh ghi PCH (chứa các bit cao còn lại). Tại sao là 
13 bit?? Câu trả lời là phải dùng 13 bit để mã hóa hết được địa chỉ của bộ nhớ chương 
trình có dung lượng là 8K word của PIC16F877A (8K word = 23x210 word = 213  word). 
Như vậy mới bảo đảm có thể truy xuất đến bất kì ô nhớ nào trong bộ nhớ chương trình 
của vi điều khiển.  
Trước mắt ta sẽ không cần quan tâm tới thanh ghi PCH (vì thanh ghi này không 
nằm trong bộ nhớ dữ liệu) mà chỉ quan tâm tới thanh ghi PCL. Thanh ghi này có trong 
bộ nhớ dữ liệu, diều đó có nghĩa nó cho phép các thao tác như một thanh ghi thông 
thường (ghi, xóa, truy xuất, ..). Thay đổi giá trị trong thanh ghi PCL sẽ làm thay đổi 
quá trình truy xuất bộ nhớ chương trình của vi điều khiển. Việc thao tác trên thanh ghi 
PCL cần hết sức cẩn trọng vì nó sẽ làm thay đổi quá trình thực thi lệnh và làm ảnh 

Người báo cáo: 

Nguyễn Trung Chính 

Tài liệu: 

TUT03.02 

Ngày: 

3/6/2006 

Trang: 

9/14 

hưởng nghiêm trọng đến giải thuật cũng như tác dụng của chương trình. Tuy nhiên 
nếu kiểm sát được, ta có thể điều khiển một cách linh động dòng chảy của chương trình 
khi vi điều khiển hoạt động. Cần kiểm soát một cách chặt chẽ việc thao tác trên thanh 
ghi PCL, đó cũng là yêu cầu quan trọng của kĩ thuật bảng.  
Có thể tìm hiểu thêm thông tin về thanh ghi này trong datasheet của nhà sản xuất. 
Ta cũng nên tìm hiểu các để biết thêm và để kiếm chứng lại các thông tin trong bai, 
đồng thời giúp ta có thêm được một số kĩ năng trong việc khai thác thông tin trong  
datasheet của một sản phẩm điện tử. Trong bài này ta chỉ cần tìm hiểu các thông tin đủ 
để phục vụ cho bài. 
 

2.2.

Phân tích giải thuật kĩ thuật bảng 

Ta sẽ phân tích kĩ thuật này thông qua một ứng dụng. Yêu cầu của ứng dụng như ứng 
dụng 1 mà ta đã thực hiện thành công ở phần 1, đó là cho một LED chạy từ trái sang phải, 
nhưng lần này thay vì sử dụng lệnh RLF hay RRF, ta sẽ sử dụng kĩ thuật bảng. Việc ứng 
dụng kĩ thuật bảng trong trường hợp này không mang tính chất tối ưu hóa giải thuật, mà 
chỉ mang tính chất tìm hiểu một kĩ thuật viết chương tình mới. 
Chương trình trong ví dụ 1 được viết lại như sau: 
 

Chương trình 3.2: 
;============================================================================= 
; WWW.PICVIETNAM.COM 
; Lap trinh:   

 

; Ngay bat dau:             

NGUYEN TRUNG CHINH 
23 thang 01 nam 2006 

; Ngay hoan thanh:            23 thang 01 nam 2006 
; Kiem tra chuong trinh:      picvietnam@googlegroups.com 
; Ngay kiem tra: 

 

 

; Su dung vi dieu khien Microchip: 
 

title 

 

PIC16F877A 

“chuongtrinh3‐2.asm” 

processor 

16f877a 

 

 

 

 

include 

<p16f877a.inc> 

 

__CONFIG  _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & 

 

 _XT_OSC & _WRT_OFF & _LVP_OFF & _CPD_OFF 
; Cap nhat va bo sung: 

Người báo cáo: 

Nguyễn Trung Chính 

Tài liệu: 

TUT03.02 

Ngày: 

3/6/2006 

Trang: 

10/14 

; Mo ta chuong trinh:  

Chuong trinh dung de dieu khien cac LED gan vao  

 

 

 

PORTB lần lượt chạy từ trái sang phải sau moi khoang thoi  

 

 

 

gian 100 ms. 

 

 

 

Su dung ki thuat bang 

; Mo ta phan cung:   

8 LED duoc gan vao PORTB thong qua cac dien tro, cac  

thanh phan di kem bao gom thach anh, mach reset va nguon 

 

 

 

;=============================================================================  
;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
; Khoi tao cac bien 
;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
count1 

EQU  0x20   

 

; Dùng cho chương trình delay 

counta 

EQU  0x21   

 

; Dùng cho chương trình delay 

countb 

EQU  0x22   

 

; Dùng cho chương trình delay 

count   

EQU  0x23   

 

;  dùng để tra bảng dữ liệu 

;============================================================================= 
;CHUONG TRINH CHINH 
;============================================================================= 
 

ORG   

0x000 

 

GOTO  

start 

start 
;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
; Khởi tạo PORT B 
;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
 

BCF     

STATUS,RP1 

 

BSF 

STATUS,RP0  

; chọn BANK1 

 

CLRF   

TRISB  

; PORTB <‐ outputs 

 

BCF   

STATUS,RP0  

 

 

;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
; Vòng lặp chính của chương trình 
;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 

; chọn BANK0 

Người báo cáo: 

Nguyễn Trung Chính 

Tài liệu: 

TUT03.02 

Ngày: 

3/6/2006 

Trang: 

11/14 

Loop1 
 

CLRF   

count   

 

; reset thanh ghi  

Loop2 
 

MOVF 

count, 0 

 

; đưa giá trị thanh ghi “count” vào thanh ghi W 

 

CALL  

table   

 

; gọi chương trình con “table” 

 

MOVWF 

PORTB 

 

; xuất giá trị chứa trong thanh ghi W ra PORTB 

 

CALL  

delay100ms   

 

INCF                 count, 0 

 

 
; tăng giá trị thanh ghi “count” 

            ; kết quả chứa trong thanh ghi W 
 

XORLW 

d’8’ 

 

 

; thực hiện phép toán XORgiữa thanh ghi W và  

 

 

 

 

 

; giá trị 8, kết quả chứa trong thanh ghi W 

 

BTFSC 

STATUS,Z 

 

; kiểm tra bit Z (Zero) 

 

GOTO  

Loop1  

 

; nhảy về label Loop1 nếu Z = 1  

 

INCF   

count, 1 

 

; thực thi lệnh này nếu Z = 0 

 

GOTO  

Loop2 

 

;=========================================================================== 
; Các chương trình con 
;=========================================================================== 
;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
; Chương trình con cho kĩ thuật bảng 
;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
table   
 

 

 

 

 

 

ADDWF         PCL,1  

 

; cộng giá trị trong thanh ghi W vào thanh ghi 
; PCL, kết quả chứa trong thanh ghi PCL 

 

RETLW 

b’10000000’   

 

RETLW 

b’01000000’ 

 

RETLW 

b’00100000’ 

 

RETLW 

b’00010000’ 

 

RETLW 

b’00001000’ 

 

RETLW 

b’00000100’ 

; dữ liệu của bảng  

Người báo cáo: 

Nguyễn Trung Chính 

Tài liệu: 

TUT03.02 

Ngày: 

3/6/2006 

Trang: 

12/14 

 

RETLW 

b’00000010’ 

 

RETLW 

b’00000001’ 

;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
; Chương trình con delay 100 ms 
;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐ 
delay100ms 
 

MOVLW 

d’100’ 

 

MOVWF 

count1 

d1 

 

 

MOVLW 

0xC7 

 

MOVWF 

counta 

 

MOVLW 

0x01 

 

MOVWF 

countb 

delay_0 

 

 

 

DECFSZ 

counta,1 

 

GOTO  

$+2 

 

DECFSZ 

countb,1 

 

GOTO  

delay_0 

 

DECFSZ 

count1,1 

 

GOTO  

d1 

 

 

 

 

RETURN 

 

 

 

 

 

END   

;=============================================================================  
Ta cùng phân tích giải thuật của chương trình dựa trên các thông tin đã được cung cấp 
ở phần 2.1. Sau mỗi lần lệnh “CALL  table” đuợc gọi, lệnh RETLW trong chương trình con 
“table” sẽ mang giá trị từ bảng dữ liệu chứa trong thanh ghi W trở về chương trình chính. 
Dữ liệu này được xuất ra thanh ghi PORT B để điều khiển việc bật tắt các LED gắn vào 
PORT B. Sau mỗi lần như vậy, giá trị trong thanh ghi count sẽ được tăng lên 1 đơn vị thông 
qua lệnh “INCF  count,1”. Giá trị trong thanh ghi “count” lại được đưa vào thanh ghi W 
thông qua lệnh “MOVF  count,0” để cộng vào thanh ghi PCL thông qua lệnh “ADDWF  
count,1” ở chương trình con “table” để điều khiển chương trình nhảy tới đúng địa chỉ cần 
lấy dữ liệu trở về chương trình chính thông qua lệnh “RETLW    …”. 

Người báo cáo: 

Nguyễn Trung Chính 

Tài liệu: 

TUT03.02 

Ngày: 

3/6/2006 

Trang: 

13/14 

Để đề phòng trường hợp giá trị biến “count” cộng vào thanh ghi PCL vượt quá ví trí 
của bảng dữ liệu (trường hợp này xảy ra khi biến “count” mang giá trị lớn hơn 8, vì bảng 
dữ liệu chỉ chứa 8 giá trị), khi đó dòng chương trình thực thi sẽ không còn đúng như ta 
mong muốn, biến count sau mỗi lần tăng sẽ được so sánh với giá trị “8” thông qua lệnh 
“XORLW” và bit trạng thái Z được kiểm tra thông qua lệnh “BTFSC   STATUS,Z” (giái 
thuật cho việc so sánh đã được đề cập ở phần trên). Nếu giá trị trong thanh ghi count chưa 
bằng 8, bit Z chưa mang giá trị 0, lệnh “GOTO  Loop1” được bỏ qua và quá trình lấy dữ 
liệu lai được tiếp tục thông qua các lệnh tiếp theo sau đó. Nếu thanh ghi count đã bằng 8, 
bit Z sẽ mang giá trị 1, lệnh “GOTO  Loop1” sẽ được thực thi, biến count khi đó được reset 
về 0 thông qua lệnh “CLRF   count” và quá trình lấy dữ liệu xuất ra PORT B của vi điều 
khiển tiếp tục được thực thi. Quá trình này được bảo đảm thực thi không ngừng chừng nào 
vi điều khiển còn hoạt động. 
Cần chú ý đến việc sắp xếp các giá trị trong bảng dữ liệu một cách phù hợp với mục 
đích điều khiển. Trong trường hợp này, do ta muốn LED chạy từ trái sang phải nên trong 
bảng dữ liệu, giá trị 1 cũng được di chuyển dần từ trái sang phải. 
Bây giờ, ta có thể điều khiển LED chạy theo bất cứ yêu cầu nào thông qua một thao tác 
đơn giản: thay đổi các giá trị trong bảng dữ liệu. Đó cũng là ưu thế rõ rệt của phương pháp 
bảng dữ liệu so với các lệnh RLF hay RRF. Tuy nhiên, tùy trường hợp cụ thể mà ta có thể 
chọn được giải pháp hiệu quả nhất tương ứng.  
Đã đến lúc các bạn phát huy tính sáng tạo của mình để điều khiển mấy con LED nhảy 
múa theo ý muốn. Nhịp điệu để nhảy sẽ được quyết định bởi thời gian delay, và hình 
tượng của điệu nhảy sẽ được thể hiện thông qua việc chớp tắt mấy con LED. Đây cũng là 
thao tác nên thực hiện để giúp làm quen với kĩ thuật mới này. 
Như thường lệ, sau đây sẽ là một số kết luận cho bài 3. 
 

3.

Kết luận 

Kĩ thuật bảng được xây dựng dựa trên các thông tin về cấu tạo vi điều khiển PIC, đó là các 
thông tin về thanh ghi PC (Program Counter) và nguyên tăc hoạt động của nó. Bên cạnh đó là 
thông tin về lệnh RETLW và cách ứng dụng của nó.  
Sử dụng kĩ thuật bảng cho phép điều khiển một cách linh hoạt việc thay đổi dữ liệu trong 
thanh ghi W và thông qua đó, các dữ liệu sử dụng trong chương trình cũng sẽ được truy xuất 
một cách linh hoạt hơn.  
Giải thuật kĩ thuật bảng cũng đòi hỏi việc sắp xếp và tổ chức chương trình ở một cấp độ 
cao hơn, bằng chứng là yêu cầu khắt khe trong việc kiểm soát việc thực thi các lệnh trong 
chương trình và các lệnh hỗ trợ cho kĩ thuật này cũng khá nhiều. Bên cạnh đó là yêu cầu trong 
việc tổ chức và sắp xếp một cách hợp lí dữ liệu trong bảng. 

Người báo cáo: 

Nguyễn Trung Chính 

Tài liệu: 

TUT03.02 

Ngày: 

3/6/2006 

Trang: 

14/14 

Ứng dụng của kĩ thuật bảng trong việc xây dựng các giải thuật cho chương trình viết cho vi 
điều khiển PIC cũng rất đa dạng và thường xuyên. Nhận định này sẽ được thể hiện rõ ràng 
hơn trong các bài sau. Có thể nói đây là một kĩ thuật quan trọng. 
 Thông qua bài này, ta cũng cảm nhận được một nhược điểm của họ vi điều khiển PIC 
cũng như các vi điều khiển RISC, đó là các lệnh hỗ trợ cho vi điều khiển không nhiều, dẫn đến 
số lượng các công cụ hỗ trợ ban đầu cũng không nhiều và gây nhiều khó khăn cho việc lập 
trình ứng dụng. Tuy nhiên các lệnh của vi điều khiển RISC hoàn toàn có đủ khả năng để  xây 
dựng các ứng dụng trên vi điều khiển, vấn đề là phải tìm ra các phương pháp giải quyết thích 
hợp dựa trên các công cụ ban đầu đó.  

Sign up to vote on this title
UsefulNot useful