原创 stm32使用fsmc时地址移位问题

2011-1-19 17:05 5910 8 8 分类: MCU/ 嵌入式

stm32平台使用fsmc时,当操作数据宽度为8位时,HADDR【25:0】与FSMC【25:0】对齐,当操作的数据为16位时,HADDR【25:1】与FSMC【24:0】对齐,HADDR【0】未接。(见stm32手册19.4.1 NOR和PSRAM地址映像 一节)。

也就是当操作8位数据的时候,用stm32往地址(Bank1_NOR1_ADDR+offset)这个地址写数据的时候,引脚实际输出的地址是(Bank1_NOR1_ADDR+offset)的地址。而当操作16位数据的时候,用stm32往地址(Bank1_NOR1_ADDR+offset)这个地址写数据的时候,引脚实际输出的地址是(Bank1_NOR1_ADDR+offset/2)的地址。

而自己第一次在使用的时候还没出现问题。结果在之后使用fsmc发送8位数据的时候竟然输出的地址也是(Bank1_NOR1_ADDR+offset/2)。找了几天没找出原因,由于项目催的急,就把地址全部左移一位,然后再写数据。这几天又出现这个问题,又开始调,并且16位方式读写的时候时序不是很稳定。从公司里面复制了份别人的程序,8位读写地址不用移位,16位读写也没问题。仔细分析了几个小时,才分析出问题在哪儿。

下面是自己错误的fsmc初始化程序(IO初始化没出问题,就不贴了)

void CPLD_Configuration(void)

{

 

       FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;

       FSMC_NORSRAMTimingInitTypeDef  p;

 

       p.FSMC_AddressSetupTime = 3;  //6

       p.FSMC_AddressHoldTime = 3;     //3

       p.FSMC_DataSetupTime = 8;  //25

       p.FSMC_BusTurnAroundDuration = 0;

       p.FSMC_CLKDivision = 0;

       p.FSMC_DataLatency = 0;

       p.FSMC_AccessMode = FSMC_AccessMode_A;

      

 

       FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM4;

       FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;

       FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;

       FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b;

       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 = &p;

       FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;

      

       FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); 

       RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);

       FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE);

}

最后查出来竟然发现把RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);放在这个初始化程序开始就没问题了。正确程序如下

void CPLD_Configuration(void)

{

 

       FSMC_NORSRAMInitTypeDef  FSMC_NORSRAMInitStructure;

       FSMC_NORSRAMTimingInitTypeDef  p;

 

       RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);

 

       p.FSMC_AddressSetupTime = 3;  //6

       p.FSMC_AddressHoldTime = 3;     //3

       p.FSMC_DataSetupTime = 8;  //25

       p.FSMC_BusTurnAroundDuration = 0;

       p.FSMC_CLKDivision = 0;

       p.FSMC_DataLatency = 0;

       p.FSMC_AccessMode = FSMC_AccessMode_A;

      

 

       FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM4;

       FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;

       FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;

       FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b;

       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 = &p;

       FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;

      

       FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); 

       FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM4, ENABLE);

}

 

试了好多次这两个程序,上面那个8位读写时输出地址确实一直是右移了一位,下面那个程序就没问题,让自己纠结了好多天的程序,希望大家不要犯这个错误,呵呵。

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
8
关闭 站长推荐上一条 /1 下一条