通过RS来区分是命令还是数据
在WR高电平时,将数据放入D[0:15]数据线上
在WR上升沿,读取D[0:15]数据线上的数据
//提前把默认信号设置为对应电平
static inline void LcdSendCmd(uint16_t cmdVal)
{
LCD_CS_RESET();//cs输出低电平,表示片选信号开始工作
LCD_RS_RESET();//rs=1,表示数据
LCD_WR_SET();
LCD_RD_SET(); //rd保持高电平,//三个前置条件设置好了
LCD_DATA_WRITE(cmdVal);
LCD_WR_RESET();
LCD_WR_SET();//产生上升沿,LCD读取data数据
LCD_CS_SET();//cs输出低电平,表示片选信号结束工作
}
static inline void LcdSendData(uint16_t dataVal)
{
LCD_CS_RESET();
LCD_RS_SET();
//LCD_RD_SET();
LCD_DATA_WRITE(dataVal);
LCD_WR_RESET();
LCD_WR_SET();
LCD_CS_SET();
}
static inline uint16_t LcdGetData(void)
{
uint16_t data;
LCD_CS_RESET(); //
LCD_RS_SET();
LCD_RD_RESET(); //HX8352B have a Dummy RD
LCD_RD_SET();
LCD_RD_RESET(); //So HX8352B have 2 RD. After test,HX8352A HX8352C ST7793 SPFD5420 R61509V all OK
LCD_RD_SET();
data = LCD_DATA_READ();
LCD_CS_SET();
return data;
}
static inline void LcdWriteReg(uint16_t addr, uint16_t data)
{
LcdSendCmd(addr);
LcdSendData(data);
}
static inline uint16_t LcdReadReg(uint16_t addr)
{
uint16_t data;
LcdSendCmd(addr);
/*SET GPIOB Input*/
gpio_init(GPIOB, GPIO_MODE_IPU, GPIO_OSPEED_MAX, GPIO_PIN_ALL);
data = LcdGetData();
/*SET GPIOB Output*/
gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_MAX, GPIO_PIN_ALL);
return data;
}
#include <stdint.h>
#include <stdio.h>
#include "gd32f30x.h"
#include "delay.h"
#include "lcd_drv.h"
#include "RTT_Debug.h"
static void GpioInit(void)
{
/* 使能RCU相关时钟 */
rcu_periph_clock_enable(RCU_AF);
rcu_periph_clock_enable(RCU_GPIOA); // 使能GPIOA的时钟
rcu_periph_clock_enable(RCU_GPIOB); // 使能GPIOB的时钟
rcu_periph_clock_enable(RCU_GPIOC); // 使能GPIOC的时钟
/*
*WR---PC0 RS---PC1
*CS---PC2 RD---PC3//pb3和pb4是给JTAG接口使用的 JTMS JTCK JTDI JTD0 四个引脚
*RST--PC8 BK---PA8
*D0--D15 PB0--15
*/
/* 数据总线 */
gpio_pin_remap_config(GPIO_SWJ_SWDPENABLE_REMAP, ENABLE);//关闭JTAG和使能swD的模式
gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_MAX, GPIO_PIN_ALL); // D0~D15
gpio_port_write(GPIOB, 0);//默认GPIOB所有pin都输出低电平
/* 控制信号 */
gpio_init(GPIOC, GPIO_MODE_OUT_PP, GPIO_OSPEED_MAX, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_8);
gpio_bit_set(GPIOC, GPIO_PIN_8);//复位信号
gpio_bit_reset(GPIOC, GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3);
/* 背光信号 */
gpio_init(GPIOA, GPIO_MODE_OUT_PP, GPIO_OSPEED_2MHZ, GPIO_PIN_8);
gpio_bit_reset(GPIOA, GPIO_PIN_8);
}
#define LCD_RST_SET() gpio_bit_set(GPIOC, GPIO_PIN_8)
#define LCD_RST_RESET() gpio_bit_reset(GPIOC, GPIO_PIN_8)
#define LCD_RD_SET() gpio_bit_set(GPIOC, GPIO_PIN_3)
#define LCD_RD_RESET() gpio_bit_reset(GPIOC, GPIO_PIN_3)
#define LCD_CS_SET() gpio_bit_set(GPIOC, GPIO_PIN_2)
#define LCD_CS_RESET() gpio_bit_reset(GPIOC, GPIO_PIN_2)
#define LCD_RS_SET() gpio_bit_set(GPIOC, GPIO_PIN_1)
#define LCD_RS_RESET() gpio_bit_reset(GPIOC, GPIO_PIN_1)
#define LCD_WR_SET() gpio_bit_set(GPIOC, GPIO_PIN_0)
#define LCD_WR_RESET() gpio_bit_reset(GPIOC, GPIO_PIN_0)
#define LCD_BK_ON() gpio_bit_set(GPIOA, GPIO_PIN_8)
#define LCD_BK_OFF() gpio_bit_reset(GPIOA, GPIO_PIN_8)
#define LCD_DATA_WRITE(data) gpio_port_write(GPIOB, data)
#define LCD_DATA_READ() gpio_input_port_get(GPIOB)
// 8080写时序图 https://i-blog.csdnimg.cn/direct/01e0ae04b5a94ad68201b5b8b1faf312.png
static inline void LcdSendCmd(uint16_t cmdVal)
{
LCD_CS_RESET();//cs输出低电平,表示片选信号开始工作
LCD_RS_RESET();//rs=1,表示数据
LCD_RD_SET(); //rd保持高电平,
LCD_DATA_WRITE(cmdVal);
LCD_WR_RESET();
LCD_WR_SET();
LCD_CS_SET();
}
static inline void LcdSendData(uint16_t dataVal)
{
LCD_CS_RESET();
LCD_RS_SET();
//LCD_RD_SET();
LCD_DATA_WRITE(dataVal);
LCD_WR_RESET();
LCD_WR_SET();
LCD_CS_SET();
}
//https://i-blog.csdnimg.cn/direct/6232e4d7ef3b489bb62a21447a169cf8.png
static inline uint16_t LcdGetData(void)
{
uint16_t data;
LCD_CS_RESET(); //
LCD_RS_SET();
LCD_RD_RESET(); //HX8352B have a Dummy RD
LCD_RD_SET();
LCD_RD_RESET(); //So HX8352B have 2 RD. After test,HX8352A HX8352C ST7793 SPFD5420 R61509V all OK
LCD_RD_SET();
data = LCD_DATA_READ();
LCD_CS_SET();
return data;
}
static inline void LcdWriteReg(uint16_t addr, uint16_t data)
{
LcdSendCmd(addr);
LcdSendData(data);
}
static inline uint16_t LcdReadReg(uint16_t addr)
{
uint16_t data;
LcdSendCmd(addr);
/*SET GPIOB Input*/
gpio_init(GPIOB, GPIO_MODE_IPU, GPIO_OSPEED_MAX, GPIO_PIN_ALL);
data = LcdGetData();
/*SET GPIOB Output*/
gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_MAX, GPIO_PIN_ALL);
return data;
}
#define LCD_ID 0x65
static void LcdInit(void)
{
LCD_RST_RESET();
DelayNms(100);
LCD_RST_SET();
DelayNms(100);
uint16_t id;
id = LcdReadReg(0);
DBG_log("LCD ID:%x\n", id);
if ((id & 0xFF) != LCD_ID)
{
DBG_Error("LCD init error\n");
return;
}
#if 0
LcdWriteReg(0xE2, 0x15); //VREFsetting
LcdWriteReg(0xE5, 0x28);
LcdWriteReg(0xE7, 0x28);
LcdWriteReg(0xE8, 0x48);
LcdWriteReg(0xEC, 0x09);
LcdWriteReg(0xED, 0x06);
// Power on Setting
LcdWriteReg(0x17, 0x05);
LcdWriteReg(0x23, 0x76);
LcdWriteReg(0x24, 0x57);
LcdWriteReg(0x25, 0x71);
LcdWriteReg(0x1B, 0x1E); //VREG1 = 4.5V
LcdWriteReg(0x01, 0x00);
LcdWriteReg(0x1C, 0x04);
// Power on sequence
LcdWriteReg(0x18, 0x88);
LcdWriteReg(0x19, 0x01);
DelayNms(5);
LcdWriteReg(0x1F, 0x8C);
LcdWriteReg(0x1F, 0x84);
DelayNms(5);
LcdWriteReg(0x1F, 0x94);
DelayNms(5);
LcdWriteReg(0x1F, 0xD4);
DelayNms(5);
// Gamma Setting
LcdWriteReg(0x40, 0x08);
LcdWriteReg(0x41, 0x31);
LcdWriteReg(0x42, 0x2F);
LcdWriteReg(0x43, 0x3E);
LcdWriteReg(0x44, 0x3D);
LcdWriteReg(0x45, 0x3F);
LcdWriteReg(0x46, 0x2F);
LcdWriteReg(0x47, 0x79);
LcdWriteReg(0x48, 0x08);
LcdWriteReg(0x49, 0x06);
LcdWriteReg(0x4A, 0x08);
LcdWriteReg(0x4B, 0x0E);
LcdWriteReg(0x4C, 0x17);
LcdWriteReg(0x50, 0x00);
LcdWriteReg(0x51, 0x02);
LcdWriteReg(0x52, 0x01);
LcdWriteReg(0x53, 0x10);
LcdWriteReg(0x54, 0x0E);
LcdWriteReg(0x55, 0x37);
LcdWriteReg(0x56, 0x06);
LcdWriteReg(0x57, 0x50);
LcdWriteReg(0x58, 0x08);
LcdWriteReg(0x59, 0x11);
LcdWriteReg(0x5A, 0x17);
LcdWriteReg(0x5B, 0x19);
LcdWriteReg(0x5C, 0x17);
LcdWriteReg(0x5D, 0xFF);
// Display ON Setting
LcdWriteReg(0x16, 0x0B);
LcdWriteReg(0x28, 0x20);
DelayNms(5);
LcdWriteReg(0x28, 0x38);
DelayNms(5); // Waiting 2 frames al least
LcdWriteReg(0x28, 0x3C);
DelayNms(100);
#endif
#if 1
LcdWriteReg(0x00E2, 0x0000);
LcdWriteReg(0x00E5, 0x0000);
LcdWriteReg(0x00E7, 0x0000);
LcdWriteReg(0x00E8, 0x005E);
LcdWriteReg(0x00EC, 0x0008);
LcdWriteReg(0x00ED, 0x0047);
LcdWriteReg(0x00EE, 0x0020);
LcdWriteReg(0x00EF, 0x0059);
LcdWriteReg(0x0029, 0x0000);
LcdWriteReg(0x002A, 0x0010);
LcdWriteReg(0x002B, 0x0003);
LcdWriteReg(0x0023, 0x007C); // Power on Setting
LcdWriteReg(0x0024, 0x0080);
LcdWriteReg(0x0025, 0x004F);
LcdWriteReg(0x0026, 0x0007);
LcdWriteReg(0x0029, 0x0000); //Frame control
LcdWriteReg(0x002A, 0x0000);
LcdWriteReg(0x002B, 0x0003);
LcdWriteReg(0x001B, 0x001E);
LcdWriteReg(0x0018, 0x00EF); // Power on sequence
LcdWriteReg(0x0019, 0x0001);
DelayNms(10),
LcdWriteReg(0x001F, 0x008C);
LcdWriteReg(0x001F, 0x0084);
DelayNms(10),
LcdWriteReg(0x001F, 0x0094);
DelayNms(10),
LcdWriteReg(0x001F, 0x00D4);
DelayNms(10),
LcdWriteReg(0x002F, 0x0000);
LcdWriteReg(0x0040, 0x0000); // Gamma Setting
LcdWriteReg(0x0041, 0x0029);
LcdWriteReg(0x0042, 0x0026);
LcdWriteReg(0x0043, 0x003E);
LcdWriteReg(0x0044, 0x003D);
LcdWriteReg(0x0045, 0x003F);
LcdWriteReg(0x0046, 0x001F);
LcdWriteReg(0x0047, 0x0074);
LcdWriteReg(0x0048, 0x0008);
LcdWriteReg(0x0049, 0x0004);
LcdWriteReg(0x004A, 0x0006);
LcdWriteReg(0x004B, 0x000C);
LcdWriteReg(0x004C, 0x0017);
LcdWriteReg(0x0050, 0x0000);
LcdWriteReg(0x0051, 0x0002);
LcdWriteReg(0x0052, 0x0001);
LcdWriteReg(0x0053, 0x0019);
LcdWriteReg(0x0054, 0x0016);
LcdWriteReg(0x0055, 0x003F);
LcdWriteReg(0x0056, 0x000B);
LcdWriteReg(0x0057, 0x0060);
LcdWriteReg(0x0058, 0x0008);
LcdWriteReg(0x0059, 0x0013);
LcdWriteReg(0x005A, 0x0019);
LcdWriteReg(0x005B, 0x001B);
LcdWriteReg(0x005C, 0x0017);
LcdWriteReg(0x005D, 0x00FF);
LcdWriteReg(0x0016, 0x000B); // Display ON Setting
LcdWriteReg(0x0017, 0x0055);
LcdWriteReg(0x0028, 0x0020);
DelayNms(40);
LcdWriteReg(0x0028, 0x0038);
DelayNms(40); // Waiting 2 frames al least
LcdWriteReg(0x0028, 0x003C);
LcdWriteReg(0x0002, 0x0000); // Set active window
DelayNms(100);
#endif
}
static void LcdSetCursor(LcdArea_t *area)
{
LcdWriteReg(0x02, area->x1 >> 8);
LcdWriteReg(0x03, area->x1);
LcdWriteReg(0x04, area->x2 >> 8);
LcdWriteReg(0x05, area->x2);
LcdWriteReg(0x06, area->y1 >> 8);
LcdWriteReg(0x07, area->y1);
LcdWriteReg(0x08, area->y2 >> 8);
LcdWriteReg(0x09, area->y2);
LcdWriteReg(0x80, area->x1 >> 8);
LcdWriteReg(0x81, area->x1);
LcdWriteReg(0x82, area->y1 >> 8);
LcdWriteReg(0x83, area->y1);
LcdSendCmd(0x22);
}
void LcdFillPureColor(LcdArea_t *area, uint16_t color)
{
if ((area->x1 > LCD_PIXEL_WIDTH - 1) || (area->x2 > LCD_PIXEL_WIDTH - 1)
|| (area->y1 > LCD_PIXEL_HEIGHT - 1) || (area->y2 > LCD_PIXEL_HEIGHT - 1))
{
return;
}
LcdSetCursor(area);
uint32_t totalPoint = (area->x2 - area->x1 + 1) * (area->y2 - area->y1 + 1);
LCD_CS_RESET();
LCD_RD_SET();
LCD_RS_SET();
LCD_DATA_WRITE(color);
for (uint32_t i = 0; i < totalPoint; i++)
{
LCD_WR_RESET();
LCD_WR_SET();
}
LCD_CS_SET();
}
void LcdDrvInit(void)
{
GpioInit();
LcdInit();
// LCD_BK_ON();
LcdArea_t area = {0, 0, LCD_PIXEL_WIDTH - 1, LCD_PIXEL_HEIGHT - 1};
LcdFillPureColor(&area, BLACK);
}
void LcdDrawChar(uint16_t x, uint16_t y, uint8_t ascii, uint16_t textColor, uint16_t bkColor, AsciiFontDesc_t *font)
{
uint8_t *bitmap;
LcdArea_t area;
uint8_t data;
uint16_t i, j, k;
if (!font->isJustNum)
{
bitmap = (uint8_t *)font->bitmap + (ascii - ' ') * font->charHasBytes;
}
else
{
bitmap = (uint8_t *)font->bitmap + (ascii - '0') * font->charHasBytes;
}
area.x1 = x;
area.y1 = y;
area.x2 = x + (font->width - 1);
area.y2 = y + (font->height - 1);
LcdSetCursor(&area);
for (i = 0; i < font->height; i++)
{
for (j = 0; j < font->width / 8; j++)
{
data = *(bitmap++);
for (k = 0; k < 8; k++)
{
if (data & 0x80)
{
LcdSendData(textColor);
}
else
{
LcdSendData(bkColor);
}
data <<= 1;
}
}
if (font->width % 8 == 0)
{
continue;
}
data = *(bitmap++);
for (k = 0; k < font->width % 8; k++)
{
if (data & 0x80)
{
LcdSendData(textColor);
}
else
{
LcdSendData(bkColor);
}
data <<= 1;
}
}
}
void LcdDrawString(uint16_t x, uint16_t y, char *str, uint16_t textColor, uint16_t bkColor, AsciiFontDesc_t *font)
{
uint8_t i = 0;
while (*str != '\0')
{
LcdDrawChar(x + (i * font->width), y, *str, textColor, bkColor, font);
str++;
i++;
}
}
void LcdDrawChinese(uint16_t x, uint16_t y, uint16_t textColor, uint16_t bkColor, ChineseFontDesc_t *font)
{
uint8_t *bitmap;
LcdArea_t area;
uint8_t data;
uint16_t i, j, k, m;
bitmap = (uint8_t *)font->bitmap;
for (i = 0; i < font->charNums; i++)
{
area.x1 = x + (i * font->width);
area.y1 = y;
area.x2 = area.x1 + (font->width - 1);
area.y2 = y + (font->height - 1);
LcdSetCursor(&area);
for (j = 0; j < font->height; j++)
{
for (k = 0; k < font->width / 8; k++)
{
data = *(bitmap++);
for (m = 0; m < 8; m++)
{
if (data & 0x80)
{
LcdSendData(textColor);
}
else
{
LcdSendData(bkColor);
}
data <<= 1;
}
}
if (font->width % 8 == 0)
{
continue;
}
data = *(bitmap++);
for (m = 0; m < font->width % 8; m++)
{
if (data & 0x80)
{
LcdSendData(textColor);
}
else
{
LcdSendData(bkColor);
}
data <<= 1;
}
}
}
}
void LcdDrawPicture(uint16_t x, uint16_t y, uint16_t pictureColor, uint16_t bkColor, PictureDesc_t *picDesc)
{
uint8_t *picture;
uint8_t data;
LcdArea_t area;
uint16_t i, j, k;
picture = (uint8_t *)picDesc->picture;
data = *picture;
area.x1 = x;
area.y1 = y;
area.x2 = x + (picDesc->width - 1);
area.y2 = y + (picDesc->height - 1);
LcdSetCursor(&area);
for (i = 0; i < picDesc->height; i++)
{
for(j = 0; j < picDesc->width; )
{
for (k = 0; k < 8; k++)
{
if (data & 0x80)
{
LcdSendData(pictureColor);
}
else
{
LcdSendData(bkColor);
}
data <<= 1;
j++;
if (j == picDesc->width)
{
break;
}
}
picture++;
data = *picture;
}
}
}
void TurnOnScreen(void)
{
LCD_BK_ON();
}
void TurnOffScreen(void)
{
LCD_BK_OFF();
}