情况相当吊诡,根据商家发的驱动和网上教程,重复检查了几遍并搞了好几天,却仍然出现问题。至今仍未搞明白,但一位朋友发现软件SPI却可以正常使用。后来又找到了一篇描述此情况的博客,解决方案在后面。具体情形为:可以正常初始化,屏幕会出现那种灰底格子状
但是无法使用LCD_Clear()进行刷屏,偶然间在对LCD_Clear()修改时,发现只要把yEnd设置为300就可以涂色,只不过涂色范围跟其他坐标没有任何关系,只会从头开始涂
void LCD_Clear(uint16_t Color)
{
LCD_SetWindows(100, 100, 319, 300);//yend必须为300才能刷屏
for (uint32_t i = 0; i < 16000; ++i)
{
Lcd_WriteData_16Bit(0x4fff);
}
}
static inline void LCD_SetWindows(uint16_t xStar, uint16_t yStar, uint16_t xEnd, uint16_t yEnd)
{
LCD_WR_REG(0x2A);
LCD_WR_DATA(xStar >> 8);
LCD_WR_DATA(0x00FF & xStar);
LCD_WR_DATA(xEnd >> 8);
LCD_WR_DATA(0x00FF & xEnd);
LCD_WR_REG(0x2B);
LCD_WR_DATA(yStar >> 8);
LCD_WR_DATA(0x00FF & yStar);
LCD_WR_DATA(yEnd >> 8);
LCD_WR_DATA(0x00FF & yEnd);
LCD_WR_REG(0x2C);//开始写入GRAM
}
最终提炼出了下面代码,可以完成跟上面一样的效果
LCD_WR_REG(0x2A);
LCD_WR_REG(0x2B);
LCD_WR_DATA(44);
LCD_WR_REG(0x2C);//开始写入GRAM
for (uint32_t i = 0; i < 16000; ++i)
{
Lcd_WriteData_16Bit(0x4fff);
}
这还不是最糟的情况,后来买了一块同样的SPI屏仍会出现相同的问题。虽然两块新屏幕同时出现故障的可能性很低,但并非没有可能。此间我也会怀疑过是TI芯片的问题,可SPI协议终归都是相同的,并且同样使用SPI的OLED屏就没有任何问题。
作为对照组,下面是初始化失败后的图片——白屏,只要接通电源就默认白屏,但做不了任何操作。SPI协议配错、初始化函数配错等都会导致白屏
初始化代码如下,根据芯片手册校准了多次:
void LCD_Init(void)
{
SPI_Init(5, 0);
DL_GPIO_initDigitalOutput(GPIO_LCD_RS_IOMUX);
DL_GPIO_initDigitalOutput(GPIO_LCD_RST_IOMUX);
DL_GPIO_initDigitalOutput(GPIO_LCD_LED_IOMUX);
DL_GPIO_clearPins(GPIO_LCD_PORT, GPIO_LCD_RS_PIN |
GPIO_LCD_RST_PIN |
GPIO_LCD_LED_PIN);
DL_GPIO_enableOutput(GPIO_LCD_PORT, GPIO_LCD_RS_PIN |
GPIO_LCD_RST_PIN |
GPIO_LCD_LED_PIN);
LCD_RESET();//LCD 复位
/************************************/
/*Adjust Control 3 (F7h)*/
LCD_WR_REG(0XF7);
LCD_WR_DATA(0xA9);
LCD_WR_DATA(0x51);
LCD_WR_DATA(0x2C);
LCD_WR_DATA(0x82);
/* Power Control 1 (C0h) */
LCD_WR_REG(0xC0);
LCD_WR_DATA(0x11);//1.25 x 3.75 = 4.6875V
LCD_WR_DATA(0x09);//-1.25 x 3.30 = -4.1250
/* Power Control 2 (C1h) */
LCD_WR_REG(0xC1);
LCD_WR_DATA(0x41);
/* VCOM Control (C5h) */
LCD_WR_REG(0XC5);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x0A);
LCD_WR_DATA(0x80);
LCD_WR_DATA(0x40);**************************************
/* Frame Rate Control (In Normal Mode/Full Colors) (B1h) */
LCD_WR_REG(0xB1);
LCD_WR_DATA(0xB0);//68.36Hz,65.65Hz
LCD_WR_DATA(0x11);
/* Display Inversion Control (B4h) */
LCD_WR_REG(0xB4);
LCD_WR_DATA(0x02);
/* Display Function Control (B6h) */
LCD_WR_REG(0xB6);
LCD_WR_DATA(0x02);
LCD_WR_DATA(0x42);//网上教程为22,导致了屏幕初始化失败
LCD_WR_DATA(0x3B);****************************************
/* Entry Mode Set (B7h) */
LCD_WR_REG(0xB7);
LCD_WR_DATA(0xc6);
/* HS Lanes Control (BEh) */
LCD_WR_REG(0xBE);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x04);
/* Set Image Function (E9h) */
LCD_WR_REG(0xE9);
LCD_WR_DATA(0x00);
LCD_WR_REG(0x36);
LCD_WR_DATA(0x08);
/* Interface Pixel Format (3Ah) */
LCD_WR_REG(0x3A);
LCD_WR_DATA(0x66); /* 0x55 : 16 bits/pixel */
/* PGAMCTRL (Positive Gamma Control) (E0h) */
LCD_WR_REG(0xE0);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x07);
LCD_WR_DATA(0x10);
LCD_WR_DATA(0x09);
LCD_WR_DATA(0x17);
LCD_WR_DATA(0x0B);
LCD_WR_DATA(0x41);
LCD_WR_DATA(0x89);
LCD_WR_DATA(0x4B);
LCD_WR_DATA(0x0A);
LCD_WR_DATA(0x0C);
LCD_WR_DATA(0x0E);
LCD_WR_DATA(0x18);
LCD_WR_DATA(0x1B);
LCD_WR_DATA(0x0F);
/* NGAMCTRL (Negative Gamma Control) (E1h) */
LCD_WR_REG(0XE1);
LCD_WR_DATA(0x00);
LCD_WR_DATA(0x17);
LCD_WR_DATA(0x1A);
LCD_WR_DATA(0x04);
LCD_WR_DATA(0x0E);
LCD_WR_DATA(0x06);
LCD_WR_DATA(0x2F);
LCD_WR_DATA(0x45);
LCD_WR_DATA(0x43);
LCD_WR_DATA(0x02);
LCD_WR_DATA(0x0A);
LCD_WR_DATA(0x09);
LCD_WR_DATA(0x32);
LCD_WR_DATA(0x36);
LCD_WR_DATA(0x0F);
// /* Sleep Out11h */
// LCD_WR_REG(0x11);//至少等5ms,不然电源不稳定。加载厂商默认寄存器值。休眠则需要等待120ms
// delay_ms(120);
/* LCD_WR_REG(0x29);
LCD_WriteReg(0X36, 0X08);
LCD_WR_REG(0x2A);
LCD_WR_DATA(0);
LCD_WR_DATA(0);
LCD_WR_DATA((320 - 1) >> 8);
LCD_WR_DATA((320 - 1) & 0XFF);
LCD_WR_REG(0x2B);
LCD_WR_DATA(0);
LCD_WR_DATA(0);
LCD_WR_DATA((480 - 1) >> 8);
LCD_WR_DATA((480 - 1) & 0XFF);*/
/* Sleep Out11h */
LCD_WR_REG(0x11);//至少等5ms,不然电源不稳定。加载厂商默认寄存器值。休眠则需要等待120ms
delay_ms(120);
LCD_WR_REG(0x29);
LCD_LED_HIGH(); //点亮背光
// LCD_Clear(0x7fff);//
}
解决方案:
无意中搜到了一篇博客,讲的非常详细,总之就是波形连续导致的,根本原因未知GD32F303调试小记(二)之SPI(软件SPI、硬件SPI、硬件SPI+DMA)_gd32 spi dma-CSDN博客
只要多加个等待语句就行了,不过不知道为什么TI官方给的示例工程里只有一个等待语句,而stm32的会有两个等待语句
static inline void SPI_WriteByte(uint8_t data)
{
while (DL_SPI_isBusy(SPI_0_INST))
;
DL_SPI_transmitData8(SPI_0_INST, data);
//后面再多加一个等待语句,原TI示例工程里没有这一句
while (DL_SPI_isBusy(SPI_0_INST))
;
}