STM32单片机基础17——使用硬件SPI驱动TFT-LCD(ST7789)

本文详细介绍了如何使用STM32CubeMX配置STM32L431RCT6的硬件SPI外设,驱动1.3寸ST7789V2液晶控制器的TFT-LCD屏幕。从配置时钟源、GPIO、SPI接口到编写LCD驱动代码,包括控制引脚宏、初始化函数、发送数据和命令的函数,最后实现LCD的背光控制、显示RAM地址指定、清屏及初始化功能。

本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的硬件SPI外设与ST7789通信,驱动16bit TFT-LCD 屏幕。

0. 前言

学习 SPI 外设驱动LCD屏幕没有必要手写驱动,学习这部分代码的目的是为了了解TFT-LCD的工作原理,每个像素点是如何显示的,不要花过多的精力在弄明白每个命令的意思,建议基于本驱动,学习一下打点,画线算法,画圆算法,画多边形算法等等,还可以学习显示英文字符,中文字符,最后还可以移植STemwin显示界面等等好玩的东西~

mark

mark

mark

1. 准备工作

硬件准备

mark

  • LCD屏幕
    小熊派开发板板载LCD屏幕大小1.3寸,分辨率240*240,色彩深度16bit,使用ST7789V2液晶控制器

软件准备

  • 需要安装好Keil - MDK及芯片对应的包,以便编译和下载生成的代码;

Keil MDK和串口助手的安装包都可以关注“小熊派开源社区”微信公众号,在资料教程一栏中可获取安装包。

2.生成MDK工程

选择芯片型号

打开STM32CubeMX,打开MCU选择器:
mark

搜索并选中芯片STM32L431RCT6:
mark

配置时钟源

  • 如果选择使用外部高速时钟(HSE),则需要在System Core中配置RCC;
  • 如果使用默认内部时钟(HSI),这一步可以略过;

这里我都使用外部时钟:

mark

配置LCD控制GPIO

mark

配置SPI2接口

查看小熊派LCD接口的原理图:

mark

mark

引脚对应表如下:

LCD引脚 MCU引脚
SPI2_MOSI PC3
SPI2_CLK PB13
LCD_WR_RS PC6
LCD_RESET PC7
LCD_POWER PB15

MCU只需要通过SPI向LCD控制器发送命令/数据即可,所以硬件上接 SPI2 的 SCK 和 MOSI 引脚,软件上将SPI2配置为发送主机模式,接下来开始配置SPI2接口:

参数设置如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DUX2uXV4-1581661413301)(http://mculover666.cn/image/20190829/1DHh2ytSwgcp.png?imageslim)]

SPI2默认SCK引脚是PB10,和开发板不对应,所以重新修改引脚为PB13:

mark

配置时钟树

STM32L4的最高主频到80M,所以配置PLL,最后使HCLK = 80Mhz即可:
mark

生成工程设置

mark

代码生成设置

最后设置生成独立的初始化文件:
mark

生成代码

点击GENERATE CODE即可生成MDK-V5工程:
mark

3. 编写LCD驱动(ST7789)—— 封装宏和底层函数

3.1. 封装控制LCD控制引脚高低电平的宏

控制引脚宏定义已经包含在 main.h 中,如图:

mark

在编写驱动的过程中需要不断的控制这些控制引脚的电平,所以首先在 lcd_spi2_drv.h 头文件中编写控制这些引脚的宏:

#include "main.h"

#define	LCD_PWR(n)		(n?\
						HAL_GPIO_WritePin(LCD_PWR_GPIO_Port,LCD_PWR_Pin,GPIO_PIN_SET):\
						HAL_GPIO_WritePin(LCD_PWR_GPIO_Port,LCD_PWR_Pin,GPIO_PIN_RESET))
#define	LCD_WR_RS(n)	(n?\
						HAL_GPIO_WritePin(LCD_WR_RS_GPIO_Port,LCD_WR_RS_Pin,GPIO_PIN_SET):\
						HAL_GPIO_WritePin(LCD_WR_RS_GPIO_Port,LCD_WR_RS_Pin,GPIO_PIN_RESET))
#define	LCD_RST(n)		(n?\
						HAL_GPIO_WritePin(LCD_RST_GPIO_Port,LCD_RST_Pin,GPIO_PIN_SET):\
						HAL_GPIO_WritePin(LCD_RST_GPIO_Port,LCD_RST_Pin,GPIO_PIN_RESET))

3.2. 宏定义屏幕分辨率和颜色值

//LCD屏幕分辨率定义
#define LCD_Width   240
#define LCD_Height  240
//颜色定义
#define WHITE   0xFFFF	//白色
#define YELLOW  0xFFE0	//黄色
#define BRRED   0XFC07  //棕红色
#define PINK    0XF81F	//粉色
#define RED     0xF800	//红色
#define BROWN   0XBC40  //棕色
#define GRAY    0X8430  //灰色
#define GBLUE   0X07FF	//兰色
#define GREEN   0x07E0	//绿色
#define BLUE    0x001F  //蓝色
#define BLACK   0x0000	//黑色

接下来开始在 lcd_spi2_drv.c 编写驱动程序~

3.3. 封装LCD控制引脚初始化函数

首先包含必要的头文件:

#include "lcd_spi2_drv.h"
#include "gpio.h"
#
### 使用SPI接口驱动TFT LCD显示屏 尽管提供的参考资料主要讨论了通过FSMC接口来控制TFT LCD显示屏[^1],这里将介绍如何使用SPI接口实现相同的功能。SPI(Serial Peripheral Interface)是一种同步串行通信协议,在嵌入式系统中广泛用于连接微控制器和其他外围设备。 #### SPI接口简介 SPI通常由四条信号线组成:MOSI(Master Out Slave In)、MISO(Master In Slave Out)、SCK(Serial Clock),以及SS/CS(Slave Select)。对于大多数TFT LCD模块来说,仅需使用其中三条线——即MOSI、SCK和CS;而有些情况下还需要额外的数据命令选择线DC(Data/Command select line)和重置线RESET。 #### TFT LCDSTM32SPI接线方式 根据常见的引脚定义[^2],可以得出如下表所示的标准SPI接法: | 功能 | 描述 | STM32 GPIO | |------|------------|-----------| | GND | 接地 | 地 | | VCC | 供电电压 | 3.3V | | MOSI | 主发送 | PA7 (SPI1) | | SCLK | 同步时钟 | PA5 (SPI1) | | CS | 片选信号 | PA4 | | DC | 数据/指令选择 | PA3 | | RESET| 复位信号 | PA2 | 请注意实际应用中的具体型号可能有所不同,因此建议查阅所使用的特定TFT LCD数据手册确认具体的管脚分配。 #### 初始化设置及配置 为了使能SPI外设并正确配置它以适配TFT LCD的操作需求,下面给出了一段C语言代码片段作为参考: ```c #include "stm32f1xx_hal.h" // 定义SPI句柄结构体实例化对象 extern SPI_HandleTypeDef hspi1; void MX_SPI1_Init(void){ /* USER CODE BEGIN SPI1_Init 0 */ /* USER CODE END SPI1_Init 0 */ hspi1.Instance = SPI1; hspi1.Init.Mode = SPI_MODE_MASTER; // 设置为主模式 hspi1.Init.Direction = SPI_DIRECTION_2LINES;// 双向传输方向 hspi1.Init.DataSize = SPI_DATASIZE_8BIT; // 数据大小为一字节(8bit) hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; // 时钟极性低电平有效 hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; // 第一沿采样 hspi1.Init.NSS = SPI_NSS_SOFT; // 软件管理NSS信号 hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; // 波特率预分频器设定 hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; // MSB先传 HAL_SPI_Init(&hspi1); // 初始化SPI } /** * @brief 发送单字节到LCD * @param data 待发送的数据 */ static void spi_write_byte(uint8_t data){ while(HAL_SPI_GetState(&hspi1)!=HAL_SPI_STATE_READY); HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);//拉低片选 HAL_SPI_Transmit(&hspi1,&data,sizeof(data),HAL_MAX_DELAY); HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET); //恢复高阻态 } ``` 这段程序展示了如何初始化SPI端口,并提供了一个简单的函数`spi_write_byte()`用来向TFT LCD写入单一字符。这只是一个基础框架,完整的库文件会包含更多功能比如读取状态寄存器、执行各种显示操作等。
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值