需要提前准备好SDRAM驱动,如果没有SDRAM可以进行纯色彩测试,底层时钟,IO操作相关看注释,我使用的是寄存器封装的。
- /*************************************************************************************************************
- * 文件名 : stm32f7_ltdc.c
- * 功能 : STM32F7 外部RGB LCD驱动
- * 创建时间 : 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:宽度和高度
- * 返回 : 无
- * 依赖 : 底层宏定义
- * 作者 : <a href="mailto:cp1300@139.com">cp1300@139.com</a>
- * 时间 : 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 接口初始化
- * 参数 : 无
- * 返回 : 无
- * 依赖 : 底层宏定义
- * 作者 : <a href="mailto:cp1300@139.com">cp1300@139.com</a>
- * 时间 : 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 刷新层配置(修改层配置后必须重新加载,否则不会生效)
- * 参数 : 无
- * 返回 : 无
- * 依赖 : 底层宏定义
- * 作者 : <a href="mailto:cp1300@139.com">cp1300@139.com</a>
- * 时间 : 2019-10-29
- * 最后修改时间 : 2019-10-29
- * 说明 : 修改层配置后必须重新加载,否则不会生效
- *************************************************************************************************************************/
- void LTDC_LayerRefreshConfig(void)
- {
- LTDC->SRCR|=1<<0; //重新加载配置-必须重新加载,否则上面的层不会更新,折腾好久才发现,叫啥影子寄存器重载,也不说清楚
- }
- /*************************************************************************************************************************
- * 函数 : void LTDC_Enable(bool Enable)
- * 功能 : LTDC使能设置
- * 参数 : Enable:TRUE:使能;FALSE:失能
- * 返回 : 无
- * 依赖 : 底层宏定义
- * 作者 : <a href="mailto:cp1300@139.com">cp1300@139.com</a>
- * 时间 : 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:失能
- * 返回 : 无
- * 依赖 : 底层宏定义
- * 作者 : <a href="mailto:cp1300@139.com">cp1300@139.com</a>
- * 时间 : 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
- * 返回 : 是否设置成功
- * 依赖 : 底层宏定义
- * 作者 : <a href="mailto:cp1300@139.com">cp1300@139.com</a>
- * 时间 : 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:需要填充的颜色
- * 返回 : 无
- * 依赖 : 底层宏定义
- * 作者 : <a href="mailto:cp1300@139.com">cp1300@139.com</a>
- * 时间 : 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:需要填充的颜色
- * 返回 : 无
- * 依赖 : 底层宏定义
- * 作者 : <a href="mailto:cp1300@139.com">cp1300@139.com</a>
- * 时间 : 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:需要填充的图像地址
- * 返回 : 无
- * 依赖 : 底层宏定义
- * 作者 : <a href="mailto:cp1300@139.com">cp1300@139.com</a>
- * 时间 : 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驱动
- * 作者 : <a href="mailto:cp1300@139.com">cp1300@139.com</a>
- * 创建时间 : 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_
|