我最近使用STM32的FSMC发现这样一个奇怪的现象,FSMC输出的地址信号整体向右偏移了一位,数据信号正常,例如我要向60004000H的地址写入1,通过示波器测量STM32的管脚发现实际输出的情况是向60002000H的地址写入1,通过其他的例子也同样证实了这个特点,搞得我的地址映射都要跟着变化,我的FSMC都是按照芯片资料上面说明进行配置的,况且16位的数据地址总线数据能够正常输出地址却发生偏移,不知道什么原因,不知道有没有碰到过这方面问题的朋友,还请不吝赐教,谢谢。
问题在于你没有好好看手册,你想错了。
你还可以参考ST发布的开发板的线路图,ST网站可以下载:
http://www.st.com/mcu/modules.php?name=mcu&file=familiesdocs&FAM=110
下面是STM32参考手册上有关FSMC地址映射的相关部分:
以下是我的FSMC的引脚定义和总线连接示意图,请版主帮忙分析一下,是否存在问题,谢谢。
FSMC引脚定义:
引脚 FSMC(NOR MUX)
PE2-------------A23
PE3-------------A19
PE4-------------A20
PE5-------------A21
PE6-------------A22
PE7-------------DA4
PE8-------------DA5
PE9-------------DA6
PE10------------DA7
PE11------------DA8
PE12------------DA9
PE13------------DA10
PE14------------DA11
PE15------------DA12
PD8-------------DA13
PD9-------------DA14
PD10------------DA15
PD11------------A16
PD12------------A17
PD13------------A18
PD14------------DA0
PD15------------DA1
PD0-------------DA2
PD1-------------DA3
PD3-------------CLK
PD4-------------NOE
PD5-------------NEW
PD6-------------NWAIT
PD7-------------NE1
PB7-------------NAVD
PE0-------------NBL0
PE1-------------NBL1
FSMC的软件初始化里面是通过下面设置选择存储块还是还有其他的设置:
/*选择设置的BANK及片选信号*/
FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1;
/*设置是否数据地址总线分时复用*/
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Enable;
/*设置存储器类型*/
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;//FSMC_MemoryType_SRAM;//
/*设置数据宽度*/
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
/* Enable FSMC Bank1_SRAM Bank */
FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);
我的存储器是西门子的协议芯片,8位的双口RAM,STM32通过FSMC访问DPRAM,我这个是做profibus-DP从站来着,只是一般很少人用STM32做这个,一般都是用51来做。
不明白你为什么要把STM32的低8位数据线接地?把STM32的高8位数据线接到外部存储器的低8位数据线?不明白为什么要使用A16~A23,而不使用A0~A7或A8~A15?你到底是要用地址/数据复用,还是不复用?如果是复用总线,为什么没有地址锁存器?
我用的就是数据地址复用模式(我的片子是103VC只能采用复用模式),不用低8位数据地址线,只用高8位数据地址线就是为了省一个锁存器,SPC3带有地址锁存,NAVD接到SPC3的ALE引脚,SPC3侧是8位数据地址总线复用,再加上高8位地址线(其中的4位作为片选,4位作为地址线,SPC3总共1.5k空间只需12根地址线即可全部访问)。
既然这样,为什么不使用STM32的数据/地址的低8位?使用8位外部数据宽度不是更好?这样还能够保证地址低端的连续性。
使用低8位数据地址总线就需要加锁存器啊,使用高8位就是为了省锁存器,这个是由SPC3的读写时序决定的,而且板子的面积受到限制,加不下那么多东西了。我现在想知道为什么我的FSMC输出的地址会发生偏移,怎么样解决这个问题,是要软件设置还是要硬件修改,请指教,谢谢。
关于地址偏移的问题,我在2楼已经说清楚了,而且还贴出了文档中对应的内容,你再仔细看看我贴出的表68的第2行。
我就是不明白为什么你会认为使用数据地址总线的高8位,就可以节省地址锁存器?而使用低8位数据地址总线就需要加锁存器?既然是使用的数据地址总线复用的方式,高8位(DA8~DA15)和低8位(DA0~DA7)都是需要使用NADV(即ALE)来区分是地址还是数据。
硬件是别人设计的,搞得我现在写软件业很难受,从SPC3的时序图上应该可以看出来。
ALE-地址锁存信号,由STM32的NADV提供;XRD-读信号,由STM32的NOE提供;XWR-写信号,由STM32的NEW提供。
如果硬件不是你设计的,请你最好找设计人员谈清楚。关于地址偏移的问题,手册中写清楚了,你的硬件设计人员当初是不是想当然了?
你应该直接使用DA0~DA7,软件中设置使用8位的数据宽度。
硬件现在已经不能改了啊,只能按这个做,没办法,我现在就是按照向右偏移一位的特点做的,比如我要向SPC3的0040H写值,STM32里面就是向60008000H写值,通过FSMC输出就是向60004000H写值,低8位地址没用,正好对应SPC3的0040H地址,不知道这样用有没有问题?
当然可以这样操作,不知道你认为会有什么问题?
楼主位的问题是“为什么会产生地址移位”,想必这个问题你已经清楚了。
如果现在你一定要这样做,请不要把STM32的DA0~DA7接地,这样很容易损坏这些引脚。
不管怎样,强烈建议你们修改硬件,直接使用DA0~DA7,这样软件写起来可以省很多事情,也便于项目的管理。
呵呵,谢谢版主的悉心指导,由于涉及到改版以及周期的影响,修改硬件已经不可能了,STM32的DA0~DA7不接地直接悬空吗?
如果DA0~DA7配置为输入,可以接地,可是一旦配置错误,则很容易烧坏引脚。所以最好是外部接上拉电阻,大约10K~20K即可。
ALE-地址锁存信号,由STM32的NADV提供;XRD-读信号,由STM32的NOE提供;XWR-写信号,由STM32的NEW提供。
提醒你一下,STM32的NADV不等于ALE,可能要加一个非门