STM32L475 SPI驱动LCD ST7789V2详解

概述

最近在学习正点原子潘多拉开发板,在此结合原子哥的代码,
对SPI驱动LCD做一个详细介绍。

TFTLCD 和 SPI

TFTLCD介绍

TFT-LCD 即薄膜晶体管液晶显示器。其英文全称为:Thin Film Transistor-Liquid Crystal Display。TFT-LCD 与无源TN-LCD、STN-LCD 的简单矩阵不同,它在液晶显示屏的每一个象素上都设置有一个薄膜晶体管(TFT),可有效地克服非选通时的串扰,使显示液晶屏的静态特性与扫描线数无关,因此大大提高了图像质量。TFT-LCD 也被叫做真彩液晶显示器。

SPI介绍

SPI 是英语Serial Peripheral interface 的缩写,顾名思义就是串行外围设备接口。是Motorola首先在其MC68HCXX 系列处理器上定义的。SPI 接口主要应用在 EEPROM,FLASH,实时时钟,AD 转换器,还有数字信号处理器和数字信号解码器之间。SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为PCB 的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议,STM32L4 也有SPI 接口。

SPI驱动LCD代码详解

spi.h

void SPI3_Init(void);
void SPI3_SetSpeed(u8 SPI_BaudRatePrescaler);  // 设置波特率传输速度
u8 SPI3_ReadWriteByte(u8 TxData);              // 读写数据
u8 SPI3_WriteByte(u8 *TxData,u16 size);        // 写字节

spi.c

#include "spi3.h"
#include "delay.h"

SPI_HandleTypeDef SPI3_Handler;  // 生成SPI3句柄
/**
 * 功能描述:SPI3初始化代码,配置成主机模式
 *
 * 参数: void
 *
 * 返回值:void
 */
void SPI3_Init(void)
{
     
    SPI3_Handler.Instance=SPI3;                         //SPI3
    SPI3_Handler.Init.Mode=SPI_MODE_MASTER;             //设置SPI工作模式,设置为主模式
    SPI3_Handler.Init.Direction=SPI_DIRECTION_2LINES;   //设置SPI单向或者双向的数据模式:SPI设置为双线模式
    SPI3_Handler.Init.DataSize=SPI_DATASIZE_8BIT;       //设置SPI的数据大小:SPI发送接收8位帧结构
    SPI3_Handler.Init.CLKPolarity=SPI_POLARITY_HIGH;    //串行同步时钟的空闲状态为高电平
    SPI3_Handler.Init.CLKPhase=SPI_PHASE_2EDGE;         //串行同步时钟的第二个跳变沿(上升或下降)数据被采样,偶数个跳变沿时被采样
    SPI3_Handler.Init.NSS=SPI_NSS_SOFT;                 //NSS信号由硬件(NSS管脚)还是软件(使用SSI位)管理:内部NSS信号有SSI位控制
    SPI3_Handler.Init.BaudRatePrescaler=SPI_BAUDRATEPRESCALER_2;//定义波特率预分频的值:波特率预分频值为256
    SPI3_Handler.Init.FirstBit=SPI_FIRSTBIT_MSB;        //指定数据传输从MSB位还是LSB位开始:数据传输从MSB位开始
    SPI3_Handler.Init.TIMode=SPI_TIMODE_DISABLE;        //关闭TI模式
    SPI3_Handler.Init.CRCCalculation=SPI_CRCCALCULATION_DISABLE;//关闭硬件CRC校验
    SPI3_Handler.Init.CRCPolynomial=7;                  //CRC值计算的多项式
    HAL_SPI_Init(&SPI3_Handler);						//初始化SPI3
    
    __HAL_SPI_ENABLE(&SPI3_Handler);                    //使能SPI3
}

/**
 * @brief	SPI3底层驱动,时钟使能,引脚配置
 *
 * @param   hspi	SPI句柄
 *
 * @return  void
 */
void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)
{
     
    GPIO_InitTypeDef GPIO_Initure;
    
    __HAL_RCC_GPIOB_CLK_ENABLE();       //使能GPIOB时钟
    __HAL_RCC_SPI3_CLK_ENABLE();        //使能SPI3时钟

    //PB3.5
    GPIO_Initure.Pin=GPIO_PIN_3|GPIO_PIN_5;               // 先看复用配置,看到PB3,4,5为复用功能,然后3,5属于从主机输出到IO口,所以需要选用复用推挽输出
    GPIO_Initure.Mode=GPIO_MODE_AF_PP;              //复用推挽输出
    GPIO_Initure.Pull=GPIO_PULLUP;                  //上拉
    GPIO_Initure.Speed=GPIO_SPEED_FREQ_VERY_HIGH;   //80Mhz           
    GPIO_Initure.Alternate=GPIO_AF6_SPI3;           //PB3.5复用为SPI3
    HAL_GPIO_Init(GPIOB,&GPIO_Initure);
}

/**
 * 功能描述:SPI3 读写一个字节
 *
 * 参数:TxData	要写入的字节
 *
 * 返回值:u8		读取到的字节
 */
u8 SPI3_ReadWriteByte(u8 TxData)
{
     
    u8 Rxdata;
    HAL_SPI_TransmitReceive(&SPI3_Handler,&TxData,&Rxdata,1, 1000);       
 	return Rxdata;          		    //返回收到的数据		
}

/**
 * 功能描述:SPI3 写入一个字节
 *
 * 参数:TxData	要写入的字节
 *       size	写入字节大小
 *
 * 返回值:u8		0:写入成功,其他:写入失败
 */
u8 SPI3_WriteByte(u8 *TxData,u16 size)
{
     
	return HAL_SPI_Transmit(&SPI3_Handler,TxData,size,1000);  // 发送数据,并等待1000us
}

lcd.h

#ifndef __LCD_H
#define __LCD_H
#include "sys.h"
extern u16	POINT_COLOR;		//默认画笔颜色
extern u16	BACK_COLOR;		//默认背景颜色

//LCD的宽和高定义
#define LCD_Width 	240
#define LCD_Height 	240

//画笔颜色
#define WHITE         	 0xFFFF
#define BLACK         	 0x0000	  
#define BLUE         	 0x001F  
#define BRED             0XF81F
#define GRED 			 0XFFE0
#define GBLUE			 0X07FF
#define RED           	 0xF800
#define MAGENTA       	 0xF81F
#define GREEN         	 0x07E0
#define CYAN          	 0x7FFF //青色
#define YELLOW        	 0xFFE0
#define BROWN 			 0XBC40 //棕色
#define BRRED 			 0XFC07 //棕红色
#define GRAY  			 0X8430 //灰色
//GUI颜色

#define DARKBLUE      	 0X01CF	//深蓝色
#define LIGHTBLUE      	 0X7D7C	//浅蓝色  
#define GRAYBLUE       	 0X5458 //灰蓝色
//以上三色为PANEL的颜色 
 
#define LIGHTGREEN     	 0X841F //浅绿色
//#define LIGHTGRAY        0XEF5B //浅灰色(PANNEL)
#define LGRAY 			 0XC618 //浅灰色(PANNEL),窗体背景色

#define LGRAYBLUE        0XA651 //浅灰蓝色(中间层颜色)
#define LBBLUE           0X2B12 //浅棕蓝色(选择条目的反色)

/*
	LCD_PWR:	PB7
	LCD_RST:	PB6
	LCD_DC:		PB4
	LCD_CS:		PD7
*/
#define	LCD_PWR(n)		(n?HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET):HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET))    // 背光控制
#define	LCD_RST(n)		(n?HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET):HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET))   // 复位控制
#define	LCD_DC(n)		(n?HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_SET):HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_RESET))   // 选择数据或命令
#define	LCD_CS(n)		(n?HAL_GPIO_WritePin(GPIOD,GPIO_PIN_7,GPIO_PIN_SET):HAL_GPIO_WritePin(GPIOD,GPIO_PIN_7,GPIO_PIN_RESET))  // 片选

void LCD_Init(void);										//初始化
void LCD_DisplayOn(void);									//开显示
void LCD_DisplayOff(void);									//关显示
void LCD_Write_HalfWord(const u16 da);					    //写半个字节数据到LCD
void LCD_Address_Set(u16 x1, u16 y1, u16 x2, u16 y2);		//设置数据显示区域
void LCD_Clear(u16 color);									//清屏
void LCD_Fill(u16 x_start, u16 y_start, u16 x_end, u16 y_end, u16 color);				//填充单色
void LCD_Draw_Point(u16 x, u16 y);							//画点
void LCD_Draw_ColorPoint(u16 x, u16 y,u16 color);			//画带颜色点
void LCD_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2);			//画线
void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2);		//画矩形
void LCD_Draw_Circle(u16 x0, u16 y0, u8 r);					//画圆
void LCD_ShowChar(u16 x, u16 y, char chr, u8 size);			//显示一个字符
void LCD_ShowNum(u16 x,u16 y,u32 num,u8 len,u8 size);		//显示一个数字
void LCD_ShowxNum(u16 x,u16 y,u32 num,u8 len,u8 size,u8 mode);	//显示数字
void LCD_ShowString(u16 x,u16 y,u16 width,u16 height,u8 size,char *p);//显示字符串
void LCD_ShowChinese(u16 x, u16 y, const u8 *ch, u8 size, u8 n, u8 mode);      // 显示汉字
void LCD_Show_Image(u16 x, u16 y, u16 width, u16 height, const u8 *p);//显示图片

#endif

由于lcd.c文件中内容过多,所以在此不显示,在lcd.c文件中,可以添加需要显示的内容,比如数字、字符串等等。

你可能感兴趣的:(STM32学习,stm32)