本帖最后由 裴红恩 于 2024-3-7 14:47 编辑
# 【国民技术车规MCU N32A455开发板】测评 - 4 - 中景园TFT_LCD移植+SPI2测试
之前就移植过中景园LCD的驱动到GD32系列的单片机上,这次在测试SPI接口的时候直接驱动一下LCD屏幕并且将过程完整的记录下来
### STEP one:
ST7735S是一块1.8英寸采用SPI通信的TFT全彩屏,分辨率是128*160,这里采用RGB565 16bit的色块编译模式(RGB565即高五位为Red,第五位为Blue,中间六位为Green,共16位)。
BLK:背光开光引脚
CS:片选信号
DC:数据模式选择信号 1为写命令/0为写数据
RST:复位信号
SDA:SPI数据线
SCL:SPI时钟线
VDD:兼容+5V和+3.3V
GND:接地
简单介绍一下驱动的运行过程,首先是进行一次屏幕复位,清除所有的信号
根据数据手册我们可以知道复位时间需要低电平并且最少持续10us以上,取消复位需要等到电平置高以后120ms以后
```c
LCD_RES_Clr();//信号电平从高到低
delay_ms(100);//复位打开延时
LCD_RES_Set();//信号电平从低到高
delay_ms(120);//复位取消延时
```
打开背光,因为LCD屏幕本身是不会如同LED屏幕一样发光的将BL位电平置高
```c
LCD_BLK_Set();//打开背光
```
接下来开始进行参数的配置,写数据0x11退出休眠模式
由上图可以知道当处于Sleep Out由于寄存器的下载以及自诊断需要在120ms以后在进行其他的操作
```c
LCD_WR_REG(0x11); //Sleep out
delay_ms(120); //Delay 120ms
```
由上图可知我们的数据位选择的是16bit,所以对于串行信号是如此写入的,cs保持低电平,scl写入数据是为低电平,dc保持低电平为写入命令
```c
void LCD_Writ_Bus(u8 dat)
{
u8 i;
LCD_CS_Clr();
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();
}
```
以下是写入数据的时序图
时钟的电平时序是dc移植保持高电平,当需要写入命令的时候将dc置为低电平
接下来配置0XB1,0XB2,0XB3,0XB4寄存器
```c
LCD_WR_REG(0xB1); //写入指令操控0xb4寄存器(帧率控制模式全彩)
LCD_WR_DATA8(0x05);
LCD_WR_DATA8(0x3C);
LCD_WR_DATA8(0x3C);
```
```c
LCD_WR_REG(0xB2); //写入指令操控0xb2 帧率控制 8种颜色
LCD_WR_DATA8(0x05);
LCD_WR_DATA8(0x3C);
LCD_WR_DATA8(0x3C);
```
```c
LCD_WR_REG(0xB3); //控制命令 局部全部颜色
LCD_WR_DATA8(0x05);
LCD_WR_DATA8(0x3C);
LCD_WR_DATA8(0x3C);
LCD_WR_DATA8(0x05);
LCD_WR_DATA8(0x3C);
LCD_WR_DATA8(0x3C);
```
```c
LCD_WR_REG(0xB4); //反转控制
LCD_WR_DATA8(0x03);
```
### STEP tow:
新建工程并且将单片机给的官方例程中的SPI_FLASH中的所有文件全部都单独拎出来,并且将LCD和LCD初始化的文件放入src和inc中,打开工程文件。
main.c
```c
float t=0;//用来计时的float数
sFLASH_Init();//对于SPI引脚进行初始化并且拉高
LCD_Init();//LCD初始化
LCD_Fill(0,0,LCD_W,LCD_H,WHITE);//全部填充白色
while(1)
{
LCD_ShowChinese(0,0,"中景园电子",RED,WHITE,24,0);//打印汉字
LCD_ShowString(24,30,"LCD_W:",RED,WHITE,16,0);//打印字符串
LCD_ShowIntNum(72,30,LCD_W,3,RED,WHITE,16);//打印整形
LCD_ShowString(24,50,"LCD_H:",RED,WHITE,16,0);
LCD_ShowIntNum(72,50,LCD_H,3,RED,WHITE,16);
LCD_ShowFloatNum1(20,80,t,4,RED,WHITE,16);//打印float t
t+=0.11f;
LCD_ShowPicture(65,80,40,40,gImage_1);//打印图片
}
```
spi_flash.c
```c
void sFLASH_LowLevel_Init(void)
{
GPIO_InitType GPIO_InitStructure;
/*!< sFLASH_SPI_CS_GPIO, sFLASH_SPI_MOSI_GPIO, sFLASH_SPI_MISO_GPIO
and sFLASH_SPI_SCK_GPIO Periph clock enable */
RCC_EnableAPB2PeriphClk(
sFLASH_CS_GPIO_CLK | sFLASH_SPI_MOSI_GPIO_CLK | sFLASH_SPI_MISO_GPIO_CLK | sFLASH_SPI_SCK_GPIO_CLK | sFLASH_RES_GPIO_CLK | sFLASH_BL_GPIO_CLK, ENABLE);
/*!< sFLASH_SPI Periph clock enable */
RCC_EnableAPB2PeriphClk(sFLASH_SPI_CLK, ENABLE);
/*!< Configure sFLASH_SPI pins: SCK */
GPIO_InitStructure.Pin = sFLASH_SPI_SCK_PIN;//引脚数字
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//引脚频率
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//引脚模式
GPIO_InitPeripheral(sFLASH_SPI_SCK_GPIO_PORT, &GPIO_InitStructure);//将其初始化
/*!< Configure sFLASH_SPI pins: MOSI */
GPIO_InitStructure.Pin = sFLASH_SPI_MOSI_PIN;
GPIO_InitPeripheral(sFLASH_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);
/*!< Configure sFLASH_SPI pins: MISO */
GPIO_InitStructure.Pin = sFLASH_SPI_MISO_PIN;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_InitPeripheral(sFLASH_SPI_MISO_GPIO_PORT, &GPIO_InitStructure);
/*!< Configure sFLASH_CS_PIN pin: sFLASH Card CS pin */
GPIO_InitStructure.Pin = sFLASH_CS_PIN;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitPeripheral(sFLASH_CS_GPIO_PORT, &GPIO_InitStructure);
/*!< Configure sFLASH_rest_PIN pin: sFLASH Card CS pin */
GPIO_InitStructure.Pin = sFLASH_RES_PIN;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitPeripheral(sFLASH_RES_GPIO_PORT, &GPIO_InitStructure);
/*!< Configure sFLASH_rest_PIN pin: sFLASH Card CS pin */
GPIO_InitStructure.Pin = sFLASH_BL_PIN;
// GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitPeripheral(sFLASH_BL_GPIO_PORT, &GPIO_InitStructure);
GPIO_SetBits(sFLASH_CS_GPIO_PORT,sFLASH_SPI_SCK_PIN | sFLASH_SPI_MOSI_PIN | sFLASH_SPI_MISO_PIN | sFLASH_CS_PIN | sFLASH_RES_PIN | sFLASH_BL_PIN);
}
```
spi_flash.h
```c
#define sFLASH_SPI SPI2
#define sFLASH_SPI_CLK RCC_APB1_PERIPH_SPI2
#define sFLASH_SPI_SCK_PIN GPIO_PIN_11 /* PE.11 */
#define sFLASH_SPI_SCK_GPIO_PORT GPIOE /* GPIOE */
#define sFLASH_SPI_SCK_GPIO_CLK RCC_APB2_PERIPH_GPIOE
#define sFLASH_SPI_MISO_PIN GPIO_PIN_12 /* PE.12 */
#define sFLASH_SPI_MISO_GPIO_PORT GPIOE /* GPIOE */
#define sFLASH_SPI_MISO_GPIO_CLK RCC_APB2_PERIPH_GPIOE
#define sFLASH_SPI_MOSI_PIN GPIO_PIN_13 /* PE.13 */
#define sFLASH_SPI_MOSI_GPIO_PORT GPIOE /* GPIOE */
#define sFLASH_SPI_MOSI_GPIO_CLK RCC_APB2_PERIPH_GPIOE
#define sFLASH_CS_PIN GPIO_PIN_10 /* PE.10 */
#define sFLASH_CS_GPIO_PORT GPIOE /* GPIOE */
#define sFLASH_CS_GPIO_CLK RCC_APB2_PERIPH_GPIOE
#define sFLASH_RES_PIN GPIO_PIN_8 /* PE.8 */
#define sFLASH_RES_GPIO_PORT GPIOE /* GPIOE */
#define sFLASH_RES_GPIO_CLK RCC_APB2_PERIPH_GPIOE
#define sFLASH_BL_PIN GPIO_PIN_9 /* PE.9 */
#define sFLASH_BL_GPIO_PORT GPIOE /* GPIOE */
#define sFLASH_BL_GPIO_CLK RCC_APB2_PERIPH_GPIOE
```
```c
//-----------------LCD端口定义----------------
#define LCD_SCLK_Clr() GPIO_ResetBits(sFLASH_SPI_MISO_GPIO_PORT,sFLASH_SPI_MISO_PIN)//SCL=SCLK
#define LCD_SCLK_Set() GPIO_SetBits(sFLASH_SPI_MISO_GPIO_PORT,sFLASH_SPI_MISO_PIN)
#define LCD_MOSI_Clr() GPIO_ResetBits(sFLASH_SPI_MOSI_GPIO_PORT,sFLASH_SPI_MOSI_PIN)//SDA=MOSI
#define LCD_MOSI_Set() GPIO_SetBits(sFLASH_SPI_MOSI_GPIO_PORT,sFLASH_SPI_MOSI_PIN)
#define LCD_RES_Clr() GPIO_ResetBits(sFLASH_RES_GPIO_PORT,sFLASH_RES_PIN)//RES
#define LCD_RES_Set() GPIO_SetBits(sFLASH_RES_GPIO_PORT,sFLASH_RES_PIN)
#define LCD_DC_Clr() GPIO_ResetBits(sFLASH_BL_GPIO_PORT,sFLASH_BL_PIN)//DC
#define LCD_DC_Set() GPIO_SetBits(sFLASH_BL_GPIO_PORT,sFLASH_BL_PIN)
#define LCD_CS_Clr() GPIO_ResetBits(sFLASH_CS_GPIO_PORT,sFLASH_CS_PIN)//CS
#define LCD_CS_Set() GPIO_SetBits(sFLASH_CS_GPIO_PORT,sFLASH_CS_PIN)
#define LCD_BLK_Clr() GPIO_ResetBits(sFLASH_SPI_SCK_GPIO_PORT,sFLASH_SPI_SCK_PIN)//BLK
#define LCD_BLK_Set() GPIO_SetBits(sFLASH_SPI_SCK_GPIO_PORT,sFLASH_SPI_SCK_PIN)
```
运行代码可以正常的驱动LCD进行一些图片的打印以及汉字数字的打印,刷新帧率也完全支持。
### 结果
SPI.zip
(8.35 MB, 下载次数: 10)