FMSC16位模式地址线问题

ob99999   2010-11-3 09:18 楼主
“ 对于16位宽度的外部存储器,FSMC将在内部使用HADDR[25:1]产生外部存储器的地址FSMC_A[24:0]”

  相当与使用16位模式时,地址会自动交错一位
  如何屏蔽此功能(不交错,  0对0  1对1 2对2)

回复评论 (38)

不可以。

如果屏蔽此功能,地址最低位将始终是"0",这样做有什么意义?
点赞  2010-11-3 10:02
我的意思是在地址数据复用模式下, 我用16位宽度访问的时候就有问题了。
如下图:
STM32内部    STM32外部    连接的ASIC
HADDR[ 1] --- AD[ 0] ------AD[0]
HADDR[ 2] --- AD[ 1] ------AD[1]
-
-
HADDR[16] --- AD[15] ---- AD[15]
像上面的连接,是为了保证数据D0~D15的对齐关系。
但是STM32内部的真实数据地址却是错位的,这样我要访问0x*000 0002的地址数据,那么就必须使用
地址0x*000 0004的地址,因为STM32内部自动右移动一位。如果STM32不可以禁止这个功能的话,那
么对于这种16位宽数据访问的,地址数据复用模式的情况下,就有一半的地址出现不了了。
更严重的问题是:
如果我访问的数据室32位时,就出现无法访问的问题了。只能分2次进行读写。
所以请问,STM32如何处理这种问题呢?
点赞  2010-11-3 10:16
                                 3楼的说法是猜测还是实测?
点赞  2010-11-3 10:31
是真实的实测。现在就出现问题了。
如果原来是按照16BIT读,我可以自动把2000的地址编程4000进行读。
但是如果想连续的读32bit的数据的时候,如果我只给4000地址就出错了。读不回来了。因为内部逻辑是加2,那么MPU第一次读4000(左移变成2000),第二次读诗4002(左移变成2001,而实际应当读2002)这样出问题了。就是无法连续读数据,因为真实MPU发给ASIC的地址不是按照16位增长的。
点赞  2010-11-3 10:37
所以才问,是否可以把内部自动移位地址的这个给关闭。
在地址数据线非复用模式下是没问题的。
但是在地址数据线复用模式下就出问题了。我没办法错位地址连接,因为AD0的D0是不能错位的。
点赞  2010-11-3 10:38
                                 能贴出你的初始化代码和连接电路图吗?
点赞  2010-11-3 11:22
按照手册上来说,应该是可以:

点赞  2010-11-3 11:57
                                 按照手册上来说,应该是可以以32位的方式来访问配置成16位宽度的外部存储器的,无论它是否采用了复用方式:
点赞  2010-11-3 12:02
不知道怎么插图稍等下
代码如下


void FSMC_SRAM_Init(void)
{
        FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;
        FSMC_NORSRAMTimingInitTypeDef write_timing, read_timing;
        GPIO_InitTypeDef GPIO_InitStructure;
       
        /*-- GPIO Configuration ------------------------------------------------------*/
        /* SRAM Data lines configuration */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_8 | GPIO_Pin_9 |
                                      GPIO_Pin_10 | GPIO_Pin_14 | GPIO_Pin_15;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOD, &GPIO_InitStructure);
       
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | 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);
       

        /* ALE configuration */  
           GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_Init(GPIOB, &GPIO_InitStructure);


       
        /* NOE and NWE configuration */  
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 |GPIO_Pin_5;
        GPIO_Init(GPIOD, &GPIO_InitStructure);
       
        /* NE1 configuration */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
        GPIO_Init(GPIOD, &GPIO_InitStructure);
       
        /* NBL0, NBL1 configuration */
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
        GPIO_Init(GPIOE, &GPIO_InitStructure);
       
        /*-- FSMC Configuration ------------------------------------------------------*/
        write_timing.FSMC_AddressSetupTime = 0;
        write_timing.FSMC_AddressHoldTime = 1;
        write_timing.FSMC_DataSetupTime = 3;
        write_timing.FSMC_BusTurnAroundDuration = 10;
        write_timing.FSMC_CLKDivision = 0;
        write_timing.FSMC_DataLatency = 0;
        write_timing.FSMC_AccessMode = FSMC_AccessMode_A;


        read_timing.FSMC_AddressSetupTime = 0;
        read_timing.FSMC_AddressHoldTime = 1;
        read_timing.FSMC_DataSetupTime = 3;
        read_timing.FSMC_BusTurnAroundDuration = 10;
        read_timing.FSMC_CLKDivision = 0;
        read_timing.FSMC_DataLatency = 0;
        read_timing.FSMC_AccessMode = FSMC_AccessMode_A;


       
        FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1;
        FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Enable;
        FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_NOR;
        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_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 = &write_timing;
        FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &read_timing;
       
        FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);
       
        /* Enable FSMC Bank1_SRAM Bank */
        FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);  
}
点赞  2010-11-3 13:00
回路图
点赞  2010-11-3 13:02
                                 
点赞  2010-11-3 13:09
ASIC 可以工作在16模式下。
但每个地址 对应数据是 1byte

对十六位数据读取时  
只能给出偶地址
如 0x0000
    0x0002
    0x0004
点赞  2010-11-3 13:23
ASIC 可以工作在16模式下。
但每个地址 对应数据是 1byte

对十六位数据读取时  
只能给出偶地址
如 0x0000
    0x0002
    0x0004
ASIC 可以工作在16模式下。
但每个地址 对应数据是 1byte

这段话不理解:ASIC 工作在16位模式,为什么每个地址 对应数据是 1byte,而不是1个16位的字?
点赞  2010-11-3 13:45
你已经配置了FSMC_MemoryDataWidth_16b,也就是说每次操作(读写)外部存储器都是以16位进行的,下面我以几个例子(不考虑地址高位)说明STM32是如何操作的,看看与你看到的是否一致:

1)对地址0x0002读16位数据0x4321:
NADV=低时:AD[0] = ADDR1 = "1",AD[15:1] = ADDR[16:2] = "0"
NADV=高时:AD[0] = "1",AD[4:1] = "0",AD[5] = "1",......

2)对地址0x0002读8位数据0x21:所有的外部信号与上例相同,但在内部自动丢弃高8位数据。
2.1)对地址0x0003读8位数据0x43:所有的外部信号与上例相同,但在内部自动丢弃低8位数据。

3)对地址0x0002写16位数据0x4321:所有的外部信号与例1)相同,同时在NWE为低时,NBL1和NBL0也为低。

4)对地址0x0002写8位数据0x21:所有的外部信号与例1)相同,同时在NWE为低时,NBL0也为低。
4.1)对地址0x0003写8位数据0x43:所有的外部信号与例1)相同,同时在NWE为低时,NBL1也为低。

5)对地址0x0004读32位数据0x87654321:
5.1)先处理低16位数据 NADV=低时:AD[0] = ADDR1 = "0",AD[1] = ADDR2 = "1",AD[15:2] = ADDR[16:3] = "0"
NADV=高时:AD[15:0] = 0x4321
5.2)再处理高16位数据 NADV=低时:AD[0] = ADDR1 = "1",AD[1] = ADDR2 = "1",AD[15:2] = ADDR[16:3] = "0"
NADV=高时:AD[15:0] = 0x8765
点赞  2010-11-3 14:29
以下黑色字体是引用LZ,蓝色字体是我的话:
**********************************************************************
如果原来是按照16BIT读,我可以自动把2000的地址编程4000进行读。
>>这里你说的"2000的地址"应该指的是memory上以16bit为单位的地址;而"编程4000进行读"应该是指STM32逻辑地址线上的以8bit为单位的地址。 这一点LZ可以确定吧?
但是如果想连续的读32bit的数据的时候,如果我只给4000地址就出错了。读不回来了。因为内部逻辑是加2,那么MPU第一次读4000(左移变成2000),第二次读诗4002(左移变成2001,而实际应当读2002)这样出问题了。就是无法连续读数据,因为真实MPU发给ASIC的地址不是按照16位增长的。
>>如果上一条LZ能确定我的理解正确,那么这里要想从4000(以8bit为单位的地址)读4个字节出来,那么按照手册上,也是我刚才的贴图上可以看到的,是分成两次16bit的读操作。第一次,以4000(以8bit为单位)读两个字节,经过所谓的地址移位,转换成LZ说的2000(以16bit为单位);第二次,读4002(以8bit为单位),"左移变成2001",就是该读2001(以16bit为单位)这个地址的两个字节。 这样就好了呀。而LZ说的"而实际应当读2002",倒是貌似理解有误也。
点赞  2010-11-3 15:16
ASIC 可以工作在16模式下。
但每个地址 对应数据是 1byte

这段话不理解:ASIC 工作在16位模式,为什么每个地址 对应数据是 1byte,而不是1个16位的字? ...
因为 ASIC 就是这样设计的。
对奇数地址访问时禁止的。
点赞  2010-11-3 16:44


以下红绳字体是引用LZ,蓝色字体是我的话:
**********************************************************************
如果原来是按照16BIT读,我可以自动把2000的地址编程4000进行读。
>>这里你说的"2000的地址"应该指的是memory上以16bit为单位的地址;而"编程4000进行读"应该是指STM32逻辑地址线上的以8bit为单位的地址。 这一点LZ可以确定吧?
2000的的地址是指 ASIC 8bit 地址.

但是如果想连续的读32bit的数据的时候,如果我只给4000地址就出错了。读不回来了。因为内部逻辑是加2,那么MPU第一次读4000(左移变成2000),第二次读诗4002(左移变成2001,而实际应当读2002)这样出问题了。就是无法连续读数据,因为真实MPU发给ASIC的地址不是按照16位增长的。
>>如果上一条LZ能确定我的理解正确,那么这里要想从4000(以8bit为单位的地址)读4个字节出来,那么按照手册上,也是我刚才的贴图上可以看到的,是分成两次16bit的读操作。第一次,以4000(以8bit为单位)读两个字节,经过所谓的地址移位,转换成LZ说的2000(以16bit为单位);第二次,读4002(以8bit为单位),"左移变成2001",就是该读2001(以16bit为单位)这个地址的两个字节。 这样就好了呀。而LZ说的"而实际应当读2002",倒是貌似理解有误也

问题的关键点 是ASIC的
每个地址 对应数据是 1byte对十六位数据读取时  
只能给出偶地址
如 0x0000
    0x0002
    0x0004

所以上边所说的读
2001情况出现的话, 读取就会出错 因为奇数地址访问是禁止的
点赞  2010-11-3 16:53
大家好,我是LZ的同事
简单来说
1)ASIC只能对偶地址进行字读,不能字节读
2)ASIC的外部地址是按8位寻址的,字读的数据是由2个地址的数据组成的,连续读的偏移量应该为2(第一次2000->第二次2002)
3)MPU的外部地址是按16位寻址的,连续读的偏移量为1(第一次2000->第二次2001)
4)由2)和3)可得,第二次读的是ASIC的2001,由1)可知,不能对奇地址进行字读,出现问题
点赞  2010-11-3 17:14
ASIC 可以工作在16模式下。
但每个地址 对应数据是 1byte

>>那么你把这个ASIC配置成8bit模式好了。你的memory每个地址对应1个字节;STM32的FSMC也不会给你进行地址移位了。
点赞  2010-11-3 17:26
12下一页
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复