OpenEdv-开源电子网

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

外部RAM实验:FSMC关于寄存器地址问题

[复制链接]

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
发表于 2013-3-24 20:41:07 | 显示全部楼层 |阅读模式
因为使用16位地址模式,所以FSMC输出地址右移一位,
//在指定地址开始,连续写入n个字节.
//pBuffer:字节指针
//WriteAddr:要写入的地址
//n:要写入的字节数
void FSMC_SRAM_WriteBuffer(u8* pBuffer,u32 WriteAddr,u32 n)
{
 for(;n!=0;n--) 
 {             
  *(vu8*)(Bank1_SRAM3_ADDR+WriteAddr)=*pBuffer;  
  WriteAddr+=2;//这里需要加2,是因为STM32的FSMC地址右移一位对其.加2相当于加1.
  pBuffer++;
 }  
}
针对这个函数,WriteAddr写入后输出地址其实会右移以为,那我们在写入时候是不是其实是实际ram地址左移一位先,来得到此函数参数WriteAddr。
比如要在ram的0x01写入,这里WriteAddr是不是应该是0x10啊?
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-3-24 21:27:02 | 显示全部楼层
回复【楼主位】wwjdwy:
---------------------------------
库函数的吧?你这个有点小问题。
看寄存器版本的:
//在指定地址(WriteAddr+Bank1_SRAM3_ADDR)开始,连续写入n个字节.
//pBuffer:字节指针
//WriteAddr:要写入的地址
//n:要写入的字节数
void FSMC_SRAM_WriteBuffer(u8* pBuffer,u32 WriteAddr,u32 n)
{
for(;n!=0;n--)  
{     
*(vu8*)(Bank1_SRAM3_ADDR+WriteAddr)=*pBuffer;   
WriteAddr++;
pBuffer++;
}   
}     
//在指定地址((WriteAddr+Bank1_SRAM3_ADDR))开始,连续读出n个字节.
//pBuffer:字节指针
//ReadAddr:要读出的起始地址
//n:要写入的字节数
void FSMC_SRAM_ReadBuffer(u8* pBuffer,u32 ReadAddr,u32 n)
{
for(;n!=0;n--)  
{     
*pBuffer++=*(vu8*)(Bank1_SRAM3_ADDR+ReadAddr);    
ReadAddr++;
}  
}
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
 楼主| 发表于 2013-3-25 09:50:17 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
+2 变成了++???
原子哥能不能解释一下啊。
我上面关于WriteAddr 的理解对不对啊。因为FSMC里面要右移一位,我是不是应该先左移一位,才能算是这里参数WriteAddr

比如要在ram的0x01写入,这里WriteAddr是不是应该是0x10啊?
回复 支持 反对

使用道具 举报

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
 楼主| 发表于 2013-3-25 10:18:53 | 显示全部楼层
回复【2楼】正点原子:
---------------------------------
原子哥,还有一个小问题,也是关于地址的,在手册4.6节,讲MDK中地址映射,两个相邻寄存器之间的偏移都是0X04,这是因为寄存器都是32位,32/8=4byte么?

在sram中地址都是偏移0x01,这是因为512k*16位=1MB,我们寻址时候只寻址512k的数据量。而上面寄存器映射的寻址如果也是1MB空间,我们就相当于寻址1MB的数据量。

这样理解对么?
看的有点晕晕的,自己琢磨了很久,不知道我的理解有没有想歪
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-3-25 16:17:47 | 显示全部楼层
回复【3楼】wwjdwy:
---------------------------------
这里是因为SRAM用了FSMC的UB/LB信号,控制字节高地位了。
因为SRAM是16位的,当你要读写8位数据的时候,UB/LB就发挥作用了,比如在SRAM的地址0写入1个8位的字节,那么LB会输出有效,而UB则保持不变(高电平),表示写入地址0的低8位,写法就是:
*(vu8*)(Bank1_SRAM3_ADDR+0)=0Xaa;//0XAA是你想写入的字节。
而如果要在SRAM地址0写入高8位,那么对于STM32来说,地址就相应加1即可,即:
*(vu8*)(Bank1_SRAM3_ADDR+1)=0XAA;
此时LB会输出高电平,UB会输出有效电平(低电平),表示写入地址0,的高字节。
这样,对STM32来说,地址就是连续的了,0,1,2,3,4,5,都是合法的了,自然就不需要你的地址右移对齐了,硬件通过UB/LB去控制了。

回复【4楼】wwjdwy:
---------------------------------
32位就是占4字节的。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
 楼主| 发表于 2013-3-25 20:36:38 | 显示全部楼层
回复【5楼】正点原子:
---------------------------------
谢谢原子哥这么耐心的讲解,看懂了。
1,地址映射里的地址偏移每个寄存器都是便宜0x04,是因为每个寄存器32位四字节。
2,那我的SRAM要在地址1写入呢?写入地址1的低字节就是*(vu8*)(Bank1_SRAM3_ADDR+2),写入地址1的高字节就是*(vu8*)(Bank1_SRAM3_ADDR+3)???
一次写入一个16位的数据呢?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-3-25 20:50:07 | 显示全部楼层
回复【6楼】wwjdwy:
---------------------------------
2,是的,如果一次写入16位数据,直接就在地址0写入,之后就是地址2,再是地址4
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-3-25 20:50:12 | 显示全部楼层
以此类推
回复 支持 反对

使用道具 举报

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
 楼主| 发表于 2013-3-25 21:01:15 | 显示全部楼层
回复【7楼】正点原子:
---------------------------------
那写入的是8位数据,就相当于把地址从512k变成了1M,可以连续的写地址0,1,2,3,。。。。,512,。。。。1023,1024
写入16位数据时候,地址0,2,4,6,8,10.....512,。。。。1024。也就可以理解为0,1,2,3.。。512连续地址左移一位变成了0,2,4,6,8,.....512,。。。。1024

那这个地址+1或者+2要根据写入数据是8位还是16位来确定喽?

void FSMC_SRAM_WriteBuffer(u8* pBuffer,u32 WriteAddr,u32 n)
{
 for(;n!=0;n--)  
 {              
  *(vu8*)(Bank1_SRAM3_ADDR+WriteAddr)=*pBuffer;   
  WriteAddr+=2;//这里需要加2,是因为STM32的FSMC地址右移一位对其.加2相当于加1.
  pBuffer++;
 }   
}

这里u8* pBuffer,所以WriteAddr++才对,是这么理解吧

我比较弱,劳烦原子哥了嘿嘿
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-3-26 00:31:50 | 显示全部楼层
回复【9楼】wwjdwy:
---------------------------------
是的
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
 楼主| 发表于 2013-3-26 09:43:58 | 显示全部楼层
回复【10楼】正点原子:
---------------------------------
总算开始有点入门的感觉了嘿嘿!多谢啊。
对了原子哥你们做其他ARM开发板或者外包活么?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-3-26 11:06:49 | 显示全部楼层
回复【11楼】wwjdwy:
---------------------------------
没。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手上路

积分
24
金钱
24
注册时间
2013-5-14
在线时间
0 小时
发表于 2013-5-14 09:54:03 | 显示全部楼层
你好,我发现开发板原理图上,外扩sram:IS62WV51216 的管脚定义,比如  A0、A1、A2  和这个芯片的PDF文档不一致,是不是这个芯片地址管脚就可以这样用,还是别的什么问题啊?我想按照原理图扩展一片sram,可是这个让我很迷惑,请指教,谢谢
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2013-5-14 09:58:16 | 显示全部楼层
回复【13楼】yelang21:
---------------------------------
是不一致,但是用起来没问题的,因为地址的唯一性决定了。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

0

主题

3

帖子

0

精华

新手上路

积分
24
金钱
24
注册时间
2013-5-14
在线时间
0 小时
发表于 2013-5-14 10:04:19 | 显示全部楼层
也就是说,芯片的地址管脚可以按照自己的布局方便任意使用了,我明白了,谢谢您的解惑。
回复 支持 反对

使用道具 举报

10

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
106
金钱
106
注册时间
2012-7-7
在线时间
2 小时
发表于 2014-5-15 17:33:48 | 显示全部楼层
回复【5楼】正点原子:
---------------------------------
我也明白了,如果给*(u8 *)(地址)=赋的值,则就给地址上的数据赋8位值,同时如果是设置的16位数据,ubl和ubh就起作用了
如果用*(u16 *)(地址)=赋的值,则就给地址上的数据赋16位值,而且地址要在HADDR[25:1]上,HADDR[0]不起作用。ubl和ubh一直都是高电平
回复 支持 反对

使用道具 举报

10

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
106
金钱
106
注册时间
2012-7-7
在线时间
2 小时
发表于 2014-5-15 17:35:02 | 显示全部楼层
回复【16楼】heiselpy:
---------------------------------
ubl就是NLB引脚
ubh就是NUB引脚
回复 支持 反对

使用道具 举报

10

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
106
金钱
106
注册时间
2012-7-7
在线时间
2 小时
发表于 2014-5-15 17:36:24 | 显示全部楼层
回复【17楼】heiselpy:
---------------------------------
ubl就是NLB引脚  就是FSMC_NBL0
ubh就是NUB引脚 就是FSMC_NBL1
回复 支持 反对

使用道具 举报

15

主题

181

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
389
金钱
389
注册时间
2014-11-8
在线时间
40 小时
发表于 2015-3-25 20:13:35 | 显示全部楼层
回复【9楼】wwjdwy:
---------------------------------
那写入的是8位数据,就相当于把地址从512k变成了1M,可以连续的写地址0,1,2,3,。。。。,512,。。。。1023,1024
写入16位数据时候,地址0,2,4,6,8,10.....512,。。。。1024。也就可以理解为0,1,2,3.。。512连续地址左移一位变成了0,2,4,6,8,.....512,。。。。1024

请问为什么 “512连续地址左移一位变成了0,2,4,6,8,.....512,。。。。1024”?
1.在16位传输数据的时候不是右移吗?
2.这句话是什么意思?
本人初次接触fsmc,求指教
Good good study , day day up...
回复 支持 反对

使用道具 举报

15

主题

181

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
389
金钱
389
注册时间
2014-11-8
在线时间
40 小时
发表于 2015-3-25 20:30:41 | 显示全部楼层
回复【9楼】wwjdwy:
---------------------------------
这是转的,原文地址    http://www.openedv.com/posts/list/0/33759.htm

这里说一下我对FSMC地址操作的一点认识

首先说一个前提:STM32 单片机的一个地址(如:0x20000000)是一个字节
也就是说如果定义一个16位数组 u16 temp[5]  如果temp对应的地址是0x00000000 那么temp+1对应的地址是0x00000002 (地址是加2)

假设此时我们有一个 64K*8bit 的sram
那很简单 stm32的A0~A15 与存储器A0~A15连接 大家很容易理解

若此时是 64K*16bit 的sram
也就是此时sram的一个地址对应两个字节 但是stm32是一个地址一个字节 这就出现了对准的问题
如果我们的地址线依然是stm32A0~A15 和 存储器的A0~A15 连接 
如果stm32要从sram中读取前面提到数组中的temp[1]
stm32会给出0x0002(二进制地址0000000000000010b) 可是对于我们这个sram来说 读到却是temp[2],因为sram一个地址就是一个16位数据 
为了解决这个问题 我们只需要在给sram送地址时 右移一位 再送地址 即可(sram的一个地址对应stm32两个地址的数据)
比如读取0x0002 右移一位(即除2)为0x0001(0000000000000010b) 此时对应的就是temp[1]
而为了给用户提供方便 如果你选择的是16位宽度的sram FSMC会在你送地址的时候自动为你做右移一位的操作 
此时会有另外一个问题 每次都右移一位 A0没用吗 也即只能读写偶地址的数据吗?
这也就是NBL0和NBL1的作用了 如果你要进行字节操作 
如stm32发送地址0x0001读取一个字节 右移一位对应的是sram地址0x0000处的16位数据 FSMC会根据AO 来控制NBLO和NBL1为10 读取高字节数据
所以呢  偶字节读写时仅NBL0有效,奇字节读写时仅NBL1有效 字读写都有效(低电平有效)
请问楼主是如何理解上面这段话的?
Good good study , day day up...
回复 支持 反对

使用道具 举报

54

主题

537

帖子

0

精华

高级会员

Rank: 4

积分
797
金钱
797
注册时间
2012-2-27
在线时间
7 小时
 楼主| 发表于 2015-3-26 09:12:49 | 显示全部楼层
回复【20楼】Just Beat It:
---------------------------------
两年了,实在是想不起来了,抱歉啊
回复 支持 反对

使用道具 举报

15

主题

181

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
389
金钱
389
注册时间
2014-11-8
在线时间
40 小时
发表于 2015-3-26 09:41:17 | 显示全部楼层
回复【21楼】wwjdwy:
---------------------------------
恩恩,好的,我再查查资料
Good good study , day day up...
回复 支持 反对

使用道具 举报

1

主题

3

帖子

0

精华

新手入门

积分
27
金钱
27
注册时间
2015-1-31
在线时间
0 小时
发表于 2015-5-16 22:29:20 | 显示全部楼层
回复【10楼】正点原子:
---------------------------------
请问,原子哥——
这里*(vu8*)(Bank1_SRAM3_ADDR+WriteAddr)=*pBuffer;跟FSMC_NSInitStructure.FSMC_MemoryDataWidth=FSMC_MemoryDataWidth_16b; //存储器数据宽度为16bit   
的数据长度为什么可以不一样?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-5-16 23:11:21 | 显示全部楼层
回复【23楼】lcp:
---------------------------------
因为有NBL0,NBL1控制。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-22 11:03

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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