这篇跟大家分享如何使用硬件SPI驱动LCD屏。
【硬件环境】
1、灵动Mini-F5265-OB 开发板
2、ST7735LCD屏
【连接方式】
1 GND GND 2 3.3V VCC 3 PA5 SCL 4 PA7 SDA 7 PA4 CS 5 PA1 RES 6 PA3 DC 8 VCC BL
【代码实现】
1、开发板的示例提供了基于flash的代码,他使用了硬件片选的功能,因为ST7735相比Flash示例,多了两个引脚即数据/命令脚DC,复位RES(其中的背光我这里直连VCC),因此我对LCD的硬件初始如下:
void LcdIoInit(void) { GPIO_InitTypeDef GPIO_InitStruct; SPI_InitTypeDef SPI_InitStruct; RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE); SPI_StructInit(&SPI_InitStruct); SPI_InitStruct.SPI_Mode = SPI_Mode_Master; SPI_InitStruct.SPI_DataSize = SPI_DataSize_8b; SPI_InitStruct.SPI_DataWidth = 8; SPI_InitStruct.SPI_CPOL = SPI_CPOL_Low; SPI_InitStruct.SPI_CPHA = SPI_CPHA_1Edge; SPI_InitStruct.SPI_NSS = SPI_NSS_Soft; SPI_InitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4; SPI_InitStruct.SPI_FirstBit = SPI_FirstBit_MSB; SPI_Init(SPI1, &SPI_InitStruct); SPI_BiDirectionalLineConfig(SPI1, SPI_Enable_RX); SPI_BiDirectionalLineConfig(SPI1, SPI_Enable_TX); RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); GPIO_PinAFConfig(GPIOA, GPIO_PinSource4, GPIO_AF_5); GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_5); GPIO_PinAFConfig(GPIOA, GPIO_PinSource6, GPIO_AF_5); GPIO_PinAFConfig(GPIOA, GPIO_PinSource7, GPIO_AF_5); GPIO_StructInit(&GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7 ; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_StructInit(&GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOA, &GPIO_InitStruct); SPI_Cmd(SPI1, ENABLE); //初始化复位、数据引脚 GPIO_StructInit(&GPIO_InitStruct); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_3; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_Init(GPIOA, &GPIO_InitStruct); }
初始化这里要特别提一句,如果分频系数过大会造成与LCD通信对不上,我最起先使用256分频,结果点不亮,查找原因好久,后面使用64分频就亮了。
2、接着修改驱动中的写入数据、写命令:
void LCD_Writ_Bus(uint8_t dat) { SPI_SendData(SPI1, dat); while (RESET == SPI_GetFlagStatus(SPI1, SPI_FLAG_TXEPT)) { } } void LCD_WR_DATA8(uint8_t dat) { SPI_FLASH_CS_L(); LCD_DC_HIGH();//дÊý¾Ý LCD_Writ_Bus(dat); SPI_FLASH_CS_H(); } void LCD_WR_DATA(uint16_t dat) { SPI_FLASH_CS_L(); LCD_DC_HIGH();//дÊý¾Ý LCD_Writ_Bus(dat>>8); LCD_Writ_Bus(dat); SPI_FLASH_CS_H(); } void LCD_WR_REG(uint8_t dat) { SPI_FLASH_CS_L(); LCD_DC_LOW();//дÃüÁî LCD_Writ_Bus(dat); LCD_DC_HIGH();//дÊý¾Ý SPI_FLASH_CS_H(); }
4、当然我还需要声明一些宏命令:
#define SPI_FLASH_CS_H() SPI_CSInternalSelected(SPI1, DISABLE) #define SPI_FLASH_CS_L() SPI_CSInternalSelected(SPI1, ENABLE) #define LCD_DC_LOW() GPIO_WriteBit(GPIOA, GPIO_Pin_3, Bit_RESET) #define LCD_DC_HIGH() GPIO_WriteBit(GPIOA, GPIO_Pin_3, Bit_SET) #define LCD_RES_LOW() GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_RESET) #define LCD_RES_HIGH() GPIO_WriteBit(GPIOA, GPIO_Pin_1, Bit_SET)
这样我们的代码移植就完成了。(注:代码我附)
附工程源码: