You are on page 1of 79

ĐẠI HỌC QUỐC GIA TP.

HCM
TRƯỜNG ĐẠI HỌC BÁCH KHOA
KHOA KHOA HỌC VÀ KỸ THUẬT MÁY TÍNH

THỰC HÀNH VI XỬ LÝ

BM Kỹ thuật Máy tính

2009
Giới thiệu
Mục Lục
Mục Lục .............................................................................................................................. 1
Bài 1 : Giới thiệu MPLAB IDE và KIT PIC .................................................................. 1
1.1 Môi trường phát triển MPLAB ................................................................................. 1
1.2 Nạp file hex vào vi điều khiển PIC........................................................................... 8
1.3 Debug dùng MpLab SIM ........................................................................................ 12
1.4 Debug onchip dùng Mplab ICD2............................................................................ 15
1.5 Bài tập ..................................................................................................................... 15
Bài 2 : Khảo sát cổng xuất nhập ................................................................................... 16
2.1 Kiến thức liên quan................................................................................................. 16
2.1.1 Các thanh ghi điều khiển cổng xuất nhập ........................................................ 16
2.1.2 Kết nối mạch .................................................................................................... 16
2.2 Các bước hiện thực yêu cầu 1 ................................................................................. 18
2.3 Chương trình mẫu yêu cầu 1................................................................................... 20
2.4 Các bước hiện thực yêu cầu 2 ................................................................................. 21
2.5 Chương trình mẫu yêu cầu 2................................................................................... 22
2.6 Bài tập ..................................................................................................................... 23
Bài 3 : Khảo sát cơ chế ngắt quãng, giao tiếp LCD ký tự ............................................ 24
3.1 Kiến thức liên quan................................................................................................. 24
3.1.1 Tóm tắt các thanh ghi điều khiển ngắt ............................................................. 24
3.2 Các bước hiện thực yêu cầu 1 ................................................................................. 25
3.3 Chương trình mẫu yêu cầu 1................................................................................... 28
3.4 LCD ký tự 2x16 ...................................................................................................... 31
3.4.1 Hình dạng và ý nghĩa các chân: ....................................................................... 31
3.4.2 Tổ chức vùng nhớ của LCD............................................................................. 32
3.4.3 Các lệnh giao tiếp với LCD ............................................................................. 34
3.4.4 Khởi tạo LCD................................................................................................... 35
3.5 Các bước hiện thực yêu cầu 2 ................................................................................. 36
3.6 Bài tập ..................................................................................................................... 41
Bài 4 : Khảo sát bộ định thời ........................................................................................ 42
4.1 Các bước hiện thực yêu cầu 1 ................................................................................. 42
4.2 Chương trình mẫu ................................................................................................... 46
4.3 Bài tập ..................................................................................................................... 48
Bài 5 : Kỹ thuật quét ma trận phím .............................................................................. 49
5.1 Kết nối mạch ma trận phím..................................................................................... 49
5.2 Các bước hiện thực ................................................................................................. 50
5.3 Bài tập ..................................................................................................................... 54
Bài 6 : Kỹ thuật quét LED ............................................................................................ 56
6.1 Cấu tạo LED 7 đoạn và LED ma trận ..................................................................... 56
6.2 Kết nối mạch ........................................................................................................... 58
6.3 Các thanh ghi liên quan và cách điều khiển............................................................ 59
6.4 Các bước hiện thực. ................................................................................................ 62
6.5 Bài tập ..................................................................................................................... 65
Bài 7 : Khảo sát bộ truyền nhận nối tiếp ...................................................................... 66
7.1 Các bước hiện thực. ................................................................................................ 66
7.2 Chương trình mẫu ................................................................................................... 68
7.3 Bài tập ..................................................................................................................... 70
Bài 8 : Khảo sát khối chuyển đổi A-D.......................................................................... 71
8.1 Các bước hiện thực ................................................................................................. 71
8.2 Bài tập ..................................................................................................................... 72
Bài 9 : Khảo sát các khối chức năng đặc biệt khác ...................................................... 73
9.1 Các bước hiện thực PWM....................................................................................... 73
9.2 Chương trình mẫu ................................................................................................... 74
9.3 Bài tập ..................................................................................................................... 75
Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Bài 1 : Giới thiệu MPLAB IDE và KIT PIC


Nội dung :
Tạo project trên MPLAB IDE.
Viết chương trình ASM.
Dịch và nạp chương trình vào vi điều khiển PIC.
Chạy và gỡ rối chương trình.

1.1 Môi trường phát triển MPLAB

Double Click vào biểu tượng MPLAB trên Desktop hoặc theo cách sau: Start ->
All Programs -> Microchip -> MPLAB IDE v76.2 -> MPLAB IDE.
Từ thanh Menu, click chọn tab Project -> Project Wirazd…

Cửa sổ Welcome hiện lên và bạn chọn Next.

Bộ môn Kỹ Thuật Máy Tính 1 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Chọn PIC cần sử dụng tại khung Device >> Click Next:

Chọn tool Microchip C18 Toolsuite tại Active Toolsuite.


Chọn MPLAB C18 C Compiler tại Tollsuite contents.
Nếu lập trình bằng assembly thì ta chon Active Toolsuite theo hình sau:

Click Next

Bộ môn Kỹ Thuật Máy Tính 2 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Chọn Browse…. Để chọn thư mục lưu project.

Đánh vào tên Project muốn tạo. Save, sau đó chúng ta chọn Next thì hiện ra của
sổ như sau:

Đây là nơi để các bạn add thư viện cho project.

Bộ môn Kỹ Thuật Máy Tính 3 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Bạn nên add hết các file cần thiết cho việc lập trình trước khi bắt đầu viết chương
trình gồm file .lib và file .lkr. Nếu viết chương trình cho con chip nào thì ta lấy file .lib
và file .lkr của chíp tương ứng, như hình trên chung ta đang sử dụng chip 18f4550.

Click Next.

Click Finish. Ta sẽ được một project như hình sau:

Bộ môn Kỹ Thuật Máy Tính 4 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Một project đơn giản nhất phải gồm có 2 thành phần Source files và Hearder
Files. Thư mục Source files chứa file text *.asm hoặc file *.c chứa code lâp trình. Thư
mục Hearder Files chứa file *.h hoặc *.INC: file có sẵn của microchip. User khai báo
dùng loại chip gì => add vào thư mục này.
Nếu bạn quên không add các file cần có vào thì làm theo hướng dẫn sau.
ADD header file: ( Copy header file vào thư mục chứa project để tiện cho việc sử dụng
sau này).

Bộ môn Kỹ Thuật Máy Tính 5 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Chọn header file phù hợp với PIC mình đã chọn. Open.

ADD source file: Click chọn New trên toolbar:


Cửa sổ hiện lên như sau: Từ Menu bar chọn File >> Save để lưu.

Đặt tên và Save với đuôi .c nếu bạn lập trình trên c18 của maplab hoặc .asm nếu
bạn lập trình trên assembly.
Nhấp phải vào Source Files chọn Add file >>> chọn file chúng ta vừa tạo xong.

Bộ môn Kỹ Thuật Máy Tính 6 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Cửa sổ hiện lên như sau:

Chúng ta đã hoàn tất việc add file vào các thư mục Source files và header files.
Công việc tiếp theo là viết code ( ở cửa sổ text editor :D:\MAPLAB\Untiled.asm).
Ðối với project mà sử dụng cùng 1 loại chip, cùng loại ngôn ngữ lập trình ( ASM hay C)
thì chỉ cần tạo 1 lần. Những lần sau, chỉ cần add/ remove file text (*.asm hoặc *.c) vào
thư mục Source files.

Bộ môn Kỹ Thuật Máy Tính 7 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

1.2 Nạp file hex vào vi điều khiển PIC


Sau khi tạo được một project, ta tiến hành build nó để tạo ra *.hex. Có thể mô tả
công việc như sau:
Ví dụ, ta có một chương trình cho PIC như sau:
;=====================================;
; Name: nut_nhan.asm
; Project: Nhap du lieu tu nút nhan RA4.
; Khi nút RA4 du?c nh?n thì led don RB0 sáng,
; Khi không nh?n RA4 thì led don RB0 t?t
; Author: BKIT HARDWARE CLUB
; Homepage: http://www.bkit4u.com/forum
; Creation Date: 7 - 31 - 2009
;======================================;

list p=18f4520
#include p18f4520.inc
org 0
goto start
start
call INIT
main
BTFSC PORTA,4 ;Wait for SW1 to be pressed
GOTO main
BSF PORTB,0 ;Turn on LED1.
SWOFF
BTFSS PORTA,4 ;Wait for SW1 to be released.
GOTO SWOFF
BCF PORTB,0 ;Switch off LED1.
GOTO main ;Repeat sequence.

INIT
clrf PORTB ; setup portb for outputs
bcf TRISB,0
bsf PORTA,4 ; setup porta.4 for input
bsf TRISA,4
return
END

Bây giờ chúng ta lưu chương trình vừa viết thành nut_nhan.asm vào một thư mục
đã tạo project phía trên. Để compile chương trình ta vào menu Project -> Build All như
hình bên dưới.

Bộ môn Kỹ Thuật Máy Tính 8 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Nếu việc build thất bại, nhưng việc này thì không mong muốn, ta có thấy kết quả
như hình sau:

Bộ môn Kỹ Thuật Máy Tính 9 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Nếu thành công, ta sẽ thấy hình sau:

Nếu việc build đã thành công, chương trình sẽ dịch nut_nhan.asm thành
nut_nhan.hex trong cùng thư mục chương trình nut_nhan.asm.

Sau khi đã có được file hex, công việc tiếp theo là làm thế nào để nạp được file
Hex xuống board. Đầu tiên là chọn mạch nạp bằng cách vào menu Programmer ->
Select Programmer -> Mplab ICD2 như hình sau :

Sau khi chọn Mplab ICD2 xong thì ta sẽ thấy giao diện như sau:

Bộ môn Kỹ Thuật Máy Tính 10 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Lúc này để nạp chương trình ta chỉ cần vào menu Programmer -> Program như
hình sau là có thể nạp được chương trình.

Sau khi nhấn Program nếu download xuống chip thành công thì ta sẽ thấy hiển thị
ra cửa sổ Output như sau:
MPLAB ICD 2 Ready
Programming Target...
...Validating configuration fields
...Erasing Part
...Programming Program Memory (0x0 - 0x3F)
Verifying...
...Program Memory
...Verify Succeeded
Programming Configuration Bits
.. Config Memory
Verifying configuration memory...
...Verify Succeeded
...Programming succeeded

Bộ môn Kỹ Thuật Máy Tính 11 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

04-Aug-2009, 14:23:39

MPLAB ICD 2 Ready

Để bắt đầu chạy chương trình ta phải rút dây kết nối mạch nạp và kit ra. Khi đó
chương trình mới có thể chạy được.

Trên đây là toàn bộ các bước để tạo một project, viết assembly cho Pic trên Mplab
cũng như làm thế nào để compile và download chương trình xuống chip để thực thi. Đây
là trường hợp lý tưởng là khi viết code không có lỗi nào xảy ra. Nếu có lỗi nào xảy ra thì
ta phải debug nó như thế nào. Trong chương này sẽ hướng dẫn các bạn hai cách debug.

1.3 Debug dùng MpLab SIM


Bước 1: Để sử dụng MpLab SIM ta vào menu Debugger -> Select Debugger ->
Mplab SIM như hình vẽ sau:

Bước 2: Khi đã chọn Mplab SIM xong thì trên menu Debugger có thêm nhiều
chức năng khác để hỗ trợ cho việc debug như hình sau:

Bộ môn Kỹ Thuật Máy Tính 12 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Từ đây ta đã có thể mô phỏng được chương trình của mình một cách dễ dàng.
Ví dụ như Run (F9) dùng để chạy chương trình, chương trình sẽ chạy liên tục đến
khi nào có breakpoint thì dừng. Vậy làm thế nào để tạo Breakpoint, ta sử dụng lệnh
Breakpoints (F2) như trên hình để tạo ra breakpoint tại vị trí hiện tại của con trỏ hoặc
double click vào hàng code mình mong muốn đặt con trỏ. Hay sử dụng Step Into (F7) để
chạy từng lệnh một, gặp lời gọi hàm thì nó sẽ vào bên trong lời gọi hàm chạy từng lệnh
trong đó. Khác với Step Over (F8) một tí là khi có lời gọi hàm thì Step Over xem như đó
là một lệnh bình thường, không đi vào hàm chi tiết như Step Into.
Reset: trở về đầu chương trình.

Bước 3: Khi debug thì ta cũng cần phải biết giá trị của các thanh ghi cũng như bộ
nhớ của chip như thế nào, để xem được các giá trị này thì chúng ta qua menu View.
Để xem được giá trị của các thanh ghi trong PIC ta chọn View -> File registers sẽ xuất
hiện cửa sổ như hình sau:

Bộ môn Kỹ Thuật Máy Tính 13 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Để xem được giá trị của các thanh ghi SFR thì ta chọn View -> Special Function
Registers sẽ xuất hiện của sổ như hình sau:

Hay để xem một và thanh ghi mà ta quan tâm thì có thể dùng Watch để xem bằng
cách vào View -> Watch thì hình sau sẽ xuất hiện:

Bộ môn Kỹ Thuật Máy Tính 14 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Muốn xem thanh ghi nào, ta chỉ việc chọn thanh ghi tương ứng trong combobox
bên trên, sau đó nhấn Add SFR.

1.4 Debug onchip dùng Mplab ICD2.


Cũng giống như debug trên Mplab SIM, Mplab ICD2 cũng có những tính năng
tương tự, nhưng khi sử dụng Mplab ICD2 thì cần phải có mạch debug, và các hiện tượng
xảy ra giống như khi chạy thực tế.

1.5 Bài tập

Bộ môn Kỹ Thuật Máy Tính 15 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Bài 2 : Khảo sát cổng xuất nhập

Nội dung:
Khảo sát hoạt động của nút nhấn, LED.
Khảo sát các thanh điều khiển cổng xuất nhập.
Tính toán thời gian thực thi lệnh, viết chương trình con làm nhiệm vụ delay.
Viết chương trình đọc giá trị của tổ hợp nút nhấn và điều khiển giá trị hiển thị
LED.
Yêu cầu:
Viết chương trình xuất dữ liệu ra 4 led đơn đếm từ 0 -> 15 -> 0. Thời gian giữa
các lần đếm lên 1 đơn vị là 1s.
Nhập dữ liệu từ nút nhấn RA4. Khi nút RA4 được nhấn thì led đơn RB0 sáng,
khi không nhấn RA4 thì led đơn RB0 tắt.

2.1 Kiến thức liên quan


2.1.1 Các thanh ghi điều khiển cổng xuất nhập
Mỗi Port có ba thanh ghi điều khiển hoạt động chính:
Các bit trong thanh ghi TRIS: thiết lập chân tương ứng là ngõ vào (logic 1) hoặc
ngõ ra (logic 0).
Các bit trong thanh ghi PORT: đọc mức logic từ chân tương ứng.
Các bit trong thanh ghi LAT: ghi mức logic ra chân tương ứng.

2.1.2 Kết nối mạch

Vị trí LED hiển thị và nút nhấn trên board như hình dưới đây:

Bộ môn Kỹ Thuật Máy Tính 16 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

LED hiển thị có kết nối như sau:


D2 R21 470
RB0
LED

D3 R22 470
RB1
LED

D4 R23 470
RB2
LED

D5 R24 470
RB3
LED

J6
1 2

Để LED sáng, J6 phải được nối lại và chân điều khiển tương ứng được thiết lập là
ngỏ ra và ở mức logic 1.
Các nút nhấn có kết nối như sau:

VCC VCC VCC

R1
10K
R3 R7
10K 10K

D401
4007
MCLR RA4 RB0

S1 S2 C1 S3 C2
RESET SW RA4 104 SW RB0 104

Nút nhấn RESET dùng để reset vi điều khiển


Nút nhấn RA4, RB0 khi được nhấn sẽ làm cho chân tương ứng ở mức logic 0.
Cần thiết lập các chân RA4 và RB0 là ngõ vào.
Hiện tượng rung phím:

VCC

R7
10K

RB0

S3 C2
SW RB0 104

Khi phím được nhấn, do tác động của hiện tượng rung cơ học, tín hiệu điện tại

Bộ môn Kỹ Thuật Máy Tính 17 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

ngõ ra bị chuyển trạng thái giữa logic 0 và logic 1. Khi phím được thả, hiện tượng rung
cũng xảy ra tương tự.
Bộ dao động chính có kết nối như sau:
Y2
C4 VCC
22pF OSC1 1 4
NC/OE VCC
Y1
C5

2
4MHz 2 3 OSC1
22pF OSC2 J7 GND OUT

4MHz
C3

1
R4
VCC
4.7K
22pF

Trên kit thí nghiệm, thạch anh Y2 được sử dụng cho tất cả các bài thí nghiệm.

2.2 Các bước hiện thực yêu cầu 1

Bước 1: Tạo project mới giống như hướng dẫn ở chương 1 lấy tên project
là Led_don, tạo file led_don.asm và chọn chip 18f4520. Ta được hình sau:

Bước 2: Include file p18f4520.inc vào file led_don.asm.


Bước 3: Khởi tạo PortB là output sử dụng các lệnh clrf, bcf.
INIT
clrf PORTB ; setup portb for outputs

Bộ môn Kỹ Thuật Máy Tính 18 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

bcf TRISB,0 ; clear trisb.0


bcf TRISB,1 ; clear trisb.1
bcf TRISB,2 ; clear trisb.1
bcf TRISB,3 ; clear trisb.1
return
Bước 4: Tạo hàm delay1ms sử dụng các lệnh CLRF, NOP, DECFSZ,
GOTO.
delay equ 0ch ; declare variable “delay”

Delay1ms ;Approxiamtely at 4Mhz


clrf delay ; clear variable “delay”
Delay_1
nop
decfsz delay
goto Delay_1
return

Bước 5: Từ đây ta có thể tạo ra được hàm delay1s:

Delay1s
Movwf .4
Movlw delay_1sa
Delay1s_1
Movwf .250
Movlw delay_1sb
Delay1s_2
Call Delay1ms
decfsz delay_1sb
goto Delay1s_2
decfsz delay_1sa
goto Delay1s_1
return

Bước 6: Viết chương trình cho hàm main thực hiện các yêu cầu của
đề bài sử dụng lệnh INCF:
begin
INCF PORTB
call Delay1s
goto begin

Bộ môn Kỹ Thuật Máy Tính 19 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

2.3 Chương trình mẫu yêu cầu 1


;=====================================;
; Name: led_don.asm
; Project: Xuất dữ liệu ra 4 led đơn đếm từ 0 -> 15 -> 0.
; Thời gian giữa các lần đếm lên 1 đơn vị là 1s.
; Author: BKIT HARDWARE CLUB
; Homepage: http://www.bkit4u.com/forum
; Creation Date: 7 - 31 - 2009
;======================================;

list p=18f4520
#include p18f4520.inc
delay res 1
delay_1sa res 1
delay_1sb res 1
org 0
goto start
start
call INIT
begin
INCF PORTB
call Delay1ms
goto begin

INIT
clrf PORTB ; setup portb for outputs
bcf TRISB,0
bcf TRISB,1
bcf TRISB,2
bcf TRISB,3
return

Delay1ms ;Approxiamtely at 4Mhz


clrf delay
Delay_1
nop
decfsz delay
goto Delay_1
return

Delay1s
movwf .4
movlw delay_1sa

Bộ môn Kỹ Thuật Máy Tính 20 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Delay1s_1
movwf .250
movlw delay_1sb
Delay1s_2
call Delay1ms
decfsz delay_1sb
goto Delay1s_2
decfsz delay_1sa
goto Delay1s_1
return

END

Sau khi có chương trình mẫu ta thực hiện việc compile chương trình và nạp
xuống mạch để chạy chương trình như hướng dẫn ở chương 1.

2.4 Các bước hiện thực yêu cầu 2

Bước 1: Tạo project mới giống như hướng dẫn ở chương 1 lấy tên project
là Nut_nhan và chọn chip 18f4520. Ta được hình sau:

Bước 2: Include file p18f4520.inc vào file nut_nhan.asm.

Bộ môn Kỹ Thuật Máy Tính 21 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Bước 3: Khởi tạo PortB là output và PortA là input sử dụng các lệnh clrf,
bcf, bsf
INIT
CLRF PORTB ;setup portb for outputs
BCF TRISB,0
BCF TRISB,1
BCF TRISB,2
BCF TRISB,3
BSF PORTA,4 ; setup porta.4 for input
BSF TRISA,4
RETURN
Bước 4: Viết chương trình cho hàm main thực hiện yêu cầu của đề bài

MAIN
BTFSC PORTA,4 ;Wait for SW1 to be pressed
GOTO MAIN
BSF PORTB,0 ;Turn on LED1.
SWOFF
BTFSS PORTA,4 ;Wait for SW1 to be released.
GOTO SWOFF
BCF PORTB,0 ;Switch off LED1.
GOTO MAIN ;Repeat sequence.

2.5 Chương trình mẫu yêu cầu 2


;=====================================;
; Name: nut_nhan.asm
; Project: Nhập dữ liệu từ nút nhấn RA4.
; Khi nút RA4 được nhấn thì led đơn RB0 sáng,
; Khi không nhấn RA4 thì led đơn RB0 tắt
; Author: BKIT HARDWARE CLUB
; Homepage: http://www.bkit4u.com/forum
; Creation Date: 7 - 31 - 2009
;======================================;

list p=18f4520
#include p18f4520.inc
ORG 0
GOTO START
START
CALL INIT
MAIN
BTFSC PORTA,4 ;Wait for SW1 to be pressed

Bộ môn Kỹ Thuật Máy Tính 22 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

GOTO MAIN
BSF PORTB,0 ;Turn on LED1.
SWOFF
BTFSS PORTA,4 ;Wait for SW1 to be released.
GOTO SWOFF
BCF PORTB,0 ;Switch off LED1.
GOTO MAIN ;Repeat sequence.
INIT
CLRF PORTB ; setup portb.0 for outputs
BCF TRISB,0
BSF PORTA,4 ; setup porta.4 for input
BSF TRISA,4
RETURN
END
Sau khi có chương trình mẫu ta thực hiện việc compile chương trình và nạp
xuống mạch để chạy chương trình như hướng dẫn ở chương 1.

2.6 Bài tập


Viết chương trình để khi nhấn RA4 thì các led sẽ sáng đếm lên, mỗi lần
nhấn đếm lên 1 đơn vị.
Viết chương trình sao cho mỗi lần nhấn RA4 thì 2 led trái và 2 led phải
thay nhau sáng.
Tạo hiệu ứng light river trên 4 led của board mạch starter kit. Nhấn RA4 để
thay đổi chiều của light river.

Bộ môn Kỹ Thuật Máy Tính 23 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Bài 3 : Khảo sát cơ chế ngắt quãng, giao tiếp LCD ký


tự

Nội dung:
Khảo sát các nguyên nhân gây ngắt quảng, cách xử lý ngắt quãng, tính ưu tiên
giữa các ngắt của vi điều khiển PIC16F877.
Khảo sát ngắt ngoài của vi điều khiển PIC16F877.
Điều khiển LCD ký tự 2x16.
Yêu cầu:
1. Viết chương trình khởi tạo 2 ngắt:
Ngắt ngoài 0 với độ ưu tiên cao.
Ngắt timer 0 với độ ưu tiên thấp.
Trong chương trình ngắt ngoài 0 bật 3 led đơn RB1, RB2, RB3sáng
cùng lúc.
Trong chương trình timer 0 sau 1s khi 3 led được bật ở trong ngắt ngoài
thì tắt 3 led đơn RB1, RB2, RB3 cùng lúc.
2. Viết chương trình hiển thị kí tự lên LCD.

3.1 Kiến thức liên quan


3.1.1 Tóm tắt các thanh ghi điều khiển ngắt

Thanh ghi INTCON:

Thanh ghi PIE1:

Thanh ghi PIE2:

Thanh ghi PIR1:

Bộ môn Kỹ Thuật Máy Tính 24 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Thanh ghi PIR2:

Sơ đồ điều khiển ngắt:

3.2 Các bước hiện thực yêu cầu 1


Bước 1: Tạo project mới giống như hướng dẫn ở chương 1 lấy tên project
là Interrupt, tạo file interrupt.asm và chọn chip 18f4520. Ta được hình sau:

Bộ môn Kỹ Thuật Máy Tính 25 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Bước 2: Include file p18f4520.inc vào file interrupt.asm


Bước 3: Khởi tạo PortB là output sử dụng các lệnh clrf, bcf
INIT
;assigning PORTB is a digital output
MOVLW 0x0e
MOVWF ADCON1
; setup portb for outputs
BCF TRISB,1
BCF PORTB,1
BCF TRISB,2
BCF PORTB,2
BCF TRISB,3
BCF PORTB,3
;initialize delay variable
MOVLW .10
MOVWF delay
RETURN
Bước 4: Khởi tạo timer 0, cho timer 0 ngắt có độ ưu tiên thấp, thiết lập
timer0 cứ 100ms thì xảy ra ngắt một lần.
INIT_TIMER0
BSF RCON,IPEN ;enable priority interrupts.
BCF INTCON2,TMR0IP ;timer0 with low priority

Bộ môn Kỹ Thuật Máy Tính 26 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

BSF INTCON,TMR0IF;set timer0 interrupt flag bit


BSF INTCON,TMR0IE ; enable timer 0
;set the global interrupt enable bits
BSF INTCON,GIEH
BSF INTCON,GIEL
CLRF T0CON
MOVLW 0x3c
MOVWF TMR0H
MOVLW 0xAF
MOVWF TMR0L
BSF T0CON,TMR0ON
RETURN
Bước 5: Khởi tạo ngắt ngoài 0 tích cực cạnh xuống.
Đối với ngắt ngoài 1 và ngắt ngoài 2 thì độ ưu tiên ngắt phụ thuộc vào 2 bit
INT1IP và INT2IP trong thanh ghi INTCON3. Còn với ngắt ngoài 0 thì không có
bít xác định độ ưu tiên, nó chỉ có một mức ưu tiên là high priority.

INIT_EXTERNAL_INTERRUPT
;falling edge on RB0
BCF INTCON2,INTEDG0
; clear external interrupt flag bit
BCF INTCON,INT0IF
; enable external 0 interrupt
BSF INTCON,INT0IE
;set the global interrupt enable bits
BSF INTCON,GIEH
BSF INTCON,GIEL
RETURN

Bước 6: Viết chương trình cho ngắt ngoài 0, bật 3 đèn led đơn cùng
sáng và khởi tạo lại giá trị cho biến delay để 1s sau thì ngắt timer sẽ tắt 3 đèn đó.
EXTERNAL_INTERUPT_ROUTINE
BCF INTCON,INT0IF
BSF PORTB,1
BSF PORTB,2
BSF PORTB,3
MOVLW .10
MOVWF delay
RETURN
Bước 7: Viết chương trình cho ngắt timer0, sau 1s sau khi led được bật
sáng thì nó sẽ làm cho led tắt.
Thời gian để timer đếm lên 1 đơn vị đựơc tính bằng công thức :

Bộ môn Kỹ Thuật Máy Tính 27 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

T = 1/((Focs/4)/2) = 1/((4Mhz/4)/2) = 0.5us


Nên khi ta để giá trị trong các thanh ghi của timer giá trị 50000 thì cứ sau
100ms, timer sẽ ngắt một lần. Để tính được giá trị số Hex gán cho thanh ghi đếm
của timer ta làm như sau:
Đổi số 50000 sang số hex: C350.
Lấy FFFF – C350 = 3CAF.
Byte cao sẽ được lưu vào TMR0H, byte thấp lưu vào TMR0L.

TIMER0_INTERRUPT_ROUTINE
BCF INTCON,TMR0IF
DECFSZ delay,1
GOTO TIMER0_ROUTINE_1
BCF PORTB,1
BCF PORTB,2
BCF PORTB,3
MOVLW .10
MOVWF delay
TIMER0_ROUTINE_1
BCF T0CON,TMR0ON
MOVLW 0x3C
MOVWF TMR0H
MOVLW 0xAF
MOVWF TMR0L
BSF T0CON,TMR0ON
RETURN

3.3 Chương trình mẫu yêu cầu 1


;=====================================;
; Name: led_don.asm
; Project: Viết chương trình khởi tạo 2 ngắt:
;- Ngắt ngoài 0 với độ ưu tiên cao.
;- Ngắt timer 0 với độ ưu tiên thấp.
;- Trong chương trình ngắt ngoài 0 bật 3 led đơn RB1, RB2, RB3sáng cùng
;lúc
;- Trong chương trình timer 0 sau 1s khi 3 led được bật ở trong ngắt ngoài thì
;tắt 3 led đơn RB1, RB2, RB3 cùng lúc
; Author: BKIT HARDWARE CLUB
; Homepage: http://www.bkit4u.com/forum
; Creation Date: 7 - 31 - 2009
;======================================;

Bộ môn Kỹ Thuật Máy Tính 28 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

list p = 18f4520
#include P18f4520.inc
delay res 1
ORG 00h
GOTO MAIN
ORG 08H
GOTO ISR_HIGH
ORG 18H
GOTO ISR_LOW
MAIN
CALL INIT
CALL INIT_TIMER0
CALL INIT_EXTERNAL_INTERRUPT
GOTO $
INIT
;assigning PORTB is a digital output
MOVLW 0x0e
MOVWF ADCON1
BCF TRISB,1
BCF PORTB,1
BCF TRISB,2
BCF PORTB,2
BCF TRISB,3
BCF PORTB,3
MOVLW .10
MOVWF delay
RETURN

INIT_TIMER0
BSF RCON,IPEN ;enable priority interrupts.
BCF INTCON2,TMR0IP
BSF INTCON,TMR0IF
BSF INTCON,TMR0IE
BSF INTCON,GIEH ;set the global interrupt enable bits
BSF INTCON,GIEL
CLRF T0CON
MOVLW 0x3c
MOVWF TMR0H
MOVLW 0xAF
MOVWF TMR0L
BSF T0CON,TMR0ON
RETURN
INIT_EXTERNAL_INTERRUPT

Bộ môn Kỹ Thuật Máy Tính 29 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

;Interrupt priority for INT1 and INT2 is determined by the


;value contained in the interrupt priority bits, INT1IP
;(INTCON3<6>) and INT2IP (INTCON3<7>). There is
;no priority bit associated with INT0. It is always a high
;priority interrupt source

BCF INTCON2,INTEDG0
BCF INTCON,INT0IF
BSF INTCON,INT0IE
BSF INTCON,GIEH ;set the global interrupt enable bits
BSF INTCON,GIEL
RETURN

EXTERNAL_INTERUPT_ROUTINE
BCF INTCON,INT0IF
BSF PORTB,1
BSF PORTB,2
BSF PORTB,3
MOVLW .10
MOVWF delay
RETURN

TIMER0_INTERRUPT_ROUTINE
; BSF INTCON,INT0IF
BCF INTCON,TMR0IF
DECFSZ delay,1
GOTO TIMER0_ROUTINE_1
BCF PORTB,1
BCF PORTB,2
BCF PORTB,3
MOVLW .10
MOVWF delay
TIMER0_ROUTINE_1
BCF T0CON,TMR0ON
MOVLW 0x3c
MOVWF TMR0H
MOVLW 0xaf
MOVWF TMR0L
BSF T0CON,TMR0ON

RETURN

ISR_HIGH

Bộ môn Kỹ Thuật Máy Tính 30 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

CALL EXTERNAL_INTERUPT_ROUTINE
RETFIE

ISR_LOW
CALL TIMER0_INTERRUPT_ROUTINE
RETFIE
END

Sau khi có chương trình mẫu ta thực hiện việc compile chương trình và nạp
xuống mạch để chạy chương trình như hướng dẫn ở chương 1.

3.4 LCD ký tự 2x16


3.4.1 Hình dạng và ý nghĩa các chân:

Tên chân Mức logic Mô tả


GND - Đất (0V)
VCC - Nguồn (+5V)
VEE - Chỉnh contrast (0 – VCC)
RS 0 D0-D7 là giá trị lệnh
1 D0-D7 là giá trị dữ liệu
R/W 0 Ghi giá trị vào LCD
1 Đọc giá trị ra từ LCD
E 0 Cấm truy xuất LCD
1 LCD hoạt động trao đổi dữ liệu
Từ 1 xuống 0 Dữ liệu/Lệnh đưa vào LCD
D0 0/1 Bit 0/LSB
D1 0/1 Bit1
D2 0/1 Bit2
D3 0/1 Bit3
D4 0/1 Bit4
D5 0/1 Bit5
D6 0/1 Bit6

Bộ môn Kỹ Thuật Máy Tính 31 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

D7 0/1 Bit7/MSB
A - Chân Anode của đèn nền
K - Chân Cathode của đèn nền

3.4.2 Tổ chức vùng nhớ của LCD


Display Data Ram (DDRAM): lưu trữ mã ký tự hiển thị ra màn hình. Mã này
giống với mã ASCII. Có tất cả 80 ô nhớ DDRAM. Vùng hiển thị tương ứng với cửa sổ
gồm 16 ô nhớ hàng đầu tiên và 16 ô nhớ hàng thứ hai. Chúng ta có thể tạo hiệu ứng dịch
chữ bằng cách sử dụng lệnh dịch (mô tả sau), khi đó cửa sổ hiển thị sẽ dịch đem lại hiệu
ứng dịch chữ.

Character Generator Ram (CGRAM): lưu trữ tám mẫu ký tự do người dùng định
nghĩa. Tám mẫu ký tự này tương ứng với các mã ký tự D7-D0 = 0000*D2D1D0 (* mang
giá trị tùy định 0 hay 1).

Character Generator Rom (CGROM): lưu trữ cứng các mẫu ký tự tương ứng với
mã ASCII. Dưới đây là bảng ánh xạ giữa mã ký tự và mẫu ký tự.

Bộ môn Kỹ Thuật Máy Tính 32 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Chúng ta muốn hiển thị chữ “CE” ở giữa hàng đầu tiên, giả sử cửa sổ hiển thị
đang bắt đầu từ vị trí đầu tiên (hàng thứ nhất hiển thị dữ liệu của ô nhớ từ 0x00 đến 0x0f,
hàng thứ hai hiển thị dữ liệu của ô nhớ từ 0x40 đến 0x4f, đây là vị trí home). Giá trị của ô
nhớ 0x07 là 0x43 (ký tự C), của ô nhớ 0x08 là 0x45 (ký tự E).
Chúng ta muốn hiển thị chữ “®” ở giữ hàng thứ hai, giả sử cử sổ hiển thị đang ở
vị trí home. Trong bảng mẫu ký tự chúng ta thấy không có mẫu “®”. Lúc này chúng ta
phải định nghĩa mẫu “®” 5x8 điểm, gồm có 8 byte, sau đó lưu vào vị trí của mẫu ký tự
CGRAM thứ nhất. Lúc này giá trị của ô nhớ 0x47 là 0x00 hoặc 0x08 (vị trí của mẫu ký
tự CGRAM thứ nhất “®”).

Bộ môn Kỹ Thuật Máy Tính 33 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

3.4.3 Các lệnh giao tiếp với LCD

Thời gian
Lệnh RS RW D7 D6 D5 D4 D3 D2 D1 D0
thực thi
Clear display
0 0 0 0 0 0 0 0 0 1 1.52ms
Return home
0 0 0 0 0 0 0 0 1 * 1.52ms
Entry mode set
0 0 0 0 0 0 0 1 I/D SH 37µs
Display on/off
0 0 0 0 0 0 1 D C B 37µs
control
Cursor/Display S/ R/
0 0 0 0 0 1 * * 37µs
shift C L
Function set
0 0 0 0 1 DL N F * * 37µs
Set CGRAM
0 0 0 1 CGRAM address 37µs
address
Set DDRAM
0 0 1 DDRAM address 37µs
address
Read BUSY flag
0 1 BF DDRAM address 0µs
(BF)
Write to
DDRAM or 1 0 D7 D6 D5 D4 D3 D2 D1 D0 43µs
CGRAM
Read from
DDRAM or 1 1 D7 D6 D5 D4 D3 D2 D1 D0 43µs
CGRAM

Các bit trên bảng tóm tắt các lệnh có ý nghĩa như sau:

I/D 1 Increment 0 Decrement


SH 1 Entire shift on 0 Entire shift off
S/C 1 Display shift 0 Cursor move
R/L 1 Shift to the Right 0 Shift to the Left
DL 1 8 bits 0 4 bits
N 1 2 Lines 0 1 Lines
F 1 5x10 dots Font 0 5x8 dots Font
BF 1 Internally operating 0 Can accept instruction

Trên kit thí nghiệm LCD ký tự 2x16 được kết nối vào Port D ở chế độ 4 bit. Ở chế
độ 4 bit, để đọc hay ghi một byte phải tiến hành cài dữ liệu hai lần, lần đầu là 4 bit cao,
lần thứ hai là 4 bit thấp.

Bộ môn Kỹ Thuật Máy Tính 34 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

3.4.4 Khởi tạo LCD

Sơ đồ kết nối LCD:


VCC

R20 2.2K
RD7 Q2
MMBT2222A

LCD1
1
2 Vss
3 Vdd
RD4 4 Vee
RD5 5 RS
RD6 6 R/W
7 E
8 D0
9 D1
10 D2
RD0 11 D3
RD1 12 D4
RD2 13 D5
RD3 14 D6
15 D7
16 A
K

Trước khi xuất ký tự ra màn hình LCD, LCD controller phải được khởi tạo khi
mới được cấp nguồn. Trình tự khởi tạo như lược đồ sau. Trên lược đồ, lệnh “Display
clear” có giá trị 0x01 được gửi hai lần, lần đầu là 4 bit cao có giá trị 0x0, lần thứ hai là
bốn bit thấp có giá trị 0x01. Lệnh “Function set” gửi hai lần giá trị 0x2.

Bộ môn Kỹ Thuật Máy Tính 35 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Bật nguồn
(chân PD7 out ra mức logic 1)

Chờ tối thiểu 30ms


(Đợi VDD > 4.5V) Chờ tối thiểu 39µs

Gửi lệnh Gửi lệnh


“Function set” “Display clear”

RS RW D7 D6 D5 D4 RS RW D7 D6 D5 D4

0 0 0 0 1 0 0 0 0 0 0 0

0 0 0 0 1 0 0 0 0 0 0 1

0 0 N F * *
Gửi lệnh
“Entry mode set”
Chờ tối thiểu 39µs RS RW D7 D6 D5 D4

0 0 0 0 0 0
Gửi lệnh
0 0 0 1 I/D SH
“Display on/off control”
RS RW D7 D6 D5 D4

0 0 0 0 0 0 Kết thúc khởi tạo

0 0 1 D C B

3.5 Các bước hiện thực yêu cầu 2


Bước 1: Tạo project mới giống như hướng dẫn ở chương 1 lấy tên project
là LCD, tạo file lcd.asm và chọn chip 18f4520. Ta được hình sau:

Bộ môn Kỹ Thuật Máy Tính 36 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Bước 2: Include file p18f4520.inc vào file lcd.asm


Bước 3: Dựa vào sơ đồ nguyên lý kết nối vi điều khiển với LCD kí tự ta
define lại để dễ dàng sử dụng hơn.
#define LCD_D4 PORTD, 0 ; LCD data bits
#define LCD_D5 PORTD, 1
#define LCD_D6 PORTD, 2
#define LCD_D7 PORTD, 3
#define LCD_D PORTD

#define LCD_D4_DIR TRISD, 0 ; LCD data bits


#define LCD_D5_DIR TRISD, 1
#define LCD_D6_DIR TRISD, 2
#define LCD_D7_DIR TRISD, 3

#define LCD_E PORTD, 6 ; LCD E clock


#define LCD_RW PORTD, 5 ; LCD read/write line
#define LCD_RS PORTD, 4 ; LCD register select line

#define LCD_E_DIR TRISD, 6


#define LCD_RW_DIR TRISD, 5
#define LCD_RS_DIR TRISD, 4

#define LCD_INS 0
#define LCD_DATA 1

Bộ môn Kỹ Thuật Máy Tính 37 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Bước 4: Viết hàm xuất dữ liệu 4 bít ra cho LCD kí tự :


LCDWriteNibble
btfss STATUS, C ; Set the register select
bcf LCD_RS
btfsc STATUS, C
bsf LCD_RS
bcf LCD_RW ; Set write mode
bcf LCD_D4_DIR ; Set data bits to outputs
bcf LCD_D5_DIR
bcf LCD_D6_DIR
bcf LCD_D7_DIR
NOP ; Small delay
NOP
bsf LCD_E ; Setup to clock data
NOP ; Small delay
NOP
btfss temp_wr, 7 ; Set high nibble
bcf LCD_D7
btfsc temp_wr, 7
bsf LCD_D7
btfss temp_wr, 6
bcf LCD_D6
btfsc temp_wr, 6
bsf LCD_D6
btfss temp_wr, 5
bcf LCD_D5
btfsc temp_wr, 5
bsf LCD_D5
btfss temp_wr, 4
bcf LCD_D4
btfsc temp_wr, 4
bsf LCD_D4
NOP ; Small delay
NOP
bcf LCD_E ; Send the data
return

Bước 5: Tiếp tục ta viết hàm để truyền lệnh (command) cho lcd kí tự.
Macro LCDWrite_command có một đối số là data, ta dùng đối số này để
truyền lệnh cho lcd. Ở đây, LCD ta thiết lập chế độ 4 bít nên khi truyền lệnh nó
cũng chỉ cần 4 bit để điều khiển. Trong macro này data1 chỉ sử dụng 4 bit cao mà
thôi.

Bộ môn Kỹ Thuật Máy Tính 38 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

LCDWrite_command macro data1


bcf LCD_RS ;write command
movlw data1
movwf temp_wr
call LCDWriteNibble
movlw 0xF
movwf delay
rcall DelayXCycles
endm

Bước 6: Sau đó viết thêm hàm truyền dữ liệu hiển thị ra LCD kí tự.
Macro LCDWrite_data có một đối số là data1, ta dùng macro với đối số
tương ứng để truyền data hiển thị lên màn hình LCD. Như trên ta đã đề cập, trong
ứng dụng này ta sử dụng LCD chế độ 4 bít, nên data ở đây được truyền theo thứ tự
là 4 bit cao truyền trước sau đó 4 bít thấp được truyền sau.
LCDWrite_data macro data1
bsf LCD_RS ;write data
movff data1,temp_wr
rcall LCDBusy
bsf STATUS, C
rcall LCDWrite
movlw 0x0F ;Wait ~100us @ 20 MHz
movwf delay
rcall DelayXCycles
endm
Bước 7: Hàm quan trọng nhất của LCD kí tự chính là hàm khởi tạo LCD.
Trước khi sử dụng được lcd ta phải khởi tạo cho nó theo như giản đồ khởi tạo lcd
ở trên phần hướng dẫn lý thuyết. Ngoài ra do thiết kế mạch, để LCD có thể hiện
thị bình thường trước tiên ta phải bật nguồn của LCD lên, chân nguồn của LCD
được điều khiển bởi PortD.7 tích cực mức cao, nên trước khi muốn sử dụng LCD
ta phải bật PortD.7 lên 1.
LCDInit1
CALL Init_variable

bsf LATD,7
bcf TRISD,7
bsf LATD,7
bcf LCD_E_DIR ;configure control lines
bcf LCD_RW_DIR
bcf LCD_RS_DIR

movlw b'00001110'
movwf ADCON1

Bộ môn Kỹ Thuật Máy Tính 39 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

movlw 0xff ; Wait ~15ms @ 20 MHz


movwf COUNTER
lil11
movlw 0xFF
movwf delay
rcall DelayXCycles
decfsz COUNTER,F
bra lil11

LCDWrite_command 0x20
LCDWrite_command 0x20
LCDWrite_command 0x80
LCDWrite_command 0x00
LCDWrite_command 0xf0
LCDWrite_command 0x00
LCDWrite_command 0x10
call LongDelay ;2ms
call LongDelay ;2ms
LCDWrite_command 0x00
LCDWrite_command 0x20

call Lcd_clear
return
Bước 8: Đến đây ta có thể viết chương trình để hiển thị kí tự lên lcd kí tự.
Ý tưởng thực hiện ở đây là lúc đầu ta khai báo một vùng nhớ gồm 32 ô nhớ
tương ứng với 32 vị trí trên lcd kí tự. Hàm lcd_display của chúng ta sẽ thực hiện
một việc đơn giản là lấy dữ liệu chứa trong vùng nhớ này ra hiển thị lên lcd kí tự.
Còn người dùng muốn hiển thị lên lcd thì chỉ cần update giá trị vào vùng nhớ này
là xong.
Lcd_display
movff INDF0,temp_wr1
movlw .0
cpfseq temp_wr1
goto Lcd_display1
movlw 0x20
movwf temp_wr1
Lcd_display1
LCDWrite_data temp_wr1

INCF FSR0L
CLRF WREG
ADDWFC FSR0H,F

Bộ môn Kỹ Thuật Máy Tính 40 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

MOVLW .0
cpfseq flag_line
goto Lcd_display_line2
;display line1
INCF index_of_lcd
MOVLW MAX_INDEX
CPFSEQ index_of_lcd
GOTO Exit_Lcd_display
CLRF Index_of_lcd
MOVLW .1
MOVWF flag_line
Set_cursor .0,.1
goto Exit_Lcd_display

;display line2
Lcd_display_line2
INCF index_of_lcd
MOVLW MAX_INDEX
CPFSEQ index_of_lcd
GOTO Exit_Lcd_display
CLRF Index_of_lcd
MOVLW .0
MOVWF flag_line
Movlw HIGH Lcd_buffer
Movwf FSR0H
Movlw LOW Lcd_buffer
Movwf FSR0L
Set_cursor .0, .0

Exit_Lcd_display
RETURN

3.6 Bài tập


Viết chương trình chạy chữ qua LCD.
Viết chương trình thay đổi chữ hiển thị trên LCD khi nhấn nút.

Bộ môn Kỹ Thuật Máy Tính 41 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Bài 4 : Khảo sát bộ định thời

Nội dung:
Khảo sát các chế độ hoạt động của các bộ định thời.
Khảo sát các thanh ghi điều khiển bộ định thời.
Sử dụng bộ định thời trong chương trình.
Yêu cầu:
Sử dụng bộ timer 1 cứ sau 1s đếm lên 1 đơn vị rồi xuất giá trị ra led đơn.
Viết chương trình sử dụng bộ định thời làm đồng hồ điều khiển đèn giao thông.

4.1 Các bước hiện thực yêu cầu 1


Bước 1: Tạo project mới giống như hướng dẫn ở chương 1 lấy tên project
là timer và chọn chip 18f4520. Ta được hình sau:

Bước 2: Include file p18f4520.inc vào file timer.asm


Bước 3: Khởi tạo PortB là output.
Cần gán giá trị cho thanh ghi ADCON1 vì thanh ghi này có chức năng chọn
các PORT có chức năng là input/output digital hay là input Analog. Do đó, trước
khi sử dụng các port ta phải kiểm tra xem thanh ghi ADCON1 đã cấu hình đúng
chưa.
INIT

Bộ môn Kỹ Thuật Máy Tính 42 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

;assigning PORTB is a digital output


MOVLW 0x0e
MOVWF ADCON1
; setup portb for outputs
CLRF TRISB
CLRF PORTB
RETURN
Bước 4: Khởi tạo các vector ngắt.
Địa chỉ 0x00 bắt đầu chương trình chính.
Địa chỉ 0x08 địa chỉ của vector ngắt có độ ưu tiên cao
Địa chỉ 0x18 địa chỉ của vector ngắt có độ ưu tiên thấp.
Chú ý: VĐK Pic chỉ có 2 độ ưu tiên khi ngắt xảy ra như nói ở trên.
org 0x0
goto MAIN

ORG 0x000008 ; high priority interrupt vector


GOTO ISR_HIGH

ORG 0x000018 ; low priority interrupt vector


GOTO ISR_LOW

MAIN
GOTO MAIN
;interrupt sevice routine for high priority interrupt
ISR_HIGH
RETFIE
;interrupt sevice routine for low priority interrupt
ISR_LOW
RETFIE

Bước 5: Khởi tạo ngắt timer 0 cứ sau 100ms thì vào ngắt một lần.
Thời gian để timer đếm lên 1 đơn vị đựơc tính bằng công thức
T = 1/((Focs/4)/2) = 1/((4Mhz/4)/2) = 0.5us
Nên khi ta để giá trị trong các thanh ghi của timer giá trị 50000 thì cứ sau
100ms, timer sẽ ngắt một lần. Để tính được giá trị số Hex gán cho thanh ghi đếm
của timer ta làm như sau :
Đầu tiên đổi số 50000 sang số hex: C350.
Sau đó lấy FFFF – C350 = 3CAF.
Có được số này rồi ta lấy byte cao lưu vào TMR0H, byte thấp lưu vào
TMR0L.

Bộ môn Kỹ Thuật Máy Tính 43 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

;=====================;
; Initializing timer 0: 16BIT
;=====================;
INIT_TIMER0
;enable priority interrupts.
BSF RCON,IPEN

;set Timer0 as a HIGH priority interrupt source


BSF INTCON2,TMR0IP

;Clear the Timer0 interrupt flag.


BCF INTCON,TMR0IF

;enable Timer0 interrupts


BSF INTCON,TMR0IE

;set the global interrupt enable bits


BSF INTCON,GIEH
BSF INTCON,GIEL
;initialize timer0: 10ms
CLRF T0CON
MOVLW 0x3c
MOVWF TMR0H
MOVLW 0xaf
MOVWF TMR0L
;turn on timer0
BSF T0CON,TMR0ON
RETURN
Bước 6: Viết chương trình con chạy trong timer, sau 1s tăng giá trị hiện thị
ra ngoài led đơn.
Vì cứ 100ms thì có ngắt một lần, do đó để sau 1s ta tăng lên một giá trị thì
cần 10 lần ngắt như vậy, nên ban đầu ta phải khởi tạo cho biến delay = 10. Và đây
là hàm chính thực hiện chức năng của bài tập 1.

TIMER0_ROUTINE
BCF INTCON,TMR0IF
DECFSZ delay,1
GOTO TIMER0_ROUTINE_1
INCF PORTB
MOVLW .10
MOVWF delay
TIMER0_ROUTINE_1
BCF T0CON,TMR0ON

Bộ môn Kỹ Thuật Máy Tính 44 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

MOVLW 0x3c
MOVWF TMR0H
MOVLW 0xaf
MOVWF TMR0L
BSF T0CON,TMR0ON
RETURN

Bộ môn Kỹ Thuật Máy Tính 45 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

4.2 Chương trình mẫu


;=====================================;
; Name: timer.asm
; Project: Sử dụng bộ timer 1 cứ sau 1s đếm lên 1 đơn vị rồi xuất giá trị ra led
; đơn.
; Author: BKIT HARDWARE CLUB
; Homepage: http://www.bkit4u.com/forum
; Creation Date: 8 - 6 - 2009
;======================================;

list p=18f4520
#include p18f4520.inc
delay res 1
org 0x0
goto MAIN

ORG 0x000008 ; high priority interrupt vector


GOTO ISR_HIGH

ORG 0x000018 ; low priority interrupt vector


GOTO ISR_LOW

MAIN
CALL INIT
CALL INIT_TIMER0
GOTO $
INIT
;assigning PORTB is a digital output
movlw 0x0e
movwf ADCON1
; setup portb for outputs
clrf TRISB
clrf PORTB
MOVLW .10
MOVWF delay
return

Bộ môn Kỹ Thuật Máy Tính 46 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

;===========================================;
; Initializing timer 0: 16BIT
;===========================================;
;to calculate the accurately timing scheduling of timer 0.
;we have to know something
;1. External clock: 4Mhz (this ex)
;2. Timer0 Prescaler: 1/2 (this ex)
;cycle of timer0 = 1/((Fexternal/4)/2) = 0.5us
INIT_TIMER0
BSF RCON,IPEN ;enable priority interrupts.
BSF INTCON2,TMR0IP
BSF INTCON,TMR0IF
BSF INTCON,TMR0IE
BSF INTCON,GIEH
BSF INTCON,GIEL
CLRF T0CON
MOVLW 0x3c
MOVWF TMR0H
MOVLW 0xAF
MOVWF TMR0L
BSF T0CON,TMR0ON
RETURN
ISR_HIGH ; high priority isr
BTFSC INTCON,TMR0IF
GOTO ISR_TIMER0_HIGH
ISR_TIMER0_HIGH
CALL TIMER0_ROUTINE
GOTO EXIT_ISR_HIGH
EXIT_ISR_HIGH
RETFIE
;===============================================;
; interrupt service routine for low priority interrupts
;===============================================;
ISR_LOW
BTFSC INTCON,TMR0IF
GOTO ISR_TIMER0_LOW
ISR_TIMER0_LOW
CALL TIMER0_ROUTINE
GOTO EXIT_ISR_LOW
EXIT_ISR_LOW
RETFIE

Bộ môn Kỹ Thuật Máy Tính 47 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

;===============================================;
;===============================================;
;===============================================;
;===============================================;
TIMER0_ROUTINE
BCF INTCON,TMR0IF
DECFSZ delay,1
GOTO TIMER0_ROUTINE_1
INCF PORTB
MOVLW .10
MOVWF delay
TIMER0_ROUTINE_1
BCF T0CON,TMR0ON
MOVLW 0x3c
MOVWF TMR0H
MOVLW 0xaf
MOVWF TMR0L
BSF T0CON,TMR0ON
RETURN
END

Yêu cầu 2 của bài thực hành này xem như bài tập

4.3 Bài tập


Dùng bộ định thời tạo xung vuông chu kì 10ms, duty cycle 30%.

Bộ môn Kỹ Thuật Máy Tính 48 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Bài 5 : Kỹ thuật quét ma trận phím

Nội dung:
Khảo sát cấu tạo, hoạt động của ma trận phím.
Tìm hiểu kỹ thuật lấy dữ liệu từ ma trận phím, chống rung phím nhấn.
Yêu cầu:
Viết chương trình lấy dữ liệu từ phím nhấn sau đó hiện thị giá trị của phím nhấn
ra led đơn.

5.1 Kết nối mạch ma trận phím


R1
ROW1
1 4 1 4 1 4 1 4
SW1 SW5 SW9 SW13
10K

R2
ROW2 2 3 2 3 2 3 2 3
1 4 1 4 1 4 1 4
SW2 SW6 SW10 SW14
10K

R3
ROW3 2 3 2 3 2 3 2 3
1 4 1 4 1 4 1 4
SW3 SW7 SW11 SW15
10K

R4
ROW4 2 3 2 3 2 3 2 3
1 4 1 4 1 4 1 4
SW4 SW8 SW12 SW16
10K

2 3 2 3 2 3 2 3
COLUMN1 COLUMN2 COLUMN3 COLUMN4

VCC R5 R6 R7 R8
100R 100R 100R 100R

COL1 COL2 COL3 COL4

J4

COL2 1 2 COL1
COL4 3 RD1 RD0 4 COL3
ROW2 5 RD3 RD2 6 ROW1
ROW4 7 RD5 RD4 8 ROW3
9 RD7 RD6 10
11 RE1 RE0 12
GNDVCC VCC

CON12A

Ma trận phím gồm 16 phím nhấn kết nối chung 4 hàng và 4 cột. Bốn cột COL1-
COL4 nối vào bốn bit thấp của Port D D0-D3. Bốn hàng ROW1-ROW4 nối vào bốn bit
cao của Port D D4-D7. Bốn hàng được nối với điện trở kéo lên để đảm bảo mức logic 1
khi phím không được nhấn.

Bộ môn Kỹ Thuật Máy Tính 49 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

5.2 Các bước hiện thực


Bước 1: Tạo project mới giống như hướng dẫn ở chương 1 lấy tên project
là Key và chọn chip 18f4520. Ta được hình sau:

Bước 2: Include file p18f4520.inc vào file key.asm


Bước 3: Define các port tương ứng với hàng và cột của ma trận phím để dễ

Bộ môn Kỹ Thuật Máy Tính 50 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

sử dụng sau này. Dựa vào sơ đồ mạch ta định nghĩa như sau:
#define COLUMN_1 PORTD, 0
#define COLUMN_2 PORTD, 1
#define COLUMN_3 PORTD, 2
#define COLUMN_4 PORTD, 3

#define ROW_1 PORTD, 4


#define ROW_2 PORTD, 5
#define ROW_3 PORTD, 6
#define ROW_4 PORTD, 7

Bước 4: Khởi tạo input và output cho các port tương ứng. Ở đây column là
output, còn row là input. Portb dùng để hiển thị led đơn cũng được cấu hình là
output.
INIT_IO
;assigning PORTB is a digital output
MOVLW 0x0F
MOVWF ADCON1
; setup portb for outputs
CLRF TRISB
CLRF PORTB
MOVLW 0x0F
MOVWF TRISD
MOVLW 0xFF
MOVWF PORTD
RETURN
Bước 5: Khởi tạo timer, phần này chúng ta đã học từ chương 4, ta có thể có
một hàm khởi tạo timer đơn giản như sau:
INIT_TIMER0
BSF RCON,IPEN ;enable priority interrupts.
BSF INTCON2,TMR0IP
BSF INTCON,TMR0IF
BSF INTCON,TMR0IE
BSF INTCON,GIEH
BSF INTCON,GIEL
CLRF T0CON
MOVLW 0x3c
MOVWF TMR0H
MOVLW 0xAF
MOVWF TMR0L
BSF T0CON,TMR0ON
RETURN
Bước 6: Viết hàm Get_key với 2 đối số. Đối số thứ nhất có tên là temp_wr,

Bộ môn Kỹ Thuật Máy Tính 51 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

chính là giá trị output tương ứng với các cột của ma trận phím, đối số thứ 2 có tến
là col chính là giá trị bắt đầu của mỗi cột. Ví dụ cột 1 thì giá trị đó bằng 0, cột 2 thì
giá trị đó bằng 1, cột 3 thì giá trị đó bằng 2 và cột 4 thì giá trị đó bằng 3.
GET_KEY
BTFSS temp_wr, 0
BCF COLUMN_1
BTFSS temp_wr, 0
BSF COLUMN_1
BTFSS temp_wr, 1
BCF COLUMN_2
BTFSS temp_wr, 1
BSF COLUMN_2
BTFSS temp_wr, 2
BCF COLUMN_3
BTFSS temp_wr, 2
BSF COLUMN_3
BTFSS temp_wr, 3
BCF COLUMN_4
BTFSS temp_wr, 3
BSF COLUMN_4

BTFSC PORTD,4 ;BIT TEST F, SKIP IF SET


GOTO NEXT_BUTTON_1
MOVLW .0
MOVWF KeyReg1
GOTO EXIT_GET_KEY

NEXT_BUTTON_1
BTFSC PORTD,5 ;BIT TEST F, SKIP IF SET
GOTO NEXT_BUTTON_2
MOVLW .4
MOVWF KeyReg1
GOTO EXIT_GET_KEY
NEXT_BUTTON_2
BTFSC PORTD,6 ;BIT TEST F, SKIP IF SET
GOTO NEXT_BUTTON_3
MOVLW .8
MOVWF KeyReg1
GOTO EXIT_GET_KEY
NEXT_BUTTON_3
BTFSC PORTD,7 ;BIT TEST F, SKIP IF SET
GOTO NEXT_BUTTON_2
MOVLW .12

Bộ môn Kỹ Thuật Máy Tính 52 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

MOVWF KeyReg1

EXIT_GET_KEY
MOVFF COL,W
ADDWF KeyReg1,d
RETURN
Bước 7: Dựa vào hàm Get_key ở trên ta có thể hoàn thiện hàm
Scan_button một cách dễ dàng. Ở đây ta nhắc lại cách mà sử lý phím để nhận dữ
liệu ngược trở về là tại một thời điểm chỉ cho một cột được tích cực (ở đây là mức
0) sau đó đọc ngược giá trị từ các hàng. Hàng 1 tương ứng với cột 1 là số 0, tương
tự hàng 2 với cột 1 là số 4…
Khi nhấn phím thì sẽ có hiện tượng rung phím, để giải quyết trường hợp
này ta có một cách giải quyết ở đây là đọc dữ liệu 3 lần liên tiếp mỗi lần cách nhau
10ms, sau đó so sánh 3 giá trị đọc được. Nếu 3 giá trị bằng nhau thì ta xem như có
một nút nhấn được nhấn. Trong hàm Scan_button ta dùng 3 biến KeyReg1,
KeyReg2 và KeyReg3 để lưu giá trị của 3 lần đọc dữ liệu liên tiếp, khi kiểm tra 3
biến này có giá trị bằng nhau thì ta sẽ lưu vào biến KeyReg và xuất dữ liệu ra
PORTB.

Scan_button
MOVFF KeyReg2,KeyReg3
MOVFF KeyReg1,KeyReg2

MOVLW 0x0E
MOVWF temp_wr
MOVLW .0
MOVWF COL
CALL GET_KEY

MOVLW 0x0D
MOVWF temp_wr
MOVLW .1
MOVWF COL
CALL GET_KEY

MOVLW 0x0B
MOVWF temp_wr
MOVLW .2
MOVWF COL
CALL GET_KEY

MOVLW 0x07
MOVWF temp_wr

Bộ môn Kỹ Thuật Máy Tính 53 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

MOVLW .3
MOVWF COL
CALL GET_KEY

MOVFF KeyReg1,W
CPFSEQ KeyReg2
GOTO EXIT_SCAN_BUTTON
CPFSEQ KeyReg3
GOTO EXIT_SCAN_BUTTON

MOVFF KeyReg,W
CPFSEQ KeyReg1
GOTO Scan_button1
GOTO EXIT_SCAN_BUTTON
Scan_button1
MOVFF KeyReg1,KeyReg
CALL Button_process

EXIT_SCAN_BUTTON
RETURN
Bước 8: Như giải thuật trên nói là cứ mỗi 10ms thì ta đọc dữ liệu một lần,
để cho điều này được thực hiện dễ dàng thì ta phải dùng đến interrupt timer. Ta
khởi tạo một interrupt timer cứ sau 10ms thì interrupt một lần. Để làm được điều
này các bạn có thể xem lại chương timer để có thể làm việc một cách dễ dàng.
Ở đây chỉ giới thiệu cho các bạn là hàm Timer0_routine, hàm này được gọi
trong interrupt timer và trong hàm này ta gọi hàm Scan_button ở trên.

TIMER0_ROUTINE

BCF INTCON,TMR0IF
BCF T0CON,TMR0ON
MOVLW 0x3c
MOVWF TMR0H
MOVLW 0xaf
MOVWF TMR0L
BSF T0CON,TMR0ON
CALL SCAN_BUTTON
RETURN

5.3 Bài tập


Cải tiến hàm chống rung phím, khi nhấn đè 1 phím thì phải sau 1 thời gian
TimeOutForKey thì mới tích cực phím nhấn đó.
Viết ứng dụng đồng hồ casio đơn giản (hiển thị giờ, ngày, cho phép chỉnh sửa

Bộ môn Kỹ Thuật Máy Tính 54 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

ngày giờ) sử dụng ma trận phím và LCD.

Bộ môn Kỹ Thuật Máy Tính 55 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Bài 6 : Kỹ thuật quét LED

Nội dung:
Khảo sát cấu tạo, hoạt động của LED 7 đoạn, LED ma trận.
Tìm hiểu kỹ thuật quét LED 7 đoạn và LED ma trận.
Yêu cầu:
Viết chương trình cho phép hiển thị giá trị ra led 7 đoạn và led ma trận.

6.1 Cấu tạo LED 7 đoạn và LED ma trận


LED 7 đoạn gồm có 7 đoạn được đánh dấu: a, b, c, d, e, f, g và một điểm dp.

LED 7 đoạn có hai loại là Common Anode và Common Cathode, tương ứng các
LED nối chung Anode hay nối chung Cathode.

LED ma trận 8x8 hai màu được bố trí thành 8 hàng và 8 cột. Mỗi điểm có hai
LED.

Bộ môn Kỹ Thuật Máy Tính 56 Thực hành Vi xử lý


Edited by Foxit Reader
Copyright(C) by Foxit Corporation,2005-2010
Trường ĐH. Bách Khoa TP.HCM For Evaluation Only. Khoa KH & KTMT

Các LED trên cùng một hàng nối chung Anode, các LED cùng loại trên cùng một
cột nối chung Cathode.

Bộ môn Kỹ Thuật Máy Tính 57 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

6.2 Kết nối mạch


ENABLE_LED1 ENABLE_LED2 ENABLE_LED3 ENABLE_LED4

LED1 LED2 LED3 LED4

8
A 7 A 7 A 7 A 7

Vcc

Vcc

Vcc

Vcc

Vcc

Vcc

Vcc

Vcc
B 6 a B 6 a B 6 a B 6 a
C 4 b C 4 b C 4 b C 4 b
D 2 c D 2 c D 2 c D 2 c
E 1
F 9
G 10
d
e
f
g
8. E 1
F 9
G 10
d
e
f
g
8. E 1
F 9
G 10
d
e
f
g
8. E 1
F 9
G 10
d
e
f
g
8.
DOT5 DOT5 DOT5 DOT5
dot dot dot dot

led7 led7 led7 led7

Green.1

Green.2

Green.3

Green.4
Row.1

Row.2

Row.3

Row.4
Red.1

Red.2

Red.3

Red.4
24 23 22 21 20 19 18 17 16 15 14 13
GR1

RD1

RW1

GR2

RD2

RW2

GR3

RD3

RW3

GR4

RD4

RW4
LED 8x8x2 ML1
GR5

RD5

RW5

GR6

RD6

RW6

GR7

RD7

RW7

GR8

RD8

RW8

1 2 3 4 5 6 7 8 9 10 11 12
Row.5

Row.6

Row.7

Row.8
Green.5

Green.6

Green.7

Green.8
Red.5

Red.6

Red.7

Red.8

Mạch LED mở rộng gồm có 4 LED 7 đoạn và 1 LED ma trận hai màu xanh đỏ.
Mạch được nối vào một phần của Port PICtail. Dữ liệu được dịch nối tiếp và được cài bởi
IC 74HC595, TPIC6595. Module SPI của PIC đảm nhận việc dịch dữ liệu nối tiếp thông
qua chân dữ liệu SDO và chân clock dịch SCK. Sau khi dịch đủ 4 byte, tín hiệu LATCH
chuyển từ mức 0 lên mức 1 sẽ đẩy dữ liệu của 4 byte tạm ra 4 byte ngõ ra QA-QH tương
ứng. Tín hiệu CLR_DISP tích cực mức 0 không cho phép hiển thị.

Bộ môn Kỹ Thuật Máy Tính 58 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

U1 TPIC6595

SDO 3 18
SDI SDO
LATCH 12 4 330 R1 Red.1
SCK 13 RCLK DRAIN0 5 330 R2 Red.2
VCC SRCLK DRAIN1 6 330 R3 Red.3
8 DRAIN2 7 330 R4 Red.4
CLR_DISP 9 SRCLR DRAIN3 14 330 R5 Red.5
G DRAIN4 15 330 R6 Red.6
DRAIN5 16 330 R7 Red.7
DRAIN6 17 330 R8 Red.8
DRAIN7

U2 TPIC6595
3 18
SDI SDO
LATCH 12 4 100 R9 Green.1
SCK 13 RCLK DRAIN0 5 100 R10 Green.2
VCC SRCLK DRAIN1 6 100 R11 Green.3
8 DRAIN2 7 100 R12 Green.4
CLR_DISP 9 SRCLR DRAIN3 14 100 R13 Green.5
G DRAIN4 15 100 R14 Green.6
DRAIN5 16 100 R15 Green.7 PICtail
DRAIN6 17 100 R16 Green.8 12
DRAIN7 SDO 11 RA3
10 RC5
SCK 9 RC4
U3 TPIC6595 8 RC3
3 18 LATCH 7 RA0
SDI SDO CLR_DISP 6 RA1
LATCH 12 4 330 R17 A 5 RA2
SCK 13 RCLK DRAIN0 5 330 R18 B 4 RC0
VCC SRCLK DRAIN1 6 330 R19 C 3 RC1
8 DRAIN2 7 330 R20 D 2 RC2
SRCLR DRAIN3 VCC +5V
CLR_DISP 9 14 330 R21 E 1
G DRAIN4 15 330 R22 F GND
DRAIN5 16 330 R23 G CON12
DRAIN6 17 330 R24 DOT
DRAIN7

U4 74HC595 VCC
14 9 U3
SDI SDO
9

LATCH 12 15 1 18 Row.1 ENABLE_LED1


V+

SCK 11 RCLK QA 1 2 IN1 OUT1 17 Row.2 ENABLE_LED2


VCC SRCLK QB 2 3 IN2 OUT2 16 Row.3 ENABLE_LED3
10 QC 3 4 IN3 OUT3 15 Row.4 ENABLE_LED4
13 CLR QD 4 5 IN4 OUT4 14 Row.5
G QE 5 6 IN5 OUT5 13 Row.6
QF 6 7 IN6 OUT6 12 Row.7
QG 7 8 IN7 OUT7 11 Row.8
QH IN8 OUT8
10
COM
UDN2981

6.3 Các thanh ghi liên quan và cách điều khiển


- Thanh ghi trạng thái SSPSTAT:

Bộ môn Kỹ Thuật Máy Tính 59 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

- Thanh ghi điều khiển SSPCON1:

- Sơ đồ khối module Synchronous Serial Port:

Với sơ đồ mạch trên, mỗi lần có một hàng LED ở LED ma trận hay một con LED
7 đoạn hiển thị dữ liệu. Lợi dụng hiện tượng lưu ảnh của mắt, dữ liệu của mỗi hàng LED
ma trận hay mỗi con LED 7 đoạn được xuất ra tuần tự hàng (con) này đến hàng (con)
khác, chúng ta sẽ thấy được hình ảnh của cả màn hình ma trận LED hay của cả 4 con
LED 7 đoạn.
Khi tất cả các hàng LED ma trận và tấc cả các con LED 7 đoạn đã được hiển thị
(quét) qua một lần, ta nói đã hiển thị một frame. Để mắt không cảm thấy hình ảnh bị rung
thì số lần hiển thị frame trong một giây phải lớn hơn 24 lần (thường là 30 lần).
Đầu tiên tín hiệu CLR_DISP tích cực (mức 0) không cho LED hiển thị, sau đó
dịch bốn byte dữ liệu, tín hiệu LATCH chuyển từ mức 0 lên mức 1 đưa dữ liệu mong
muốn sẵn sàn ở ngõ ra, cuối cùng đưa tín hiệu CLR_DISP lên mức 1 cho phép LED hiển
thị dữ liệu mong muốn. Cứ như vậy lặp lại chu trình này.

Bộ môn Kỹ Thuật Máy Tính 60 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Bốn byte dữ liệu được dịch ra mỗi lần có ý nghĩa tương ứng là dữ liệu của một
hàng LED đỏ, dữ liệu của một hàng LED xanh, dữ liệu của một con LED 7 đoạn, điều
khiển hàng (con) LED nào hiển thị.
Cách điều khiển được minh họa thông qua hình sau :

Giá trị của byte “control” chỉ chứa nhiều nhất một bit 1. Như hình vẽ, cần 12 lần
xuất dữ liệu (4 byte) cho 1 frame gồm cả LED ma trận và LED 7 đoạn, 8 lần xuất dữ liệu
cho 1 frame gồm chỉ có LED ma trận (không quan tâm nội dung hiển thị LED 7 đoạn), 4

Bộ môn Kỹ Thuật Máy Tính 61 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

lần xuất dữ liệu cho 1 frame gồm chỉ có LED 7 đoạn(không quan tâm nội dung hiển thị
LED ma trận).

6.4 Các bước hiện thực.


Bước 1: Tạo project mới giống như hướng dẫn ở chương 1 lấy tên project
là Led và chọn chip 18f4520. Ta được hình sau:

Bước 2: Include file p18f4520.inc vào file Led_matran.asm


Bước 3: Khai báo các buffer cần thiết để viết driver cho led. Vì ở đây ta
viết driver nên mọi người khi sử dụng những module này sẽ không sử dụng những
hàm mà chúng ta viết trong này chỉ có thể thao tác trên các buffer mà thôi.
GREEN_SCREEN_BUFFER RES .8
RED_SCREEN_BUFFER RES .8
SEVEN_LED_BUFFER RES .8
COLUMN_BUFFER RES .8

INDEX_OF_BUFFER RES .1

RED_DATA RES .1
GREEN_DATA RES .1
SEVEN_LED_DATA RES .1
COLUMN_DATA RES .1

Bước 4: Ngoài ra nhìn vào mạch ta có thể dễ dàng nhận thấy được rằng dữ
liệu của chúng ta được truyền theo kiểu truyền đồng bộ nối tiếp, chính xác hơn ở
đây người ta sử dụng chức năng SPI để truyền dữ liệu. Do đó ta phải cấu hình cho
chip làm sao có thể hoạt động được ở chế độ SPI này.
INIT_SPI
CLRF SSPCON1 ;SET Fspi = f/4
BSF SSPCON1,5 ;ENALBLE SPI MODE
BCF TRISC,5

Bộ môn Kỹ Thuật Máy Tính 62 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

BCF TRISC,3
RETURN
Trên đây ta mới chỉ khởi tạo module SPI để nó có thể hoạt động nhưng
nhìn lại sơ đồ mạch ta lại thấy có thêm vài kết nối nữa từ vi điều khiển ra
IC74595. Để IC này hoạt động được thì ta cần thêm một chân tạo clock để có thể
chuyển dữ liệu nối tiếp ra song song của IC này. Ta define thêm cho chân Latch
của IC 74595.
#define LATCH_DIR TRISA,1
#define LATCH_DATA PORTA,1
Đồng thời khởi tạo các PORT liên quan:
INIT
MOVLW 0x0F
MOVWF ADCON1

BCF LATCH_DIR
BCF LATCH_DATA
CLRF INDEX_OF_BUFFER
RETURN
Bước 5: Ngoài ra để thực hiện được bài này không thể nào thiếu timer
được, vì để hiển thị ra led ma trận ta phải quét từng cột led trên ma trận led.
Khi nhìn vào cấu tạo của ma trận led ta thấy để hiện thị được một hình gì
đó trên ma trận led thì ta phải quét led, vì tại một thời điểm chỉ có thể hiển thị một
cột led mà thôi. Nhờ vào hiện tượng lưu ảnh ở mắt mà khi quét với tần số cao thì
mắt ta sẽ thấy như là cột đó sáng chứ không phải chớp nháy nữa.
Vậy làm sao biết được ta quét led với tần số bao nhiêu là hợp lý. Như trong
phim ảnh khi xem phim thực chất ta biết là nó đang chạy với tần số là 24 hình /s.
Ở đây ta cũng giả sử như vậy, cả màn hình của led cũng chớp nháy với tần số là 24
hình/s, mà mỗi hình ta phải quét 8 lần vì có 8 cột. Từ đó ta có thể suy ra tần số ta
cần phải quét cho mỗi cột là 8x24 lần/s. Từ đây ta có thể dễ dàng tính được timer
của chúng ta cần bao nhiêu để có thể quét led được một cách dễ dàng.
INIT_TIMER0
BSF RCON,IPEN ;enable priority interrupts.
BSF INTCON2,TMR0IP
BSF INTCON,TMR0IF
BSF INTCON,TMR0IE
BSF INTCON,GIEH
BSF INTCON,GIEL
CLRF T0CON
MOVLW 0x3c
MOVWF TMR0H
MOVLW 0xAF
MOVWF TMR0L
BSF T0CON,TMR0ON

Bộ môn Kỹ Thuật Máy Tính 63 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

RETURN
Bước 6: Ban đầu ta khởi tạo các buffer để hiển thị cũng như quét cột led.
Để dễ dàng trong việc sử lý ta sẽ khởi tạo cho Column_Buffer các giá trị tương
ứng làm sao, khi xuất ra nó chỉ tích cực một cột của led mà thôi. Ở đây giả sử tích
cực tại mỗi cột là tích cực mức cao thì ta có thể khởi tạo cho Column_buffer các
giá trị sau: 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80.
Bước 7: Đến đây mọi sử chuẩn bị đã xong, ta có thể bắt đầu viết hàm để
hiển thị dữ liệu ra led. Đầu tiên ta sẽ viết một macro SPI_transmit với đối số sẽ là
giá trị byte sẽ được truyền nối tiếp ra ngoài.
SPI_TRANSMIT MACRO TEMP_DATA
;Has data been received (transmit complete)?
BTFSS SSPSTAT, BF
GOTO $-2 ;No
MOVF TEMP_DATA, W ;W reg = contents of TXDATA
MOVWF SSPBUF
ENDM
Bước 8: Tiếp theo là làm sao lấy dữ liệu từ các buffer để đưa vào các biến
tương ứng xuất ra led. Ta viết thêm một Macro nữa gồm 2 đối số là buffer và
temp_data. Macro này sẽ làm nhiệm vụ là lấy dữ liệu tại vị trí (được lưu trong biến
index_of_buffer) của buffer lưu vào temp_data.
UPDATE_DATA MACRO BUFFER,TEMP_DATA
MOVLW HIGH BUFFER
MOVWF FSR0H
MOVLW LOW BUFFER
MOVWF FSR0L
MOVFF INDEX_OF_BUFFER,W
ADDWF FSR0L,F
CLRF W
ADDWFC FSR0H
MOVFF INDF0,TEMP_DATA
ENDM
Bước 9: Như trên đã giới thiệu để xuất dữ liệu ra led, ngoài việc dùng
module SPI để xuất dữ liệu ta cần phải có thêm một tín hiệu clock tác động lên
IC74595 thì dữ liệu nối tiếp của ta mới chuyển qua song song và hiển thị ra led.
Do đó ta phải viết thêm một hàm tạo clock trên chân đã define khi nãy là
Latch_data.
CLOCK_STORAGE
BSF LATCH_DATA
NOP
NOP
BCF LATCH_DATA
NOP
NOP

Bộ môn Kỹ Thuật Máy Tính 64 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

BSF LATCH_DATA
RETURN
Bước 10: Cuối cùng là hàm quan trọng nhất, hàm này được gọi trong timer
để thực hiện việc quét led.
DISPLAY
CALL INCREASING_INDEX
UPDATE_DATA RED_SCREEN_BUFFER,RED_DATA
UPDATE_DATA GREEN_SCREEN_BUFFER,GREEN_DATA
UPDATE_DATA SEVEN_LED_BUFFER,SEVEN_LED_DATA
UPDATE_DATA COLUMN_BUFFER,COLUMN_DATA
SPI_TRANSMIT RED_DATA
SPI_TRANSMIT GREEN_DATA
SPI_TRANSMIT SEVEN_LED_DATA
SPI_TRANSMIT COLUMN_DATA
CALL CLOCK_STORAGE
RETURN

6.5 Bài tập


Xây dựng ứng dụng cho phép số “1234” chạy qua các led 7 đoạn.
Xây dựng ứng dụng cho phép 1 dòng chữ chạy qua led ma trận.

Bộ môn Kỹ Thuật Máy Tính 65 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Bài 7 : Khảo sát bộ truyền nhận nối tiếp

Nội dung:
Khảo sát cổng COM máy PC, các thông số truyền nối tiếp.
Khảo sát bộ truyền nối tiếp của PIC.
Tìm hiểu cách sử dụng chương trình Hyper Terminal truyền nhận nối tiếp trên
máy PC.
Yêu cầu:
Viết chương trình giao tiếp giữa máy tính và vi điều khiển PIC.

7.1 Các bước hiện thực.


Bước 1: Tạo project mới giống như hướng dẫn ở chương 1 lấy tên project
là Uart và chọn chip 18f4520. Ta được hình sau:

Bước 2: Include file p18f4520.inc vào file uart.asm


Bước 3: Khởi tạo PortB là output, PORTC.6 là output, PORTC.7 là input.
INIT_PORT
CLRF LATB ; Clear PORTB output latches
CLRF TRISB ; Config PORTB as all outputs
BCF TRISC,6 ; Make RC6 an output

Bộ môn Kỹ Thuật Máy Tính 66 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

BSF TRISC,7
RETURN

Bước 4: Khởi tạo các vector ngắt

org 00000h ; Reset Vector


goto Start

org 00008h ; Interrupt vector


goto IntVector

Start
GOTO $
IntVector
RETFIE

Bước 5: Khởi tạo cho ngắt UART, tốc độ 9600baud tại tần số 4Mhz.
INIT_UART
MOVLW 19h ; 9600 baud @4MHz
MOVWF SPBRG

BSF TXSTA,TXEN ; Enable transmit


BSF TXSTA,BRGH ; Select high baud rate

BSF RCSTA,SPEN ; Enable Serial Port


BSF RCSTA,CREN ; Enable continuous reception

BCF PIR1,RCIF ; Clear RCIF Interrupt Flag


BSF PIE1,RCIE ; Set RCIE Interrupt Enable
BSF INTCON,PEIE ; Enable peripheral interrupts
BSF INTCON,GIE ; Enable global interrupts
RETURN
Bước 6: Viết chương trình trong ngắt thực hiện nhiệm vụ nhận một dữ liệu
từ máy tính truyền xuống sau đó gởi lại kí tự đó cho máy tình nhận lại.
IntVector
btfss PIR1,RCIF ; Did USART cause interrupt?
goto ISREnd ; No, some other interrupt
movlw 06h ; Mask out unwanted bits
andwf RCSTA,W ; Check for errors
btfss STATUS,Z ; Was either error status bit set?
goto RcvError ; Found error, flag it

Bộ môn Kỹ Thuật Máy Tính 67 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

movf RCREG,W ; Get input data


movwf LATB ; Display on LEDs
movwf TXREG ; Echo character back
goto ISREnd ; go to end of ISR, restore context,
return

RcvError
bcf RCSTA,CREN ; Clear receiver status
bsf RCSTA,CREN
movlw 0FFh ; Light all LEDs
movwf PORTB
goto ISREnd ; go to end of ISR, restore context,
return

ISREnd
retfie

7.2 Chương trình mẫu


;=====================================;
; Name: uart.asm
; Project: Viết chương trình giao tiếp giữa máy tính và vi điều khiển PIC.
; Author: BKIT HARDWARE CLUB
; Homepage: http://www.bkit4u.com/forum
; Creation Date: 8 - 8 - 2009
;======================================;

list p=18F4520 ; set processor type


include <P18f4520.INC>

;************************************************************
; Reset and Interrupt Vectors

org 00000h ; Reset Vector


goto Start

org 00008h ; Interrupt vector


goto IntVector

;************************************************************
; Program begins here

Bộ môn Kỹ Thuật Máy Tính 68 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

org 00020h ; Beginning of program EPROM


Start
CALL INIT_PORT
CALL INIT_UART
Main
goto Main ; loop to self doing nothing

INIT_PORT
clrf LATB ; Clear PORTB output latches
clrf TRISB ; Config PORTB as all outputs
bcf TRISC,6 ; Make RC6 an output
bsf TRISC,7 ; Make RC7 an input
RETURN

INIT_UART
movlw 19h ; 9600 baud @4MHz
movwf SPBRG

bsf TXSTA,TXEN; Enable transmit


bsf TXSTA,BRGH ; Select high baud rate

bsf RCSTA,SPEN ; Enable Serial Port


bsf RCSTA,CREN ; Enable continuous reception

bcf PIR1,RCIF ; Clear RCIF Interrupt Flag


bsf PIE1,RCIE ; Set RCIE Interrupt Enable
bsf INTCON,PEIE ; Enable peripheral interrupts
bsf INTCON,GIE; Enable global interrupts
RETURN

;************************************************************
; Interrupt Service Routine

IntVector
btfss PIR1,RCIF ; Did USART cause interrupt?
goto ISREnd ; No, some other interrupt

movlw 06h ; Mask out unwanted bits


andwf RCSTA,W ; Check for errors
btfss STATUS,Z ; Was either error status bit set?
goto RcvError ; Found error, flag it

Bộ môn Kỹ Thuật Máy Tính 69 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

movf RCREG,W ; Get input data


movwf LATB ; Display on LEDs
movwf TXREG ; Echo character back
goto ISREnd ; go to end of ISR, restore context, return

RcvError
bcf RCSTA,CREN ; Clear receiver status
bsf RCSTA,CREN
movlw 0FFh ; Light all LEDs
movwf PORTB
goto ISREnd ; go to end of ISR, restore context, return

ISREnd
retfie
end

7.3 Bài tập


Viết chương trình trên PC, gửi 1 chuỗi string xuống board, dòng chữ này sẽ chạy
qua led ma trận hoặc LCD.
Khi nhấn 1 phím trên board nhấn, sẽ gửi 1 chuỗi string lên PC qua cổng COM,
viết chương trình trên PC nhận chuỗi string này và in ra giao diện.

Bộ môn Kỹ Thuật Máy Tính 70 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Bài 8 : Khảo sát khối chuyển đổi A-D

Nội dung:
Khảo sát hoạt động khối chuyển đổi A-D.
Khảo sát các thanh ghi điều khiển hoạt động khối chuyển đổi A-D.
Yêu cầu:
Viết chương trình đọc và hiển thị giá trị điện áp thay đổi bởi biến trở.

8.1 Các bước hiện thực


Bước 1: Tạo project mới giống như hướng dẫn ở chương 1 lấy tên project
là a2d và chọn chip 18f4520. Ta được hình sau:

Bước 2: Include file p18f4520.inc vào file a2d.asm


Bước 3: Khởi tạo module ADC để ta có thể sử dụng một cách dễ dàng.
InitializeAD
Movlw B'00000100' ; Make RA0,RA1,RA4 analog inputs
movwf ADCON1
movlw B'11000001' ; Select RC osc, AN0 selected,
movwf ADCON0 ; A/D enabled
movlw 0x01
movwf ADCON2
call SetupDelay ; delay for 15 instruction cycles
bsf ADCON0,GO ; Start first A/D conversion
return
Để khởi tạo được module ADC ta chỉ cần quan tâm chủ yếu tới các thanh

Bộ môn Kỹ Thuật Máy Tính 71 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

ghi ADCCON1, ADCCON0, ADCON2. Như chương trình khởi tạo trên ta thấy
đầu tiên phải cấu hình cho các pin tương ứng phải là chân AN0, mặc định của các
chân này có chức năng là Input/Output digital. Sau đó ta phải chọn kênh ADC
tương ứng, ở đây ta sử dụng kênh AD0. Và một điểm quan trọng nữa chính là bit
GO trong thanh ghi ADCON0, khi bít này được bật lên thì module AD mới bắt
đầu chuyển đổi tín hiệu.
Bước 4: Tiếp theo là hàm đọc giá trị ADC:
Update_adc
bsf ADCON0,GO ;start conversion
btfsc ADCON0,GO
bra $-2
movf ADRESH,W
return
Sau khi chuyển đổi tín hiệu A-D, giá trị số sẽ được lưu vào thanh ghi
ADRESH. Đến đây tùy vào ứng dụng cụ thể mà ta có thể biến đổi giá trị này tùy
theo yêu cầu mà ta mong muốn.

8.2 Bài tập


Tích hợp module LCD, lấy giá trị điện thế từ biến trở hiển thị lên LCD.
Sử dụng module ADC của Pic để đo nhiệt độ trong phòng, dùng LCD để hiển thị
giá trị nhiệt độ.

Bộ môn Kỹ Thuật Máy Tính 72 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

Bài 9 : Khảo sát các khối chức năng đặc biệt khác

Nội dung:
Khảo sát khối chức năng WDT.
Khảo sát khối chức năng PWM .
Khảo sát các chế độ hoạt động của vi điều khiển.
Yêu cầu:
Viết chương trình sử dụng chức năng WDT.
Viết chương trình sử dụng chức năng PWM điều khiển độ sáng của LED.
Viết chương trình sử dụng chức năng Power control.

9.1 Các bước hiện thực PWM


Bước 1: Tạo project mới giống như hướng dẫn ở chương 1 lấy tên project
là pwm và chọn chip 18f4520. Ta được hình sau:

Bước 2: Include file p18f4520.inc vào file pwm.asm.


Bước 3: Tích hợp module LCD vào project pwm, tham khảo bài tập về
LCD.
Bước 4: Khởi tạo module PWM để ta có thể sử dụng một cách dễ dàng.
Init_pwm
;configure CCP1 module for buzzer
bcf TRISC,2
movlw 0x80

Bộ môn Kỹ Thuật Máy Tính 73 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

movwf PR2 ;initialize PWM period


movlw 0x80 ;initialize PWM duty cycle
movwf CCPR1L
bcf CCP1CON,CCP1X
bcf CCP1CON,CCP1Y

;postscale 1:1, prescaler 4, Timer2 ON


movlw 0x05
movwf T2CON
movlw 0x0F ;turn buzzer on
movwf CCP1CON
return

Để khởi tạo chức năng pwm, đầu tiên ta phải cấu hình cho PORTC2 là
output. Tiếp theo khởi tạo chu kì của PWM thông qua việc cấu hình thanh ghi
PR2. Sau đó ta khởi tạo duty cycle của xung pwm bằng cách cấu hình thanh ghi
CCPR1L.

9.2 Chương trình mẫu


;=====================================;
; Name: pwm.asm
; Project: Su dung Pwm de xuat am thanh ra loa.
; Author: BKIT HARDWARE CLUB
; Homepage: http://www.bkit4u.com/forum
; Creation Date: 20 - 8 - 2009
;======================================;

list p=18f4520
#include "p18f4520.inc"

; vectors

org 0x000000 ; reset vector


bra START

;************************************************************
; program
START
call Init_pwm

Bộ môn Kỹ Thuật Máy Tính 74 Thực hành Vi xử lý


Trường ĐH. Bách Khoa TP.HCM Khoa KH & KTMT

goto $

Init_pwm
bcf TRISC,2
movlw 0x80
movwf PR2 ;initialize PWM period
movlw 0x80 ;initialize PWM duty cycle
movwf CCPR1L
bcf CCP1CON,CCP1X
bcf CCP1CON,CCP1Y

;postscale 1:1, prescaler 4, Timer2 ON


movlw 0x05
movwf T2CON
movlw 0x0F ;turn buzzer on
movwf CCP1CON
return

END

9.3 Bài tập


Tìm hiểu và hiện thực chương trình điều khiển RC Servo.

Bộ môn Kỹ Thuật Máy Tính 75 Thực hành Vi xử lý

You might also like