stm32F407驱动LCD屏幕
这个折腾了两次才搞好,一是能力有限写不了驱动;二是没搞懂arm的时钟,配置起来困难。这次总算弄好了。
一、硬件
LCD参数如下:
- 驱动芯片:ST7789
- 像素:240**240
- 大小:1.23inch
- 一共8个引脚
二、配置
(一)引脚功能
引脚 | 功能 |
---|---|
VCC | LCD 供电电源引脚(3.3V) |
CS | LCD 片选信号(低电平有效) |
SDA | LCD 的 SDA 信号线 |
RESET | LCD 的复位信号(低电平有效) |
WR(DC) | 写命令/写数据信号(0:写命令;1:写数据) |
SCK | LCD 的 SCK 时钟线 |
PWR/BLK | LCD 背光控制引脚(0:关闭;1:打开) |
GND | 电源地 |
(二)接线方法
我的开发板上的SPI1被用作链接到外扩的Flash上,所以就使用了SPI2,使用方式是一样的,就是注意一下参数即可。
开发板引脚 | ST7789引脚 | ST7789引脚 | 开发板引脚 |
---|---|---|---|
PC0 | DC/WR | RST | PC1 |
PB10 | SCK | SDA | PC3 |
PC4 | PWR/BLK | CS | PC5 |
- PB10和PC3为系统默认为SPI2分配的引脚,无需修改;
- 其余4个引脚均在GPIO中设置为OUTPUT模式
- VCC和GND引脚,任意电源和接地引脚即可
(三)项目配置
- RCC和SYS保持和之前的默认配置即可;
- GPIO配置:根据上面的引脚接法,PC0/PC1/PC4/PC5,配置为OUTPUT,输出低电平;
- SPI2的配置
- Connectivity-->SPI2-->MODE:Transimit only maste(主设备仅发送模式)r,NSS:disable(配合下面的使用软件控制)
- GPIO Settings:保持默认设置即可,就是两个gpio接口
- Parameter Settings:这是最重要的一个配置:
- Basic Parameters:Frame format(motorola);Data Size:8Bits; First Bit:MSB
- Clock Parameters:prescaler:8;CPOL:High;CPHA:2edge
- Advance Parameters:CRC:disable;NSS:Software
- NVIC Settings:启用中断
三、驱动移植
(一)将驱动包含至编译路径
将驱动文件(驱动和字体库)解压至项目的core目录下(新建一个文件夹存放,如LCD)
然后将该驱动目录包含至include文件中,如下设置:
Project-->Properties-->C/C++ build-->Settings-->MCU GCC Complier-->include paths
(二)修改lcd.h文件
驱动开发的作者,在这里写死DC和RST两个gpio引脚,修改为刚才在GPIO中配置的引脚,如下所示:
/*
LCD_RST: PC1
LCD_DC: PC0
*/
#define LCD_RST(n) (n?HAL_GPIO_WritePin(GPIOC,GPIO_PIN_1,GPIO_PIN_SET):HAL_GPIO_WritePin(GPIOC,GPIO_PIN_1,GPIO_PIN_RESET))
#define LCD_DC(n) (n?HAL_GPIO_WritePin(GPIOC,GPIO_PIN_0,GPIO_PIN_SET):HAL_GPIO_WritePin(GPIOC,GPIO_PIN_0,GPIO_PIN_RESET))
(三)实现SPI_WriteByte(data, size)函数
- 在驱动程序中,作者这个文件名字为:SPI1_WriteByte(data, size),我把名字改了下,这里可改可不改
- 这是函数调用是在lcd.c文件中,我们需要在main.c文件中实现,当然在lcd.c中是写亦可以,我是在main.c文件中实现。
- 我这里使用的是SPI2接口,因此需要使用&hspi2
/* USER CODE BEGIN 4 */ uint8_t SPI_WriteByte(uint8_t * data,uint16_t size) { return HAL_SPI_Transmit(&hspi2, data, size, 0xff); } /* USER CODE END 4 */
- 同时要在main.h文件中,将此方法声明
/* USER CODE BEGIN Private defines */ uint8_t SPI_WriteByte(uint8_t * data,uint16_t size); /* USER CODE END Private defines */
(四)启用背光和片选功能
- ST7789的背光是高电平有效,需要开启了才能看得清(可能是我这LCD屏的问题);
- 片选(CS)是低电平有效,可开启可不开启,我已经把引脚接好了,所以开启了。
- 在GPIO初始化之后,设置这两个功能引脚
- 本操作在main.c文件中
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_SET); //片选应交可开可不开,低电平有效,gpio默认输出低电平 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET);
四、实现
SPI驱动LCD最难的地方是配置和驱动的移植,实现反而比较简单,无非是初始化LCD然后打印文字或者图形,这里就简要介绍,需要设置复杂的功能,可以查看驱动的函数
以下操作均在main.c文件中
包含lcd.h头文件
/* USER CODE BEGIN Includes */ #include "lcd.h" /* USER CODE END Includes */
初始化LCD
/* USER CODE BEGIN 2 */ //背光必须要打开,否则lcd屏幕是黑色的,设置为1,高电平 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_4, GPIO_PIN_SET); //片选应交可开可不开,低电平有效,gpio默认输出低电平 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_5, GPIO_PIN_RESET); LCD_Init(); /* USER CODE END 2 */
输出文字和绘制图形
while (1) { LCD_Clear(RED); LCD_ShowString(5, 10, 240, 24, 24, "Bytetoy,cn,Welcome!"); LCD_ShowString(5, 50, 240, 32, 32, "TFT-LCD:ST7789"); LCD_ShowString(5, 100, 240, 32, 32, "Resolution:"); LCD_ShowString(140, 140, 240, 24, 24, "-240*240"); LCD_ShowString(5, 170, 240, 32, 32, "Size:"); LCD_ShowString(140, 210, 240, 24, 24, "-1.3inch"); HAL_Delay(2000); LCD_Clear(BLUE); LCD_Draw_Circle(120, 120, 100);//画圆 半径r=100 LCD_Draw_Circle(120, 120, 80);//画圆 半径r=80 LCD_Draw_Circle(120, 120, 60);//画圆 半径r=60 LCD_Draw_Circle(120, 120, 40);//画圆 半径r=40 LCD_Draw_Circle(120, 120, 20);//画圆 半径r=20 // LCD_Draw_Circle(120, 120, 1);//画圆 半径r=1 LCD_Draw_Point(120,120); HAL_Delay(1500); LCD_Clear(GRAY); LCD_DrawRectangle(70, 70, 170, 170); LCD_Fill(70, 70, 170, 170, GREEN); HAL_Delay(1500); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ }
烧录程序后,即可在LCD上看到文字和图形
五、注意事项
- 驱动文件需要导入到include path中
- 驱动文件的移植,因为使用的是SPI2,而且引脚不同,要注意配置
- GPIO引脚的接法不能错,同时背光要开
- 配置中,注意极性和相位的配置