Đề tài Chương trình hợp ngữ giao tiếp nút nhấn/công tắc và LCD với dsPIC

Trong ví dụ này có 2 lệnh mới được dùng, cp và setm. Lệnh cp dùng để so sánh giữa hai giá trị, một trong hai giá trị đó phải được lưu trong một thanh ghi làm việc Wn, đặc biệt là phải được lưu trong thanh ghi WREG (W0)nếu toán hạng thứ hai là một thanh ghi (ô nhớ) bình thường nằm trong 8192 địa chỉ RAM đầu tiên. Toán hạng thứ hai có thể là một toán hạng tức thời (có độ lớn 5-bit) hay một thanh ghi làm việc khác. Lệnh setm thực hiện thao tác ngược lại với lệnh clear. Lệnh setm được dùng để bật(đặt bằng 1)tất cả các bit của một thanh ghi làm việc hay một thanh ghi bình thường nằm trong 8192 địa chỉ RAM đầu tiên.

pdf15 trang | Chia sẻ: lylyngoc | Lượt xem: 2886 | Lượt tải: 1download
Bạn đang xem nội dung tài liệu Đề tài Chương trình hợp ngữ giao tiếp nút nhấn/công tắc và LCD 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 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 dong ky hieu 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: ;Vong lap nay xuat dong ky hieu ra dong 1 LCD mov.b [W4++], W0 ;Doc mot ky tu cp0.b W0 ;Da het chuoi chua? bra z, sw_stat ;Da het chuoi, vay khoi tao trang thai switch 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_loop1 ;Chuyen sang ky tu ke tiep sw_stat: Người báo cáo: Nguyễn Quang Nam Tài liệu: TUT04.01 Ngày: 8/3/2006 Trang: 12/15 mov SW_DAT, W0 ;Doc trang thai cua cac switch and #0x001F, W0 ;Xoa 11 bit cao nhat mov W0, sw_old ;va ghi vao bien luu trang thai main_loop: 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 sw_old, W3 mov #5, W5 ;So switch can cap nhat trang thai updat_loop: mov.b #'0', W0 ;Gia su muc '0' btsc W3, #0 ;Kiem tra bit thap nhat mov.b #'1', W0 ;Dang la muc '1', dat lai ky tu can xuat 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 mov.b #' ', W0 ;Them mot khoang trang 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 mov.b #' ', W0 ;Them mot khoang trang nua 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 lsr W3, W3 ;Dich phai 1 bit (doc switch ke tiep) dec W5, W5 ;Giam so switch can cap nhat di 1 bra nz, updat_loop ;Cap nhat tiep neu chua het sw_chg: mov SW_DAT, W0 ;Doc trang thai cua cac switch and #0x001F, W0 ;Xoa 11 bit cao nhat 1 cp sw_old ;Neu khong thay doi bra z, sw_chg ;thi kiem tra tiep update_LCD: ;Co thay doi, cap nhat LCD mov W0, sw_old ;Luu trang thai moi cua cac switch bra main_loop ;va cap nhat cac switch ;------------------------------------------------------------------------------- Người báo cáo: Nguyễn Quang Nam Tài liệu: TUT04.01 Ngày: 8/3/2006 Trang: 13/15 . . . ;Chuong trinh con khoi tao cac cong I/O, de noi voi LCD, va cac switch ;------------------------------------------------------------------------------- Init_PORTS: mov LCD_DAT, W0 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 2 setm ADPCFG ;RB0..RB4 la cac chan digital mov #0x001F, W0 mov W0, SW_TRIS ;Cac chan du lieu RB0..RB4 la ngo vao return ;------------------------------------------------------------------------------- Hoạt động của chương trình có thể giải thích vắn tắt như sau. Sau khi thực hiện các khởi tạo cho các cổng vào/ra, bộ định thời Timer 1, và LCD, chương trình sẽ xuất một dòng ký hiệu ‘S1 S2 S3 S4 S5’ ra dòng 1 của LCD. Tiếp đến, chương trình đọc trạng thái ban đầu của các công tắc và đi vào vòng lặp chính. Vòng lặp chính sẽ xuất thông tin về trạng thái các công tắc ra dòng 2 của LCD, sau đó kiểm tra xem có sự thay đổi trạng thái của các công tắc hay không, và chỉ thực hiện cập nhật trạng thái của các công tắc khi có sự thay đổi kể từ lần cập nhật trước. Cần lưu ý là lệnh đọc trạng thái các công tắc sẽ đọc từ port B chứ không phải đọc từ latch B. Do hoạt động read-modify-write của một số lệnh, các thanh ghi LATx được dùng để khắc phục tình trạng các thanh ghi chốt trạng thái cổng bị ghi giá trị của chân ngõ vào. Như vậy, việc ghi vào PORTx và LATx sẽ có cùng tác dụng, đó là ghi vào thanh ghi chốt trạng thái cổng. Việc đọc thanh ghi PORTx sẽ đọc giá trị của chân ngõ vào trong khi việc đọc thanh ghi LATx sẽ đọc giá trị được lưu giữ ở thanh ghi chốt trạng thái cổng. Người báo cáo: Nguyễn Quang Nam Tài liệu: TUT04.01 Ngày: 8/3/2006 Trang: 14/15 Trong ví dụ này có 2 lệnh mới được dùng, cp và setm. Lệnh cp dùng để so sánh giữa hai giá trị, một trong hai giá trị đó phải được lưu trong một thanh ghi làm việc Wn, đặc biệt là phải được lưu trong thanh ghi WREG (W0) nếu toán hạng thứ hai là một thanh ghi (ô nhớ) bình thường nằm trong 8192 địa chỉ RAM đầu tiên. Toán hạng thứ hai có thể là một toán hạng tức thời (có độ lớn 5-bit) hay một thanh ghi làm việc khác. Lệnh setm thực hiện thao tác ngược lại với lệnh clear. Lệnh setm được dùng để bật (đặt bằng 1) tất cả các bit của một thanh ghi làm việc hay một thanh ghi bình thường nằm trong 8192 địa chỉ RAM đầu tiên. 3.2. Ví dụ 3-3 Bạn hãy loại bỏ tập tin “Vidu3-2.s” khỏi project, và thêm vào project tập tin “Vidu3-3.s”. Ví dụ này chỉ khác ví dụ 3-2 ở điểm là cờ bận của LCD được kiểm tra trong ví dụ này thay vì dùng một khoảng thời gian chờ như trong ví dụ 3-2. Khi thực hiện việc kiểm tra cờ bận, các chân giao tiếp dữ liệu với LCD cần được đổi chiều truyền thông tin, do vậy chúng ta cần chú ý trong việc thiết lập các bit TRIS (điều khiển chiều dữ liệu) cho các chân dữ liệu này. Để cho gọn, tôi chỉ liệt kê phần mã của chương trình con kiểm tra trạng thái cờ bận ở đây. Trích mã nguồn “Vidu3-3.s”: ;Chuong trinh con poll bit trang thai BF cua LCD ;Se huy noi dung cua W0, W1, W2 ;------------------------------------------------------------------------------- LCD_BFpoll: mov LCD_TRIS, W2 ior.b #0x0F, W2 mov W2, LCD_TRIS ;Cac chan du lieu LCD la ngo vao bset LATD, #LCD_RW bclr LATD, #LCD_RS ;Dat che do doc du lieu DelayNTcy 8 is_busy: bset LATE, #LCD_EN ;Tao xung Enable DelayNTcy 4 mov LCD_PORT, W1 ;Doc nibble cao (RE3..RE0 = D7..D4) DelayNTcy 4 bclr LATE, #LCD_EN ;keo dai toi thieu 4.5 us DelayNTcy 8 bset LATE, #LCD_EN ;Tao xung Enable DelayNTcy 8 bclr LATE, #LCD_EN ;keo dai toi thieu 4.5 us DelayNTcy 4 Người báo cáo: Nguyễn Quang Nam Tài liệu: TUT04.01 Ngày: 8/3/2006 Trang: 15/15 btsc W1, #3 ;Con ban hay khong? bra is_busy ;Con, vay tiep tuc cho mov LATE, W0 and.b #0xF0, W0 mov W0, LATE mov LCD_TRIS, W2 and.b #0xF0, W2 mov W2, LCD_TRIS ;Cac chan du lieu LCD la ngo ra return ;Het ban, vay tro ve chuong trinh goi ;------------------------------------------------------------------------------- Chương trình con này khá trực quan, ngoại trừ điểm cần chú ý là chúng ta nên đặt trạng thái của thanh ghi LAT trước rồi mới đổi chiều các chân I/O từ ngõ vào thành ngõ ra. Điều này sẽ giúp chúng ta tránh được các gai điện áp (glitch) có thể xuất hiện tại các chân I/O khi đổi chiều dữ liệu. 4. Tóm tắt Qua tutorial này, một số lệnh mới đã được giới thiệu, cùng với kỹ thuật đọc các ngõ vào. Một số chương trình con cơ bản dùng cho giao tiếp LCD đã được cung cấp, và bạn có thể sử dụng chúng như một tập hợp nhỏ các hàm thực hiện giao tiếp LCD trong chương trình của bạn. Hai kỹ thuật mới: macro và định thời dùng ngắt tối thiểu cũng đã được trình bày. Mong rằng bạn đã hiểu thêm đôi chút về phần vi điều khiển của các dsPIC, từ đó tiến gần hơn đến việc làm chủ dòng chip rất nhiều tiềm năng này. Chúc bạn thành công!

Các file đính kèm theo tài liệu này:

  • pdf04_01_giao_tiep_voi_cong_tac_valcd_9588.pdf