OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 9461|回复: 12

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

[复制链接]

94

主题

369

帖子

0

精华

高级会员

Rank: 4

积分
865
金钱
865
注册时间
2016-8-25
在线时间
485 小时
发表于 2018-4-1 18:41:23 | 显示全部楼层 |阅读模式
本帖最后由 学习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

2.jpg
3.jpg
1.jpg
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

2

主题

8

帖子

0

精华

初级会员

Rank: 2

积分
51
金钱
51
注册时间
2018-4-1
在线时间
10 小时
发表于 2018-4-21 15:26:00 | 显示全部楼层
你讲的很详细!看了原子哥的视频,没弄懂,看了你的理解,懂了!谢谢楼主!
回复 支持 反对

使用道具 举报

1

主题

23

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
456
金钱
456
注册时间
2017-9-4
在线时间
70 小时
发表于 2018-5-6 22:36:49 | 显示全部楼层
有点懂了
回复 支持 反对

使用道具 举报

6

主题

105

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
368
金钱
368
注册时间
2018-8-31
在线时间
115 小时
发表于 2018-8-31 21:16:00 | 显示全部楼层
,对于0x6800 0002,FSMC向外部SRAM发送的地址是00 00000000 0000 0000 0000 0010。若FSMC不自动右移一位,这个地址明显发错了,因为期望读取的SRAM地址为0x0000 0001中的数据。
这句是为什么??
回复 支持 反对

使用道具 举报

6

主题

105

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
368
金钱
368
注册时间
2018-8-31
在线时间
115 小时
发表于 2018-8-31 21:20:50 | 显示全部楼层
“”,向地址为0x6800 0000的单元读写16位数据时,实际上是向SRAM地址为0x0000 0000的单元读写16位数据;向地址为0x6800 0002的单元读写16位数据时,实际上是向SRAM地址为0x0000 0001的单元读写16位数据。
“”不明白啊。我知道单片机一个地址表示一个字节,到SRAM一个地址处理2个字节,所以HDDR内部线地址转换的时候到FSMC就少了一位,不过不明白为啥  “为啥0000对应FSMC_A[0]=0   (2字节),为啥0010对应FSMC_A[0]=1   (2字节)”
回复 支持 反对

使用道具 举报

94

主题

369

帖子

0

精华

高级会员

Rank: 4

积分
865
金钱
865
注册时间
2016-8-25
在线时间
485 小时
 楼主| 发表于 2018-8-31 21:58:21 | 显示全部楼层
长昵称不被占用 发表于 2018-8-31 21:16
,对于0x6800 0002,FSMC向外部SRAM发送的地址是00 00000000 0000 0000 0000 0010。若FSMC不自动右移一位, ...

FSMC与外部SRAM之间,存在地址映射。理解成排线直连吧。STM32通过操作FSMC的映射地址,来达到操作SRAM的目的。
若不右移一位,SRAM接收到的地址是0x10,而期望的地址是0x01。
回复 支持 反对

使用道具 举报

94

主题

369

帖子

0

精华

高级会员

Rank: 4

积分
865
金钱
865
注册时间
2016-8-25
在线时间
485 小时
 楼主| 发表于 2018-8-31 22:02:00 | 显示全部楼层
长昵称不被占用 发表于 2018-8-31 21:20
“”,向地址为0x6800 0000的单元读写16位数据时,实际上是向SRAM地址为0x0000 0000的单元读写16位数据;向 ...

还是FSMC与SRAM之间有地址映射,FSMC与16位SRAM进行地址映射时,STM32发送给FSMC的地址,FSMC将此地址右移一位发送给SRAM。
回复 支持 反对

使用道具 举报

6

主题

105

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
368
金钱
368
注册时间
2018-8-31
在线时间
115 小时
发表于 2018-9-1 08:52:40 | 显示全部楼层
学习stm32f4 发表于 2018-8-31 22:02
还是FSMC与SRAM之间有地址映射,FSMC与16位SRAM进行地址映射时,STM32发送给FSMC的地址,FSMC将此地址右 ...

可不可以这样理解:
mcu在BANK1的第一块区域有自己的地址,这个地址并没有发送给SRAM,只是用来标记,mcu自己明白这个地址是多少。然后对LCD读数据的时候请求LCD某个地址的数据的时候,用A10(RS)的高低电平来区分是LCD——REG请求还是LCD_RAM请求,之后就是通过16个数据口发送请求数据的地址,然后等待指定时间来取数据??
回复 支持 反对

使用道具 举报

6

主题

105

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
368
金钱
368
注册时间
2018-8-31
在线时间
115 小时
发表于 2018-9-1 08:57:26 | 显示全部楼层
学习stm32f4 发表于 2018-8-31 21:58
FSMC与外部SRAM之间,存在地址映射。理解成排线直连吧。STM32通过操作FSMC的映射地址,来达到操作SRAM的 ...

FSMC_A[0]=0   (2字节),为啥0010对应FSMC_A[0]=1   (2字节)
这里的FSMC_A[0]=0  等于0表示什么?,后来FSMC_A[0]=1    等于1表示什么?为啥不等于0了
回复 支持 反对

使用道具 举报

6

主题

105

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
368
金钱
368
注册时间
2018-8-31
在线时间
115 小时
发表于 2018-9-1 09:07:33 | 显示全部楼层
又从新看了一遍您的帖子,想明白了你说的地址映射,不明白的是用famc的数据口接LCD的数据口(16位),访问某个地址上的数据,地址和数据都是通过这16位来复用实现先后发送接收的把??请讲一下mcu请求某个地址然后读取某个地址上数据的工作过程吗
回复 支持 反对

使用道具 举报

94

主题

369

帖子

0

精华

高级会员

Rank: 4

积分
865
金钱
865
注册时间
2016-8-25
在线时间
485 小时
 楼主| 发表于 2018-9-1 14:25:34 | 显示全部楼层
长昵称不被占用 发表于 2018-9-1 09:07
又从新看了一遍您的帖子,想明白了你说的地址映射,不明白的是用famc的数据口接LCD的数据口(16位),访问 ...

建议将原子哥的视频多看几遍,我当初是看了不下4、5遍,然后再在论坛里翻翻帖子,看看别人的分享的。
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

新手上路

积分
26
金钱
26
注册时间
2019-7-3
在线时间
10 小时
发表于 2020-4-13 16:35:52 | 显示全部楼层
顶帖,STM32一个地址存储8位数据,而SRAM一个地址存储16位,有点明白了。。。
回复 支持 反对

使用道具 举报

41

主题

113

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
208
金钱
208
注册时间
2019-8-20
在线时间
83 小时
发表于 2020-4-30 16:35:15 | 显示全部楼层
MARK!!!!!!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-2-28 06:53

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表