配置SMC驱动SDRAM
[]()
[]()首先创建一个工程文件 参考官方原理图配置系统时钟和FMC接口
时钟配置

时钟树如下显示
在RCC选项中启用外部高速晶振

配置总线时钟速度位180Mhz
配置FMC接口 并添加SDRAM驱动文件
SDRAM通过FMC接口访问SDRAM FMC配置如下

完成上图配置 生成代码文件
在keil中添加SDRAM驱动文件,
#define BUFFER_SIZE ((uint32_t)0x1000)
#define WRITE_READ_ADDR ((uint32_t)0x0800)
#define SDRAM_BANK_ADDR ((uint32_t)0xC0000000)
/* #define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_8 */
#define SDRAM_MEMORY_WIDTH FMC_SDRAM_MEM_BUS_WIDTH_16
#define SDCLOCK_PERIOD FMC_SDRAM_CLOCK_PERIOD_2
/* #define SDCLOCK_PERIOD FMC_SDRAM_CLOCK_PERIOD_3 */
#define SDRAM_TIMEOUT ((uint32_t)0xFFFF)
#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)
hsdram.Instance = FMC_SDRAM_DEVICE;
SDRAM_Timing.LoadToActiveDelay = 2;
SDRAM_Timing.ExitSelfRefreshDelay = 6;
SDRAM_Timing.SelfRefreshTime = 4;
SDRAM_Timing.RowCycleDelay = 6;
SDRAM_Timing.WriteRecoveryTime = 2;
SDRAM_Timing.RPDelay = 2;
SDRAM_Timing.RCDDelay = 2;
hsdram.Init.SDBank = FMC_SDRAM_BANK1;
hsdram.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;
hsdram.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
hsdram.Init.MemoryDataWidth = SDRAM_MEMORY_WIDTH;
hsdram.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
hsdram.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_2;
hsdram.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
hsdram.Init.SDClockPeriod = SDCLOCK_PERIOD;
hsdram.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
hsdram.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
/* Initialize the SDRAM controller */
if(HAL_SDRAM_Init(&hsdram, &SDRAM_Timing) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}
/* Program the SDRAM external device */
BSP_SDRAM_Initialization_Sequence(&hsdram, &command);
/*##-2- SDRAM memory read/write access #####################################*/
/* Fill the buffer to write */
Fill_Buffer(aTxBuffer, BUFFER_SIZE, 0xA244250F);
/* Write data to the SDRAM memory */
for (uwIndex = 0; uwIndex < BUFFER_SIZE; uwIndex++)
{
*(__IO uint32_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 4*uwIndex) = aTxBuffer[uwIndex];
}
/* Read back data from the SDRAM memory */
for (uwIndex = 0; uwIndex < BUFFER_SIZE; uwIndex++)
{
aRxBuffer[uwIndex] = *(__IO uint32_t*) (SDRAM_BANK_ADDR + WRITE_READ_ADDR + 4*uwIndex);
}
/*##-3- Checking data integrity ############################################*/
for (uwIndex = 0; (uwIndex < BUFFER_SIZE) && (uwWriteReadStatus == 0); uwIndex++)
{
if (aRxBuffer[uwIndex] != aTxBuffer[uwIndex])
{
uwWriteReadStatus++;
}
}
在初始化完FMC接口之后 初始化SDRAM芯片 这里我们在SDRAM测试函数中打断点 如果数据写入成功并校验成功 断点会停在对应位置


如图这个时候SDRAM就已经成功驱动了
[]()在keil的memory界面中输入SDRAM的基地址

可以看到数据已经存到SDRAM中
配置LTDC屏幕接口
首先启用DM2D加速模块

LDTC接口配置


将显存地址配置到SDRAM的地址当中

之后直接生成工程
TouchGFX工程编辑
打开touchgfx工程


添加控件 并生成代码
[]()
[]()在Keil工程目录下找到TouchGFXApp这个文件 将头文件复制到Freertos文件中

#include "app_touchgfx.h"
返回freertos.c
void StartTouchGFXTask(void const * argument)
{
/* USER CODE BEGIN StartTouchGFXTask */
/* Infinite loop */
for(;;)
{
MX_TouchGFX_Process();
osDelay(1);
}
/* USER CODE END StartTouchGFXTask */
}
在TouchGFX任务中添加函数
[]()编译并且运行
成功显示 |