STM32 HAL库 ST7789驱动

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
												
												
										

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值