LCD1602显示预设字符和自定义字符


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wiringPi.h>

// 定义LCD1602的相关指令
#define LCD_CMD_CLEAR_DISPLAY 0x01
#define LCD_CMD_RETURN_HOME 0x02
#define LCD_CMD_FUNCTION_SET 0x20
#define LCD_CMD_DISPLAY_CONTROL 0x08
#define LCD_CMD_ENTRY_MODE_SET 0x04
#define LCD_CMD_SET_CGRAM_ADDR 0x40
#define LCD_CMD_SET_DDRAM_ADDR 0x80

// 定义LCD1602的相关地址
#define LCD_ADDR_COMMAND 0x00
#define LCD_ADDR_DATA 0x01

// 定义GPIO口的编号
#define PIN_RS 0
#define PIN_RW 1
#define PIN_E 2
#define PIN_D4 3
#define PIN_D5 4
#define PIN_D6 5
#define PIN_D7 6

// 函数声明
void lcd_send_cmd(unsigned char cmd);
void lcd_send_data(unsigned char data);
void lcd_init();
void lcd_display_preset_character();
void lcd_display_custom_character();

int main() {
    // 初始化wiringPi库
    wiringPiSetup();
    
    // 设置GPIO口的模式为输出
    pinMode(PIN_RS, OUTPUT);
    pinMode(PIN_RW, OUTPUT);
    pinMode(PIN_E, OUTPUT);
    pinMode(PIN_D4, OUTPUT);
    pinMode(PIN_D5, OUTPUT);
    pinMode(PIN_D6, OUTPUT);
    pinMode(PIN_D7, OUTPUT);
    
    lcd_init();
    lcd_display_preset_character();
    lcd_display_custom_character();
    return 0;
}

// 发送命令到LCD1602
void lcd_send_cmd(unsigned char cmd) {
    digitalWrite(PIN_RS, 0);  // 设置RS为0,表示发送的是命令
    digitalWrite(PIN_RW, 0);  // 设置RW为0,表示写入数据
    
    // 发送高4位数据
    digitalWrite(PIN_D4, (cmd >> 4) & 0x01);
    digitalWrite(PIN_D5, (cmd >> 5) & 0x01);
    digitalWrite(PIN_D6, (cmd >> 6) & 0x01);
    digitalWrite(PIN_D7, (cmd >> 7) & 0x01);
    
    // 拉高E,使LCD1602读取数据
    digitalWrite(PIN_E, 1);
    delayMicroseconds(1);
    
    // 拉低E,完成一次数据传输
    digitalWrite(PIN_E, 0);
    delayMicroseconds(1);
    
    // 发送低4位数据
    digitalWrite(PIN_D4, cmd & 0x01);
    digitalWrite(PIN_D5, (cmd >> 1) & 0x01);
    digitalWrite(PIN_D6, (cmd >> 2) & 0x01);
    digitalWrite(PIN_D7, (cmd >> 3) & 0x01);
    
    // 拉高E,使LCD1602读取数据
    digitalWrite(PIN_E, 1);
    delayMicroseconds(1);
    
    // 拉低E,完成一次数据传输
    digitalWrite(PIN_E, 0);
    delayMicroseconds(1);
}

// 发送数据到LCD1602
void lcd_send_data(unsigned char data) {
    digitalWrite(PIN_RS, 1);  // 设置RS为1,表示发送的是数据
    digitalWrite(PIN_RW, 0);  // 设置RW为0,表示写入数据
    
    // 发送高4位数据
    digitalWrite(PIN_D4, (data >> 4) & 0x01);
    digitalWrite(PIN_D5, (data >> 5) & 0x01);
    digitalWrite(PIN_D6, (data >> 6) & 0x01);
    digitalWrite(PIN_D7, (data >> 7) & 0x01);
    
    // 拉高E,使LCD1602读取数据
    digitalWrite(PIN_E, 1);
    delayMicroseconds(1);
    
    // 拉低E,完成一次数据传输
    digitalWrite(PIN_E, 0);
    delayMicroseconds(1);
    
    // 发送低4位数据
    digitalWrite(PIN_D4, data & 0x01);
    digitalWrite(PIN_D5, (data >> 1) & 0x01);
    digitalWrite(PIN_D6, (data >> 2) & 0x01);
    digitalWrite(PIN_D7, (data >> 3) & 0x01);
    
    // 拉高E,使LCD1602读取数据
    digitalWrite(PIN_E, 1);
    delayMicroseconds(1);
    
    // 拉低E,完成一次数据传输
    digitalWrite(PIN_E, 0);
    delayMicroseconds(1);
}

// 初始化LCD1602
void lcd_init() {
    delay(50);  // 等待LCD1602上电稳定
    
    // 发送初始化指令到LCD1602
    lcd_send_cmd(0x30);
    delay(5);
    lcd_send_cmd(0x30);
    delay(1);
    lcd_send_cmd(0x30);
    delay(1);
    
    // 设置显示模式为2行,5x8点阵
    lcd_send_cmd(LCD_CMD_FUNCTION_SET | 0x08);
    delay(1);
    
    // 设置光标不闪烁,不显示
    lcd_send_cmd(LCD_CMD_DISPLAY_CONTROL | 0x04);
    delay(1);
    
    // 设置文字从左向右滚动
    lcd_send_cmd(LCD_CMD_ENTRY_MODE_SET | 0x02);
    delay(1);
    
    // 清屏
    lcd_send_cmd(LCD_CMD_CLEAR_DISPLAY);
    delay(2);
}

// 显示预设字符
void lcd_display_preset_character() {
    // 设置DDRAM地址为0x00,即第一行第一列
    lcd_send_cmd(LCD_CMD_SET_DDRAM_ADDR | 0x00);
    
    // 显示预设字符的代码
    // 例如,显示ASCII码为65的字符'A'
    lcd_send_data(65);
}

// 显示自定义字符
void lcd_display_custom_character() {
    // 设置DDRAM地址为0x40,即第二行第一列
    lcd_send_cmd(LCD_CMD_SET_DDRAM_ADDR | 0x40);
    
    // 定义自定义字符模式
    unsigned char custom_character[8] = {
        0b00000,
        0b01010,
        0b00100,
        0b11111,
        0b00100,
        0b00100,
        0b00100,
        0b00000
    };
    
    // 将自定义字符模式写入CGRAM
    lcd_send_cmd(LCD_CMD_SET_CGRAM_ADDR);
    for (int i = 0; i < 8; i++) {
        lcd_send_data(custom_character[i]);
    }
    
    // 设置DDRAM地址为0x41,即第二行第二列
    lcd_send_cmd(LCD_CMD_SET_DDRAM_ADDR | 0x41);
    
    // 显示自定义字符
    lcd_send_data(0x00);  // 使用CGRAM中的第一个自定义字符
    
    // 可以继续设置其他位置的自定义字符
    // ...
}

在LCD1602中,预设字符是存储在CGROM(Character Generator ROM)中的,每个字符占用5x8的像素点阵。当我们调用lcd_send_data(65)时,实际上是将ASCII码为65的字符'A'的对应编码(即CGROM中的地址)发送给LCD1602。

LCD1602的内部控制器会根据这个编码从CGROM中读取对应的像素点阵,并在屏幕上显示出来。因此,预设字符的显示是由LCD1602的内部控制器完成的,而不是由我们的代码直接控制的。

对于自定义字符,LCD1602的内部控制器并不会直接从CGRAM中读取字符的像素点阵。相反,我们需要通过将自定义字符的编码(即CGRAM中的地址)发送给LCD1602,让它在屏幕上显示出来。

具体来说,当我们调用lcd_send_data(0x00)时,实际上是将CGRAM中的第一个自定义字符的对应编码发送给LCD1602。LCD1602的内部控制器会根据这个编码从CGRAM中读取对应的像素点阵,并在屏幕上显示出来。

在上面的代码示例中,我们通过调用lcd_send_cmd(LCD_CMD_SET_CGRAM_ADDR)将CGRAM的地址设置为写入模式,然后通过循环将自定义字符的像素数据写入CGRAM。最后,我们调用lcd_send_data(0x00)来显示CGRAM中的第一个自定义字符。

需要注意的是,LCD1602的CGRAM共有8个字符的存储空间,每个字符占用5x8的像素点阵。因此,我们可以定义最多8个不同的自定义字符,并通过设置不同的CGRAM地址来显示它们。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值