需要提前准备好SDRAM驱动,如果没有SDRAM可以进行纯色彩测试,底层时钟,IO操作相关看注释,我使用的是寄存器封装的。
/*************************************************************************************************************
* 文件名 : stm32f7_ltdc.c
* 功能 : STM32F7 外部RGB LCD驱动
* 作者 : [email protected]
* 创建时间 : 2019-09-12
* 最后修改时间 : 2019-09-12
* 详细:
*************************************************************************************************************/
#include "stm32f7_ltdc.h"
#include "SYSTEM.H"
#include "stm32f7_sdram.h"
#include "DMA2D.h"
u32 g_LTDC_BUFF_RGB888[2][LTDC_HEIGHT][LTDC_WIDTH] __attribute__ ((at(Bank5_SDRAM_ADDR))); //需要SDRAM支持,LCD帧缓冲区,RGB888格式
//记录全局层配置信息
typedef struct
{
u16 sx; //层开始X坐标,从0开始
u16 sy; //层开始Y坐标,从0开始
u16 width; //层宽度
u16 height; //层高度
u32 *pFrameBuff; //帧缓冲区指针,需要进行初始化
}LTDC_LayerConfig;
//全局的LTDC配置信息
typedef struct
{
u16 lcd_width; //显示器宽度
u16 lcd_height; //显示器高度
LTDC_LayerConfig LayerConfig[2]; //层信息
}LTDC_ConfigData;
static LTDC_ConfigData sg_LTDC_ConfigData; //记录全局的LCD配置
//显示屏信息
typedef struct
{
u16 Width; //面板宽度,单位:像素
u16 Height; //面板高度,单位:像素
u8 Thbp; //水平后廊
u8 Thfp; //水平前廊
u8 Thw; //水平同步宽度
u8 Tvbp; //垂直后廊
u8 Tvfp; //垂直前廊
u8 Tvw; //垂直同步宽度
u8 DCLK; //时钟速度,MHz
u8 HSPOL; //水平同步极性,0:低电平有效;1:高电平有效
u8 VSPOL; //垂直同步极性,0:低电平有效;1:高电平有效
u8 DEPOL; //数据使能极性,0:低电平有效;1:高电平有效
bool PCPOL; //像素时钟反向
}LTDC_INFO_TYPE;
LTDC_INFO_TYPE DefaultLCD_Info =
{
480, //面板宽度,单位:像素
272, //面板高度,单位:像素
41, //水平后廊
8, //水平前廊
2, //水平同步宽度
2, //垂直后廊
4, //垂直前廊
10, //垂直同步宽度
9, //时钟速度,MHz
0, //水平同步极性,0:低电平有效;1:高电平有效
0, //垂直同步极性,0:低电平有效;1:高电平有效
1, //数据使能极性,0:低电平有效;1:高电平有效
FALSE, //像素时钟反向
};
bool LTDC_ClockInit(u16 ClockFreq); //STM32F4 LTDC时钟初始化
/*************************************************************************************************************************
* 函数 : void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha)
* 功能 : LTDC 层窗口尺寸设置(会自动根据窗口尺寸以及像素格式设置帧缓冲区大小)
* 参数 : LayerIndex:层选择(0-1);sx,sy:起始坐标;width,height:宽度和高度
* 返回 : 无
* 依赖 : 底层宏定义
* 作者 : [email protected]
* 时间 : 2019-10-28
* 最后修改时间 : 2019-10-28
* 说明 : 不会使能层,不会更新层,只设置配置,需要刷新层配置后更新
*************************************************************************************************************************/
void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha)
{
u32 temp;
u8 pixformat=0;
if(LayerIndex==0)
{
//基本配置
LTDC_Layer1->CFBAR = FrameBuff; //设置层颜色帧缓存起始地址
LTDC_Layer1->PFCR = LTDC_PIXEL_FORMAT; //设置层颜色格式
LTDC_Layer1->CACR = Alpha; //常数 Alpha,255分频;设置255,则不透明
LTDC_Layer1->DCCR = 0x00; //设置默认颜色:透明的黑色
LTDC_Layer1->BFCR = ((u32)6<<8)|7; //设置层混合系数
//配置窗口
temp = (sx+width+((LTDC->BPCR&0X0FFF0000)>>16))<<16;
LTDC_Layer1->WHPCR = (sx+((LTDC->BPCR&0X0FFF0000)>>16)+1)|temp;//设置行起始和结束位置
temp = (sy+height+(LTDC->BPCR&0X7FF))<<16;
LTDC_Layer1->WVPCR = (sy+(LTDC->BPCR&0X7FF)+1)|temp; //设置列起始和结束位置
pixformat = LTDC_Layer1->PFCR&0X07; //得到颜色格式
if(pixformat == 0)temp=4; //ARGB8888,一个点4个字节
else if(pixformat == 1)temp=3; //RGB888,一个点3个字节
else if(pixformat==5||pixformat==6)temp=1; //L8/AL44,一个点1个字节
else temp=2; //其他格式,一个点2个字节
LTDC_Layer1->CFBLR = (width*temp<<16)|(width*temp+3); //帧缓冲区长度设置(字节为单位)
LTDC_Layer1->CFBLNR = height; //帧缓冲区行数设置
//记录层窗口大小位置信息
sg_LTDC_ConfigData.LayerConfig[0].sx = sx;
sg_LTDC_ConfigData.LayerConfig[0].sy = sy;
sg_LTDC_ConfigData.LayerConfig[0].width = width;
sg_LTDC_ConfigData.LayerConfig[0].height = height;
}else
{
//基本配置
LTDC_Layer2->CFBAR = FrameBuff; //设置层颜色帧缓存起始地址
LTDC_Layer2->PFCR = LTDC_PIXEL_FORMAT; //设置层颜色格式
LTDC_Layer2->CACR = Alpha; //常数 Alpha,255分频;设置255,则不透明
LTDC_Layer2->DCCR = 0x00; //设置默认颜色:透明的黑色
LTDC_Layer2->BFCR = ((u32)6<<8)|7; //设置层混合系数
//配置窗口
temp = (sx+width+((LTDC->BPCR&0X0FFF0000)>>16))<<16;
LTDC_Layer2->WHPCR = (sx+((LTDC->BPCR&0X0FFF0000)>>16)+1)|temp; //设置行起始和结束位置
temp = (sy+height+(LTDC->BPCR&0X7FF))<<16;
LTDC_Layer2->WVPCR = (sy+(LTDC->BPCR&0X7FF)+1)|temp; //设置列起始和结束位置
pixformat = LTDC_Layer2->PFCR&0X07; //得到颜色格式
if(pixformat == 0)temp=4; //ARGB8888,一个点4个字节
else if(pixformat == 1)temp=3; //RGB888,一个点3个字节
else if(pixformat == 5||pixformat==6)temp=1; //L8/AL44,一个点1个字节
else temp = 2; //其他格式,一个点2个字节
LTDC_Layer2->CFBLR = (width*temp<<16)|(width*temp+3); //帧缓冲区长度设置(字节为单位)
LTDC_Layer2->CFBLNR = height; //帧缓冲区行数设置
//记录层窗口大小位置信息
sg_LTDC_ConfigData.LayerConfig[1].sx = sx;
sg_LTDC_ConfigData.LayerConfig[1].sy = sy;
sg_LTDC_ConfigData.LayerConfig[1].width = width;
sg_LTDC_ConfigData.LayerConfig[1].height = height;
}
}
/*************************************************************************************************************************
* 函数 : void LTDC_Init(void)
* 功能 : LTDC 接口初始化
* 参数 : 无
* 返回 : 无
* 依赖 : 底层宏定义
* 作者 : [email protected]
* 时间 : 2019-09-08
* 最后修改时间 : 2019-09-08
* 说明 : 用于初始化STM32F7 LTDC 接口
*************************************************************************************************************************/
void LTDC_Init(void)
{
u32 temp;
SYS_DeviceClockEnable(DEV_LTDC, TRUE); //LTDC时钟使能
SYS_DeviceReset(DEV_LTDC); //STM32F7外设复位
SYS_DeviceClockEnable(DEV_GPIOE, TRUE); //使能GPIOE时钟
SYS_DeviceClockEnable(DEV_GPIOG, TRUE); //使能GPIOG时钟
SYS_DeviceClockEnable(DEV_GPIOJ, TRUE); //使能GPIOJ时钟
SYS_DeviceClockEnable(DEV_GPIOK, TRUE); //使能GPIOK时钟
SYS_DeviceClockEnable(DEV_GPIOI, TRUE); //使能GPIOI时钟
//初始化IO
SYS_GPIOx_Init(GPIOE, BIT4, AF_PP_OPU, SPEED_100M); //PE4
SYS_GPIOx_Init(GPIOG, BIT12, AF_PP_OPU, SPEED_100M); //PG12
SYS_GPIOx_Init(GPIOJ, 0Xffff&(~BIT12), AF_PP_OPU, SPEED_100M); //PJ0~11/13/14/15
SYS_GPIOx_Init(GPIOK, BIT0|BIT1|BIT2|BIT4|BIT5|BIT6|BIT7, AF_PP_OPU, SPEED_100M); //PK0/1/2/4/5/6/7
SYS_GPIOx_Init(GPIOI, BIT9|BIT10|BIT14|BIT15, AF_PP_OPU, SPEED_100M); //PI9/10/14/15
SYS_GPIOx_SetAF(GPIOE, 4, AF14_LTDC); //PE4,AF14
SYS_GPIOx_SetAF(GPIOG, 12, AF14_LTDC); //PG12,AF14
SYS_GPIOx_SetAF(GPIOJ, 0, AF14_LTDC); //PJ0,AF14
SYS_GPIOx_SetAF(GPIOJ, 1, AF14_LTDC); //PJ1,AF14
SYS_GPIOx_SetAF(GPIOJ, 2, AF14_LTDC); //PJ2,AF14
SYS_GPIOx_SetAF(GPIOJ, 3, AF14_LTDC); //PJ3,AF14
SYS_GPIOx_SetAF(GPIOJ, 4, AF14_LTDC); //PJ4,AF14
SYS_GPIOx_SetAF(GPIOJ, 5, AF14_LTDC); //PJ5,AF14
SYS_GPIOx_SetAF(GPIOJ, 6, AF14_LTDC); //PJ6,AF14
SYS_GPIOx_SetAF(GPIOJ, 7, AF14_LTDC); //PJ7,AF14
SYS_GPIOx_SetAF(GPIOJ, 8, AF14_LTDC); //PJ8,AF14
SYS_GPIOx_SetAF(GPIOJ, 9, AF14_LTDC); //PJ9,AF14
SYS_GPIOx_SetAF(GPIOJ, 10, AF14_LTDC); //PJ10,AF14
SYS_GPIOx_SetAF(GPIOJ, 11, AF14_LTDC); //PJ11,AF14
SYS_GPIOx_SetAF(GPIOJ, 13, AF14_LTDC); //PJ13,AF14
SYS_GPIOx_SetAF(GPIOJ, 14, AF14_LTDC); //PJ14,AF14
SYS_GPIOx_SetAF(GPIOJ, 15, AF14_LTDC); //PJ15,AF14
SYS_GPIOx_SetAF(GPIOK, 0, AF14_LTDC); //PK0,AF14
SYS_GPIOx_SetAF(GPIOK, 1, AF14_LTDC); //PK1,AF14
SYS_GPIOx_SetAF(GPIOK, 2, AF14_LTDC); //PK2,AF14
SYS_GPIOx_SetAF(GPIOK, 4, AF14_LTDC); //PK4,AF14
SYS_GPIOx_SetAF(GPIOK, 5, AF14_LTDC); //PK5,AF14
SYS_GPIOx_SetAF(GPIOK, 6, AF14_LTDC); //PK6,AF14
SYS_GPIOx_SetAF(GPIOK, 7, AF14_LTDC); //PK7,AF14
SYS_GPIOx_SetAF(GPIOI, 9, AF14_LTDC); //PI9,AF14
SYS_GPIOx_SetAF(GPIOI, 10, AF14_LTDC); //PI10,AF14
SYS_GPIOx_SetAF(GPIOI, 14, AF14_LTDC); //PI14,AF14
SYS_GPIOx_SetAF(GPIOI, 15, AF14_LTDC); //PI15,AF14
LTDC_ClockInit(DefaultLCD_Info.DCLK); //设置像素时钟 9Mhz
//设置LTDC 全局控制寄存器 (LTDC_GCR)
temp = 0;
temp |= (DefaultLCD_Info.HSPOL&0x01) << 31; //水平同步极性
temp |= (DefaultLCD_Info.VSPOL&0x01) << 30; //垂直同步极性
temp |= (DefaultLCD_Info.DEPOL&0x01) << 29; //数据使能极性
temp |= (DefaultLCD_Info.PCPOL&0x01) << 28; //像素时钟极性
LTDC->GCR = temp;
//LTDC 后沿配置寄存器 (LTDC_BPCR)
temp = (DefaultLCD_Info.Tvw + DefaultLCD_Info.Tvbp - 1) << 0; //这些位定义累加水平后沿宽度(水平同步像素加水平后沿像素减 1)。
temp |= (DefaultLCD_Info.Thw + DefaultLCD_Info.Thbp - 1) << 16; //这些位定义累加垂直后沿宽度(垂直同步行加垂直后沿行减 1)。
LTDC->BPCR=temp;
//LTDC 有效宽度配置寄存器 (LTDC_AWCR)
temp=(DefaultLCD_Info.Tvw+DefaultLCD_Info.Tvbp+DefaultLCD_Info.Height-1)<<0; //累加有效高度=垂直脉宽+垂直后沿+垂直分辨率-1
temp|=(DefaultLCD_Info.Thw+DefaultLCD_Info.Thbp+DefaultLCD_Info.Width-1)<<16; //累加有效宽度=水平脉宽+水平后沿+水平分辨率-1
LTDC->AWCR=temp;
//LTDC 总宽度配置寄存器 (LTDC_TWCR)
temp=(DefaultLCD_Info.Tvw+DefaultLCD_Info.Tvbp+DefaultLCD_Info.Height+DefaultLCD_Info.Tvfp-1)<<0; //总高度=垂直脉宽+垂直后沿+垂直分辨率+垂直前廊-1
temp|=(DefaultLCD_Info.Thw+DefaultLCD_Info.Thbp+DefaultLCD_Info.Width+DefaultLCD_Info.Thfp-1)<<16; //总宽度=水平脉宽+水平后沿+水平分辨率+水平前廊-1
LTDC->TWCR=temp;
//背景设置
LTDC->BCCR=0xffffff; //设置背景层颜色寄存器(RGB888格式)
LTDC_Enable(TRUE); //开启LTDC
//初始化层1
LTDC_SetLayerConfig(0, 0, 0, LTDC_WIDTH, LTDC_HEIGHT, (u32)g_LTDC_BUFF_RGB888[0], 255);
//初始化层2
LTDC_SetLayerConfig(1, 0, 0, LTDC_WIDTH, LTDC_HEIGHT, (u32)g_LTDC_BUFF_RGB888[1], 255);
LTDC_Clear(0, 0xFF000000); //清屏层1-不透明的黑色
LTDC_Clear(1, 0x00000000); //清屏层2-透明的黑色
LTDC_LayerEnable(0, TRUE); //使能层1
LTDC_LayerRefreshConfig(); //LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)
LCD_DispIoInit(); //初始化DISP引脚-启动显示
}
/*************************************************************************************************************************
* 函数 : void LTDC_LayerRefreshConfig(void)
* 功能 : LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)
* 参数 : 无
* 返回 : 无
* 依赖 : 底层宏定义
* 作者 : [email protected]
* 时间 : 2019-10-29
* 最后修改时间 : 2019-10-29
* 说明 : 修改层配置后必须重新加载,否则不会生效
*************************************************************************************************************************/
void LTDC_LayerRefreshConfig(void)
{
LTDC->SRCR|=1<<0; //重新加载配置-必须重新加载,否则上面的层不会更新,折腾好久才发现,叫啥影子寄存器重载,也不说清楚
}
/*************************************************************************************************************************
* 函数 : void LTDC_Enable(bool Enable)
* 功能 : LTDC使能设置
* 参数 : Enable:TRUE:使能;FALSE:失能
* 返回 : 无
* 依赖 : 底层宏定义
* 作者 : [email protected]
* 时间 : 2019-10-29
* 最后修改时间 : 2019-10-29
* 说明 :
*************************************************************************************************************************/
void LTDC_Enable(bool Enable)
{
if(Enable)
{
LTDC->GCR |= BIT0; //打开LTDC
}
else
{
LTDC->GCR &= ~BIT0; //关闭LTDC
}
}
/*************************************************************************************************************************
* 函数 : void LTDC_LayerEnable(u8 LayerIndex, bool Enable)
* 功能 : LTDC 层使能设置
* 参数 : LayerIndex:层选择0-1;Enable:TRUE:使能;FALSE:失能
* 返回 : 无
* 依赖 : 底层宏定义
* 作者 : [email protected]
* 时间 : 2019-10-29
* 最后修改时间 : 2019-10-29
* 说明 :
*************************************************************************************************************************/
void LTDC_LayerEnable(u8 LayerIndex, bool Enable)
{
if(Enable)
{
if(LayerIndex == 0) //层1
{
LTDC_Layer1->CR |= BIT0; //使能层1
}
else
{
LTDC_Layer2->CR |= BIT0; //使能层2
}
}
else
{
if(LayerIndex == 0) //层1
{
LTDC_Layer1->CR &= ~BIT0; //失能层1
}
else
{
LTDC_Layer2->CR &= ~BIT0; //失能层2
}
}
}
/*************************************************************************************************************************
* 函数 : bool LTDC_ClockInit(u16 ClockFreq)
* 功能 : STM32F7 LTDC时钟初始化
* 参数 : ClockFreq:时钟频率,2-168MHZ
* 返回 : 是否设置成功
* 依赖 : 底层宏定义
* 作者 : [email protected]
* 时间 : 2019-10-28
* 最后修改时间 : 2019-10-28
* 说明 : 输入时钟频率在系统主时钟初始化之后就会设置为1MHz,通过设置SAI PLL实现LTDC所需频率,VCO频率范围:49~432
*************************************************************************************************************************/
bool LTDC_ClockInit(u16 ClockFreq)
{
u32 TimeOut = 0;
u32 VCO;
u32 PLLSAIR; //PLLSAICFGR[30:28]
u32 PLLSAIDIVR; //DCKCFGR1[17:16]
u32 temp;
if(ClockFreq < 1)ClockFreq = 1;
if(ClockFreq > 100) ClockFreq = 100;
RCC->CR &= ~(1<<28); //关闭SAI时钟
TimeOut = 0;
while(RCC->CR&(1<<29)) //等待关闭成功
{
nop;
TimeOut ++;
if(TimeOut > 0xFFFF) return FALSE; //关闭超时
}
//计算分频与VCO频率,通过PLLSAICFGR[30:28]可以设置2-7分频
//通过PLLSAICFGR[17:16]可以设置00:2 01:4 10:8 11:16分频
//通过PLLSAICFGR[14:6]可以设置为49-432MHz的VCO频率
if(ClockFreq <= 6)
{
PLLSAIR = 4; //4分频
PLLSAIDIVR = 3; //16分频
VCO = ClockFreq * PLLSAIR * 16; //VCO范围:64-384;
}
else if(ClockFreq <= 13)
{
PLLSAIR = 4; //4分频
PLLSAIDIVR = 2; //8分频
VCO = ClockFreq * PLLSAIR * 8; //VCO范围:224-416;
}
else if(ClockFreq <= 26)
{
PLLSAIR = 2; //2分频
PLLSAIDIVR = 2; //8分频
VCO = ClockFreq * PLLSAIR * 8; //VCO范围:224-416;
}
else if(ClockFreq <= 52)
{
PLLSAIR = 2; //2分频
PLLSAIDIVR = 1; //4分频
VCO = ClockFreq * PLLSAIR * 4; //VCO范围:216-416;
}
else if(ClockFreq <= 104)
{
PLLSAIR = 2; //2分频
PLLSAIDIVR = 0; //2分频
VCO = ClockFreq * PLLSAIR * 2; //VCO范围:212-416;
}
//设置PLLSAICFGR
temp = RCC->PLLSAICFGR;
temp &= ~((3<<28) | (0x1FF<<6)); //清除之前的设置
temp |= PLLSAIR << 28; //设置分频PLLSAICFGR[30:28]
temp |= VCO << 6; //设置VCO
RCC->PLLSAICFGR = temp;
//设置DCKCFGR1
temp = RCC->DCKCFGR1;
temp &= ~(3<<16); //清除之前的设置
temp |= PLLSAIDIVR << 16; //设置分频DCKCFGR1[17:16]
RCC->DCKCFGR1 = temp;
//启动时钟
RCC->CR |= 1<<28; //启动SAI时钟
TimeOut = 0;
while((RCC->CR&(1<<29)) == 0) //等待开启成功
{
nop;
TimeOut ++;
if(TimeOut > 0xFFFF) return FALSE; //开启超时
}
return TRUE;
}
/*************************************************************************************************************************
* 函数 : void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color)
* 功能 : 矩形填充(使用DMA2D)
* 参数 : LayerIndex:层选择0-1;sx,sy:开始坐标;ex,ey:结束坐标,color:需要填充的颜色
* 返回 : 无
* 依赖 : 底层宏定义
* 作者 : [email protected]
* 时间 : 2019-10-30
* 最后修改时间 : 2019-10-30
* 说明 : 采用DMA2D实现
*************************************************************************************************************************/
void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color)
{
DMA2D_FillColorToFGRAM((u32)&g_LTDC_BUFF_RGB888[LayerIndex][sy][sx], ex-sx+1, ey-sy+1, LTDC_WIDTH-(ex-sx+1), DMA2D_COLOR_ARGB8888, color); //DMA2D进行单色填充
DMA2D_WaitTransferComplete(500); //等待DMA2D传输完成
}
/*************************************************************************************************************************
* 函数 : void LTDC_Clear(u8 LayerIndex,u32 color)
* 功能 : 清屏(使用DMA2D)
* 参数 : LayerIndex:层选择0-1;color:需要填充的颜色
* 返回 : 无
* 依赖 : 底层宏定义
* 作者 : [email protected]
* 时间 : 2019-10-30
* 最后修改时间 : 2019-10-30
* 说明 : 采用DMA2D实现
*************************************************************************************************************************/
void LTDC_Clear(u8 LayerIndex,u32 color)
{
DMA2D_FillColorToFGRAM((u32)&g_LTDC_BUFF_RGB888[LayerIndex][0][0], LTDC_WIDTH, LTDC_HEIGHT, 0, DMA2D_COLOR_ARGB8888, color); //DMA2D进行单色填充
SYS_DelayMS(5);
DMA2D_WaitTransferComplete(500); //等待DMA2D传输完成
}
/*************************************************************************************************************************
* 函数 : void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr)
* 功能 : 矩形图像填充(相同坐标范围传输,要求源图像与目标显示器分辨率一致,使用DMA2D)
* 参数 : LayerIndex:层选择0-1;sx,sy:开始坐标;ex,ey:结束坐标,ImageAddr:需要填充的图像地址
* 返回 : 无
* 依赖 : 底层宏定义
* 作者 : [email protected]
* 时间 : 2019-10-30
* 最后修改时间 : 2019-10-30
* 说明 : 采用DMA2D实现,将源图像指定位置传输到现存,要求源图像与显存大小一致
*************************************************************************************************************************/
void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr)
{
DMA2D_FillImageToFGRAM(ImageAddr+sy*LTDC_WIDTH+sx, (u32)&g_LTDC_BUFF_RGB888[LayerIndex][sy][sx], ex-sx+1, ey-sy+1, LTDC_WIDTH-(ex-sx+1), LTDC_WIDTH-(ex-sx+1), DMA2D_COLOR_ARGB8888);//DMA2D进行矩形图形填充
DMA2D_WaitTransferComplete(500);
}
/*************************************************************************************************************
* 文件名 : stm32f7_ltdc.h
* 功能 : STM32F7 外部RGB LCD驱动
* 作者 : [email protected]
* 创建时间 : 2019-09-12
* 最后修改时间 : 2019-09-12
* 详细:
*************************************************************************************************************/
#ifndef __STM32F7_LTDC_H_
#define __STM32F7_LTDC_H_
#include "system.h"
#include "DMA2D.h"
#define LTDC_WIDTH 480
#define LTDC_HEIGHT 272
extern u32 g_LTDC_BUFF_RGB888[2][LTDC_HEIGHT][LTDC_WIDTH];
//像素格式定义
typedef enum
{
LTDC_ARGB8888 = 0,
LTDC_RGB888 = 1,
LTDC_RGB565 = 2,
/*LTDC_ARGB1555 = 3,
LTDC_ARGB4444 = 4,
LTDC_L8 = 5, //8 位 Luminance
LTDC_AL44 = 6, //4 位 Alpha,4 位 Luminance
LTDC_AL88 = 7, //8 位 Alpha,8 位 Luminance*/
}LTDC_PixelFormat;
#define LTDC_PIXEL_FORMAT LTDC_ARGB8888 //选择ARGB8888格式
//画点函数32bit ARGB8888格式
__inline void LTDC_DrawPoint(u8 LayerIndex, u16 Xpos,u16 Ypos,u32 ARGB8888_Color)
{
g_LTDC_BUFF_RGB888[LayerIndex][Ypos][Xpos] = ARGB8888_Color;
}
//初始化DISP引脚
__inline void LCD_DispIoInit(void)
{
SYS_GPIOx_Init(GPIOI, BIT12, OUT_PP, SPEED_25M); //PI12 LCD_DISP H:正常模式;L:低功耗
PIout(12) = 1; //DISP = H 2019-10-16:一直忽略将此引脚置为高电平,调试走了很多弯路
}
void LTDC_Enable(bool Enable); //LTDC使能设置
void LTDC_Init(void); //LTDC 接口初始化
void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha);//LTDC 层窗口尺寸设置
void LTDC_LayerEnable(u8 LayerIndex, bool Enable); //LTDC 层使能设置
void LTDC_LayerRefreshConfig(void); //LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)
//图形相关API
void LTDC_DrawPoint(u8 LayerIndex, u16 Xpos,u16 Ypos,u32 ARGB8888_Color); //画点函数32bit ARGB8888格式
void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color); //矩形填充(使用DMA2D)
void LTDC_Clear(u8 LayerIndex,u32 color); //清屏(使用DMA2D)
void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr);//矩形图像填充(相同坐标范围传输,要求源图像与目标显示器分辨率一致,使用DMA2D)
#endif //__STM32F7_LTDC_H_