前言
上一篇LTDC的圖形是直接載入存在flash中的ST_LOGO_1[]陣列,
STM32CubeMX在設定LTDC的Layer Buffer Address指定起始位址0xD0000000 (FMC映射外部SDRAM)
接下來的操作將啟動SDRAM,並把ST_LOGO_1[]丟到SDRAM,LCD來顯示
操作環境
- Board:32F429IDISCOVERY
- LCD:2.4" QVGA(240x320) FRD240C48003-B
- IDE:STM32CubeIDE
- Code:STM32CubeMX
- Software Packs:STM32Cube_FW_F4_V1.28.0
- Picture:st_logo1.bmp
操作步驟
0.
把上一篇的程式加入的這一段刪除
main.c
static void MX_LTDC_Init(void)
{
/* USER CODE BEGIN LTDC_Init 2 */
//pLayerCfg.FBStartAdress = (uint32_t)&ST_LOGO_1;//戴入圖檔
//if (HAL_LTDC_ConfigLayer(&hltdc, &pLayerCfg, 0) != HAL_OK)
//{
// Error_Handler();
//}
/* USER CODE END LTDC_Init 2 */
}
1.加入SDRAM的初始化程式
這段程式的出處
..\STM32Cube_FW_F4_V1.28.0\Projects\STM32F429I-Discovery\Examples\FMC\FMC_SDRAM\Src\main.c
main.c
FMC_SDRAM_CommandTypeDef command;
#define REFRESH_COUNT ((uint32_t)0x056A) /* SDRAM refresh counter (90MHz SDRAM clock) */
#define SDRAM_BANK_ADDR ((uint32_t)0xD0000000)
#define SDRAM_MODEREG_BURST_LENGTH_1 ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_LENGTH_2 ((uint16_t)0x0001)
#define SDRAM_MODEREG_BURST_LENGTH_4 ((uint16_t)0x0002)
#define SDRAM_MODEREG_BURST_LENGTH_8 ((uint16_t)0x0004)
#define SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL ((uint16_t)0x0000)
#define SDRAM_MODEREG_BURST_TYPE_INTERLEAVED ((uint16_t)0x0008)
#define SDRAM_MODEREG_CAS_LATENCY_2 ((uint16_t)0x0020)
#define SDRAM_MODEREG_CAS_LATENCY_3 ((uint16_t)0x0030)
#define SDRAM_MODEREG_OPERATING_MODE_STANDARD ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_PROGRAMMED ((uint16_t)0x0000)
#define SDRAM_MODEREG_WRITEBURST_MODE_SINGLE ((uint16_t)0x0200)
static void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command)
{
__IO uint32_t tmpmrd =0;
/* Step 3: Configure a clock configuration enable command */
Command->CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);
/* Step 4: Insert 100 ms delay */
HAL_Delay(100);
/* Step 5: Configure a PALL (precharge all) command */
Command->CommandMode = FMC_SDRAM_CMD_PALL;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);
/* Step 6 : Configure a Auto-Refresh command */
Command->CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
Command->AutoRefreshNumber = 4;
Command->ModeRegisterDefinition = 0;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);
/* Step 7: Program the external memory mode register */
tmpmrd = (uint32_t)SDRAM_MODEREG_BURST_LENGTH_2 |
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL |
SDRAM_MODEREG_CAS_LATENCY_3 |
SDRAM_MODEREG_OPERATING_MODE_STANDARD |
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE;
Command->CommandMode = FMC_SDRAM_CMD_LOAD_MODE;
Command->CommandTarget = FMC_SDRAM_CMD_TARGET_BANK2;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = tmpmrd;
/* Send the command */
HAL_SDRAM_SendCommand(hsdram, Command, 0x1000);
/* Step 8: Set the refresh rate counter */
/* (15.62 us x Freq) - 20 */
/* Set the device refresh counter */
HAL_SDRAM_ProgramRefreshRate(hsdram, REFRESH_COUNT);
}
main.c
int main(void)
{
SDRAM_Initialization_Sequence(&hsdram1, &command);
HAL_SDRAM_Write_16b(&hsdram1, (uint32_t*)SDRAM_BANK_ADDR, ST_LOGO_1, (240*320));
}