Kỹ thuật bảng, Pic
Trang 1
Gửi đến: picvietnam@googlegroups.com
Nội dung: Bài 3: KĨ THUẬT BẢNG
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.
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.
R5
D2
4 MHz
HI
R6
D7
D5 D4
0
R2 R1
0
R9
D3
HI
SW1
D8
0
D1
0
R3
R4
PIC16F877A
8 9 10
12
14 15 17 18 19 20
21 23 25 26 27 28 30 31 1
13
2 4 5
34 36 37 39 40
11
32 RE0/RD/AN5
RE1/WR/AN6 RE2/CS/AN7
GND
OSC2/CLKOUT RC0/T1OSO/T1CKI RC1/T1OSI/CCP2 RC2/CCP1 RC3/SCK/SCL RD0/PSP0
RD2/PSP2 RD3/PSP3 RC4/SDI/SDA RC5/SDO RC6/TX/CK RC7/RX/DT RD4/PSP4 RD5/PSP5 RD7/PSP7 GND MCLR/VPP
OSC1/CLKIN
RA0/AN0 RA1/AN1 RA2/AN2/VREF-/CVREF RA3/AN3/VREF+
RA4/TOCKI/C1OUT
RB1 RB2 RB3/PGM RB4 RB5 RB6/PGC RB7/PGD
VDD
VDD
R8
C1
30 pF
D6
C2
30 pF
Hình 1: Sơ đồ nguyên lí mạch ứng dụng.
Trang 2Ta đã 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: NGUYEN TRUNG CHINH
; Ngay bat dau: 23 thang 01 nam 2006
Trang 3; 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”
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
; 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
;=============================================================================
GOTO start
start ; chương trình chính bắt đầu tại đây
;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
; Khởi tạo PORT B
;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
Trang 4BCF 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 ; chương trình con delay 100 ms
MOVLW d’100’
MOVWF count1
d1
MOVLW 0xC7
MOVWF counta
MOVLW 0x01
MOVWF countb
delay_0
DECFSZ counta,1
DECFSZ countb,1
GOTO delay_0
Trang 5DECFSZ count1,1
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.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 k (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
Trang 6STATUS. 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.
Trang 7Cú 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:
Trang 8
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
Trang 9hưở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: NGUYEN TRUNG CHINH
; Ngay bat dau: 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: PIC16F877A
title “chuongtrinh3‐2.asm”
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:
Trang 10; 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
; 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
;=============================================================================
start
;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
; Khởi tạo PORT B
;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
BCF STATUS,RP1
CLRF TRISB ; PORTB <‐ outputs
;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
; Vòng lặp chính của chương trình
;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
Trang 11CLRF 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
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
;===========================================================================
; Các chương trình con
;===========================================================================
;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
; Chương trình con cho kĩ thuật bảng
;‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐‐
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’ ; dữ liệu của bảng
RETLW b’01000000’
RETLW b’00100000’
RETLW b’00010000’
RETLW b’00001000’
RETLW b’00000100’