OpenEdv-开源电子网

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

STM32F103使用FSMC外扩SRAM 写字节时出错,求助

[复制链接]

5

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2014-2-28
在线时间
2 小时
发表于 2014-2-28 11:18:30 | 显示全部楼层 |阅读模式
改动官方例程,使用STM32F103VCT(100pin),is61LV51216的SRAM,8M,FSMC配置如下:

#define Bank1_SRAM3_ADDR    ((u32)0x68000000)
    void FSMC_SRAM_Init(void)
{
  FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
  FSMC_NORSRAMTimingInitTypeDef  p;
  GPIO_InitTypeDef GPIO_InitStructure; 
  
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOE , ENABLE);
  
/*-- GPIO Configuration ------------------------------------------------------*/
  /* SRAM Data lines configuration */


  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 |
                                GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(GPIOE, &GPIO_InitStructure); 
  
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 |
                                 GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
                                
  GPIO_Init(GPIOE, &GPIO_InitStructure);
  
  /* SRAM Address lines configuration  */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | 
                                GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;  
                                
  GPIO_Init(GPIOD, &GPIO_InitStructure);
  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11 | 
                                GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
  GPIO_Init(GPIOD, &GPIO_InitStructure);
  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8; 
  GPIO_Init(GPIOC, &GPIO_InitStructure);
   
  /* NOE and NWE configuration */  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 |GPIO_Pin_11;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
  
  /* NE3 configuration */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; 
  GPIO_Init(GPIOC, &GPIO_InitStructure);
  
  /* NBL0, NBL1 configuration */ 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5; 
  GPIO_Init(GPIOC, &GPIO_InitStructure);  

 RCC -> AHBENR |= 0x00000114;       使能FSMC时钟
  
/*-- FSMC Configuration ------------------------------------------------------ */
  p.FSMC_AddressSetupTime = 2;
  p.FSMC_AddressHoldTime = 0;
  p.FSMC_DataSetupTime = 3;
  p.FSMC_BusTurnAroundDuration = 1;
  p.FSMC_CLKDivision = 0;
  p.FSMC_DataLatency = 0;
  p.FSMC_AccessMode = FSMC_AccessMode_A;

  FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM3;
  FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;  //地址/数据不复用
  FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;  //存储器类型
  FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;  //数据宽度
  FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode = FSMC_BurstAccessMode_Disable;  //成组模式访问
  FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity = FSMC_WaitSignalPolarity_Low;  //等待信号极性
  FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;  //对齐成组模式
  FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive = FSMC_WaitSignalActive_BeforeWaitState;  //配置等待时序
  FSMC_NORSRAMInitStructure.FSMC_WriteOperation = FSMC_WriteOperation_Enable;   //允许FSMC对存储器写操作
  FSMC_NORSRAMInitStructure.FSMC_WaitSignal = FSMC_WaitSignal_Disable;   //等待使能位  禁止
  FSMC_NORSRAMInitStructure.FSMC_ExtendedMode = FSMC_ExtendedMode_Disable;   //扩展模式选择
  FSMC_NORSRAMInitStructure.FSMC_AsyncWait = FSMC_AsyncWait_Disable;   //
  FSMC_NORSRAMInitStructure.FSMC_WriteBurst = FSMC_WriteBurst_Disable;   //成组写使能选择
  FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;   //
  FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;   //

  FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);   

  /* Enable FSMC Bank1_SRAM Bank  */
  FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM3, ENABLE);  
}

写字节函数:
void FSMC_SRAM_WriteBuffer(u16* pBuffer, u32 WriteAddr, u32 NumHalfwordToWrite)
{
  for(; NumHalfwordToWrite != 0; NumHalfwordToWrite--) /* while there is data to write */
  {
    /* Transfer data to the memory */
    *(u16 *) (Bank1_SRAM3_ADDR + WriteAddr) = *pBuffer++;
    
    /* Increment the address*/  
    WriteAddr += 2;
  }   
}

问题来了:我在仿真的时候观察地址中写入的数据时发现,一进入写字节函数0X68008000以后的地址全都是0x1FF0,


执行完 *(u16 *) (Bank1_SRAM3_ADDR + WriteAddr) = *pBuffer++;这条语句后, 0X68008000以后的地址全都被写入0x3212,

0x3212这个数写的是对的,但是为什么0x68008000以后的地址全都被写成0x3212啊?
另外,再执行 for(; NumHalfwordToWrite != 0; NumHalfwordToWrite--)  时, 0X68008000以后的地址又全都写入0x1FF0, 导致最后读出的数据全是0X1FF0,看写字节函数中应该是1个字一个字写呀,为什么写完之后全被0x1FF0覆盖呀,求教,不胜感激





正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2014-2-28 15:13:02 | 显示全部楼层
你用100pin的去扩展SRAM?
用144的多好,呵呵。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

5

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2014-2-28
在线时间
2 小时
 楼主| 发表于 2014-2-28 15:31:13 | 显示全部楼层
我这有现成的100PIN啊,不用采购了,现在关键是我写字节的时候不能一个一个写,读出的时候没问题,可以一个一个读出,并且读出的数据也对,原子哥求教了
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2014-2-28 21:23:43 | 显示全部楼层
回复【4楼】single104:
---------------------------------
你怎么接线的?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

5

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2014-2-28
在线时间
2 小时
 楼主| 发表于 2014-3-1 10:19:48 | 显示全部楼层
 我用E口接数据总线,D口的16个脚和C口的三个脚接地址总线,C口的5个脚接SRAM的控制脚,如下图:



接线应该不会有问题吧?我用万用表都量了一遍SRAM和stm32的连线,都是通的没问题,而且我把地址、数据的建立、保持时间都配置大点试过,也不行,求教,谢谢
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2014-3-1 14:36:01 | 显示全部楼层
你没用锁存器???
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

5

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2014-2-28
在线时间
2 小时
 楼主| 发表于 2014-3-1 15:47:37 | 显示全部楼层
???必须要用锁存器吗,我这是参考我们公司另一个项目中用到这个SRAM了,但他MCU用的不是stm32 的,他就直接接的SRAM
回复 支持 反对

使用道具 举报

5

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2014-2-28
在线时间
2 小时
 楼主| 发表于 2014-3-3 16:05:50 | 显示全部楼层
原子哥,我改动你开发板上的例程试了试,也不行,也是要写就全都写入了,用示波器查了一下地址总线,发现A4,A5,A7老是保持高电平,其他地址都是低电平,不科学啊
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2014-3-3 21:24:31 | 显示全部楼层
回复【9楼】single104:
---------------------------------
当然不行了,必须用锁存器啊,你地址低16位和数据线共用了,不用锁存器怎么行...
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

5

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2014-2-28
在线时间
2 小时
 楼主| 发表于 2014-3-4 08:53:24 | 显示全部楼层
可是我的地址低16位接的是D口,数据接的是E口,这算是复用吗?而且我在BCR3->MUXEN中设置的是地址/数据不服用啊,没想清楚怎么共用了,能再给指点一下吗
回复 支持 反对

使用道具 举报

5

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2014-2-28
在线时间
2 小时
 楼主| 发表于 2014-3-4 09:46:44 | 显示全部楼层
我仿真查了一下,在FSMC初始化函数中,地址线的A4,A5,A7总是在使能FSMC时钟,并且设置相应的I/O口为复用推挽输出后,就保持高电平不变了,初始化后一直保持高电平不变,这样地址总线不变的话,数据肯定写不对,但不知道是哪儿的问题,用官方例程和原子哥开发板的例程,都存在这种情况,请高手们给指点指点,不胜感激
回复 支持 反对

使用道具 举报

5

主题

16

帖子

0

精华

初级会员

Rank: 2

积分
66
金钱
66
注册时间
2014-2-28
在线时间
2 小时
 楼主| 发表于 2014-3-4 11:10:04 | 显示全部楼层
知道问题在哪儿了,我下载的那个STM32F103XX的资料的管脚定义误导我了,没有标FSMC的复用功能,所以我以为103vc的FSMC是地址和数据不复用的,直接自己定义了FSMC的数据和地址管脚,汗...,不过谢谢原子哥这两天不胜其烦的指点
再请教一下原子哥,我现在板子已经画成这样了,不知道撇开FSMC功能,模拟IS的时序实现外扩,行不行?您有没有这方面的资料,有的话方不方便给小弟发一份,邮箱49005646@qq.com,谢谢!
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2014-3-4 17:04:14 | 显示全部楼层
回复【13楼】single104:
---------------------------------
100脚的stm32,是没有地址线A0~A15的,是和数据线复用,如果没锁存器,你这板基本废了,除非不用外部SRAM了。
重画PCB吧。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

17

主题

37

帖子

0

精华

初级会员

Rank: 2

积分
138
金钱
138
注册时间
2012-5-21
在线时间
3 小时
发表于 2015-2-13 16:49:33 | 显示全部楼层
回复【14楼】正点原子:
---------------------------------
原子哥,有个问题,如果我要用100pin的stm32采用FSMC复用方式,就一定要地址锁存器,能不能推荐一下用哪种锁存器?因为我发现,FSMC的NADV信号是先低电平是地址,变高电平时是数据。可最常用的锁存器74HC573的锁存信号LE在低电平时锁存。也就是我的NADV需要通过一个反向器再接到LE才行,可是接个反向器就要多延时几十ns,网上找半天没有FSMC复用的原理图,不知道原子哥用过没?用的什么锁存器?
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165524
金钱
165524
注册时间
2010-12-1
在线时间
2116 小时
发表于 2015-2-13 22:58:23 | 显示全部楼层
回复【15楼】sundonga:
---------------------------------
没得推荐.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

4

主题

15

帖子

0

精华

初级会员

Rank: 2

积分
75
金钱
75
注册时间
2013-7-8
在线时间
5 小时
发表于 2016-2-27 11:55:05 | 显示全部楼层
正点原子 发表于 2015-2-13 22:58
回复【15楼】sundonga:
---------------------------------
没得推荐.

用100pin的VET系列不能用16位的这个SRAM么?
回复 支持 反对

使用道具 举报

27

主题

78

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
225
金钱
225
注册时间
2015-12-17
在线时间
44 小时
发表于 2016-3-2 11:29:23 | 显示全部楼层
single104 发表于 2014-3-4 11:10
知道问题在哪儿了,我下载的那个STM32F103XX的资料的管脚定义误导我了,没有标FSMC的复用功能,所以我以为1 ...

特别想要一份楼主这个例程,最近也正在调试FSMC控制外部SRAM,初学者都不明白   ,想请楼主请教,可不可以给我发一份您的例程,我邮箱 guoxiaoyan@tycmc.net  谢谢  不胜感激
回复 支持 反对

使用道具 举报

3

主题

55

帖子

0

精华

初级会员

Rank: 2

积分
174
金钱
174
注册时间
2016-8-13
在线时间
14 小时
发表于 2017-2-1 20:36:52 | 显示全部楼层
MARK!楼主你用100pin的是没有FSMC_A[15:0]的,因此必须要用FSMC_D[15:0]分时复用,但例程里却写着FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;       
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-5-29 15:37

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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