-
内部 SRAM:0x20000000 起,大小 0x140000 = 1.25MB。片上 RAM。
-
外部 SDRAM:0x60000000 起 = 8MB。
LTDC
LTDC = LCD-TFT 显示控制器,一个专用显示外设,用它来配置屏幕的各项连接数据。他还能直接将一段内存通过DMA直接渲染到界面上。
它:
- 用内部计数器自己产生 VSYNC/HSYNC/DE/PCLK 时序
- 作为总线主设备,按像素时钟不断从显存(CFBAR)取像素发到屏
- 做图层混合(Layer1/Layer2)、透明度、RGB565/RGB888 格式
- 用影子寄存器 + 消隐期重载实现无撕裂换帧
屏幕参数
enum {
LCD_WIDTH = 240U, //屏幕像素
LCD_HEIGHT = 320U,//屏幕像素
LCD_HSYNC = 10U, //行同步信号
LCD_VSYNC = 4U,//帧同步信号
LCD_HBACK_PORCH = 10U, //
LCD_VBACK_PORCH = 4U,
LCD_HFRONT_PORCH = 38U,
LCD_VFRONT_PORCH = 8U
};
配置时钟
LTDC提供了多个4时钟源:PLL1R,PLL2P,PLL2Q,PLL2R

static void pixel_clock_init(void)
{
/*
* PLL2复用PLL1M预分频后的1MHz参考时钟:
* PLL2 VCO = 1MHz × 84 = 84MHz;
* PLL2R = 84MHz ÷ 12 = 7MHz。
*/
ClockEnable(ClockNodePLL2G, false);//先关闭时钟
ClockMultiply(ClockNodePLL2, 84U); //ClockMultiply 倍频x84 = 84MHz
ClockDivide(ClockNodePLL2R, 12U); //ClockDivide 分频为÷12 = 7MHz
ClockEnable(ClockNodePLL2G, true);//配置好后再开启时钟
while (RCC_GetFlagStatus(RCC_FLAG_PLL2RDY) == RESET) {//等待PLL2锁定
}
ClockSelect(ClockNodeDPC, ClockNodePLL2R);//选择ClockNodePLL2R作为LTDC时钟输入
}
配置io脚
static void ltdc_gpio_init(void)
{
GPIO_InitTypeDef gpio;
PeripheralEnable(PeripheralGPIOA, true);
/*省略GPIOB-H*/
PeripheralEnable(PeripheralGPIOI, true);
PeripheralEnable(PeripheralPCFG, true);
//配置电气特性
gpio.GPIO_Speed = GPIO_Speed_50MHz;
gpio.GPIO_Mode = GPIO_Mode_AF;
gpio.GPIO_OType = GPIO_OType_PP;
gpio.GPIO_PuPd = GPIO_PuPd_NOPULL;
/*配置DE PCLK VSYNC HSYNC*/
GPIO_PinAFConfig(GPIOF, GPIO_PinSource10, GPIO_AF_LTDC); /* DE */
gpio.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOF, &gpio);
GPIO_PinAFConfig(GPIOG, GPIO_PinSource7, GPIO_AF_LTDC); /* PCLK */
gpio.GPIO_Pin = GPIO_Pin_7 ;
GPIO_Init(GPIOG, &gpio);
GPIO_PinAFConfig(GPIOI, GPIO_PinSource9, GPIO_AF_LTDC); /* VSYNC */
GPIO_PinAFConfig(GPIOI, GPIO_PinSource10, GPIO_AF_LTDC); /* HSYNC */
gpio.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;
GPIO_Init(GPIOI, &gpio);
/*配置18线RGB的引脚*/
/*省略*/
}
初始化LTDC
void ltdc_init(void)
{
LTDC_InitTypeDef controller; //配置LTDC结构体
PeripheralEnable(PeripheralLTDC, true);//开启LTDC功能
LTDC_StructInit(&controller); //初始化LTDC结构体主要是清零
//配置信号极性 HSYNC低有效 VSYNC低有效 DE高有效 PCLK反相
controller.LTDC_HSPolarity = LTDC_HSPolarity_AL;//(uint32_t)0x00000000
controller.LTDC_VSPolarity = LTDC_VSPolarity_AL;//(uint32_t)0x00000000
controller.LTDC_DEPolarity = LTDC_DEPolarity_AH; //(uint32_t)0x20000000
controller.LTDC_PCPolarity = LTDC_PCPolarity_IIPC; //(uint32_t)0x10000000
//配置时钟同步 LTDC计数器从0开始 所以要-1U
controller.LTDC_HorizontalSync = LCD_HSYNC - 1U;
controller.LTDC_VerticalSync = LCD_VSYNC - 1U;
//配置后肩 LTDC计数器从0开始 所以要-1U
controller.LTDC_AccumulatedHBP = LCD_HSYNC + LCD_HBACK_PORCH - 1U;
controller.LTDC_AccumulatedVBP = LCD_VSYNC + LCD_VBACK_PORCH - 1U;
//有效区结束位置 LTDC计数器从0开始 所以要-1U
controller.LTDC_AccumulatedActiveW = LCD_HSYNC + LCD_HBACK_PORCH + LCD_WIDTH - 1U;
controller.LTDC_AccumulatedActiveH = LCD_VSYNC + LCD_VBACK_PORCH + LCD_HEIGHT - 1U;
//整行和整帧结束位置 LTDC计数器从0开始 所以要-1U
controller.LTDC_TotalWidth = LCD_HSYNC + LCD_HBACK_PORCH +
LCD_WIDTH + LCD_HFRONT_PORCH - 1U;
controller.LTDC_TotalHeigh = LCD_VSYNC + LCD_VBACK_PORCH +
LCD_HEIGHT + LCD_VFRONT_PORCH - 1U;
LTDC_Init(&controller);//写入配置
/*
* 配置Layer
*/
LTDC_Layer_InitTypeDef layer; //图层,支持多个图层
LTDC_LayerStructInit(&layer);
//图层水平起点终点
layer.LTDC_HorizontalStart = LCD_HSYNC + LCD_HBACK_PORCH;
layer.LTDC_HorizontalStop = layer.LTDC_HorizontalStart + LCD_WIDTH - 1U;
//图层垂直起点终点
layer.LTDC_VerticalStart = LCD_VSYNC + LCD_VBACK_PORCH;
layer.LTDC_VerticalStop = layer.LTDC_VerticalStart + LCD_HEIGHT - 1U;
//输入这个Layer的显存像素格式、alpha、首地址
layer.LTDC_PixelFormat = LTDC_Pixelformat_ARGB8888;
layer.LTDC_ConstantAlpha = 0xFFU;
layer.LTDC_CFBStartAdress = framebuffer_address;
//行有效显存数据 & 当前行到下一行跨过多少字节
layer.LTDC_CFBLineLength = LCD_WIDTH * 4U;
layer.LTDC_CFBPitch = LCD_WIDTH * 4U;
//帧缓冲行数
layer.LTDC_CFBLineNumber = LCD_HEIGHT;
//混合因子1,混合因子2,每个图层混合情况
layer.LTDC_BlendingFactor_1 = LTDC_BlendingFactor1_PAxCA;
layer.LTDC_BlendingFactor_2 = LTDC_BlendingFactor2_PAxCA;
//开始写入配置
LTDC_LayerInit(LTDC_Layer1, &layer);
//关闭Layer2,开启关闭Layer1
LTDC_LayerCmd(LTDC_Layer2, DISABLE);
LTDC_LayerCmd(LTDC_Layer1, ENABLE);
//LTDC->AHBCFG |= 0x07U;
LTDC->AHBCFG |= 0x07U;
//Reload配置
/*
CPU写配置
↓
Shadow Register
↓ Reload
Active Register
↓
LTDC实际使用
*/
LTDC_ReloadConfig(LTDC_IMReload);//LTDC_IMReload 立即加载
//启动LTDC
LTDC_Cmd(ENABLE);
}