Tìm hiểu Lập trình hợp ngữ với dsPIC

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.

pdf15 trang | Chia sẻ: lvbuiluyen | Lượt xem: 2561 | Lượt tải: 1download
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