首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

stm32使用fsmc时地址移位问题

stm32使用fsmc时地址移位问题

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位读写时输出地址确实一直是右移了一位,下面那个程序就没问题,让自己纠结了好多天的程序,希望大家不要犯这个错误,呵呵。
继承事业,薪火相传
返回列表