Trong tutorial 2, việc xuấtdữ liệu ra các ngõ rasố đã được giới thiệu. Tutorial này
giới thiệu thêm thao tác đọc các ngõ vàosố,với các vídụcụ thể là đọc trạng thái các
công tác và trạng tháicờbậncủaLCD. Mộtsốlệnhmới thuộc các nhómlệnh di chuyển
dữ liệu, lệnhluậnlý, vàlệnh so sánh được giới thiệu ở đây. Ngoài ra, macro vàkỹ thuật
định thờidùng ngắt ởmứctối thiểucũng được giới thiệu.
15 trang |
Chia sẻ: lvbuiluyen | Lượt xem: 2561 | Lượt tải: 1
Bạn đang xem nội dung tài liệu Tìm hiểu Lập trình hợp ngữ với dsPIC, để tải tài liệu về máy bạn click vào nút DOWNLOAD ở trên
Người báo cáo: Nguyễn Quang Nam Tài liệu: TUT04.01
Ngày: 8/3/2006 Trang: 1/15
Tutorial no 04.01
Gửi đến: Đoàn Hiệp, www.picvietnam.com
Nội dung: Chương trình hợp ngữ giao tiếp nút nhấn/công tắc và LCD với dsPIC
MICROSOFT WORD
Tóm tắt:
Đây là tutorial 3 về lập trình hợp ngữ với dsPIC. Tutorial này hướng dẫn viết chương trình hợp
ngữ giao tiếp với các nút nhấn/công tắc và LCD cho dsPIC: minh hoạ cách đọc tín hiệu ngõ vào số,
điều khiển LCD bằng phương pháp định thời và kiểm tra cờ bận (busy flag). Một số lệnh và kỹ thuật
lập trình mới cũng được giới thiệu.
1. Giới thiệu
Trong tutorial 2, việc xuất dữ liệu ra các ngõ ra số đã được giới thiệu. Tutorial này
giới thiệu thêm thao tác đọc các ngõ vào số, với các ví dụ cụ thể là đọc trạng thái các
công tác và trạng thái cờ bận của LCD. Một số lệnh mới thuộc các nhóm lệnh di chuyển
dữ liệu, lệnh luận lý, và lệnh so sánh được giới thiệu ở đây. Ngoài ra, macro và kỹ thuật
định thời dùng ngắt ở mức tối thiểu cũng được giới thiệu.
2. Các quy ước trong tài liệu
Mô tả Biểu thị Ví dụ
Font Palatino Linotype:
In nghiêng Tài liệu tham khảo
dsPIC30F/33F
Programmer’s Reference
Manual
Viết hoa chữ đầu Một menu, hộp thoại Chọn Project Wizard
Đặt trong dấu nháy kép
Tên riêng (của tập tin,
project, …) “Vidu3”
Font Courier:
Mã nguồn mov #0x8010, W0
Courier thường
Tên tập tin Vidu3-1.s
3. Các ví dụ về công tắc và LCD
Bạn hãy chép các tập tin nguồn được đính kèm vào một thư mục nào đó mà bạn sẽ
dùng để tạo ra project “Vidu3”. Hình 3.1 thể hiện sơ đồ nguyên lý của mạch phần cứng
Người báo cáo: Nguyễn Quang Nam Tài liệu: TUT04.01
Ngày: 8/3/2006 Trang: 2/15
được dùng với tutorial này, chú ý là chân RF3 cùng với mạch điều khiển đèn nền
(backlight) của LCD không được thể hiện trong sơ đồ nguyên lý. Cũng tương tự như
trong tutorial 2, bạn không cần thực hiện phần mạch nằm trong khung nét đứt nếu bạn
dùng bộ dao động nội của dsPIC.
RE[0..3]
RB[0..4]
RB0
RB1
RB2
RB3
RB4
R
B
0
R
B
0
R
B
1
R
B
1
R
B
2
R
B
2
R
B
3
R
B
3
R
B
4
R
B
4
RE0
RE1
RE2
RE3
R
D
1
R
D
0
R
E
8
RE8
RD0
RD1
R
E
0
R
E
1
R
E
2
R
E
3
CLKIN/OSC19
RC15/CLKO/OSC210
MCLR1
RB0/CN2/VREF+/AN0/EMUD32
RB1/CN3/VREF-/AN1/EMUC33
RB2/CN4/SS1/AN24
RB3/CN5/INDX/AN35
RB4/CN6/IC7/QEA/AN46
RB5/CN7/IC8/QEB/AN57
RC13/CN1/U1ATX/T2CK/SOSCI/EMUD11
RC14/CN0/U1ARX/T1CK/SOSCO/EMUC12
EMUC2/OC1/IC1/INT1/RD015
EMUD2/OC2/IC2/INT2/RD114
RE0/PWM1L 26
RE1/PWM1H 25
RE2/PWM2L 24
RE3/PWM2H 23
RE4/PWM3L 22
RE5/PWM3H 21
FLTA/INT0/RE8 16
RF2/SDA/SDI1/U1RX/EMUC/PGC 18
RF3/SCL/SDO1/U1TX/EMUD/PGD 17
AVDD 28
AVSS 27
U1
DSPIC30F4012DIP
Vdd
X1
8MHz
C1
33pF
C2
33pF
Vdd
R1 33k
1234567
141312111098
SW1
2345678 1
RP1
10k
D
7
14
D
6
13
D
5
12
D
4
11
D
3
10
D
2
9
D
1
8
D
0
7
E
6
R
W
5
R
S
4
V
SS
1
V
D
D
2
V
EE
3
LCD1
LM016L
RV1
5k
Hình 3.1: Sơ đồ nguyên lý phần cứng dùng cho tutorial 3
3.1. Ví dụ 3-1
Làm theo các bước như trong tutorial 1 để tạo ra một project có tên là “Vidu3”, sau
đó bạn thêm vào project tập tin nguồn “Vidu3-1.s” và kịch bản liên kết
“p30f4012.gld”. Để tiện theo dõi, chương trình nguồn “Vidu3-1.s” được liệt kê
dưới đây, với một số phần chú thích được cắt bỏ cho thuận tiện. Vì các lệnh đã được
chú thích khá chi tiết, tôi chỉ giải thích một số điểm mới trong chương trình, tại những
dòng lệnh mà tôi đã đánh số (để tiện giải thích).
Liệt kê mã nguồn “Vidu3-1.s”:
.include "p30fxxxx.inc"
config __FOSC, CSW_FSCM_OFF & FRC_PLL4 ;Clock = 32 MHz
config __FWDT, WDT_OFF
config __FBORPOR, MCLR_EN & PBOR_OFF
config __FGS, CODE_PROT_OFF
Người báo cáo: Nguyễn Quang Nam Tài liệu: TUT04.01
Ngày: 8/3/2006 Trang: 3/15
;-------------------------------------------------------------------------------
;Cac hang so cua chuong trinh (gia tri tuc thoi dung trong chuong trinh)
.equiv ms_count, 125 ;So dem tuong ung voi 1 ms, cho timer 1
.equiv LCD_BL, 3 ;Tin hieu Back Light cho LCD, chan RF3
.equiv LCD_EN, 8 ;Tin hieu Enable cho LCD, chan RE8
.equiv LCD_RW, 0 ;Tin hieu Read/Write cho LCD, chan RD0
.equiv LCD_RS, 1 ;Tin hieu Reset cho LCD, chan RD1
.equiv LCD_DAT, LATE ;Cac tin hieu Data cho LCD, chan RE0..RE3 (D4..D7)
.equiv LCD_TRIS, TRISE ;Tristate cua cac tin hieu Data cho LCD
.equiv LCD_clear, 0x01 ;Xoa man hinh LCD
.equiv LCD_home, 0x02 ;Tro ve dau dong
.equiv LCD_normal, 0x06 ;Che do nhap du lieu binh thuong
.equiv LCD_normal_s, 0x07 ;Che do nhap du lieu binh thuong, dich man hinh
.equiv LCD_off, 0x08 ;Tat man hinh
.equiv LCD_on, 0x0C ;Bat man hinh
.equiv LCD_on_crsr, 0x0E ;Bat man hinh va con tro
.equiv LCD_on_blink, 0x0F ;Bat man hinh va con tro (nhap nhay)
.equiv LCD_4b2l, 0x28 ;Che do 2 dong, giao tiep 4 bit du lieu
.equiv LCD_homeL1, 0x80 ;Ve dau dong 1
.equiv LCD_homeL2, 0xC0 ;Ve dau dong 2
;-------------------------------------------------------------------------------
;Cac khai bao toan cuc:
.global __reset ;Khai bao nhan bat dau chuong trinh (bat buoc)
.global __T1Interrupt;Khai bao toan cuc chuong trinh xu ly ngat Timer 1
;Khai bao bang hang so trong ROM
.section Chuoi1, psv, address(0x0300) ;Chuoi ky tu se xuat ra LCD
.asciz "Hello world!" ;Chuoi ky tu se duoc xuat ra LCD
;-------------------------------------------------------------------------------
;Khai bao cac bien trong RAM
.section .bss
.align 2 ;Chinh dia chi theo boi so cua 2
time_out: .space 2 ;Khai bao bien 'time_out' kieu word (2 byte)
;-------------------------------------------------------------------------------
;Cac macro
Người báo cáo: Nguyễn Quang Nam Tài liệu: TUT04.01
Ngày: 8/3/2006 Trang: 4/15
.macro DelayNTcy n ;Macro tao tre n chu ky lenh, n > 2
1 repeat #(\n-1)
2 nop
.endm
;-------------------------------------------------------------------------------
;Doan ma trong vung nho chuong trinh
.text ;Bat dau doan ma chuong trinh
__reset:
mov #__SP_init, W15 ;Khoi tao con tro ngan xep (stack)
mov #__SPLIM_init, W0
mov W0, SPLIM ;Khoi tao thanh ghi gioi han con tro ngan xep (stack)
nop ;Can mot lenh NOP sau khi ghi vao SPLIM
clr W0 ;Xoa thanh ghi lam viec W0
mov W0, W14 ;Xoa cac thanh ghi W1 den W14
repeat #12
mov W0,[++W14] ;Dia chi cua cac thanh ghi: 0x0002 - 0x001C
clr W14
;-------------------------------------------------------------------------------
rcall Init_TMR1 ;Khoi tao cho TMR1
rcall Init_PORTS ;Khoi tao cac cong I/O
bset CORCON, #PSV ;Cho phep dung PSV
mov #psvpage(Chuoi1), W0 ;Lay dia chi cua chuoi ky tu
mov W0, PSVPAG ;ghi vao thanh ghi trang PSV
mov #psvoffset(Chuoi1), W4 ;W4 la con tro den chuoi ky tu
mov #(ms_count*50), W0 ;Nguong tran 50 ms cho timer 1
rcall Delay_ms ;Yeu cau cho 50 ms
rcall Init_LCD ;Het thoi gian cho, vay khoi tao module LCD
mov #(ms_count*500), W0 ;Nguong tran 500 ms cho timer 1
rcall Delay_ms ;Yeu cau cho 500 ms
wrt_loop1:
mov.b [W4++], W0 ;Doc mot ky tu
3 cp0.b W0 ;Da het chuoi chua?
bra z, homeL2 ;Da het chuoi, vay nhay den lenh chuyen dong
rcall LCD_dat4 ;Chua het chuoi, xuat ky tu trong W0 ra LCD
mov #(ms_count*1), W0 ;Nguong tran 1 ms cho timer 1
rcall Delay_ms ;Yeu cau cho 1 ms
Người báo cáo: Nguyễn Quang Nam Tài liệu: TUT04.01
Ngày: 8/3/2006 Trang: 5/15
bra wrt_loop1 ;Chuyen sang ky tu ke tiep
homeL2:
mov #LCD_homeL2, W0 ;Chuyen den dau dong thu hai
rcall LCD_cmd4
mov #(ms_count*1), W0 ;Nguong tran 1 ms cho timer 1
rcall Delay_ms ;Yeu cau cho 1 ms
mov #psvoffset(Chuoi1), W4 ;W4 la con tro den chuoi ky tu
wrt_loop2:
mov.b [W4++], W0 ;Doc mot ky tu
cp0.b W0 ;Da het chuoi chua?
bra z, main_loop ;Da het chuoi, vay nhay den vong lap chinh
rcall LCD_dat4 ;Xuat ky tu trong W0 ra LCD
mov #(ms_count*1), W0 ;Nguong tran 1 ms cho timer 1
rcall Delay_ms ;Yeu cau cho 1 ms
bra wrt_loop2 ;Chuyen sang ky tu ke tiep
main_loop:
nop
nop
bra main_loop ;Vong lap chinh, khong lam viec gi het
;-------------------------------------------------------------------------------
;Chuong trinh con khoi tao TMR1
;TMR1 duoc dung de dem so ms troi qua, o muc xung 8 Mips (fcy = 8 MHz)
;-------------------------------------------------------------------------------
Init_TMR1:
clr TMR1 ;Xoa so dem cua TMR1
mov #ms_count, W0 ;TMR1 tran moi ms
mov W0, PR1 ;Dat nguong tran vao PR1
bclr IFS0, #T1IF ;Xoa co ngat cua TMR1
mov #0x0020, W0 ;TMR1 dung fcy lam clock, prescale la 1:64,
mov W0, T1CON ;nhung chua cho phep TMR1 chay
bset IEC0, #T1IE ;Cho phep ngat khi TMR1 tran
return
;-------------------------------------------------------------------------------
;Chuong trinh con khoi tao cac cong I/O, de noi voi LCD
;-------------------------------------------------------------------------------
Init_PORTS:
Người báo cáo: Nguyễn Quang Nam Tài liệu: TUT04.01
Ngày: 8/3/2006 Trang: 6/15
mov LCD_DAT, W0
4 and.b #0xF0, W0
mov W0, LCD_DAT ;Xoa cac bit chot du lieu LCD
mov LCD_TRIS, W0
and.b #0xF0, W0
mov W0, LCD_TRIS ;Cac chan du lieu LCD la ngo ra
bset LATF, #LCD_BL ;
bclr TRISF, #LCD_BL ;RF3 la ngo ra, noi vao back light LED
bclr LATE, #LCD_EN ;
bclr TRISE, #LCD_EN ;RE8 la ngo ra, noi vao Enable cua LCD
bclr LATD, #LCD_RW ;
bclr TRISD, #LCD_RW ;RD0 la ngo ra, noi vao R/W cua LCD
bclr LATD, #LCD_RS ;
bclr TRISD, #LCD_RS ;RD1 la ngo ra, noi vao Reset cua LCD
return
;-------------------------------------------------------------------------------
;Chuong trinh con delay bang timer 1, gia tri so dem nam trong W0
;-------------------------------------------------------------------------------
Delay_ms:
mov W0, PR1 ;Dat nguong tran vao PR1
bclr time_out, #0 ;Xoa co het thoi gian cho
bset T1CON, #TON ;Bat timer 1
btss time_out, #0 ;Chua het thoi gian cho?
bra $-2 ;Dung, vay tiep tuc cho
bclr T1CON, #TON ;Tat timer 1
clr TMR1
return
;Chuong trinh con khoi tao module LCD
;-------------------------------------------------------------------------------
Init_LCD:
mov #LCD_4b2l, W0 ;Dat che do giao tiep 4-bit, man hinh 2 dong
rcall LCD_cmd4
mov #(ms_count*1), W0 ;Nguong tran 1 ms cho timer 1
rcall Delay_ms ;Yeu cau cho 1 ms
mov #LCD_off, W0 ;Tat man hinh
rcall LCD_cmd4
mov #(ms_count*1), W0 ;Nguong tran 1 ms cho timer 1
rcall Delay_ms ;Yeu cau cho 1 ms
mov #LCD_normal, W0 ;Che do nhap du lieu binh thuong
Người báo cáo: Nguyễn Quang Nam Tài liệu: TUT04.01
Ngày: 8/3/2006 Trang: 7/15
rcall LCD_cmd4
mov #(ms_count*1), W0 ;Nguong tran 1 ms cho timer 1
rcall Delay_ms ;Yeu cau cho 1 ms
mov #LCD_on_blink, W0 ;Bat man hinh, hien con tro nhap nhay
rcall LCD_cmd4
mov #(ms_count*1), W0 ;Nguong tran 1 ms cho timer 1
rcall Delay_ms ;Yeu cau cho 1 ms
mov #LCD_clear, W0 ;Xoa man hinh
rcall LCD_cmd4
mov #(ms_count*5), W0 ;Nguong tran 5 ms cho timer 1
rcall Delay_ms ;Yeu cau cho 5 ms
bclr LATF, #LCD_BL
return
;-------------------------------------------------------------------------------
;Chuong trinh con xuat lenh o che do 4 bit
;Lenh 8-bit dat trong W0, se huy noi dung cua W1, W2
;-------------------------------------------------------------------------------
LCD_cmd4:
bclr LATD, #LCD_RW
bclr LATD, #LCD_RS ;Dat che do xuat lenh
mov LCD_DAT, W1 ;Lay trang thai hien thoi cua thanh ghi chot cong E
and.b #0xF0, W1 ;Xoa 4 bit thap nhat cua LCD_DAT
mov W0, W2 ;Giu lai lenh can xuat trong W2
5 swap.b W0 ;Lay 4 bit cao cua lenh can xuat o RE3..RE0
and.b #0x0F, W0 ;Xoa 4 bit cao cua W0
6 ior.b W1, W0, W1
mov W1, LCD_DAT ;Xuat nibble cao cua lenh ra RE3..RE0
bset LATE, #LCD_EN ;Tao xung Enable
7 DelayNTcy 8
bclr LATE, #LCD_EN ;keo dai toi thieu 1 us
mov LCD_DAT, W1 ;Lay trang thai hien thoi cua thanh ghi chot cong E
and.b #0xF0, W1 ;Xoa 4 bit thap nhat cua LCD_DAT
mov W2, W0 ;Lay lai lenh can xuat tu W2 vao W0
and.b #0x0F, W0 ;Xoa 4 bit cao cua W0
ior.b W1, W0, W1
mov W1, LCD_DAT ;Xuat nibble thap cua lenh ra RE3..RE0
bset LATE, #LCD_EN ;Tao xung Enable
DelayNTcy 8
bclr LATE, #LCD_EN ;keo dai toi thieu 1 us
return ;Xong viec, tro ve chuong trinh goi
Người báo cáo: Nguyễn Quang Nam Tài liệu: TUT04.01
Ngày: 8/3/2006 Trang: 8/15
;-------------------------------------------------------------------------------
;Chuong trinh con xuat du lieu o che do 4 bit
;Du lieu 8-bit dat trong W0, se huy noi dung cua W1, W2
;-------------------------------------------------------------------------------
LCD_dat4:
bclr LATD, #LCD_RW
bset LATD, #LCD_RS ;Dat che do xuat du lieu
mov LCD_DAT, W1 ;Lay trang thai hien thoi cua thanh ghi chot cong E
and.b #0xF0, W1 ;Xoa 4 bit thap nhat cua LCD_DAT
mov W0, W2 ;Giu lai du lieu can xuat trong W2
swap.b W0 ;Lay 4 bit cao cua lenh can xuat o RE3..RE0
and.b #0x0F, W0 ;Xoa 4 bit cao cua W0
ior.b W1, W0, W1 ;
mov W1, LCD_DAT ;Xuat nibble cao cua du lieu ra RE3..RE0
bset LATE, #LCD_EN ;Tao xung Enable
DelayNTcy 8
bclr LATE, #LCD_EN ;keo dai toi thieu 1 us
mov LCD_DAT, W1 ;Lay trang thai hien thoi cua thanh ghi chot cong E
and.b #0xF0, W1 ;Xoa 4 bit thap nhat cua LCD_DAT
mov W2, W0 ;Lay lai du lieu can xuat tu W2 vao W0
and.b #0x0F, W0 ;Xoa 4 bit cao cua W0
ior.b W1, W0, W1 ;
mov W1, LCD_DAT ;Xuat nibble thap cua du lieu ra RE3..RE0
bset LATE, #LCD_EN ;Tao xung Enable
DelayNTcy 8
bclr LATE, #LCD_EN ;keo dai toi thieu 1 us
return ;Xong viec, tro ve chuong trinh goi
;-------------------------------------------------------------------------------
;Trinh phuc vu ngat cho TMR1
;Timer 1 dung de dinh cac thoi gian cho >= 1 ms, va toi da khoang 500 ms
;-------------------------------------------------------------------------------
__T1Interrupt: ;Ten nay da duoc dinh truoc trong tap tin lien ket
bclr IFS0, #T1IF ;Truoc tien, can xoa co ngat
bset time_out, #0 ;Bat co het thoi gian cho
retfie ;Tro ve tu ngat
;-------------------------------------------------------------------------------
.end ;Ket thuc phan ma trong tap tin nay
Người báo cáo: Nguyễn Quang Nam Tài liệu: TUT04.01
Ngày: 8/3/2006 Trang: 9/15
Các dòng 1 và 2 là phần thân của macro DelayNTcy, dùng để tạo trễ n chu kỳ lệnh
(với n > 2, vì để làm trễ 1 hay 2 chu kỳ lệnh đã có lệnh nop hay bra $+2). Bạn dùng
dẫn hướng .macro để khai báo điểm bắt đầu macro, tên của macro và danh sách
các đối số (nếu có), và dùng .endm để đánh dấu điểm kết thúc macro. Nếu bạn đã
khai báo một đối số là ds với dẫn hướng .macro, bạn có thể truy xuất đối số đó
trong macro bằng cách dùng \ds hay &ds&. Dạng truy xuất thứ hai (&ds&) cho
phép bạn nối đối số với các ký tự để tạo ra một tên ký hiệu.
Trong macro DelayNTcy, tôi dùng một đối số là n, để đặt tham số cho lệnh
repeat. Do đặc điểm của lệnh repeat, chúng ta chỉ đặt tham số cho lệnh này là n-
1 nếu cần lặp lại n lần lệnh kế tiếp. Để đảm bảo thứ tự tính toán khi trình hợp dịch
khai triển macro, chúng ta viết #(\n–1) để khi khai triển thì phép trừ được thực
hiện trước, và đối số của lệnh repeat là một giá trị tức thời. Dòng 7 minh họa cách
dùng của macro này trong chương trình. Bạn hãy tham khảo thêm phần “6.11
Directives for substitution/expansion“ của tài liệu MPLAB® ASM30/LINK30 and
Utilities User’s Guide (phiên bản hiện thời là DS51317E) về macro và các dẫn hướng
tương tự dùng cho việc thay thế và khai triển khi hợp dịch.
Tại dòng 3, chúng ta gặp một lệnh mới, cp0. Lệnh này cho phép chúng ta so sánh
một thanh ghi nào đó (nằm trong 8192 địa chỉ RAM đầu tiên) với giá trị zero (0). Bạn
có thể so sánh byte hay word, bằng cách dùng phần mở rộng .B và .W tương ứng.
Bạn có thể dùng lệnh này với chế độ định vị gián tiếp, và khi đó bạn có thể cập nhật
thanh ghi con trỏ ngay trong lệnh.
Tại dòng 4 và 6 là các lệnh and và ior, dùng để thực hiện các phép toán logic AND
và OR. Bạn chú ý là từ khóa cho lệnh thực hiện phép toán OR là ior (inclusive or),
đối lập với lệnh thực hiện phép toán XOR là xor (exclusive or). Các lệnh này cũng
cho phép bạn thao tác trên byte hay word, với các phần mở rộng tương ứng được
dùng trong lệnh. Như trong chương trình đã minh họa, bạn có thể dùng các toán
hạng tức thời với thanh ghi làm việc Wn, hai toán hạng thanh ghi làm việc Wb, Ws
và ghi kết quả vào thanh ghi làm việc thứ ba Wd. Ngoài ra, bạn còn có thể dùng một
ô nhớ và thanh ghi làm việc WREG (W0), hay một thanh ghi làm việc Wb và toán
hạng tức thời, và ghi kết quả vào thanh ghi làm việc Wd.
Dòng 5 là một ví dụ về lệnh hoán đổi các nibble trong một byte, swap.b. Đương
nhiên phần mở rộng .b là để thao tác trên một byte. Nếu bạn dùng phần mở rộng
.w hay chỉ dùng swap (vì phần mở rộng .w được hiểu ngầm), bạn sẽ thực hiện hoán
đổi các byte của một word. Lệnh swap chỉ chấp nhận toán hạng là một trong các
thanh ghi làm việc Wn.
Bạn hãy để ý rằng chương trình xử lý ngắt ở đây rất ngắn, ngoài 2 lệnh bắt buộc
phải có là xóa cờ ngắt và trở về từ ngắt, tôi chỉ dùng thêm một lệnh để bật một cờ
báo hiệu hết thời gian chờ. Như vậy, chương trình xử lý ngắt chỉ chiếm một phần rất
Người báo cáo: Nguyễn Quang Nam Tài liệu: TUT04.01
Ngày: 8/3/2006 Trang: 10/15
nhỏ trong tổng thời gian thực thi của toàn chương trình, và do đó bạn sẽ có thể dễ
dàng xử lý nhiều ngắt cùng mức ưu tiên một cách nhanh chóng.
Một điểm chú ý khác trong chương trình là chương trình con khởi tạo LCD. Theo tài
liệu kỹ thuật của chip HD44780U (đa số các chip điều khiển LCD dạng văn bản
tương thích với chip này) thì việc khởi tạo chế độ giao tiếp 4 bit cần tuân theo quy
trình sau:
- Ghi giá trị hex 3x (x là một chữ số hex bất kỳ), sau đó chờ 4.1 ms
- Ghi giá trị hex 3x, sau đó chờ 100 ms
- Ghi giá trị hex 3x, rồi đến giá trị hex 2x
Kể từ thời điểm này, chip có thể giao tiếp ở chế độ 4-bit.
Tuy nhiên, thử nghiệm thực tế của tôi cho thấy có thể bỏ qua 3 lệnh ghi giá trị hex 3x
mà vẫn có thể giao tiếp với LCD ở chế độ 4-bit, nếu module LCD này đã vừa mới
làm việc ở chế độ giao tiếp 4-bit trước đó. Tôi cho rằng một số module LCD ghi nhớ
chế độ giao tiếp gần nhất. Do đó, nếu bạn không thể khởi tạo module LCD bằng
chương trình con đã đưa ra ở đây, bạn hãy bổ sung thêm các dòng lệnh sau vào
ngay trước lệnh đầu tiên của chương trình con khởi tạo LCD.
Phần bổ sung cho chương trình con khởi tạo LCD:
mov #0x33, W0 ;Ghi 0x33 lan thu nhat
rcall LCD_cmd4
mov #(ms_count*5), W0 ;Nguong tran 5 ms cho timer 1
rcall Delay_ms ;Yeu cau cho 5 ms
mov #0x33, W0 ;Ghi 0x33 lan thu hai
rcall LCD_cmd4
mov #13, W0 ;Nguong tran 100 us cho timer 1
rcall Delay_ms ;Yeu cau cho 100 us
mov #0x33, W0 ;Ghi 0x33 lan thu ba
rcall LCD_cmd4
Ví dụ 3-2
Thực hiện các thao tác tương tự như trong tutorial 2, bạn hãy loại bỏ tập tin
“Vidu3-1.s” khỏi project, và thêm tập tin “Vidu3-2.s” vào project. Trong ví dụ này,
chương trình được thay đổi đôi chút để thực hiện việc đọc trạng thái các công tắc bên
ngoài (nối vào ) và hiển thị trạng thái của các công tắc đó ra LCD. Một số định nghĩa
cho các thanh ghi liên quan đến các công tắc được thực hiện, nhưng không thể hiện ở
đây để tránh lặp lại phần mã chương trình quá nhiều. Vì chỉ có chương trình chính và
chương trình con dùng để khởi tạo các cổng vào/ra là có thay đổi, nên tôi chỉ liệt kê các
phần mã đó ở đây.
Người báo cáo: Nguyễn Quang Nam Tài liệu: TUT04.01
Ngày: 8/3/2006 Trang: 11/15
Trích mã nguồn “Vidu3-2.s”:
. . .
;-------------------------------------------------------------------------------
;Doan ma trong vung nho chuong trinh
.text ;Bat dau doan ma chuong trinh
__reset:
mov #__SP_init, W15 ;Khoi tao con tro ngan xep (stack)
mov #__SPLIM_init, W0
mov W0, SPLIM ;Khoi tao thanh ghi gioi han con tro ngan xep (stack)
nop ;Can mot lenh NOP sau khi ghi vao