前言
GuiX移植内容较多,打算分五篇来讲述 1)GuiX移植之FMC 2)GuiX移植之LTDC 3)GuiX移植之DMA2D 4)GuiX移植之GuiX studio 5)GuiX移植
软硬件介绍:STM32F429BIT(反客的一块板子,挺适合拿来学习ThreadX的); SDRAM型号:W9812G2 ThreadX版本:6.1.3; GuiX版本:6.1.3; IDE:KEIL5 v5.31.0.0版本、STM32CubeMX; ARM编译器:AC5
一、FMC配置
1、使用STM32CubeMX配置并生成FMC工程。
2、FMC使用AHB时钟,配置符合SDRAM数据手册要求的时钟。
3、FMC详细配置如下:
①SDRAM 1和SDRAM 2控制的IO相同,所以选择哪个都可以。 ②笔者手上板子的SDRAM CKE和CS引脚接与SDCKE1+SDNE1引脚相同,所以选择SDCKE1+SDNE1。 ③其余几个配置项查看数据手册获悉。
4、时序及其他配置如下:
①SDRAM control中关闭写保护,使能突发读,可提高读写效率 ②时序配置可参考下图,在SDRAM数据手册中查找相应的项目即可
5、成功工程。
二、修改工程并测试
1、SDRAM初始化
SDRMA不同于SRAM的上电即用,SDRAM上电后需要进行初始化方可使用。故需要在FMC初始化后进行SDRAM初始化。具体可参考《安富莱STM32-V6开发板_用户手册》第39章学习。
提供一个简易版的SDRAM初始化代码:
#include "main.h"
void SDRAM_delay(__IO uint32_t nCount)
{
__IO uint32_t index = 0;
for(index = (100000 * nCount); index != 0; index--);
}
void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram, FMC_SDRAM_CommandTypeDef *Command)
{
__IO uint32_t tmpmrd = 0;
Command->CommandMode = FMC_SDRAM_CMD_CLK_ENABLE;
Command->CommandTarget = FMC_COMMAND_TARGET_BANK;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = 0;
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
SDRAM_delay(1);
Command->CommandMode = FMC_SDRAM_CMD_PALL;
Command->CommandTarget = FMC_COMMAND_TARGET_BANK;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = 0;
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
Command->CommandMode = FMC_SDRAM_CMD_AUTOREFRESH_MODE;
Command->CommandTarget = FMC_COMMAND_TARGET_BANK;
Command->AutoRefreshNumber = 8;
Command->ModeRegisterDefinition = 0;
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
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_COMMAND_TARGET_BANK;
Command->AutoRefreshNumber = 1;
Command->ModeRegisterDefinition = tmpmrd;
HAL_SDRAM_SendCommand(hsdram, Command, SDRAM_TIMEOUT);
hsdram->Instance->SDRTR |= ((uint32_t)((1386)<< 1));
}
在main.c文件中,FMC初始化后调用SDRAM初始化函数。
2、测试SDRAM
注:SDRAM映射到BANK1还是BANK2由CKE和CS决定,而不是图1中的SDRAM 1/SDRAM 2,图1中CKE和CS选择的时SDCKE1+SDNE1,所以映射到的地址空间时BANK2。
测试代码如下:
#define SDRAMSTARTADDR 0xD0000000
uint32_t x=0,y=0;
uint32_t *wp=NULL;
void FMC_TaskInit()
{
wp = (uint32_t *)SDRAMSTARTADDR;
for(x=0; x<4*1024; x++)
{
wp[x] = x;
}
}
踩坑记录
1、图1中的SDRAM 1/SDRAM 2与地址映射空间没有关系。 2、SDRAM不同于SRAM,必须初始化后才可使用。 3、KEIL DEBUG时,for循环会作为一个整体,不会单次执行。所以for循环很长时,断点不触发,会被误认为程序跑飞。
|