你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32外扩SRAM

[复制链接]
STMCU小助手 发布时间:2022-1-22 10:45
这两天调试STM32F103外扩SRAM,将调试过程中遇到的问题记录下,SRAM的规格是256K*16的异步SRAM,地址总线为18,数据线宽度为16.
在调试过程中遇到一些小问题,希望读者能少走些弯路。
先看一下FSMC内存映射图:
由图可知,stm32的FSMC模块分为四个bank,每个bank的大小事64M。
' ?! T: `' I8 D$ B% t
171548350025.png
  |( _9 p7 m# Z! R$ z
下面这张图是FSMC各个块的信号分配图。

* r$ S* ]- h4 Q1 M  n0 Q; T
191817145197319.jpg

: L$ C" q* n, f: G. u
由上图可知,bank1 NOR/PSRAM可以分为4个子块,由FSMC_NE[4:1]来选择使能哪个子块。
例如:每小块NOR/PSRAM的64M地址范围如下:
第一块:6000 0000h--63ff ffffh
第二块:6400 0000h--67ff ffffh
第二块:6800 0000h--6bff ffffh
第三块:6c00 0000h--6fff ffffh
: D, Z: `2 U$ J7 B; v- a( ]% k
我们可以通过选择HADDR[27:26]来确定当前使用的是哪个64M的分地址块,如下图所示:

# g. ~; f8 N  C1 M" G: g
191630108304613.jpg

8 `% |8 y! i0 J+ z& z0 ~/ u
这里我使用的是100脚的stm32,只有NE1引脚可用,也就是说只能用Bank1的存储块1,即FSMC_Bank1_NORSRAM1。
我用的STM32是100脚的,地址和数据总线是复用的,那么需要用到锁存器来区分地址和数据,而锁存信号是NADV输出的,注意看图173和图174的NADV信号在输出地址时是低电平,输出数据时是高电平,所以锁存器要选择一个高电平锁存或者加个反向器。
在配置STM32的FSMC的寄存器时要注意下面两句话:
  1. //使能复用模式
    - j( I$ ?5 ~+ i' u/ r2 p
  2. FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Enable;
    $ B; `+ \0 k4 j3 ?' X( \
  3. //注意这里不是FSMC_MemoryType_SRAM而是FSMC_MemoryType_NOR,手册上说要想输出NADV信号只能设置成FSMC_MemoryType_NOR。; j$ P5 R# l3 `: l4 }! j4 X  x
  4. FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR
复制代码
16180153-96bc1b2eb65a4268b2e279ccc92df16e.png 8 p' {- O+ k, W
5 R3 U. ?* u* }' {: I9 u
16180201-e2fe4eed1ade4be2b5a38a161f6074a2.png & |$ n; O0 x+ ?. [' L5 g- |. E5 i' _
3 a$ U5 @' ~6 F. H8 w7 f
SRAM参考原理图如下图:
221338029278575.png
3 m+ w0 {& t* L/ Y* V7 B7 G+ n
stm32的FSMC功能用到的复用IO口比较多,配置时需要细点心:
  1. /*
    $ ~: s  V  K8 r5 s
  2. *PD14(DA0) PD15(DA1) PD0(DA2) PD1(DA3) PE7~PE15(DA4~DA12) PD8~PD10(DA13~DA15) PD11(A16) PD12(A17)
    - {7 s! x) _0 T+ Y
  3. *PD5(WE) PD7(NE1) PD4(OE)3 Q0 @2 H8 W1 D2 y# I' l4 _; o' h- {
  4. *PE0(BL0) PE1(BL1) NADV(PB7)
    ) [& F8 X3 Y. f& k& Z
  5. */6 w: c4 w; v9 v* L' Q& p, Z
  6. void sram_gpio_configration(void)
    6 N9 i( W  ~4 g3 V) j
  7. {
    & _3 I, m; G2 \' }; t8 g. _' g* Y  e
  8. GPIO_InitTypeDef GPIO_InitStructure;# G. @& s9 L5 m) o/ ^2 @1 B

  9. . s" U- J: o' p6 D$ c! B& k) v
  10. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 |
    ( z7 a( U2 g- x. T
  11.                                GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 |
    1 M& b6 s, @) [8 t$ m
  12.                                GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_14 | GPIO_Pin_15; " H; c) Q% z8 l8 I& D  Y2 Y/ m
  13. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    " t/ ]/ u  y5 [6 |$ L+ _
  14. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    6 l3 D! f2 @) Q1 F
  15. GPIO_Init(GPIOD, &GPIO_InitStructure);
    8 ^& A% c5 [& B$ t8 F6 g; B
  16. , d$ a1 [" G: v
  17. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_7 | GPIO_Pin_8 |
    ! C0 V% ~$ L" h: w. Q9 O5 X! r
  18.           GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 |. B2 C7 A, J  x; q8 g( f
  19.           GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;! X  r6 M, I+ t  X/ h1 M1 |
  20. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  % u, y( G. V& |: [1 q
  21. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;& r' I5 z: e& j* n' L
  22. GPIO_Init(GPIOE, &GPIO_InitStructure);' n/ O7 b5 g$ ~  B/ W

  23. ; Q) K) h6 [0 [) Z! l" ~! ]
  24. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
    ' \! m* ~( R% U3 b6 R5 ^. n
  25. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  
      X2 u' @) q2 I& \) b  T
  26. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;( \0 \+ T$ \# k/ E
  27. GPIO_Init(GPIOB, &GPIO_InitStructure);
    1 X  N$ l, @7 f5 F
  28. }
复制代码

- }7 {0 z! y# `( P, \
外部SRAM的访问:
在访问SRAM时纠结了许久,最后终于弄明白了。网上看了很多资料,有说在访问时要先将地址偏移,有说直接访问就行。最后经过测试发现访问片外SRAM时跟访问内部RAM一样,直接访问就可以了,FSMC都帮我们做好了。
当访问字节数据时:*((u8*)(BANK1_SRAM_BASE+offset))。1.读取SRAM数据时,将offset设为0x00,用示波器测试SRAM的A0地址信号是低,当offset为0x01时,用示波器测试SRAM的A0地址信号也是低,当offset为0x02和0x03时SRAM的A0地址信号是高,这说明当字节访问时地址确实是偏移了1位,原因是SRAM是16位器件(SRAM的1个地址存储16位数据),一次可以访问2个字节的数据,这个时候FSMC将根据offset值判断,访问的是高8位还是低8位,即如果offset的最低位是0则访问的是16位数据的低8位,如果offset的最低位是1则访问的是16位数据的高8位。2. 向SRAM写数据时,道理也是一样的,只是写的时候通过BL[1:0]两个管脚控制写高字节还是低字节。
当访问半字数据时:*((u16*)(BANK1_SRAM_BASE+offset))。1.读取SRAM数据时,这个时候要注意了,FSMC在访问的时候要看offset的值是不是半字对齐的。如果offset是0x00,则直接访问的是SRAM的0x00地址处的16位数据,当offset是0x01时,FSMC是分两次访问的,第一次是访问SRAM的0x00地址的高字节,第二次是访问SRAM的0x01地址处的低字节(SRAM的1个地址存储16位数据),通过用示波器测量SRAM的A0地址信号得到,信号是先低在高的一个脉冲,验证了前面的说法。2. 向SRAM写数据时,道理也是一样的,只是写的时候通过BL[1:0]两个管脚控制写高字节还是低字节。
当访问字数据时:访问字时,FSMC分为2个半字访问。
总结:外部SRAM就跟片内SRAM一样用就行了。

  W- s3 V% X7 d9 a" o9 A, W, i
赞 收藏 评论0 发布时间:2022-1-22 10:45

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版