高通字库
版本 V1.0 · 更新于 2023-09-20

6. 屏模块通信

6.1 SPI 通信

本 SPI 通信例程使用模拟 SPI,如客户使用硬件 SPI 需要修改 SPI 驱动。

SPI 通信连接图

SPI 通信连接图SPI 通信连接图

SPI 通信原理图

SPI 通信原理图SPI 通信原理图

点亮屏流程

SPI 驱动点亮屏流程SPI 驱动点亮屏流程

屏需要初始化屏 IC 才能正常显示,上图为 SPI 驱动屏幕的步骤。

SPI 驱动程序

void SendDataSPI(unsigned char dat) {
    unsigned char i;
    for (i = 0; i < 8; i++) {
        LCD_SCL_LOW;
        if ((dat & 0x80) != 0) { LCD_SDA_HIGH; }
        else { LCD_SDA_LOW; }
        dat <<= 1;
        LCD_SCL_HIGH;
    }
}

void WriteComm(unsigned char command) {
    LCD_CS_LOW;
    LCD_RS_LOW;
    SendDataSPI(command);
    LCD_CS_HIGH;
}

void WriteData(unsigned char data) {
    LCD_CS_LOW;
    LCD_RS_HIGH;
    SendDataSPI(data);
    LCD_CS_HIGH;
}

OLED 初始化示例:

void OLED_init(void) {
    lcd_port_init();
    delay_ms(1);
    LCD_RS_HIGH; LCD_CS_HIGH;
    LCD_RESET_LOW; delay_ms(100);
    LCD_RESET_HIGH;
    WriteComm(0xAE); // Display Off
    WriteComm(0xD5); WriteComm(0x80); // 105Hz
    WriteComm(0xA8); WriteComm(0x3F); // 1/64 Duty
    WriteComm(0xD3); WriteComm(0x00);
    WriteComm(0x40);
    WriteComm(0x8D); WriteComm(0x14); // Enable Charge Pump
    WriteComm(0xAD); WriteComm(0x20);
    WriteComm(0xA1); WriteComm(0xC8);
    WriteComm(0xDA); WriteComm(0x12);
    WriteComm(0x81); WriteComm(0x0F);
    WriteComm(0xD9); WriteComm(0xF1);
    WriteComm(0xDB); WriteComm(0x30);
    WriteComm(0xA4); WriteComm(0xA6);
    WriteComm(0xAF); // Display ON
}

6.2 I2C 通信

如果使用 I2C 方式驱动屏幕,则需将 D2 与 D1 连接起来作为 SDA 数据引脚使用,原 DC 数据命令选择引脚作为 SA0 从地址选择使用。

I2C 通信连接图

I2C 通信连接图I2C 通信连接图

I2C 通信原理图

I2C 通信原理图I2C 通信原理图

点亮屏流程

I2C 驱动点亮屏流程I2C 驱动点亮屏流程

I2C 驱动程序

#define OLED_CMD  0  // 写命令
#define OLED_DATA 1  // 写数据

void I2C_Start(void) {
    OLED_SDA_Set(); OLED_SCL_Set(); IIC_delay();
    OLED_SDA_Clr(); IIC_delay();
    OLED_SCL_Clr(); IIC_delay();
}

void Send_Byte(u8 dat) {
    u8 i;
    for (i = 0; i < 8; i++) {
        if (dat & 0x80) { OLED_SDA_Set(); }
        else { OLED_SDA_Clr(); }
        IIC_delay(); OLED_SCL_Set(); IIC_delay();
        OLED_SCL_Clr();
        dat <<= 1;
    }
}

void OLED_WR_Byte(u8 dat, u8 mode) {
    I2C_Start();
    Send_Byte(0x78); I2C_WaitAck();
    if (mode) { Send_Byte(0x40); }
    else { Send_Byte(0x00); }
    I2C_WaitAck();
    Send_Byte(dat); I2C_WaitAck();
    I2C_Stop();
}