1.69寸SPI接口240*280TFT液晶显示模块,卖家提供了GPIO模拟SPI功能,我移植到了freertos,并点亮了屏幕,接下来是进行硬件SPI的程序修改:
上次还讲到了关于CS管脚的选通信号,再GPIO口的初始化的时候设置为高电平,在液晶显示模块初始化的时候拉低电平,使改显示模块被有效选通:
void LCD_Init(void)
{
//LCD_GPIO_Init();//初始化GPIO
//尤其是CS管脚,开始的电平必须是高电平,下拉产生选通信号,要特别注意。
LCD_RES_Clr(); //复位 感觉不是很重要
HAL_Delay(100);
LCD_RES_Set();
HAL_Delay(100);
LCD_BLK_Set(); //打开背光
HAL_Delay(100);
LCD_CS_Clr(); //============CS只要放一次就可以=====后面的程序不用处理CS管脚======
//************* Start Initial Sequence **********//
LCD_WR_REG(0x11); //Sleep out
HAL_Delay(100);
//************* Start Initial Sequence **********//
LCD_WR_REG(0x36);
if(USE_HORIZONTAL==0)LCD_WR_DATA8(0x00);
else if(USE_HORIZONTAL==1)LCD_WR_DATA8(0xC0);
else if(USE_HORIZONTAL==2)LCD_WR_DATA8(0x70);
else LCD_WR_DATA8(0xA0);
LCD_WR_REG(0x3A);
LCD_WR_DATA8(0x05);
LCD_WR_REG(0xB2);
LCD_WR_DATA8(0x0C);
LCD_WR_DATA8(0x0C);
LCD_WR_DATA8(0x00);
LCD_WR_DATA8(0x33);
LCD_WR_DATA8(0x33);
LCD_WR_REG(0xB7);
LCD_WR_DATA8(0x35);
LCD_WR_REG(0xBB);
LCD_WR_DATA8(0x32); //Vcom=1.35V
LCD_WR_REG(0xC2);
LCD_WR_DATA8(0x01);
LCD_WR_REG(0xC3);
LCD_WR_DATA8(0x15); //GVDD=4.8V 颜色深度
LCD_WR_REG(0xC4);
LCD_WR_DATA8(0x20); //VDV, 0x20:0v
LCD_WR_REG(0xC6);
LCD_WR_DATA8(0x0F); //0x0F:60Hz
LCD_WR_REG(0xD0);
LCD_WR_DATA8(0xA4);
LCD_WR_DATA8(0xA1);
LCD_WR_REG(0xE0);
LCD_WR_DATA8(0xD0);
LCD_WR_DATA8(0x08);
LCD_WR_DATA8(0x0E);
LCD_WR_DATA8(0x09);
LCD_WR_DATA8(0x09);
LCD_WR_DATA8(0x05);
LCD_WR_DATA8(0x31);
LCD_WR_DATA8(0x33);
LCD_WR_DATA8(0x48);
LCD_WR_DATA8(0x17);
LCD_WR_DATA8(0x14);
LCD_WR_DATA8(0x15);
LCD_WR_DATA8(0x31);
LCD_WR_DATA8(0x34);
LCD_WR_REG(0xE1);
LCD_WR_DATA8(0xD0);
LCD_WR_DATA8(0x08);
LCD_WR_DATA8(0x0E);
LCD_WR_DATA8(0x09);
LCD_WR_DATA8(0x09);
LCD_WR_DATA8(0x15);
LCD_WR_DATA8(0x31);
LCD_WR_DATA8(0x33);
LCD_WR_DATA8(0x48);
LCD_WR_DATA8(0x17);
LCD_WR_DATA8(0x14);
LCD_WR_DATA8(0x15);
LCD_WR_DATA8(0x31);
LCD_WR_DATA8(0x34);
LCD_WR_REG(0x21);
LCD_WR_REG(0x29);
}
经过测试,的确CS只要在开机的时候是高电平,液晶模块初始化的时候拉一次低电平选通模组一次就够了,后续不用再次变化CS管脚。
stm32CUBEIDE硬件配置的时候打开spi功能
液晶显示模块只接收数据,不需要向主机发送数据,所以只要单方向传输就可以。
配置DMA传输,提高传输效率。
void LCD_Writ_Bus(uint8_t dat)
{
uint8_t i;
//LCD_CS_Clr(); //只要初始化拉一次就可以
//HAL_SPI_Transmit_DMA(&hspi1, &dat, 1);
HAL_SPI_Transmit(&hspi1, &dat, 1, 0x0F);
// for(i=0;i<8;i++)
// {
// LCD_SCLK_Clr();
// if(dat & 0x80)
// {
// LCD_MOSI_Set();
// }
// else
// {
// LCD_MOSI_Clr();
// }
// LCD_SCLK_Set();
// dat<<=1;
// }
//LCD_CS_Set();
}
修改传输数据的方式由模拟SPI到硬件SPI功能,使用DMA和不使用DMA都可以。
使用硬件SPI后本来想得很好可以大大提高刷新率,但实际并不是十分理想,从波形图可以看出,每次传输一个字节虽然通过时钟可以看出时间很短,但整个指令占用的时间可不小,需要.8.3uS,通过计算3202402*8.3来算最少还是需要1.3秒才能刷整个屏幕。
新的思路测试:
如果使用缓冲区的方法,通过计算3202402=153.6K字节,对于只有64kRAM的CPU显然是不合适的,想用一行作为一个缓冲区的做法来测试。