text lcd

18
 I. Bn sđi đến đâu. Bài này nm trong phn ng dng AVR thuc lot bài cùng hc AVR. Trong bài ng dng này chúng ta không kho sát nhiu cu trúc AVR mà chyếu là tìm hiu Text LCD cách điu khin bng AVR. Công cchính cũng là 2 bphn mm quen thuc WinAVR và Proteus. Sau bài này, tôi hy vng bn có thhiu và thc hin được: - Cu trúc Text LCD. - Nguyên lý hot động Text LCD - Phát trin 1 thư vin điu khin Text LCD bng AVR c2 chế độ 8 bit và 4 bit. - Ví dđiu khin Text LCD bng AVR. II. Text LCD. Text LCD là các loi màn hình tinh thlng nhdùng để hin thcác dòng chhoc strong bng mã ASCII. Không ging các loi LCD ln, Text LCD được chia sn thành tng ô và ng vi mi ô chcó thhin thmt ký tASCII. Cũng vì lý do chhin thđược ký tASCII nên loi LCD này được gi là Text LCD (để phân  bit vi G raphic LC D có thhin thhình nh). Mi ô ca Text L CD bao g m các “chm ” tinh thl ng, vic kết hp “n” và “hin” các chm này sto thành mt ký tcn hin th. Trong các Text LCD, các mu ký tđược định nghĩa sn. Kích thước ca Text LCD được định nghĩa bng ský tcó thhin thtrên 1 dòng và tng sdòng mà LCD có. Ví dLCD 16x2 là loi có 2 dòng và mi dòng có thhin thti đa 16 ký t. Mt skích thước Text LCD thông thường gm 16x1, 16x2, 16x4, 20x2, 20x4…Hình 1 là mt ví dText LCD 16x2. Hình 1. Text LCD 16x2. Text LCD có 2 cách giao tiếp cơ bn là ni tiếp (như I2C) và song song. Trong phm vi bài hc này tôi chgii thiu loi giao tiếp song song, cthlà LCD 16x2 điu khin bi chip HD44780U ca hãng Hitachi. Đối vi các LCD khác bn cn tham kho datasheet riêng ca tng loi. Tuy nhiên, HD44780U cũng được coi là chun chung cho các loi Text LCD, vì thế bn có thdùng chương trình ví dtrong bài này để test trên các LCD khác vi rt ít hoc không cn chnh sa. HD44780U là bđiu khin cho các Text LCD dng ma trn đim (dot-matrix), chip này có thđược dùng cho các LCD có 1 hoc 2 dòng hin th. HD44780U có 2 mode giao tiếp là 4 bit và 8 bit. Nó cha sn 208 ký tmu kích thước font 5x8 và 32 ký tmu font 5x10 (tng cng là 240 ký tmu khác nhau). 1. Sơ đồ chân. Các Text LCD theo chun HD44780U thường có 16 chân trong đó 14 chân kết ni vi bđiu khin và 2 chân ngun cho “đèn LED nn”. Thtcác chân thường được sp xếp như sau: Bng 1. Sơ đồ chân.

Upload: nguyen-van-a

Post on 18-Jul-2015

113 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Text Lcd

5/16/2018 Text Lcd - slidepdf.com

http://slidepdf.com/reader/full/text-lcd 1/18

I. Bạn sẽ đi đến đâu.

Bài này nằm trong phần ứng dụng AVR thuộc loạt bài cùng học AVR. Trong bài ứng dụng này chúng takhông khảo sát nhiều cấu trúc AVR mà chủ yếu là tìm hiểu Text LCD cách điều khiển bằng AVR. Công cụ chícũng là 2 bộ phần mềm quen thuộc WinAVR và Proteus.

Sau bài này, tôi hy vọng bạn có thể hiểu và thực hiện được:- Cấu trúc Text LCD.- Nguyên lý hoạt động Text LCD- Phát triển 1 thư viện điều khiển Text LCD bằng AVR cả 2 chế độ 8 bit và 4 bit.- Ví dụ điều khiển Text LCD bằng AVR.

II. Text LCD.

Text LCD là các loại màn hình tinh thể lỏng nhỏ dùng để hiển thị các dòng chữ hoặc số trong bảng mãASCII. Không giống các loại LCD lớn, Text LCD được chia sẵn thành từng ô và ứng với mỗi ô chỉ có thể hiển một ký tự ASCII. Cũng vì lý do chỉ hiện thị được ký tự ASCII nên loại LCD này được gọi là Text LCD (để phâ biệt với Graphic LCD có thể hiển thị hình ảnh). Mỗi ô của Text LCD bao gồm các “chấm” tinh thể lỏng, việc khợp “ẩn” và “hiện” các chấm này sẽ tạo thành một ký tự cần hiển thị. Trong các Text LCD, các mẫu ký tự đượcđịnh nghĩa sẵn. Kích thước của Text LCD được định nghĩa bằng số ký tự có thể hiển thị trên 1 dòng và tổng số

dòng mà LCD có. Ví dụ LCD 16x2 là loại có 2 dòng và mỗi dòng có thể hiển thị tối đa 16 ký tự. Một số kíchthước Text LCD thông thường gồm 16x1, 16x2, 16x4, 20x2, 20x4…Hình 1 là một ví dụ Text LCD 16x2.

Hình 1. Text LCD 16x2.

Text LCD có 2 cách giao tiếp cơ bản là nối tiếp (như I2C) và song song. Trong phạm vi bài học này tôi chỉgiới thiệu loại giao tiếp song song, cụ thể là LCD 16x2 điều khiển bởi chip HD44780U của hãng Hitachi. Đối v

các LCD khác bạn cần tham khảo datasheet riêng của từng loại. Tuy nhiên, HD44780U cũng được coi là chuẩnchung cho các loại Text LCD, vì thế bạn có thể dùng chương trình ví dụ trong bài này để test trên các LCD khávới rất ít hoặc không cần chỉnh sửa.

HD44780U là bộ điều khiển cho các Text LCD dạng ma trận điểm (dot-matrix), chip này có thể được dùngcho các LCD có 1 hoặc 2 dòng hiển thị. HD44780U có 2 mode giao tiếp là 4 bit và 8 bit. Nó chứa sẵn 208 ký tựmẫu kích thước font 5x8 và 32 ký tự mẫu font 5x10 (tổng cộng là 240 ký tự mẫu khác nhau).

1. Sơ đồ chân.

Các Text LCD theo chuẩn HD44780U thường có 16 chân trong đó 14 chân kết nối với bộ điều khiển và 2chân nguồn cho “đèn LED nền”. Thứ tự các chân thường được sắp xếp như sau:Bảng 1. Sơ đồ chân.

Page 2: Text Lcd

5/16/2018 Text Lcd - slidepdf.com

http://slidepdf.com/reader/full/text-lcd 2/18

Trong một số LCD 2 chân LED nền được đánh số 15 và 16 nhưng trong một số trường hợp 2 chân này đượ

ghi là A (Anode) và K (Cathode). Hình 2 mô tả cách kết nối LCD với nguồn và mạch điều khiển.

Page 3: Text Lcd

5/16/2018 Text Lcd - slidepdf.com

http://slidepdf.com/reader/full/text-lcd 3/18

Hình 2. Kết nối Text LCD.

Chân 1 và chân 2 là các chân nguồn, được nối với GND và nguồn 5V. Chân 3 là chân chỉnh độ tương phản(contrast), chân này cần được nối với 1 biến trở chia áp như trong hình 2.Trong khi hoạt động, chỉnh để thay đổ

giá trị biến trở để đạt được độ tương phản cần thiết, sau đó giữ mức biến trở này. Các chân điều khiển RS, R/WEN và các đường dữ liệu được nối trực tiếp với vi điều khiển. Tùy theo chế độ hoạt động 4 bit hay 8 bit mà cácchân từ D0 đến D3 có thể bỏ qua hoặc nối với vi điều khiển, chúng ta sẽ khảo sát kỹ càng hơn trong các phần s

2. Thanh ghi và tổ chức bộ nhớ.

HD44780U có 2 thanh ghi 8 bits là INSTRUCTION REGISTER (IR) và DATA REGISTER (DR). Thanh IR chứa mã lệnh điều khiển LCD và là thanh ghi “chỉ ghi” (chỉ có thể ghi vào thanh ghi này mà không đọc đượnó). Thanh ghi DR chứa các các loại dữ liệu như ký tự cần hiển thị hoặc dữ liệu đọc ra từ bộ nhớ LCD…Cả 2thanh ghi đều được nối với các đường dữ liệu D0:7 của Text LCD và được lựa chọn tùy theo các chân điều khiRS, RW. Thực tế để điều khiển Text LCD chúng ta không cần quan tâm đến cách thức hoạt động của 2 thanh gnày, vì thế cũng không cần khảo sát chi tiết chúng.

HD44780U có 3 loại bộ nhớ, đó là bộ nhớ RAM dữ liệu cần hiển thị DDRAM (Didplay Data RAM), bộ nhớ chROM chứa bộ font tạo ra ký tự CGROM (Character Generator ROM) và bộ nhớ RAM chứa bộ font tạo ra cácsymbol tùy chọn CGRAM (Character Generator RAM). Để điều khiển hiển thị Text LCD chúng ta cần hiểu tổchức và cách thức hoạt động của các bộ nhớ này:

2.1 DDRAM .

DDRAM là bộ nhớ tạm chứa các ký tự cần hiển thị lên LCD, bộ nhớ này gồm có 80 ô được chia thành 2hàng, mỗi ô có độ rộng 8 bit và được đánh số từ 0 đến 39 cho dòng 1; từ 64 đến 103 cho dòng 2. Mỗi ô nhớ tươứng với 1 ô trên màn hình LCD. Như chúng ta biết LCD loại 16x2 có thể hiển thị tối đa 32 ký tự (có 32 ô hiển

Page 4: Text Lcd

5/16/2018 Text Lcd - slidepdf.com

http://slidepdf.com/reader/full/text-lcd 4/18

thị), vì thế có một số ô nhớ của DDRAM không được sử dụng làm các ô hiển thị. Để hiểu rõ hơn chúng ta thamkhảo hình 3 bên dưới

Hình 3. Tổ chức của DDRAM.

Chỉ có 16 ô nhớ có địa chỉ từ 0 đến 15 và 16 ô địa chỉ từ 64 đến 79 là được hiển thị trên LCD. Vì thế muốnhiển thị một ký tự nào đó trên LCD chúng ta cần viết ký tự đó vào DDRAM ở 1 trong 32 địa chỉ trên. Các ký tựnằm ngoài 32 ô nhớ trên sẽ không được hiển thị, tuy nhiên vẫn không bị mất đi, chúng có thể được dùng cho cámục đích khác nếu cần thiết.

2.2 CGROM .

CGROM là vùng nhớ cố định chứa định nghĩa font cho các ký tự. Chúng ta không trực tiếp truy xuất vùngnhớ này mà chip HD44780U sẽ tự thực hiện khi có yêu cầu đọc font để hiện thị. Một điều đáng lưu ý là địa chỉfont của mỗi ký tự vùng nhớ CGROM chính là mã ASCII của ký tự đó. Ví dụ ký tự ‘a’ có mã ASCII là 97, tha

khảo tổ chức của vùng nhớ CGROM trong hình 4 bạn sẽ nhận thấy địa chỉ font của ‘a’ có 4 bit thấp là 0001 và  bit cao là 0110, địa chỉ tổng hợp là 01100001 = 97.

CGROM và DDRAM được tự động phối hợp trong quá trình hiển thị của LCD. Giả sử chúng ta muốn hiểnthị ký tự ‘a’ tại vị trí đầu tiên, dòng thứ 2 của LCD thì các bước thực hiện sẽ như sau: trước hết chúng ta biết rằvị trí đầu tiên của dòng 2 có địa chỉ là 64 trong bộ nhớ DDRAM (xem hình 3), vì thế chúng ta sẽ ghi vào ô nhớ địa chỉ 64 một giá trị là 97 (mã ASCII của ký tự ‘a’). Tiếp theo, chip HD44780U đọc giá trị 97 này và coi như địa chỉ của vùng nhớ CGROM, nó sẽ tìm đến vùng nhớ CGROM có địa chỉ 97 và đọc bảng font đã được địnhnghĩa sẵn ở đây, sau đó xuất bản font này ra các “chấm” trên màn hình LCD tại vị trí đầu tiên của dòng 2 trênLCD. Đây chính là cách mà 2 bộ nhớ DDRAM và CGROM phối hợp với nhau để hiển thị các ký tự. Như mô tảcông việc của người lập trình điều khiển LCD tương đối đơn giản, đó là viết mã ASCII vào bộ nhớ DDRAM tạđúng vị trí được yêu cầu, bước tiếp theo sẽ do HD44780U đảm nhiệm.

Page 5: Text Lcd

5/16/2018 Text Lcd - slidepdf.com

http://slidepdf.com/reader/full/text-lcd 5/18

Hình 4. Vùng nhớ CGROM.

2.3 CGRAM .

CGRAM là vùng nhớ chứa các symbol do người dùng tự định nghĩa, mỗi symbol được có kích thước 5x8 vđược dành cho 8 ô nhớ 8 bit. Các symbol thường được định nghĩa trước và được gọi hiển thị khi cần thiết. Vùnnày có tất cả 64 ô nhớ nên có tối đa 8 symbol có thể được định nghĩa. Tài liệu này không đề cập đến sử dụng bnhớ CGRAM nên tôi sẽ không đi chi tiết phần này, bạn có thể tham khảo datasheet của HD44780U để biết thêm

3. Điều khiển hiển thị Text LCD.

3.1 Các chân điều khiển LCD.

Page 6: Text Lcd

5/16/2018 Text Lcd - slidepdf.com

http://slidepdf.com/reader/full/text-lcd 6/18

Các chân điều khiển việc đọc và ghi LCD bao gồm RS, R/W và EN.RS (chân số 3): Chân lựa chọn thanh ghi (Select Register), chân này cho phép lựa chọn 1 trong 2 thanh ghi

hoặc DR để làm việc. Vì cả 2 thanh ghi này đều được kết nối với các chân Data của LCD nên cần 1 bit để lựachọn giữa chúng. Nếu RS=0, thanh ghi IR được chọn và nếu RS=1 thanh ghi DR được chọn. Chúng ta đều biếtthanh ghi IR là thanh ghi chứa mã lệnh cho LCD, vì thế nếu muốn gởi 1 mã lệnh đến LCD thì chân RS phải đượreset về 0. Ngược lại, khi muốn ghi mã ASCII của ký tự cần hiển thị lên LCD thì chúng ta sẽ set RS=1 để chọnthanh ghi DR. Hoạt động của chân RS được mô tả trong hình 5.

Hình 5. Hoạt động của chân RS.R/W (chân số 4): Chân lựa chọn giữa việc đọc và ghi. Nếu R/W=0 thì dữ liệu sẽ được ghi từ bộ điều khiển

ngoài (vi điều khiển AVR chẳng hạn) vào LCD. Nếu R/W=1 thì dữ liệu sẽ được đọc từ LCD ra ngoài. Tuy nhiêchỉ có duy nhất 1 trường hợp mà dữ liệu có thể đọc từ LCD ra, đó là đọc trạng thái LCD để biết LCD có đang bhay không (cờ Busy Flag - BF). Do LCD là một thiết bị hoạt động tương đối chậm (so với vi điều khiển), vì thếmột cờ BF được dùng để báo LCD đang bận, nếu BF=1 thì chúng ta phải chờ cho LCD xử lí xong nhiệm vụ hiệtại, đến khi nào BF=0 một thao tác mới sẽ được gán cho LCD. Vì thế, khi làm việc với Text LCD chúng ta nhấtthiết phải có một chương trình con tạm gọi là wait_LCD để chờ cho đến khi LCD rảnh. Có 2 cách để viết chươtrình wait_LCD. Cách 1 là đọc bit BF về kiểm tra và chờ BF=0, cách này đòi hỏi lệnh đọc từ LCD về bộ điềukhiển ngoài, do đó chân R/W cần được nối với bộ điều khiển ngoài. Cách 2 là viết một hàm delay một khoảngthời gian cố định nào đó (tốt nhất là trên 1ms). Ưu điểm của cách 2 là sự đơn giản vì không cần đọc LCD, do đchân R/W không cần sử dụng và luôn được nối với GND. Tuy nhiên, nhược điểm của cách 2 là khoảng thời giadelay cố định nếu quá lớn sẽ làm chậm quá trình thao tác LCD, nếu quá nhỏ sẽ gây ra lỗi hiển thị. Trong bài nàtôi hướng dẫn bạn cách tổng quát là cách 1, để sử dụng cách 2 bạn chỉ cần một thay đổi nhỏ trong chương trìnhwait_LCD (sẽ trình bày chi tiết sau) và kết nối chân R/W của LCD xuống GND.

EN (chân số 5): Chân cho phép LCD hoạt động (Enable), chân này cần được kết nối với bộ điều khiển để c phép thao tác LCD. Để đọc và ghi data từ LCD chúng ta cần tạo một “xung cạnh xuống” trên chân EN, nói thecách khác, muốn ghi dữ liệu vào LCD trước hết cần đảm bảo rằng chân EN=0, tiếp đến xuất dữ liệu đến các chD0:7, sau đó set chân EN lên 1 và cuối cùng là xóa EN về 0 để tạo 1 xung cạnh xuống.

3.2 Tập lệnh của LCD.

Bảng 2 tóm tắt các lệnh có thể ghi vào LCD

Page 7: Text Lcd

5/16/2018 Text Lcd - slidepdf.com

http://slidepdf.com/reader/full/text-lcd 7/18

Danh sách lệnh trên được tôi tô 2 màu khác nhau, các lệnh màu đỏ sẽ được dùng thường xuyên trong lúc hthị LCD và các lệnh màu xanh thường chỉ được dùng 1 lần trong lúc khởi động LCD, riêng lệnh Read BF có thđược dùng hoặc không tùy theo cách viết chương trình wait_LCD. Phần tiếp theo tôi giải thích ý nghĩ của cáclệnh và tham số kèm theo chúng.  Trước hết là nhóm lệnh đỏ:

- Clear display – xóa LCD: lệnh này xóa toàn bộ nội dung DDRAM và vì thế xóa toàn bộ hiển thị trên LCDVì đây là 1 lệnh ghi Instruction nên chân RS phải được reset về 0 trước khi ghi lệnh này lên LCD. Mã lệnh xóaLCD là 0x01(ghi vào D0:D7).

- Cursor home – đưa con trỏ về vị trí đầu, dòng 1 của LCD: lệnh này thực hiện việc đưa con trỏ về vị trí đầtiên của bộ nhớ DDRAM, vì thế nếu sau lệnh này một biến được ghi vào DDRAM thì biến này sẽ nằm ở vị trí đtiên (1;1). RS cũng phải bằng 0 trước khi ghi lệnh. Mã lệnh là 0x02 hoặc 0x03(chọn 1 trong 2 mã lệnh, tùy ý).

- Set DDRAM address – định vị trí con trỏ cho DDRAM: di chuyển con trỏ đến một vị trí tùy ý trongDDRAM và vì thế có thể được dùng để chọn vị trí cần hiển thị trên LCD. Để thực hiện lệnh này cần reset RS=0Bit MSB của mã lệnh (D7) phải bằng 1, 7 bit còn lại của mã lệnh chính là địa chỉ DDRAM muốn di chuyển đếnVí dụ chúng ta muốn di chuyển con trỏ đến vị trí thứ 3 trên dòng 2 của LCD (địa chỉ 42) chúng ta cần ghi mã lệ0xAA vì 0xAA=10101010 (binary) trong đó bit MSB bằng 1, bảy bit còn lại là 0101010=42, địa chỉ của ô nhớ muốn đến.

- Write to CGRAM or DDRAM – ghi dữ liệu vào CGRAM hoặc DDRAM: vì đây không phải là lệnh ghiinstruction mà là 1 lệnh ghi dữ liệu nên chân RS cần được set lên 1 trước khi ghi lệnh vào LCD. Lệnh này cho phép ghi mã ASCII của một ký tự cần hiển thị vào thanh ghi DDRAM. Trường hợp ghi vào CGRAM không đưkhảo sát.

Page 8: Text Lcd

5/16/2018 Text Lcd - slidepdf.com

http://slidepdf.com/reader/full/text-lcd 8/18

  Kế đến là nhóm lệnh màu xanh: nhóm lệnh này thường chỉ thực hiện 1 lần (ít nhất là trong bài học này) vàthường được viết chung trong 1 chương trình con khởi động LCD ( chúng ta gọi là init_LCD trong bài học này

- Entry mode set – xác lập các hiện thị liên tiếp cho LCD: nói một cách dễ hiểu, lệnh này chỉ ra cách mà bạmuốn hiển thị một ký tự tiếp theo 1 ký tự trước đó. Ví dụ nếu bạn muốn hiện thị 2 ký tự liên tiếp AB, trước hết bạn viết A tại vị trí 5, dòng 1. Sau đó bạn ghi B vào LCD, lúc này có 4 cách mà LCD có thể hiển thị B như sauhiển thị B bên phải A tại vị trí số 6 (cách 1); B cũng có thể được hiển thị bên trái A, tại vị trí số 4(cách 2); hoặcLCD có thể tự dịch chuyển A về bên trái đến vị trí 4 sau đó hiển thị B bên phải A, tại vị trí 5( cách 3); và khả năcuối cùng là LCD dịch chuyển A về bên phải đến vị trí 6 sau đó hiển thị B bên trái A, tại vị trí 5( cách 4). Chúng

có thể chọn 1 trong 4 cách hiển thị trên thông qua lệnh Entry mode set. Đây là lệnh ghi Instruction nên RS=0, 5 bit cao D7:3=00000, bit D2=1, hai bit còn lại D1:0 chứa mã lệnh để lựa chọn 1 trong 4 cách hiển thị. Xem lại bảng 2, bit D1 chứa giá trị I/D và D0 chứa S. Trong đó I/D nghĩa là tăng hoặc giảm (Increment or Decrement).I/D= 1 là hiển thị tăng tức ký tự sau sẽ hiển thị bên phải ký tự trước, nếu I/D=0 thì hiển thị giảm, tức ký tự sauhiển thị bên trái ký tự trước. S là giá trị Shift, nếu S=1 thì các ký tự trước đó sẽ được “đẩy” đi, ký tự sau chiếmchỗ ký tự trước, ngược lại nếu S=0 thì vị trí hiển thị của các ký tự trước đó không thay đổi. Có thể tóm tắt 4 mohiển thị ứng với 4 mã lệnh như sau:

+ D7:0 = 0x04 (00000100) : hiển thị giảm và không shift (như cách 2 trong ví dụ).+ D7:0 = 0x05 (00000101) : hiển thị giảm và shift (như cách 4 trong ví dụ).+ D7:0 = 0x06 (00000110) : hiển thị tăng và không shift (như cách 1, khuyến khích).+ D7:0 = 0x07 (00000111) : hiển thị tăng và shift (như cách 3 trong ví dụ).

- Display on/off control – xác lập cách hiện thị cho LCD: lệnh này bao gồm các thông số cho phép LCD hithị, cho phép hiển thị cursor và mở/tắt blinking. Đây cũng là một lệnh ghi Instrcution nên RS phải bằng 0. Mãlệnh cho lệnh này có dạng 00001DCB trong đó D (Display) cho phép hiển thị LCD nếu mang giá trị 1, C(Cursor) bằng 1 thì cursor sẽ được hiển thị và B là blinking cho cursor tại vị trí hiển thị (blinking là dạng 1 ô đenhấp nháy tại vị trí ký tự đang hiển thị). Mã lệnh được dùng phổ biến cho lệnh này là 0x0E (00001110 - hiển thcursor nhưng không hiển thị blinking).

- Function set – xác lập chức năng cho LCD: đây là lệnh thiết lập phương thức giao tiếp với LCD, kích thưfont chữ và số lượng line của LCD. RS cũng phải bằng 0 khi sử dụng lệnh này. Mã lệnh function set có dạng001D¬¬LNFxx. Trong đó nếu DL=1 (DL: Data Length) thì mode giao tiếp 8 bit sẽ được dùng, lúc này tất cả cáchân từ D0 đến D7 phải được kết nối với bộ điều khiển ngoài. Nếu DL=0 thì mode 4 bit được dùng, trong trườnhợp này chỉ có 4 chân D4:7 được dùng để truyền nhận dữ liệu và kết nối với bộ điều khiển ngoài, các chân D0:

được để trống. N quy định số dòng của LCD, vì chúng ta đang khảo sát LCD loại hiển thị 2 dòng nên N=1 (N=cho trường hợp LCD 1 dòng). F là kích thước font chữ hiển thị, do LCD có 2 bộ font chữ có sẵn trong CGROMnên chúng ta cần lựa chọn thông qua bit F, nếu F=1 bộ font 5x10 được sử dụng và nếu F=0 thì font 5x8 được hthị. 2 bit thấp trong mã lệnh này có thể được gán giá trị tùy ý. Mã lệnh được dùng phổ biến cho lệnh function selà 0x38 (00111000 – giao tiếp 8 bit, 2 dòng với font 5x8 ) hoặc 0x28 (00101000 – giao tiếp 4 bit, 2 dòng với fo5x8 ). Ví dụ trong bài này sử dụng cả 2 mã lệnh trên.

3.3 Giao tiếp 8 bit và 4 bit .

Như trình bày trong lệnh function set, có 2 mode để ghi và đọc dữ liệu vào LCD đó là mode 8 bit và mode 4 bit:

- Mode 8 bit: Nếu bit DL trong lệnh function set bằng 1 thì mode 8 bit được dùng. Để sử dụng mode 8 bit,

cả các lines dữ liệu của LCD từ D0 đến D7 (từ chân 7 đến chân 14) phải được nối với 1 PORT của chip điềukhiển bên ngoài (ví dụ PORTC của ATmega32 trong ví dụ của bài này) như trong hình 3. Ưu điểm của phương pháp giao tiếp này là dữ liệu được ghi và đọc rất nhanh và đơn giản vì chip điều khiển chỉ cần xuất hoặc nhận dliệu trên 1 PORT. Tuy nhiên, phương pháp này có nhược điểm là tổng số chân dành cho giao tiếp LCD quá nhinếu tính luôn cả 3 chân điều khiển thì cần đến 11 đường cho giao tiếp LCD.

- Mode 4 bit: LCD cho phép giao tiếp với bộ điều khiển ngoài theo chế độ 4 bit. Trong chế độ này, các châD0, D1, D2 và D3 của LCD không được sử dụng (để trống), chỉ có 4 chân từ D4 đến D7 được kết nối với chipđiều khiển ngoài. Các instruction và data 8 bit sẽ được ghi và đọc bằng cách chia thành 2 phần, gọi là các Nibblmỗi nibble gồm 4 bit và được giao tiếp thông qua 4 chân D7:4, nibble cao được xử lí trước và nibble thấp sau. Ưđiểm lớn nhất của phương pháp này tối thiểu số lines dùng cho giao tiếp LCD. Tuy nhiên, việc đọc và ghi từng

Page 9: Text Lcd

5/16/2018 Text Lcd - slidepdf.com

http://slidepdf.com/reader/full/text-lcd 9/18

nibble tương đối khó khăn hơn đọc và ghi dữ liệu 8 bit. Trong bài học này, tôi sẽ trình bày 2 chương trình conđược viết riêng để ghi và đọc các nibbles gọi là Read2Nib và Write2Nib.

III. AVR và Text LCD.

1. Trình tự giao tiếp Text LCD.

Trình tự giao tiếp với LCD được trình bày trong flowchart ở hình 6.

Hình 6. Trình tự giao tiếp với Text LCD.

Để sử dụng LCD chúng ta cần khởi động LCD, sau khi được khởi động LCD đã sẵn sàng để hiển thị. Quátrình khởi động chỉ cần thực hiện 1 lần ở đầu chương trình. Trong bài này, quá trình khởi động được viết trongchương trình con tên int_LCD, khởi động LCD thường bao gồm xác lập cách giao tiếp, kích thước font, số dònLCD (funcstion set), cho phép hiển thị LCD, sursor…(Display control), chế độ hiển thị tăng/giảm, shift (Entrymode set). Các thủ tục khác như xóa LCD, viết ký tự lên LCD, di chuyển con trỏ…được sử dụng liên tục trongquá trình hiển thị LCD và sẽ được trình bày trong các đoạn chương trình con riêng.

2. AVR giao tiếp với Text LCD trong WinAVR.Phần này tôi trình bày cách điều khiển hiển thị Text LCD bằng vi điều khiển AVR trong môi trường C của

WinAVR. Hình thức là một thư viện hàm giao tiếp Text LCD trong 1 file header có tên là myLCD.h. Các hàmtrong thư viện bao gồm (chú ý là phần code trong List 0 không nằm trong file myLCD.h).

List 0. Các hàm có trong thư viện myLCD.

1234

char Read2Nib(); //đọc 2 nibbles từ LCDvoid Write2Nib(uint8_t chr); //ghi 2 nibbles vào LCDvoid Write8Bit(uint8_t chr); //ghi trự tiếp 8 bit và LCDvoid wait_LCD(); //chờ LCD rảnh

Page 10: Text Lcd

5/16/2018 Text Lcd - slidepdf.com

http://slidepdf.com/reader/full/text-lcd 10/18

5678910

void init_LCD(); //khởi động LCDvoid clr_LCD(); //xóa LCDvoid home_LCD(); //đưa cursor về home void move_LCD(uint8_t y, uint8_t x); //di chuyển cursor đế vị trí mong muốn (dòng, cột)void putChar_LCD(uint8_t chr); //ghi 1 ký tự lên LCDvoid print_LCD(char* str, unsigned char len); //hiển thị chuỗi ký tự

Tuy nhiên, trước khi viết các hàm giao tiếp LCD chúng ta cần định nghĩa một số macro và biến. Hãy tạo 1file Header có tên myLCD.h và viết các đoạn code bên dưới vào file này (bắt đầu từ List 1).

List 1. Định nghĩa các biến thay thế.

010203040506070809101112131415161718

#include <util/delay.h>#define sbi(sfr,bit) sfr|=_BV(bit)#define cbi(sfr,bit) sfr&=~(_BV(bit))#define EN 2#define RW 1#define RS 0

#define CTRL PORTB#define DDR_CTRL DDRB

#define DATA_O PORTB#define DATA_I PINB#define DDR_DATA DDRB/*#define LCD8BIT#define DATA_O PORTD#define DATA_I PIND#define DDR_DATA DDRD*/

  cbi và sbi là 2 macro được dụng để xóa và set 1 bit trong 1 thanh ghi. Ví dụ cbi(PORTA, 5) là xóa bit 5 tronthanh ghi PORT về 0. Do WinAVR không hỗ trợ tuy xuất trực tiếp các bit nên cần định nghĩa 2 macro này hỗ tr

Các biến EN, RW và RS định nghĩa số thứ tự của chân trên 1 PORT của AVR được dùng để kết nối với chân EN, R/W và RS của LCD. CTRL là biến cho biết PORT nào của AVR được dùng để kết nối với các chđiều khiển của LCD. DDR_CTRL là thanh ghi điều khiển hướng của PORT kết nối với các chân điều khiDDR_CTRL luôn phụ thuộc vào biến CTRL. Trong trường hợp của bài này, bạn thấy tôi định nghĩa CTRLPORTB nghĩa là PORTB được dùng để kết nối với các chân điều khiển LCD, vì CTRL là PORTB nDDR_CTRL phải là DDRB (thanh ghi điều khiển hướng của PORTB). EN định nghĩa bằng 2 nghĩa là chân Ecủa LCD được nối với chân 2 của PORTB (PB2), tương tự chân R/W nối với chân 1 PORTB (PB1) và chân nối với chân 0 PORTB (PB0). Việc chọn các PORT giao tiếp và thứ tự chân phụ thuộc vào kết nối thật tromạch điện giao tiếp, bạn phải thay đổi các định nghĩa này cho phù hợp với thiết kế mạch điện của bạn. Lý do việc định nghĩa các biến thay thế kiểu này là nhằm tạo ra tính tổng quát cho thư viện hàm. Ví dụ, một ngưkhông muốn dùng PORTB để điều khiển LCD mà dùng PORTA thì người này chỉ cần thay đổi định nghĩa ởdòng 7 và 8, không cần thay đổi nội dung các hàm vì trong các hàm này chúng ta chỉ dùng tên thay thế là CTRvà DDR_CTRL. Tương tự, tôi định nghĩa 3 biến thay thế là DATA_O nghĩa là PORT xuất dữ liệu, DATA_IPORT nhập dữ liệu và DDR_DATA là thanh ghi điều khiển hướng. DATA_O và DATA_I là PORT nối với cchân D0:7 (mode 8 bit) hoặc D4:7 (mode 4 bit) của LCD, đây là các đường truyền và nhận dữ liệu. Trong ví trên, tôi dùng chính PORTB làm đường data vì đây là trường hợp giao tiếp 4 bit, do 3 chân đầu của PORTB nối với các chân điều khiển nên PORTB chỉ còn thừa lại 5 chân, chúng ta sẽ nối 4 chân PB4, PB5, PB6 và P

Page 11: Text Lcd

5/16/2018 Text Lcd - slidepdf.com

http://slidepdf.com/reader/full/text-lcd 11/18

tương ứng với D4, D5, D6 và D7 của LCD. Hình 7 mô tả cách kết nối AVR và LCD theo ví dụ này. Tất nh bạn có thể sử dụng PORT khác làm đường data nhất là khi bạn muốn sử dụng mode 8 bit, vì trong mode này tới 11 đường giao tiếp (3 điều khiển + 8 data). Phần được che trong 2 dấu comment /* */ là trường hợp bạn mudủng mode 8 bit. Để sử dụng mode 8 bit, bạn cần định nghĩa 1 biến có tên LCD8BIT, bit này sẽ báo cho các đchương trình con thực hiện ghi và đọc dữ liệu theo cách 8 bit. Đồng thời, bạn phải định nghĩa lại đường giao tdata (DATA_O, DATA_I, DDR_DATA).

Hình 7. Ví dụ Kết nối LCD với AVR trong mode 4 bit (chip mega8).

Phần bên dưới là phần định nghĩa các hàm trong thư viện myLCD. Bốn hàm đầu tiên (xem lại List 0) là hàm hỗ trợ, chúng chỉ được dùng bởi các hàm khác trong thư viện và không được gọi trong các chương trình ứdụng bên ngoài.

List 2. Đọc 2 nibbles từ LCD.

01020304

05060708091011121314

char Read2Nib(){  char HNib, LNib;

DATA_O |=0xF0;

sbi(CTRL,EN); //enable DDR_DATA &=0x0F; //set 4 bits cao cua PORT DATA lam input HNib=DATA_I & 0xF0;cbi(CTRL,EN); //disable

sbi(CTRL,EN); //enableLNib = DATA_I & 0xF0;cbi(CTRL,EN); //disableLNib>>=4;

  return (HNib|LNib);

Page 12: Text Lcd

5/16/2018 Text Lcd - slidepdf.com

http://slidepdf.com/reader/full/text-lcd 12/18

15 }

Hàm này thực hiện việc đọc dữ liệu từ LCD ra ngoài, đọc theo từng nibble 4 bit, kết quả trả về là 1 số 8 bitHàm này chỉ được dùng duy nhất khi đọc cờ Busy (BF) trong chương trình chờ LCD rảnh (wait_LCD) ở mode bit. Trước hết cần định nghĩa 1 biến tạm HNib (high nibble) và LNib (Low nibble) để chứa 2 nibbles đọc về(dòng 2, List 2). Dòng 5 set chân EN lên mức 1 để chuẩn bị cho LCD làm việc. Chúng ta cần đổi hướng củaPORT dữ liệu trên AVR để sẵn sàng nhận dữ liệu về, do chỉ có 4 bit cao của PORT data kết nối với các đường

data của LCD (vì đây là mode 4 bit) nên chỉ cần set hướng cho 4 bit này trên AVR, dòng 6 thực hiện việc sethướng. Trong chế độ 4 bit, LCD sẽ truyền và nhận nibble cao trước vì thế dòng 7 đọc dữ liệu từ LCD thông qucác chân DATA_I vào biến HNib, chú ý là chúng ta chỉ cần lấy 4 bit cao của DATA_I nên cần phải dùng giảithuật mặt nạ (mask) che các bit thấp lại (and với 0xF0). Dòng 8 xóa chân EN để chuẩn bị cho bước tiếp theo.Tương tự, các dòng 10, 11 và 12 đọc nibble thấp vào biến LNib. Hai dòng 13 và 14 kết hợp 2 nibbles để tạo thàsố 8 bit và trả kết quả về cho đoạn chương trình.

List 3. Ghi 2 nibbles vào LCD.

010203040506070809101112131415

void Write2Nib(uint8_t chr){uint8_t HNib, LNib, temp_data;

temp_data=DATA_O & 0x0F; //doc 4 bit thap cua DATA_O de mask,HNib=chr & 0xF0;LNib=(chr<<4) & 0xF0;

DATA_O =(HNib |temp_data);sbi(CTRL,EN); //enablecbi(CTRL,EN); //disable

DATA_O =(LNib|temp_data);sbi(CTRL,EN); //enablecbi(CTRL,EN); //disable

}

Hàm Write2Nib thực hiện ghi một biến 8 bit có tên chr vào LCD theo từng nibble, hàm này được sử dụngnhiều lần trong mode 4 bit. Dòng 2 định nghĩa 3 biến tạm là HNib, LNib và temp_data, không giống như khi đtừ LCD, việc ghi vào LCD có thể làm ảnh hưởng đến các chân của PORT dùng làm đường dữ liệu nhất là khi đường điều khiển và dữ liệu dùng chung 1 PORT (PORTB). Biến temp_data dùng trong giải thuật mặt nạkhông làm ảnh hưởng đến các bit khác khi ghi LCD. Dòng 3 đọc dữ liệu từ PORT DATA_O và che đi các bit cchỉ lưu lại các bit thấp vào biến temp_data vì các bit thấp này không được dùng xuất nhập dữ liệu (xem hìnhcác chân thấp của PORTB dùng làm các chân điều khiển). Để ghi 1 giá trị 8 bit có tên là chr theo cách ghi từnibbles chúng ta cần tách biến chr thành 2 nibbles. Dòng 5 tách 4 bit cao của chr và chứa vào biến HNib. Dònthực hiện thêm việc di chuyển 4 bit thấp của chr qua trái rồi gán cho biến LNib. Như vậy sau 2 dòng này các b

HNib và LNib được mô tả như sau:

Page 13: Text Lcd

5/16/2018 Text Lcd - slidepdf.com

http://slidepdf.com/reader/full/text-lcd 13/18

Do dữ liêu đã được sắp xếp sẵn sàng ở các vị trí cao (ứng với các chân D4:7) nên công viêc tiếp theo chỉ đgiản là xuất 2 biến HNib và LNib ra đường DATA_O, cần phải tạo 1 “xung cạnh xuống” ở chân EN mỗi lần xdữ liệu (dòng 9, 10). Chú ý là phải xuất nibble cao trước và nibble thấp theo sau.List 4. Ghi 8 bit trực tiếp vào LCD.

010203

0405

void Write8Bit(uint8_t chr){  DATA_O=chr; //out 8 bits to DATA Line  sbi(CTRL,EN); //enable

  cbi(CTRL,EN); //disable}

  Đoạn này rất đơn giản là xuất dữ liệu 8 bit ra DATA_O, dùng trong mode 8 bit. Trong mode này, 8 chân dcủa LCD được nối với 8 đường DATA_O của AVR.

List 5. Chờ LCD rảnh.

010203040506070809101112131415161718192021222324252627282930

void wait_LCD(){  #ifdef LCD8BIT

while(1){  cbi(CTRL,EN); //xóa EN  cbi(CTRL,RS); //đây là Instruction

sbi(CTRL,RW); //chiều từ LCD ra ngoài

  DDR_DATA=0xFF; //hướng data out  DATA_O=0xFF; // gởi lệnh đọc BF

sbi(CTRL,EN); //enable

  DDR_DATA=0x00; // Đổi hướng data in  if (bit_is_clear(DATA_I,7)) break ;  }  cbi(CTRL,EN); //disable for next step

cbi(CTRL,RW); //ready for next stepDDR_DATA=0xFF; //Ready to Out

  #else  char temp_val;  while(1){  cbi(CTRL,RS); //RS=0, the following data is COMMAND 

sbi(CTRL,RW); //LCD -> AVR   temp_val=Read2Nib();  if (bit_is_clear(temp_val,7))  break ;  }  cbi(CTRL, RW); //ready for next step

DDR_DATA=0xFF;//Ready to Out #endif 

  //_delay_ms(1);}

Hàm wait_LCD chỉ làm một việc đơn giản là chờ cho đến khi LCD rảnh để gán các công việc khác. Đoạncode trong list 5 trình bày cách 1: đọc cờ Busy Flag và chờ đến khi nó bằng 0 (LCD rảnh). Việc đọc cờ BF phụthuộc và mode đang sử dụng là 8 bit hay 4 bit, vì thế lệnh #ifdef trong dòng số 2 kiểm tra mode phù hợp trước tiến hành đọc. #ifdef LCD8BIT nghĩa là nếu biến LCD8BIT đã được định nghĩa ở phía trên (mode 8 bit đượcdùng) thì sẽ tiến hành đọc BF theo mode này. Bằng cách kiểm tra sự có mặt của biến LCD8BIT chương trình s

Page 14: Text Lcd

5/16/2018 Text Lcd - slidepdf.com

http://slidepdf.com/reader/full/text-lcd 14/18

 biết cách ghi và đọc LCD phù hợp, phương pháp dùng #ifdef LCD8BIT được áp dụng cho tất cả các hàm sau nCác đoạn code từ dòng 4 đến 17 thực hiện trong mode 8 bit. Trước khi đọc BF, chúng ta cần gởi 1 lệnh đọc BFdòng 9, sau đó ở dòng 12 thực hiện đổi hướng các chân data để nhận giá trị về. Trong dòng 10, kiểm tra bit thứcủa DATA_I, DATA_I chính là giá trị đọc về và bit thứ 7 trong giá trị nhận về chính là cờ Busy Flag. Nếu BF=(bit_is_clear(DATA_I,7)) thì kết thúc quá trình lặp chờ với lệnh break;. Trong trường hợp mode 4 bit được sửdụng (#else), quá trình kiểm tra cờ BF cũng tương tự, điểm khác nhau duy nhất là cách đọc dữ liệu về có khác,chúng ta dùng hàm Read2Nib đã được viết trước đó để nhận giá trị về (xem dòng 23). Như đã trình bày, chúng có thể viết hàm wait_LCD bằng cách dùng hàm delay một khoảng thời gian cố định, trong dòng 29 bạn thấy m

hàm _delay_ms(1) không được sử dụng, nếu muốn bạn có thể xóa hết các dòng lệnh trước đó trong hàmwait_LCD và dùng hàm delay này để thay thế, LCD vẫn sẽ hoạt động tốt.

List 6. Khởi động LCD.

01020304050607080910111213141516171819202122232425262728293031323334353637

void init_LCD(){  DDR_CTRL=0xFF;  DDR_DATA=0xFF;//Function set------------------------------------------------------------------------------  cbi(CTRL,RS); // the following data is COMMAND  cbi(CTRL, RW); // AVR->LCD  cbi(CTRL, EN);  #ifdef LCD8BIT

Write8Bit(0x38);  wait_LCD();  #else  sbi(CTRL,EN); //enable  sbi(DATA_O, 5);

cbi(CTRL,EN); //disable  wait_LCD();

Write2Nib(0x28);//4 bit mode, 2 line, 5x8 font  wait_LCD();

#endif //Display control-------------------------------------------------------------------------

cbi(CTRL,RS); // the following data is COMMAND#ifdef LCD8BIT

Write8Bit(0x0E);  wait_LCD();  #else  Write2Nib(0x0E);  wait_LCD();

#endif //Entry mode set------------------------------------------------------------------------  cbi(CTRL,RS); // the following data is COMMAND 

#ifdef LCD8BIT  Write8Bit(0x06);  wait_LCD();  #else  Write2Nib(0x06);  wait_LCD();  #endif }

Page 15: Text Lcd

5/16/2018 Text Lcd - slidepdf.com

http://slidepdf.com/reader/full/text-lcd 15/18

Quá trình khởi động gồm 3 bước: function set, display control và entry mode set.Với function set, ba dòng 5,6 và 7 xác lập các chân điều khiển để chuẩn bị gởi các lệnh. Hai dòng 9 và 10

viết lệnh function set vào LCD theo mode 8 bit. Giá trị 0x38, tức 00111000 là một lệnh xác lập mode 8 bit, LCDdòng và font 5x8. Nếu mode 4 bit được dùng, chúng ta cần viết hàm function set khác đi một chút. Theo mặcđịnh, khi vừa khởi động LCD thì mode 8 bit sẽ được chọn, vì thế nếu một hàm nào đó đươc ghi vào LCD đầutiên, LCD sẽ cố gắng đọc hết các chân D0:7 để lấy dữ liệu, do trong mode 4 bit các chân D0:3 không được kết với AVR nên việc đọc lần đầu có thể dẫn đến sai số. Vì vậy, việc đầu tiên cần làm nếu muốn sử dụng mode 4 blà gởi một lệnh function set với tham số DL=0 (0010xxxx) đến LCD để báo mode chúng ta muốn dùng. Dòng

làm việc này, dòng lệnh chỉ đơn giản set bit D5 nhưng đó chính là gởi lệnh dạng 0010xxxx đến LCD, vì thế LCsẽ vào mode 4 bit sau lệnh này. Tiếp theo quá trình thao tác với LCD diễn ra bình thường, dòng 16 ghi vào LCDmã của function set, trong trường hợp này là mã 0x28, tức 00101000: mode 4 bit, LCD 2 dòng và font 5x8.  Với Display control, mã lệnh được dùng là 0x0E, tức 00001110 trong đó 00001 là mã của lệnh displaycontrol, 3 bit theo sau xác lập hiển thị LCD, hiển thị cursor và không blinking.  Với Entry mode set, mã lệnh được dùng là 0x06 tức hiển thị tăng và không shift. Xem lại phần giải thích lệnh LCD để hiểu thêm ý nghĩa của mã lệnh 0x06.

List 7. Di chuyển cursor.

01020304050607080910111213141516171819202122

void home_LCD(){  cbi(CTRL,RS); // the following data is COMMAND

#ifdef LCD8BITWrite8Bit(0x02);

  wait_LCD();#else

  Write2Nib(0x02);  wait_LCD();

#endif }void move_LCD(uint8_t y,uint8_t x){  uint8_t Ad;  Ad=64*(y-1)+(x-1)+0x80; // tính mã lệnh  cbi(CTRL,RS); // the following data is COMMAND  #ifdef LCD8BIT

Write8Bit(Ad);  wait_LCD();  #else  Write2Nib(Ad);  wait_LCD();  #endif }

  List 7 trình bày 2 hàm di chuyển cursor về home (home_LCD) và di chuyển đến 1 vị trí do người dùng đặtHàm home_LCD tương đối đơn giản vì chỉ cần ghi mã lệnh 0x02 vào LCD thì cursor sẽ tự động di chuyển vềhome (vị trí đầu tiên trên LCD).

Hàm move_LCD(uint8_t y,uint8_t x) cho phép di chuyển cursor đến vị trí dòng y, cột x. Điểm cần chú ýtrong hàm này là cách tính mã lệnh cần ghi vào LCD. Thực chất đây là lệnh set DDRAM address. Xem lại bảngta thấy mã lệnh cho lệnh này có dạng 1xxxxxxx trong đó xxxxxxx là một số 7 bit chứa địa chỉ của ô DDRAMchúng ta cần di chuyển đến. Vì thế trước khi thực hiện ghi mã lệnh này, chúng ta cần tính tham số xxxxxxx thedòng y, cột x. Xem lại tổ chức của DDRAM trong hình 3, giả sử một ô nhớ ở dòng y và cột x trên, do dòng 2 bắđầu với địa chỉ 64, 2 ô nhớ ở cùng 1 cột trên 2 dòng sẽ cách nhau 64 vị trí ( 64*(y-1)). Mặt khác do vị trí ô nhớ được tính từ 0 trong khi chúng ta muốn gán tọa độ x bắt đầu từ 1, vì thế chúng ta cần thêm (x-1) vào công thứctính. Cuối cùng chúng ta cần phải thêm mã lệnh set địa chỉ DDRAM, mã 0x80. Giá trị cuối cùng của mã lệnh là

Page 16: Text Lcd

5/16/2018 Text Lcd - slidepdf.com

http://slidepdf.com/reader/full/text-lcd 16/18

Ad=64*(y-1)+(x-1)+0x80 (dòng 13). Các dòng lệnh tiếp theo trong hàm move_LCD thực hiện ghi giá trị mã lệvào LCD.

Cuối cùng là phần code hiển thị LCD được trình bày trong list 8. Phần hiển thị bao gồm 1 chương trình conxóa LCd, hiển thị 1 ký tự và hiển thị 1 chuỗi các ký tự.

List 8. Hiển thị trên LCD.

010203040506070809101112131415161718192021222324252627

void clr_LCD(){ //xóa toàn bộ LCD  cbi(CTRL,RS); //RS=0 mean the following data is COMMAND (not normal DATA)  #ifdef LCD8BIT

Write8Bit(0x01);  wait_LCD();

#else  Write2Nib(0x01);  wait_LCD();

#endif  }void putChar_LCD(uint8_t chr){ //hiển thị 1 ký tự chr lên LCD  sbi(CTRL,RS); //this is a normal DATA

#ifdef LCD8BITWrite8Bit(chr);

  wait_LCD();#else

  Write2Nib(chr);  wait_LCD();

#endif  }void print_LCD(char * str, unsigned char len){ //Hiển thị 1 chuỗi ký tự  unsigned char i;  for (i=0; i<len; i++)  if (str[i] > 0) putChar_LCD(str[i]);  else putChar_LCD(' ');  }}

Để xóa toàn bộ LCD chúng ta cần gởi 1 instruction có mã 0x01 đến LCD, hàm clr_LCD() thực hiện việcnày. Lưu ý mã lệnh để xóa LCD là 1 instruction, vì thế cần xóa chân RS xuống 0 trước khi gởi mã này xuốngLCD (dòng 2 xóa chân RS). Hàm putChar_LCD(uint8_t chr) hiển thị 1 ký tự lên LCD, giá trị tham số của hànày là mã ASCII của ký tự cần hiển thị, chr. Nội dung của hàm hoàn toàn giống hàm xóa LCD, chỉ khác đâykhông phải là 1 instruction nên cần set chân RS lên 1 trước khi gởi mã lệnh đến LCD (dòng 12). Mã lệnh cho hnày chính là mã ASCII cần hiển thị. Cuối cùng hàm print_LCD(char* str, unsigned char len) cho phép hiển

1 chuỗi ký tự liên tiếp lên LCD, thực chất đây là quá trình lặp của hàm hiển thị 1 ký tự. Chú ý tham số len là chdài cần hiển thị của chuỗi.

IV. Ví dụ điều khiển Text LCD bằng thư viện myLCD.

Phần này tôi sẽ minh họa cách sử dụng thư viện myLCD.h để hiển thị các ký tự lên 1 Text LCD. Sử dụng phần mềm Proteus vẽ một mạch điện gồm 1 LCD 2x16 (keyword: LM016L), 1 chip Atmega32 và 1 biến trở (POT-LIN) như trong hình 8. Tạo 1 Project bằng WinAVR có tên là TextLCD_Demo và tạo file source là maintạo makefile với khai báo sữ dụng chip ATmega32 và clock 8MHz. Copy file myLCD.h vào thư mục của Projemới tạo. Viết code cho file main.c như trong list 9. Chú ý các định nghĩa chân kết nối với LCD trong phần đầu myLCD.h phải giống với kết nối thật trong hình 8.

Page 17: Text Lcd

5/16/2018 Text Lcd - slidepdf.com

http://slidepdf.com/reader/full/text-lcd 17/18

Hình 8. Mạch điện mô phỏng LCD với AVR.

List 8. Chương trình demo điều khiển TextLCD, main.c.

 #include <avr/io.h>#include <util/delay.h>

#include "myLCD.h" //include thư viện myLCD

int main(){init_LCD(); //khởi độ LCD

  clr_LCD(); // xóa toà bộ LCD

   putChar_LCD(' '); //ghi 1 khoảng trắng   putChar_LCD(' '); //ghi 1 khoảng trắng

 putChar_LCD('D'); //Hiển thị kýtự 'D'   print_LCD("emo of the",10); //hiển thị 1 chuỗi ký tự 

move_LCD(2,1); //di chuyển cursor đến dòng 2, cột đầu tiên

Page 18: Text Lcd

5/16/2018 Text Lcd - slidepdf.com

http://slidepdf.com/reader/full/text-lcd 18/18

   print_LCD("2x16 LCD Display",16); //hiển thị chuỗi thứ 2  while(1){

  };}

  Để sử dụng thư viện myLCD, chúng ta cần include file myLCD.h vào Project như trong dòng 3, #include

"myLCD.h". Hai dòng 6 và 7 thực hiện khởi động và xóa LCD. Sau đó, các dòng 9, 10 và 11 đặt 3 ký tự là cáckhoảng trắng và chữ cái D bằng hàm putChat_LCD. Dòng 12 in chuỗi “emo of the” ngay tiếp theo chữ cái Dtrước đó bằng hàm print_LCD. Dòng 13 thực hiện di chuyển cursor đến vị trí dòng thứ 2, cột đầu tiên của LCDtrước khi tiến hành in chuỗi thứ 2 “2x16 LCD Display” ở dòng code 14. Nếu bạn thực hiện đúng trình tự như trkết quả thu được sẽ như trong hình 8.