关于FSMC与16位SRAM地址映射的小注记

2019-07-20 06:17发布

本帖最后由 学习stm32f4 于 2018-4-1 19:30 编辑

大家好。
在外部SRAM实验这一节,讲到了对于16位SRAM,FSMC地址线要向右移一位。
经过思考,我的理解如下:

如图1所示,FSMC与SRAM之间,有一个地址映射。
STM32要想读外部SRAM中地址为0x0000001里的数据,根据地址映射关系,单片机会从地址为0x6800 0002(这其实是FSMC的BANK1第3区中地址)中读一个16位数据。先以0x6800  0000这个地址为例,它分解成二进制是0110 1000 0000 0000 0000 0000 0000 0000,由于一个BANK是64M的地址空间,而2^25=64M,故0x6800 0000的位[25:0]是FSMC向外部SRAM传递的真实地址,对于0x6800 0000,FSMC向外部SRAM发的地址是位[25:0],即00 0000 0000 0000 0000 0000 0000。同理,对于0x6800 0002,FSMC向外部SRAM发送的地址是00 00000000 0000 0000 0000 0010。若FSMC不自动右移一位,这个地址明显发错了,因为期望读取的SRAM地址为0x0000 0001中的数据。为了解决这一问题,当在初始化FSMC时,若选择外部SRAM为16位,则FSMC在向外部SRAM发地址时,会自动右移一位,例如刚才的0x6800 0002,FSMC在向外部发SRAM地址时,00 0000 0000 0000 0000 0000 0010会自动右移一位,变成00 0000 00000000 0000 0000 0001,即0x0000 0001,该地址正好是期望的外部SRAM地址。接着,外部SRAM从地址为0x0000 0001中取出16位数据传送给FSMC,由FSMC将这个16位数据保存在以映射地址0x6800 0002起始的两个8位存储单元中。
另外,以0x6800 0000为例,它的位[25:0]就是HADDR[25:0],这26位直接连到了FSMC_A[25:0]。这26位直接决定了BANK中区的地址空间大小是64M。0x6800 0000的位[27:26],是10,这两位就是HADDR[27:26],根据图2所示,这即是第3区。0x6800 0000的位[30:29],是11,这两位表示BANK号,例如,BANK1是0110,即6。BANK2是0111,即7。BANK3是1000,即8。BANK4是1001,即9。如图3所示。
因为FSMC与外部SRAM有地址映射关系,所以在使用时,向地址为0x6800 0000的单元读写16位数据时,实际上是向SRAM地址为0x0000 0000的单元读写16位数据;向地址为0x6800 0002的单元读写16位数据时,实际上是向SRAM地址为0x0000 0001的单元读写16位数据。
例程中,FSMC_SRAM_WriteBuffer()和FSMC_SRAM_ReadBuffer()是按字节进行读写的,这实际上利用了FSMC的UB和LB引脚,根据UB和LB的电平,按字节依次将数据存在外部SRAM的高8位和低8位,或从外部SRAM中,依次从高8位和低8位读取字节存在FSMC里的地址映射单元中。
main函数中,testsram[]数组定义为u32类型,即u32 testsram[250000] __attribute__((at(0X68000000))),经过UB和LB的电平变化,FSMC会以4字节为单元向外部SRAM写入一个数据,或者以4字节为单位,从外部SRAM读取一个数据。每隔4字节表示一个数据,数组大小为250000,故存放u32类型的250000个数据,需要4*250000=100 0000个字节单元,这差不多是1M字节了。(1024*1024=104 8576
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。