這篇文章是練習控制 Microchip APP013 開發板的 LCD 顯示,此開發板上的 LCD 是使用 16 個字元 x 2 列的文字型 LCD,以 4 bits 模式和 LCD 通訊。
LCD 控制方塊圖
LCD 腳位定義
LCD 的寫入及讀取的時序圖
Display address
此款 LCD 是 16 個字元 x 2 列,LCD 畫面對應到顯示位址如下,第一列是從 80H ~ 8FH,第二列是從 C0H ~ CFH。
LCD 指令集
4 bits 控制步驟
4 bits 控制命令的操作範例
開發板 LCD 電路圖
APP013 的 LCD Module 連接腳位如下
RS: RD4
RW: RD5
EN: RE2
RD3 ~ RD0: 使用 4 bits mode 的控制方式
程式碼
檔案:LCD.h
分別定義了 LCD RS、RW、EN 的狀態值,以及常用的 LCD Command
#ifndef _LCD_H #define _LCD_H #define LCD_RS_COMMAND 0 #define LCD_RS_DATA 1 #define LCD_RW_READ 1 #define LCD_RW_WRITE 0 #define LCD_ENABLE 1 #define LCD_DISABLE 0 // LCD Command #define DISP_2LINE_4BITS 0x2C // Function set: DL=4 bits, N=2 lines, F=5x10 dots #define DISP_ON 0x0C // Display On #define DISP_ON_C 0x0E // Display On + Curror On #define DISP_ON_B 0x0F // Display On + Curror On + Blink On #define DISP_OFF 0x08 // Display Off #define CLR_DISP 0x01 // Clear Display (must wait 1.64 ms) #define ENTRY_INCR 0x06 // Entry Mode set: I/D=increment, S=0 #define ENTRY_DECR 0x04 // Entry Mode set: I/D=decrement, S=0 #define RETURN_HOME 0x02 // Cursor return home (must wait 1.64 ms) extern void InitLCD(void); extern void LCDCmdWrite4bits(unsigned char cmd); extern void LCDCmdWrite(unsigned char cmd); extern void LCDDataWrite(unsigned char data); extern void LCDCursorPos(unsigned char row, unsigned char column); extern void putcLCD(unsigned char data); extern void putsLCD(const char *data); extern void putrsLCD(const rom char *data); #endif
檔案:LCD.c
此檔案包含了 LCD 的初始化函式、LCD 命令及資料的寫入函式,LCD 的命令分成送 4 bits 的 LCDCmdWrite4bits 及分二次送完 8 bits 命令的 LCDCmdWrite 函式。LCD 的資料顯示也是分二次送完 8 bits 的 LCDDataWrite 函式。
#include "HardwareProfile.h" void InitLCD(void) { LCD_RS = 0; LCD_RW = 0; LCD_EN = 0; LCD_RS_TRIS = 0; LCD_RW_TRIS = 0; LCD_EN_TRIS = 0; LCD_DATA_TRIS = 0; LCD_DATA = 0; delayms(2); // Delay more than 1.5 ms for LCD Power on reset LCDCmdWrite4bits(0x03); delayms(5); // Function set (Delay 4.1 ms) LCDCmdWrite4bits(0x03); delayus(100); // Function set (Delay 100 us) LCDCmdWrite4bits(0x03); delayus(100); // Function set (Delay 100 us) LCDCmdWrite4bits(0x02); // Function set: DL=4 bits LCDCmdWrite(DISP_2LINE_4BITS); // Function set: DL=4 bits, N=2 lines, F=5x10 dots LCDCmdWrite(DISP_ON_C); // Display Control: D=Display On, C=Cursor On, B=Blink off LCDCmdWrite(ENTRY_INCR); // Entry Mode set: I/D=increment, S=0 LCDCmdWrite(CLR_DISP); // Clear Display delayms(2); // Wait more than 1.64 ms for Clear Display } static void _LCDWrite(unsigned char nibble) { LCD_DATA = (LCD_DATA & 0xF0) | (nibble & 0x0F); LCD_EN = LCD_ENABLE; Nop(); Nop(); Nop(); LCD_EN = LCD_DISABLE; Nop(); Nop(); Nop(); } // Write LCD Command in 4 bits void LCDCmdWrite4bits(unsigned char cmd) { LCD_RS = LCD_RS_COMMAND; LCD_RW = LCD_RW_WRITE; _LCDWrite(cmd & 0x0F); delayus(100); } // Write LCD Command void LCDCmdWrite(unsigned char cmd) { LCD_RS = LCD_RS_COMMAND; LCD_RW = LCD_RW_WRITE; _LCDWrite(cmd >> 4); _LCDWrite(cmd & 0x0F); delayus(100); } // Write LCD Data void LCDDataWrite(unsigned char data) { LCD_RS = LCD_RS_DATA; LCD_RW = LCD_RW_WRITE; _LCDWrite(data >> 4); _LCDWrite(data & 0x0F); delayus(100); } // Cursor postion setting // 16 characters x 2 lines Display Address: // Line 1: 80 81 82 83 ... 8D 8E 8F (16 characters) // (0,0) (0,15) // Line 2: C0 C1 C2 C3 ... CD CE CF (16 characters) // (1,0) (1,15) void LCDCursorPos(unsigned char row, unsigned char column) { LCDCmdWrite(0x80 + (row * 0x40) + column); } // Print a character to LCD void putcLCD(unsigned char data) { LCDDataWrite(data); delayms(100); } // Print a string to LCD void putsLCD(const char *data) { while(*data) { putcLCD(*data++); } } // Print a rom string to LCD void putrsLCD(const rom char *data) { while(*data) { putcLCD(*data++); } }
檔名:main.c
在 main 主程式中一開始會呼叫 InitIO 進行週邊及 LCD 的初始化設定,接著以間隔 1 秒的時間分別顯示字串變數和 ROM 中的字串到 LCD 上。
void main(void) { char buff[] = "Hello World !"; InitIO(); while(1) { LCDCmdWrite(CLR_DISP); // Clear Display delayms(2); // Wait more than 1.64 ms for Clear Display putsLCD(buff); LCDCursorPos(1, 0); putrsLCD("I am a cool man."); delayms(250); delayms(250); delayms(250); delayms(250); } } void InitIO(void) { TRISD = PORTD = 0; INTCON = PIE1 = PIR1 = 0; InitLCD(); RCONbits.IPEN = 1; INTCONbits.GIEH = 0; INTCONbits.GIEL = 0; }
示範影片:
參考資料:
0 意見:
張貼留言