微處理器 - 硬體 - LCM 4bits



參考資料:
https://www.8051projects.net/lcd-interfacing/lcd-4-bit.php

腳位:

LCD腳位功能說明
1GND
2VCC
3VEE(對比控制, GND最大)
41: Data Register
0: Command Register
51: LCD Read
0: LCD Write
6Enable
7D0
8D1
9D2
10D3
11D4
12D5
13D6
14D7
15BVCC(背光VCC)
16BGND(背光GND)

RS和RW的組合配對,可以產生四種不同的控制方式

RSRW功能說明
00寫命令到LCD
01讀取忙碌旗號和目前游標位址
10寫資料到DDRAM(顯示的文字)或CGRAM(造字的字形)
11從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的排列方式如下

第一行字元位址 0x000x010x02......0x110x120x13

2行(2x20)LCD RAM的排列方式如下

第一行字元位址 0x000x010x02......0x110x120x13
第二行字元位址 0x400x410x42......0x510x520x53

4行(4x20)LCD RAM的排列方式如下

第一行字元位址 0x000x010x02......0x110x120x13
第二行字元位址 0x400x410x42......0x510x520x53
第三行字元位址 0x140x150x16......0x250x260x27
第四行字元位址 0x540x550x56......0x650x660x67

電路圖如下:

每次傳送的命令或資料必須分成兩次傳送,先送出高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);
}

完成