ST7789.c:
#include "bsp_ST7796.h"
volatile uint8_t transfer_complete = 1; // 传输完成标志
extern lv_disp_drv_t *disp_drv_temp;
// SPI + DMA 传输完成中断回调函数
void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) {
if (hspi->Instance == LCD_SPI_interrupt) { // 根据实际 SPI 实例
lv_disp_flush_ready(disp_drv_temp); // 通知LVGL刷新完成
transfer_complete = 1; // 设置传输完成标志
LCD_CS1(1); //传输完成拉高片选
}
}
/**
* @brief SPI 发送字节函数
* @param TxData 要发送的数据
* @param size 发送数据的字节大小
* @return 0:写入成功,其他:写入失败
*/
uint8_t SPI_WriteByte(uint8_t *TxData,uint16_t size)
{
//做一个同步,防止前面的DMA缓冲区数据还没发送完,下一次的就把前一次的覆盖掉了
while(!transfer_complete){
}
transfer_complete = 0;
LCD_CS1(0); //拉低片选准备传输
HAL_SPI_Transmit_DMA(LCD_SPI_handle,TxData,size);
return 0;
//return HAL_SPI_Transmit(&hspi1,TxData,size,1000);
}
/**
* @brief 写命令到LCD
* @param cmd —— 需要发送的命令
* @return none
*/
static void LCD_Write_Cmd(uint8_t cmd)
{
LCD_WR_RS(0);
//SPI_WriteByte(&cmd, 1);
LCD_CS1(0); //拉低片选准备传输
HAL_SPI_Transmit(LCD_SPI_handle,&cmd,1,HAL_MAX_DELAY);
LCD_CS1(1); //传输完成拉高片选
}
/**
* @brief 写数据到LCD
* @param dat —— 需要发送的数据
* @return none
*/
static void LCD_Write_Data(uint8_t dat)
{
LCD_WR_RS(1);
//SPI_WriteByte(&dat, 1);
LCD_CS1(0); //拉低片选准备传输
HAL_SPI_Transmit(LCD_SPI_handle,&dat,1,HAL_MAX_DELAY);
LCD_CS1(1); //传输完成拉高片选
}
/**
* @breif 打开LCD显示背光
* @param none
* @return none
*/
void LCD_DisplayOn(void)
{
LCD_BLK(1);
}
/**
* @brief 关闭LCD显示背光
* @param none
* @return none
*/
void LCD_DisplayOff(void)
{
LCD_BLK(0);
}
/*************************************************
函数名:LCD_Set_XY
功能:设置lcd显示起始点
入口参数:xy坐标
返回值:无
*************************************************/
void Lcd_SetXY(uint16_t Xpos, uint16_t Ypos)
{
LCD_Write_Cmd(0x2A); //列地址设定
LCD_Write_Data(Xpos >> 8); //列地址内容
LCD_Write_Data(Xpos);
LCD_Write_Cmd(0x2B); //页地址设定
LCD_Write_Data(Ypos >> 8); //页地址内容
LCD_Write_Data(Ypos);
LCD_Write_Cmd(0x2c); //内存写入
}
/*************************************************
函数名:LCD_Set_Region
功能:设置lcd显示区域,在此区域写点数据自动换行
入口参数:xy起点和终点
返回值:无
*************************************************/
//设置显示窗口
void Lcd_SetRegion(uint16_t xStar, uint16_t yStar,uint16_t xEnd,uint16_t yEnd)
{
LCD_Write_Cmd(0x2A); //列地址设定;
LCD_Write_Data(xStar >> 8); //x起点
LCD_Write_Data(xStar);
LCD_Write_Data(xEnd >> 8); //x终点
LCD_Write_Data(xEnd);
LCD_Write_Cmd(0x2B); //行地址设定
LCD_Write_Data(yStar >> 8); //y的起点
LCD_Write_Data(yStar);
LCD_Write_Data(yEnd >> 8); //y的终点
LCD_Write_Data(yEnd);
LCD_Write_Cmd(0x2C); //内存写入
}
/****************************************************************************
* 名 称 :void LCD_Color_Fill(uint16_t xStar, uint16_t yStar,uint16_t xEnd,uint16_t yEnd,uint16_t color)
* 功 能 :填充一个模块使用一个颜色
* 入口参数:uint16_t xStar, uint16_t yStar,uint16_t xEnd,uint16_t yEnd,uint16_t color
* 出口参数:void
* 说 明 :void
* 作 者 :koko
****************************************************************************/
void LCD_Color_Fill(uint16_t xStar, uint16_t yStar,uint16_t xEnd,uint16_t yEnd,uint16_t color)
{
int i,j;
Lcd_SetRegion(xStar,yStar,xEnd - 1,yEnd - 1);
for(i=yStar;i<yEnd;i++)
{
for(j=xStar;j<xEnd;j++)
{
LCD_Write_Data(color >> 8);
LCD_Write_Data(color);
}
}
}
/*************************************************
函数名:LCD_DrawPoint
功能:画一个点
入口参数:xy坐标和颜色数据
返回值:无
*************************************************/
void Gui_DrawPoint(uint16_t x,uint16_t y,uint16_t Data)
{
if ( ( x < LCD_Width ) && ( y < LCD_Height ) )
{
Lcd_SetXY(x,y); //描点
LCD_Write_Data(Data >> 8); //画点内容
LCD_Write_Data(Data);
}
}
//uint8_t DMA_Data[10];
/**
* @brief 以一种颜色清空LCD屏
* @param color —— 清屏颜色(16bit)
* @return none
*/
static uint8_t lcd_buf[LCD_Buf_Size];
void LCD_Clear(uint16_t color)
{
uint16_t i, j;
uint8_t data[2] = {0}; //color是16bit的,每个像素点需要两个字节的显存
/* 将16bit的color值分开为两个单独的字节 */
data[0] = color >> 8;
data[1] = color;
/* 显存的值需要逐字节写入 */
for(j = 0; j < LCD_Buf_Size / 2; j++)
{
lcd_buf[j * 2] = data[0];
lcd_buf[j * 2 + 1] = data[1];
}
/* 指定显存操作地址为全屏幕 */
Lcd_SetRegion(0, 0, LCD_Width - 1, LCD_Height - 1);
/* 指定接下来的数据为数据 */
LCD_WR_RS(1);
/* 将显存缓冲区的数据全部写入缓冲区 */
for(i = 0; i < (LCD_TOTAL_BUF_SIZE / LCD_Buf_Size); i++)
{
SPI_WriteByte(lcd_buf, (uint16_t)LCD_Buf_Size);
}
}
/**
* @brief LCD初始化
* @param none
* @return none
*/
void LCD_Init(void)
{
LCD_RST(0);
HAL_Delay(100);
LCD_RST(1);
HAL_Delay(100);
//开启显示屏背光,传输数据
LCD_DisplayOn();
HAL_Delay(100);
/* 关闭睡眠模式 */
LCD_Write_Cmd(0x11);
HAL_Delay(120);
LCD_Write_Cmd(0Xf0);
LCD_Write_Data(0xc3);
LCD_Write_Cmd(0Xf0);
LCD_Write_Data(0x96);
LCD_Write_Cmd(0x36); // Memory Access Control
if(USE_HORIZONTAL==0)LCD_Write_Data(0x48);
else if(USE_HORIZONTAL==1)LCD_Write_Data(0x88);
else if(USE_HORIZONTAL==2)LCD_Write_Data(0x28);
else LCD_Write_Data(0xE8);
LCD_Write_Cmd(0x3A);
LCD_Write_Data(0x05);
LCD_Write_Cmd(0Xe8);
LCD_Write_Data(0x40);
LCD_Write_Data(0x82);
LCD_Write_Data(0x07);
LCD_Write_Data(0x18);
LCD_Write_Data(0x27);
LCD_Write_Data(0x0a);
LCD_Write_Data(0xb6);
LCD_Write_Data(0x33);
LCD_Write_Cmd(0Xc5);
LCD_Write_Data(0x27);
LCD_Write_Cmd(0Xc2);
LCD_Write_Data(0xa7);
LCD_Write_Cmd(0Xe0);
LCD_Write_Data(0xf0);
LCD_Write_Data(0x01);
LCD_Write_Data(0x06);
LCD_Write_Data(0x0f);
LCD_Write_Data(0x12);
LCD_Write_Data(0x1d);
LCD_Write_Data(0x36);
LCD_Write_Data(0x54);
LCD_Write_Data(0x44);
LCD_Write_Data(0x0c);
LCD_Write_Data(0x18);
LCD_Write_Data(0x16);
LCD_Write_Data(0x13);
LCD_Write_Data(0x15);
LCD_Write_Cmd(0Xe1);
LCD_Write_Data(0xf0);
LCD_Write_Data(0x01);
LCD_Write_Data(0x05);
LCD_Write_Data(0x0a);
LCD_Write_Data(0x0b);
LCD_Write_Data(0x07);
LCD_Write_Data(0x32);
LCD_Write_Data(0x44);
LCD_Write_Data(0x44);
LCD_Write_Data(0x0c);
LCD_Write_Data(0x18);
LCD_Write_Data(0x17);
LCD_Write_Data(0x13);
LCD_Write_Data(0x16);
LCD_Write_Cmd(0Xf0);
LCD_Write_Data(0x3c);
LCD_Write_Cmd(0Xf0);
LCD_Write_Data(0x69);
LCD_Write_Cmd(0X29);
}
ST7789.h:
#ifndef _BSP_ST7789_H
#define _BSP_ST7789_H
#include "stm32f4xx_hal.h"
#include "main.h"
#include "spi.h"
//LCD_BLK(1)高电平开启背光,LCD_BLK(0)低电平关闭背光 n为非零时前者,0时后者
#define LCD_BLK(n) (n?\
HAL_GPIO_WritePin(LCD_BLK_GPIO_Port,LCD_BLK_Pin,GPIO_PIN_SET):\
HAL_GPIO_WritePin(LCD_BLK_GPIO_Port,LCD_BLK_Pin,GPIO_PIN_RESET))
// LCD_WR_RS(1)高电平发送DATA, LCD_WR_RS(0)低电平发送COMMAND
#define LCD_WR_RS(n) (n?\
HAL_GPIO_WritePin(LCD_DC_GPIO_Port,LCD_DC_Pin,GPIO_PIN_SET):\
HAL_GPIO_WritePin(LCD_DC_GPIO_Port,LCD_DC_Pin,GPIO_PIN_RESET))
//LCD_RST(1) LCD_RST(0)低电平复位
#define LCD_RST(n) (n?\
HAL_GPIO_WritePin(LCD_RESET_GPIO_Port,LCD_RESET_Pin,GPIO_PIN_SET):\
HAL_GPIO_WritePin(LCD_RESET_GPIO_Port,LCD_RESET_Pin,GPIO_PIN_RESET))
//LCD_CS1(1) LCD_CS1(0)低电平选中
#define LCD_CS1(n) (n?\
HAL_GPIO_WritePin(LCD_CS1_GPIO_Port,LCD_CS1_Pin,GPIO_PIN_SET):\
HAL_GPIO_WritePin(LCD_CS1_GPIO_Port,LCD_CS1_Pin,GPIO_PIN_RESET))
//LCD屏幕SPI定义
#define LCD_SPI_interrupt SPI2
#define LCD_SPI_handle &hspi2
//LCD屏幕分辨率定义
#define USE_HORIZONTAL 0 //设置横屏或者竖屏显示0或1为竖屏2或3为横屏
#if USE_HORIZONTAL==0||USE_HORIZONTAL==1
#define LCD_Width 320
#define LCD_Height 480
#else
#define LCD_Width 480
#define LCD_Height 320
#endif
#define LCD_TOTAL_BUF_SIZE (320*480*2) //color是16bit的,每个像素点需要两个字节的显存,总共307200字节
#define LCD_Buf_Size 1536 //缓冲区大小
//颜色定义
#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 //黑色
void LCD_Init(void);
void LCD_DisplayOn(void);
void LCD_DisplayOff(void);
void Gui_DrawPoint(uint16_t x,uint16_t y,uint16_t Data);
void Lcd_SetRegion(uint16_t xStar, uint16_t yStar,uint16_t xEnd,uint16_t yEnd);
void LCD_Color_Fill(uint16_t xStar, uint16_t yStar,uint16_t xEnd,uint16_t yEnd,uint16_t color);
void LCD_Clear(uint16_t color);
#endif
STM32 HAL库 ST7789驱动
于 2024-11-13 16:32:00 首次发布