LCD屏是常用的外设,常用的是SPI来驱动,下面向大家展示,如何用spi的软件摸拟spi协议与硬件SPI来驱动Gc9036的TFT屏。
【开发工具】
stm32CubeIDE
【硬件】
STM32U545RE-Q NCLEO开发板
GC9306TFT屏
【实现步骤】
1、新建stm32project 工程,工程选用NUCLEO-U545RE开发板。
2、点下一步,输入工程名称,然后按finish生成工程:
3、选中spi1,在模式选项中,选中只发送模式。
4、配置时钟主频为160M。
5、回到spi总线配置界面选为8bit,16分频,片选为失能:
6、打开GPIO配置中的spi,选择速为Very High
8、配置LCD屏的SCK、CS、RST、DC四个GPIO,分别为如下
// GND 电源地
// VCC 3.3v电源
// SCL PA1(SCLK)
// SDA PA7(MOSI)
// RES PA2
// DC PA0
// CS PA4
// BLK PB0
9、在stm32cubeIDE中配置为输出模式,并帖标签为TFT_DC、TFT_CS、TFT_SCK,如果使用背光控制可以增加TFT_BLK,如果不用,则直接接VCC就行。
10、保存交生成工程代码。
11、添加移植在其他工程的复制粘帖进工程里面
12、添加文件夹到工程:
13、修改spi的数据发送函数。在spi数据传输中,官方的库给我们封装了HAL_SPI_Transmit用于阻塞式的发送。在LCD屏的通信协议中,我们需要自己定义DC(命令、数据发送)、CS片选来实现与屏的通信协议。DC为高电平时,传输命令,DC为低电平时发送的为数据,CS为低电平时为选中TFT屏。为此我们重构SPI硬件、软件发送指令为:
void LCD_Writ_Bus(uint8_t dat)
{
LCD_CS_Clr;
#if SOFTWARE_SPI_ENABLE
uint8_t i;
for(i=0;i<8;i++)
{
LCD_SCLK_LOW();
if(dat&0x80)
{
LCD_MOSI_HIGH();
}
else
{
LCD_MOSI_LOW();
}
LCD_SCLK_HIGH();
dat<<=1;
}
#else
HAL_SPI_Transmit(&hspi1, dat, 1,1000);
#endif
LCD_CS_Set;
}
14、发送命令与数据的代码如下:
/******************************************************************************
函数说明:LCD写入数据
入口数据:dat 写入的数据
返回值: 无
******************************************************************************/
void LCD_WR_DATA8(uint8_t dat)
{
uint8_t buff[2];
buff[0] = dat;
#if SOFTWARE_SPI_ENABLE
LCD_Writ_Bus(dat);
#else
HAL_SPI_Transmit(&hspi1, buff, 1,1000);
#endif
}
/******************************************************************************
函数说明:LCD写入数据
入口数据:dat 写入的数据
返回值: 无
******************************************************************************/
void LCD_WR_DATA(uint16_t dat)
{
#if SOFTWARE_SPI_ENABLE
LCD_Writ_Bus(dat>>8);
LCD_Writ_Bus(dat);
#else
uint8_t buff[2];
buff[0] = dat>>8;
buff[1] = (uint8_t)dat;
HAL_SPI_Transmit(&hspi1, buff, 2,1000);
#endif
}
/******************************************************************************
函数说明:LCD写入命令
入口数据:dat 写入的命令
返回值: 无
******************************************************************************/
void LCD_WR_REG(uint8_t dat)
{
uint8_t buff[2];
buff[0] = dat;
LCD_DC_Clr;//写命令
#if SOFTWARE_SPI_ENABLE
LCD_Writ_Bus(dat);
#else
HAL_SPI_Transmit(&hspi1, buff, 1,1000);
#endif
LCD_DC_Set;//写数据
}
15、这样我们就把低层的三个数据接口指令全部写好了,在LCD的移植中,我们只需要重写这几个代码就行了。
16、为了适配软件摸拟SPI以及CS、REST的指令可读性,我这里用宏定义来定义了以下代码:
#define RES_PIN GPIO_PIN_2
#define DC_PIN GPIO_PIN_0
#define BLK_PIN GPIO_PIN_0
#define CS_PIN GPIO_PIN_4
#define SCK_PIN GPIO_PIN_1
#define SDA_PIN GPIO_PIN_7
#define SCK_PORT GPIOA
#define SDA_PORT GPIOA
#define CS_PORT GPIOA
#define DC_PORT GPIOA
#define RES_PORT GPIOA
#define BLK_PORT GPIOB
//-----------------LCD端口定义----------------
#define LCD_CS_Clr CS_PORT->BRR = (uint32_t)CS_PIN;
#define LCD_CS_Set CS_PORT->BSRR = (uint32_t)CS_PIN;
#define LCD_RES_Clr RES_PORT->BRR = (uint32_t)RES_PIN;
#define LCD_RES_Set RES_PORT->BSRR = (uint32_t)RES_PIN;
#define LCD_DC_Clr DC_PORT->BRR = (uint32_t)DC_PIN;
#define LCD_DC_Set DC_PORT->BSRR = (uint32_t)DC_PIN;
#define LCD_BLK_Clr BLK_PORT->BRR = (uint32_t)BLK_PIN;
#define LCD_BLK_Set BLK_PORT->BSRR = (uint32_t)BLK_PIN;
#define LCD_SCLK_LOW() SCK_PORT->BRR = (uint32_t)SCK_PIN;
#define LCD_SCLK_HIGH() SCK_PORT->BSRR = (uint32_t)SCK_PIN;
#define LCD_MOSI_LOW() SDA_PORT->BRR = (uint32_t)SDA_PIN;
#define LCD_MOSI_HIGH() SDA_PORT->BSRR = (uint32_t)SDA_PIN;
这样我们就可以,查看有标识意义的代码部分。
17、定义屏的长与宽,我们在.h定义如下:
#define LCD_W 240
#define LCD_H 320
18、其他的代码我打包放在附件中,大家可以自行查看,到此,代码移植就完成了。
【测试】
我们在main.c中引入lcd的头文件,并书写main.c的测试代码如下:
IVO28_GC9306_P4();
LCD_Fill(0,0,239,319,BLACK);
HAL_Delay(200);
LCD_Fill(0,0,239,319,0xFFFF);
LCD_ShowChinese(10,10,"电压监测系统",BLUE,WHITE,32,0);//显示汉字�?
下载后效果如图:
【SPI的总结速度的测试】
测试工具:LA2016逻辑分析仪,可以测试16路最高200M速度。
1、软件的总线通迅速:
2、SPI为32分频时的总线速度
![image.png](
"image.png")
3、分频为16时的速:
4、分频为8分频时:
5、分频为4时:
用逻辑分析仪是测得是40M,用示波器测是41.7MHz。
6、分频为2时,图像是可以正常显示的,但是因为我的逻辑分析仪的带宽,没有捕捉到正确的波形。
改用示波器捕获SCK时钟信号,测得为75.7Mhz。
【总结】
从上面的测试可以看到,SPI的时钟与实际配置的是一样的,波形也非常的正常,可以说这款芯是非常之稳定。
经过上述的测试,可以说STM32U545的SPI总线最高可以跑到80M。我在测试另一款芯片(150M)频率,跑到40M时,同样的LCD屏就不能正常显示了。
同时STM32CubeIDE也提供了非常优秀的开发环境,在图形化配置工具中我们可以实际的看到一些配置好后的参数。使用开发板进行开发时,选择对应的开发板,可以默认的把开发板的外设全部配置好,后期我们只需要进行少量的配置就可以新建开发环境。
LCD的刷新速度咋样
不是很高,主要受制于显存,如果要想速高,选U5A9或者U599J,这样有专用的LCD驱动。