当 Bank1 接的是 16 位宽度存储器的时候:HADDR[25:1]
FSMC_A[24:0]。
当 Bank1 接的是 8 位宽度存储器的时候:HADDR[25:0]
FSMC_A[25:0]。
学习正点原子的STM32时,TFTLCD显示实验用到了FSMC,对上面的内容不是很明白,看了很多帖子,感觉应该理解对了,写篇文章记录一下。
STM32的FSMC 总共管理 1GB 空间,拥有 4 个存储块(Bank),每个块支持的存储器类型不一样,FSMC 存储块地址映像如下图1所示。
图1 FSMC 存储块地址映像
这个我是这么理解的,STM32通过FSMC可以扩展1GB的片外存储器。
STM32 的 FSMC 存储块 1(Bank1)又被分为 4 个区,每个区管理 64M 字节空间,从4x64MB就可以看出4个区每个区有64M字节空间。每个区都有独立的寄存器对所连接的存储器进行配置。Bank1 的 256M 字节空间由 28 根地址线 (HADDR[27:0])寻址。如下图2所示。
图2
我们就看Bank1的第1区,后面的内容都是以这个区来讲,它的地址范围是0x6000,0000~0x63FF,FFFF,总共有0x3FFFFFF+1个地址。(0 ~ 3FF FFFF)
0x3FFFFFF = 0011 1111 1111 1111 1111 1111 1111 =67108863。
0011 1111 1111 1111 1111 1111 1111中的00刚好对应HADDR[27:26],剩下的1对应HADDR[25:0]
STM32通过HADDR的67018864个地址来管理64MB的空间,每个地址就管理一个字节的空间,可以理解成一个地址能存储一个字节的数据。为什么这样?如下面的等式可知:
1B=8bit (1个字节=8个比特/位)
1KB=1024B
1MB=1024KB
64(MB)=64x1024(KB)=65536x1024(B)=67108864(B)
外接8 位宽度存储器读取一个地址的数据时,返回的是一个字节的数据,HADDR的一个地址刚好可以存储一个字节的数据,所以不需要移位。访问第1、第2、第3....、第n个地址时HADDR的状态如下所示。
访问存储器的第几个地址 | HADDR的状态 | FSMC_A的状态 |
0 | 0b 00 0000 0000 0000 0000 0000 0000 | 0b 00 0000 0000 0000 0000 0000 0000 |
1 | 0b 00 0000 0000 0000 0000 0000 0001 | 0b 00 0000 0000 0000 0000 0000 0001 |
2 | 0b 00 0000 0000 0000 0000 0000 0010 | 0b 00 0000 0000 0000 0000 0000 0010 |
3 | 0b 00 0000 0000 0000 0000 0000 0011 | 0b 00 0000 0000 0000 0000 0000 0011 |
... | ... | ... |
外接16位宽度存储器读取一个地址的数据时,返回的是两个字节的数据,HADDR的一个地址刚好可以存储一个字节的数据,无法存储两个字节的数据怎么办?只能把第二个字节的数据存储到HADDR的第二个地址。这个时候,为了方便操作,FSMC在硬件设计上就提供了一种解决办法,将内部数据总线HADDR[25:0]错位后接到FSMC_A地址引脚上,“丢弃”地址的bit-0,从bit-1开始对地址计数即HADDR[25:1] FSMC_A[24:0]。
可以这么理解,读取16位宽度存储器的第一个地址的数据时,返回的数据有两个字节把HADDR的地址0b 0000 0000 0000 0000 0000 0000 0000 和 0b 0000 0000 0000 0000 0000 0000 0001管理的空间占了。如下表所示,表中蓝色字体的位是HADDR[0],在外接16位宽度存储器时不与FSMC_A有连接。读取第一个地址的数据后,读取第二个地址的数据时HADDR[25:0]的状态为
0b 00 0000 0000 0000 0000 0000 0010。
访问存储器的第几个地址 | HADDR的状态 | FSMC_A的状态 |
0 | 0b 00 0000 0000 0000 0000 0000 0000 | 0b 0 0000 0000 0000 0000 0000 0000 |
0b 00 0000 0000 0000 0000 0000 0001 | ||
1 | 0b 00 0000 0000 0000 0000 0000 0010 | 0b 0 0000 0000 0000 0000 0000 0001 |
0b 00 0000 0000 0000 0000 0000 0011 | ||
2 | 0b 00 0000 0000 0000 0000 0000 0100 | 0b 0 0000 0000 0000 0000 0000 0010 |
0b 00 0000 0000 0000 0000 0000 0101 |
这就是我的理解,估计也没讲明白,虚心请求指正!