參考資料:
https://www.8051projects.net/lcd-interfacing/lcd-4-bit.php
腳位:
| LCD腳位 | 功能說明 |
|---|---|
| 1 | GND |
| 2 | VCC |
| 3 | VEE(對比控制, GND最大) |
| 4 | 1: Data Register 0: Command Register |
| 5 | 1: LCD Read 0: LCD Write |
| 6 | Enable |
| 7 | D0 |
| 8 | D1 |
| 9 | D2 |
| 10 | D3 |
| 11 | D4 |
| 12 | D5 |
| 13 | D6 |
| 14 | D7 |
| 15 | BVCC(背光VCC) |
| 16 | BGND(背光GND) |
RS和RW的組合配對,可以產生四種不同的控制方式
| RS | RW | 功能說明 |
|---|---|---|
| 0 | 0 | 寫命令到LCD |
| 0 | 1 | 讀取忙碌旗號和目前游標位址 |
| 1 | 0 | 寫資料到DDRAM(顯示的文字)或CGRAM(造字的字形) |
| 1 | 1 | 從DDRAM或CGRAM讀取資料 |
LCD命令
| RS | RW | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | 需要執行時間 |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1: 清除LCD畫面 | ~2ms |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1: 游標回到原點位置 | X | ~2ms |
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0: 游標固定不動 1: 游標自動加1 |
0: LCD不自動位移 1: LCD自動位移 |
~50us |
| 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0: 關閉LCD顯示 1: 開啟LCD顯示 |
0: 關閉游標顯示 1: 開啟游標顯示 |
0: 關閉游標閃爍 1: 開啟游標閃爍 |
~50us |
| 0 | 0 | 0 | 0 | 0 | 1 | 0: 關閉LCD位移功能 1: 開啟LCD位移功能 |
0: 向左位移 1: 向右位移 |
X | X | ~50us |
| 0 | 0 | 0 | 0 | 1 | 0: 4位元模式 1: 8位元模式 |
0: 顯示1行 1: 顯示2行 |
0: 5x7字型 1: 5x10字型 |
X | X | ~50us |
| 0 | 0 | 0 | 1 | CGRAM Address | ~50us | |||||
| 0 | 0 | 1 | DDRAM Address | ~50us | ||||||
| 0 | 1 | 讀取忙碌旗標 | ~5us | |||||||
| 1 | 0 | 寫資料到DDRAM或CGRAM | ~5us | |||||||
| 1 | 1 | 從DDRAM或CGRAM讀取資料 | ~5us | |||||||
1行(1x20)LCD RAM的排列方式如下
| 第一行字元位址 | 0x00 | 0x01 | 0x02 | ...... | 0x11 | 0x12 | 0x13 |
|---|
2行(2x20)LCD RAM的排列方式如下
| 第一行字元位址 | 0x00 | 0x01 | 0x02 | ...... | 0x11 | 0x12 | 0x13 |
|---|---|---|---|---|---|---|---|
| 第二行字元位址 | 0x40 | 0x41 | 0x42 | ...... | 0x51 | 0x52 | 0x53 |
4行(4x20)LCD RAM的排列方式如下
| 第一行字元位址 | 0x00 | 0x01 | 0x02 | ...... | 0x11 | 0x12 | 0x13 |
|---|---|---|---|---|---|---|---|
| 第二行字元位址 | 0x40 | 0x41 | 0x42 | ...... | 0x51 | 0x52 | 0x53 |
| 第三行字元位址 | 0x14 | 0x15 | 0x16 | ...... | 0x25 | 0x26 | 0x27 |
| 第四行字元位址 | 0x54 | 0x55 | 0x56 | ...... | 0x65 | 0x66 | 0x67 |
電路圖如下:

每次傳送的命令或資料必須分成兩次傳送,先送出高4Bit,然後再送出低4Bit
Example
void delay(unsigned int v)
{
unsigned long m = 1000 * v;
while (m--);
}
void lcd_wr_cmd(unsigned char cmd)
{
LCD_RW = 0;
LCD_RS = 0;
LCD_PORT = cmd;
LCD_E = 1;
delay(1);
LCD_E = 0;
delay(1);
LCD_PORT = cmd << 4;
LCD_E = 1;
delay(1);
LCD_E = 0;
delay(1);
}
void lcd_wr_dat(unsigned char dat)
{
LCD_RW = 0;
LCD_RS = 1;
LCD_PORT = dat;
LCD_E = 1;
delay(1);
LCD_E = 0;
delay(1);
LCD_PORT = dat << 4;
LCD_E = 1;
delay(1);
LCD_E = 0;
delay(1);
}
void lcd_init(void)
{
lcd_wr_cmd(0x2e);
delay(10);
lcd_wr_cmd(0x0e);
delay(10);
lcd_wr_cmd(0x06);
delay(10);
lcd_wr_cmd(0x01);
delay(10);
lcd_wr_cmd(0x80);
delay(10);
}
void lcd_string(char *s)
{
unsigned char i = 0;
while (s[i] != 0x00) {
lcd_wr_dat(s[i++]);
}
}
void main(void)
{
lcd_init();
lcd_string("lcd 4-bit test !");
while (1);
}
完成