XM8A51216 的 A[0:18]并不是按顺序连接 STM32F4 的 FMSC_A[0:18],不过这并不影响我们正常使用外部 SRAM,因为地址具有唯一性。
这样设计的好处,就是可以方便我们的 PCB 布线。
使用 FSMC 的 BANK1 的sector3 来控制 XM8A51216,
因为 XM8A51216 的读写时间基本一致,所以,我们设置读写相同的时序来访问 FSMC。
++++++++++++++++++++++++++++++++++++++
使能 FSMC 时钟,并配置 FSMC 相关的 IO 及其时钟使能。
使用 FSMC,当然首先得开启其时钟。
使能 FSMC 时钟的方法为:
__HAL_RCC_FSMC_CLK_ENABLE();
配置 IO 口为复用输出的关键行代码为:
GPIO_Initure.Mode=GPIO_MODE_AF_PP; //推挽复用
GPIO_Initure.Alternate=GPIO_AF12_FSMC; //复用为 FSMC
设置 FSMC BANK1 区域 3 的相关寄存器。
使用模式 A、16 位宽,读写共用一个时序寄存器。 这个是通过调用函数 HAL_SRAM_Init 来实现的,函数原型为:
HAL_StatusTypeDef HAL_SRAM_Init(SRAM_HandleTypeDef *hsram,
FMC_NORSRAM_TimingTypeDef *Timing, FMC_NORSRAM_TimingTypeDef *ExtTiming)
使用的是 BANK1 的区域 3,所以 HADDR[27:26]=10,故外部内存的首地址为0X68000000。
+++++++++++++++++++++++++++++++++++++
FSMC 固 件 库 文 件 stm32f4xx_fsmc.c 和stm32f4xx_fsmc.h 文件。
+++++++++++++++++++++++++++++++++++++
实战,
在cubemx中,配置sram。
选择bank1的第二个chip,
选择NE3,
设置addr 为 19bits,
设置datawidth为16bits,
设置wait 为disable,
选择byte enable,
设置write operation为enable,
设置extended 为 disable,
设置addr setup为 2个Hclk,
设置data setup为 3个Hck,
设置bus turn around 为 0个Hclk.
++++++++++++++++++++++++++++++++++++
需要编写自建实用库,
void FSMC_SRAM_WriteBuffer(u8 *pBuffer,u32 WriteAddr,u32 n)
{
for(;n!=0;n--)
{
*(vu8*)(Bank1_SRAM3_ADDR+WriteAddr)=*pBuffer;
WriteAddr++;
pBuffer++;
}
}
void FSMC_SRAM_ReadBuffer(u8 *pBuffer,u32 ReadAddr,u32 n)
{
for(;n!=0;n--)
{
*pBuffer++=*(vu8*)(Bank1_SRAM3_ADDR+ReadAddr);
ReadAddr++;
}
}
++++++++++++++++++++++++++++++++
在main中添加任务代码
u32 testsram[2048] __attribute__((at(0X68000000)));//测试用数组
sram_temp_wr = 0xabcd;
FSMC_SRAM_WriteBuffer((u8*)&sram_temp_wr, (u32)0x00000004,2);
FSMC_SRAM_ReadBuffer((u8*)&sram_temp_rd, (u32)0x00000004,2);
LCD_ShowxNum(130,200,sram_temp_wr,6,32,0);
LCD_ShowxNum(130,240,sram_temp_rd,6,32,0);
LCD_ShowxNum(130,280,testsram[1],16,32,0);
这里,使用了一个GUN C的扩展特性,就是
attribute-at,
__attribute__((at(0X68000000)))
编译时,为变量或者数组指定分配的基地址。
在这里,我们为数组指定基地址,明确表示,
当我们对该数组读写时,读写操作发生在base 为 0x68000000的地址段,
也就是说,是位于SRAM之中。
+++++++++++++++++++++++++++++++