STM32第十八课(FSMC,SRAM,HAL)
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之中。
+++++++++++++++++++++++++++++++
