找回密码
 立即注册
查看: 21|回复: 1

学会用LCD1602屏显示字符

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:6
  • 最近打卡:2026-04-04 14:44:58
已绑定手机

5

主题

4

回帖

49

积分

新手上路

积分
49
发表于 4 天前 | 显示全部楼层 |阅读模式
今天是学习打卡的第二天,手上正好有一块LCD1602的屏,四针的,I2C接口,就尝试写了一个代码,显示字符,并打开背光灯。


#include "stc32g.h"
#include <intrins.h>

// I2C LCD1602地址(通常为0x27或0x3F)
#define LCD_ADDR 0x27
sbit P2_1 = P2^1;
sbit P2_0 = P2^0;
// I2C引脚定义
#define SDA_PIN P2_1
#define SCL_PIN P2_0

// LCD命令定义
#define LCD_CLEAR_DISPLAY 0x01
#define LCD_RETURN_HOME 0x02
#define LCD_ENTRY_MODE_SET 0x04
#define LCD_DISPLAY_CONTROL 0x08
#define LCD_CURSOR_SHIFT 0x10
#define LCD_FUNCTION_SET 0x20
#define LCD_SET_CGRAM_ADDR 0x40
#define LCD_SET_DDRAM_ADDR 0x80

// 延时函数
void delay_us(unsigned int us) {
    while(us--) {
        _nop_();
        _nop_();
        _nop_();
        _nop_();
    }
}

void delay_ms(unsigned int ms) {
    unsigned int i, j;
    for(i = 0; i < ms; i++) {
        for(j = 0; j < 1000; j++) {
            _nop_();
        }
    }
}

// I2C起始信号
void I2C_Start() {
    SDA_PIN = 1;
    SCL_PIN = 1;
    delay_us(5);
    SDA_PIN = 0;
    delay_us(5);
    SCL_PIN = 0;
}

// I2C停止信号
void I2C_Stop() {
    SDA_PIN = 0;
    SCL_PIN = 1;
    delay_us(5);
    SDA_PIN = 1;
    delay_us(5);
}

// I2C发送应答信号
void I2C_Ack() {
    SDA_PIN = 0;
    SCL_PIN = 1;
    delay_us(5);
    SCL_PIN = 0;
    SDA_PIN = 1;
}

// I2C发送非应答信号
void I2C_NAck() {
    SDA_PIN = 1;
    SCL_PIN = 1;
    delay_us(5);
    SCL_PIN = 0;
    SDA_PIN = 1;
}

// I2C检测应答信号
bit I2C_CheckAck() {
    bit ack;
    SDA_PIN = 1;
    SCL_PIN = 1;
    delay_us(5);
    ack = SDA_PIN;
    SCL_PIN = 0;
    delay_us(5);
    return ack;
}

// I2C发送一个字节
void I2C_SendByte(unsigned char dat) {
    unsigned char i;
    for(i = 0; i < 8; i++) {
        SDA_PIN = (dat & 0x80) ? 1 : 0;
        dat <<= 1;
        SCL_PIN = 1;
        delay_us(5);
        SCL_PIN = 0;
        delay_us(5);
    }
    I2C_CheckAck();
}

// I2C接收一个字节
unsigned char I2C_RecvByte() {
    unsigned char i, dat = 0;
    SDA_PIN = 1;
    for(i = 0; i < 8; i++) {
        SCL_PIN = 1;
        delay_us(5);
        dat <<= 1;
        if(SDA_PIN) dat |= 0x01;
        SCL_PIN = 0;
        delay_us(5);
    }
    return dat;
}

// 向LCD发送命令或数据
void LCD_Send(unsigned char dta, bit rs) {
    unsigned char high, low;
   
    // 拆分4位数据
    high = dta & 0xF0;
    low = (dta << 4) & 0xF0;
   
    I2C_Start();
    I2C_SendByte(LCD_ADDR << 1);
   
    // 发送高4位
    I2C_SendByte(high | 0x04 | (rs ? 0x01 : 0x00));  // EN=1, RS=rs
    I2C_SendByte(high | (rs ? 0x01 : 0x00));          // EN=0, RS=rs
   
    // 发送低4位
    I2C_SendByte(low | 0x04 | (rs ? 0x01 : 0x00));    // EN=1, RS=rs
    I2C_SendByte(low | (rs ? 0x01 : 0x00));           // EN=0, RS=rs
   
    I2C_Stop();
}

// LCD初始化
void LCD_Init() {
    delay_ms(50);  // 等待LCD上电稳定
   
    // 初始化I2C引脚
    P2M1 &= ~0x03;  // P2.0(SCL), P2.1(SDA) 设为推挽输出
    P2M0 |= 0x03;
   
    // 4位模式初始化序列
    LCD_Send(0x33, 0);  // 8位模式
    LCD_Send(0x32, 0);  // 8位模式
    LCD_Send(0x28, 0);  // 4位模式,2行显示,5x8点阵
   
    LCD_Send(LCD_DISPLAY_CONTROL | 0x04, 0);  // 显示开,光标关
    LCD_Send(LCD_CLEAR_DISPLAY, 0);           // 清屏
    LCD_Send(LCD_ENTRY_MODE_SET | 0x02, 0);   // 增量模式,不移位
    delay_ms(2);
}

// 在指定位置显示字符
void LCD_DisplayChar(unsigned char x, unsigned char y, unsigned char ch) {
    unsigned char addr;
    if(y == 0) addr = 0x80 + x;
    else addr = 0xC0 + x;
    LCD_Send(addr, 0);  // 设置DDRAM地址
    LCD_Send(ch, 1);    // 写入数据
}

// 显示字符串
void LCD_DisplayString(unsigned char x, unsigned char y, unsigned char *str) {
    unsigned char addr;
    if(y == 0) addr = 0x80 + x;
    else addr = 0xC0 + x;
    LCD_Send(addr, 0);  // 设置DDRAM地址
   
    while(*str != '\0') {
        LCD_Send(*str++, 1);
    }
}

// 清屏
void LCD_Clear() {
    LCD_Send(LCD_CLEAR_DISPLAY, 0);
    delay_ms(2);
}
// 背光控制函数
void LCD_Backlight(bit state) {
    I2C_Start();                          // 起始信号
    I2C_SendByte(LCD_ADDR << 1);          // 发送设备地址
    I2C_SendByte(state ? 0x08 : 0x00);    // 控制背光
    I2C_Stop();                           // 停止信号
}

// 使用示例
// LCD_Backlight(1);  // 打开背光
// LCD_Backlight(0);  // 关闭背光

void main() {
   
        LCD_Init();
   
    LCD_DisplayString(0, 0, "Hello, World!");
    LCD_DisplayString(0, 1, "STC32G12K128");
   
    while(1) {
      LCD_Backlight(1);  // 可以添加其他功能
    }
}

下载程序后

下载程序后
113.jpg
114.jpg
回复

使用道具 举报 送花

  • 打卡等级:常住居民I
  • 打卡总天数:74
  • 最近打卡:2026-04-03 08:37:07
已绑定手机

14

主题

143

回帖

986

积分

版主

积分
986
发表于 3 天前 | 显示全部楼层
请勿重复开贴
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-4-4 17:46 , Processed in 0.104338 second(s), 52 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表