作者:emouse
转自:http://www.voidcn.com/article/p-patqdlkh-qm.html
基本说明
STM32访问外部存储器是需要配置FSMC的相关函数,在STM32固件库函数说明的中文翻译版中并没有这部分的说明,因此需要参考库函数的相关说明和库中自带的例程。
以下内容来自AN2784应用笔记:
2 与非总线复用模式的异步16位NOR闪存接口
2.1
FSMC配置
控制一个NOR闪存存储器,需要FSMC提供下述功能:
●
选择合适的存储块映射NOR闪存存储器:共有4个独立的存储块可以用于与NOR闪存、SRAM和PSRAM存储器接口,每个存储块都有一个专用的片选管脚。
●
使用或禁止地址/数据总线的复用功能。
●
选择所用的存储器类型:NOR闪存、SRAM或PSRAM。
●
定义外部存储器的数据总线宽度:8或16位。
●
使用或关闭同步NOR闪存存储器的突发访问模式。
●
配置等待信号的使用:开启或关闭,极性设置,时序配置。
●
使用或关闭扩展模式:扩展模式用于访问那些具有不同读写操作时序的存储器。
因为NOR闪存/SRAM控制器可以支持异步和同步存储器,用户只须根据存储器的参数配置使用到的参数。
FSMC提供了一些可编程的参数,可以正确地与外部存储器接口。依存储器类型的不同,有些参数是不需要的。
当使用一个外部异步存储器时,用户必须按照存储器的数据手册给出的时序数据,计算和设置下列参数:
●
ADDSET:地址建立时间
●
ADDHOLD:地址保持时间
●
DATAST:数据建立时间
●
ACCMOD:访问模式 这个参数允许 FSMC可以灵活地访问多种异步的静态存储器。共有4种扩展模式允许以不同的时序分别读写存储器。 在扩展模式下,FSMC_BTR用于配置读操作,FSMC_BWR用于配置写操作。(译注:如果读时序与写时序相同,只须使用FSMC_BTR即可。)
如果使用了同步的存储器,用户必须计算和设置下述参数:
●
CLKDIV:时钟分频系数
●
DATLAT:数据延时
如果存储器支持的话,NOR闪存的读操作可以是同步的,而写操作仍然是异步的。
当对一个同步的NOR闪存编程时,存储器会自动地在同步与异步之间切换;因此,必须正确地设置所有的参数
?
?
?
程序分析
[cpp]
view plain
copy
print
?
- ???
- ??p.FSMC_AddressSetupTime?=?0x05;???????
- ??p.FSMC_AddressHoldTime?=?0x00;??????
- ??p.FSMC_DataSetupTime?=?0x07;???????
- ??p.FSMC_BusTurnAroundDuration?=?0x00;?????
- ??p.FSMC_CLKDivision?=?0x00;????????
- ??p.FSMC_DataLatency?=?0x00;???????
- ??p.FSMC_AccessMode?=?FSMC_AccessMode_B;?????
- ??
- ??FSMC_NORSRAMInitStructure.FSMC_Bank?=?FSMC_Bank1_NORSRAM2;??????
- ??
- ??FSMC_NORSRAMInitStructure.FSMC_DataAddressMux?=?FSMC_DataAddressMux_Disable;????
- ??
- ??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?=?&p;??????
- ??FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct?=?&p;??????
- ???????????????????
- ??FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);??????????
- ????
- ??FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM2,?ENABLE);??????????
- }??
?
实际例程
以下例程来自??stm3210e_eval_fsmc_nor.c具体信息参加固件库中源文件。
[c-sharp] view plaincopyprint?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ???
- ??
- #include?"stm3210e_eval_fsmc_nor.h"??
- ?
- ?
- ??
- ????
- ?
- ?
- ???
- ?
- ?
- ??
- ????
- ?
- ?
- ?
- ?
- ???
- ?
- ?
- ???
- ?
- ?
- ???
- ?
- ?
- ???
- ?
- ?
- ??
- #define?Bank1_NOR2_ADDR???????((uint32_t)0x64000000)??
- ?????
- #define?BlockErase_Timeout????((uint32_t)0x00A00000)??
- #define?ChipErase_Timeout?????((uint32_t)0x30000000)???
- #define?Program_Timeout???????((uint32_t)0x00001400)???????
- ?
- ?
- ???
- ??
- ?
- ?
- ??
- #define?ADDR_SHIFT(A)?(Bank1_NOR2_ADDR?+?(2?*?(A)))??
- #define?NOR_WRITE(Address,?Data)??(*(__IO?uint16_t?*)(Address)?=?(Data))????
- ?
- ?
- ???
- ????
- ?
- ?
- ???
- ?
- ?
- ???
- ??
- ?
- ?
- ???
- ?
- ?
- ???
- ??
- ?
- ?
- ??
- ?
- ?
- ?
- ?
- ?
- ?
- ??
- void?NOR_Init(void)??
- {??
- ??FSMC_NORSRAMInitTypeDef??FSMC_NORSRAMInitStructure;??
- ??FSMC_NORSRAMTimingInitTypeDef??p;??
- ??GPIO_InitTypeDef?GPIO_InitStructure;??
- ??RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD?|?RCC_APB2Periph_GPIOE?|???
- ?????????????????????????RCC_APB2Periph_GPIOF?|?RCC_APB2Periph_GPIOG,?ENABLE);??
- ????
- ????
- ??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);??
- ????
- ??GPIO_InitStructure.GPIO_Pin?=?GPIO_Pin_0?|?GPIO_Pin_1?|?GPIO_Pin_2?|?GPIO_Pin_3?|??
- ????????????????????????????????GPIO_Pin_4?|?GPIO_Pin_5?|?GPIO_Pin_12?|?GPIO_Pin_13?|??
- ????????????????????????????????GPIO_Pin_14?|?GPIO_Pin_15;??
- ??GPIO_Init(GPIOF,?&GPIO_InitStructure);??
- ??GPIO_InitStructure.GPIO_Pin?=?GPIO_Pin_0?|?GPIO_Pin_1?|?GPIO_Pin_2?|??
- ????????????????????????????????GPIO_Pin_3?|?GPIO_Pin_4?|?GPIO_Pin_5;??
- ??GPIO_Init(GPIOG,?&GPIO_InitStructure);??
- ??GPIO_InitStructure.GPIO_Pin?=?GPIO_Pin_11?|?GPIO_Pin_12?|?GPIO_Pin_13;??
- ??GPIO_Init(GPIOD,?&GPIO_InitStructure);??
- ??GPIO_InitStructure.GPIO_Pin?=?GPIO_Pin_3?|?GPIO_Pin_4?|?GPIO_Pin_5?|?GPIO_Pin_6;??
- ??GPIO_Init(GPIOE,?&GPIO_InitStructure);??
- ????
- ??GPIO_InitStructure.GPIO_Pin?=?GPIO_Pin_4?|?GPIO_Pin_5;??
- ??GPIO_Init(GPIOD,?&GPIO_InitStructure);??
- ????
- ??GPIO_InitStructure.GPIO_Pin?=?GPIO_Pin_9;??
- ??GPIO_Init(GPIOG,?&GPIO_InitStructure);??
- ????
- ??GPIO_InitStructure.GPIO_Pin?=?GPIO_Pin_6;??
- ??GPIO_InitStructure.GPIO_Mode?=?GPIO_Mode_IN_FLOATING;??
- ??GPIO_Init(GPIOD,?&GPIO_InitStructure);??
- ????
- ????
- ??p.FSMC_AddressSetupTime?=?0x02;??
- ??p.FSMC_AddressHoldTime?=?0x00;??
- ??p.FSMC_DataSetupTime?=?0x05;??
- ??p.FSMC_BusTurnAroundDuration?=?0x00;??
- ??p.FSMC_CLKDivision?=?0x00;??
- ??p.FSMC_DataLatency?=?0x00;??
- ??p.FSMC_AccessMode?=?FSMC_AccessMode_B;??
- ??FSMC_NORSRAMInitStructure.FSMC_Bank?=?FSMC_Bank1_NORSRAM2;??
- ??FSMC_NORSRAMInitStructure.FSMC_DataAddressMux?=?FSMC_DataAddressMux_Disable;??
- ??FSMC_NORSRAMInitStructure.FSMC_MemoryType?=?FSMC_MemoryType_NOR;??
- ??FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth?=?FSMC_MemoryDataWidth_16b;??
- ??FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode?=?FSMC_BurstAccessMode_Disable;??
- ??FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait?=?FSMC_AsynchronousWait_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_WriteBurst?=?FSMC_WriteBurst_Disable;??
- ??FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct?=?&p;??
- ??FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct?=?&p;??
- ??FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);??
- ????
- ??FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM2,?ENABLE);??
- }??
- ?
- ?
- ?
- ?
- ?
- ??
- void?NOR_ReadID(NOR_IDTypeDef*?NOR_ID)??
- {??
- ??NOR_WRITE(ADDR_SHIFT(0x0555),?0x00AA);??
- ??NOR_WRITE(ADDR_SHIFT(0x02AA),?0x0055);??
- ??NOR_WRITE(ADDR_SHIFT(0x0555),?0x0090);??
- ??NOR_ID->Manufacturer_Code?=?*(__IO?uint16_t?*)?ADDR_SHIFT(0x0000);??
- ??NOR_ID->Device_Code1?=?*(__IO?uint16_t?*)?ADDR_SHIFT(0x0001);??
- ??NOR_ID->Device_Code2?=?*(__IO?uint16_t?*)?ADDR_SHIFT(0x000E);??
- ??NOR_ID->Device_Code3?=?*(__IO?uint16_t?*)?ADDR_SHIFT(0x000F);??
- }??
- ?
- ?
- ?
- ?
- ?
- ??
- NOR_Status?NOR_EraseBlock(uint32_t?BlockAddr)??
- {??
- ??NOR_WRITE(ADDR_SHIFT(0x0555),?0x0080);??
- ??NOR_WRITE(ADDR_SHIFT(0x0555),?0x00AA);??
- ??NOR_WRITE(ADDR_SHIFT(0x02AA),?0x0055);??
- ??NOR_WRITE((Bank1_NOR2_ADDR?+?BlockAddr),?0x30);??
- ??return?(NOR_GetStatus(BlockErase_Timeout));??
- }??
- ?
- ?
- ?
- ?
- ?
- ??
- NOR_Status?NOR_EraseChip(void)??
- {??
- ??NOR_WRITE(ADDR_SHIFT(0x0555),?0x0055);??
- ??NOR_WRITE(ADDR_SHIFT(0x0555),?0x0010);??
- ??return?(NOR_GetStatus(ChipErase_Timeout));??
- }??
- ?
- ?
- ?
- ?
- ?
- ?
- ??
- NOR_Status?NOR_WriteHalfWord(uint32_t?WriteAddr,?uint16_t?Data)??
- {??
- ??NOR_WRITE(ADDR_SHIFT(0x0555),?0x00A0);??
- ??NOR_WRITE((Bank1_NOR2_ADDR?+?WriteAddr),?Data);??
- ??return?(NOR_GetStatus(Program_Timeout));??
- }??
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ??
- NOR_Status?NOR_WriteBuffer(uint16_t*?pBuffer,?uint32_t?WriteAddr,?uint32_t?NumHalfwordToWrite)??
- {??
- ??NOR_Status?status?=?NOR_ONGOING;???
- ??do??
- ??{??
- ??????
- ????status?=?NOR_WriteHalfWord(WriteAddr,?*pBuffer++);??
- ????WriteAddr?=?WriteAddr?+?2;??
- ????NumHalfwordToWrite--;??
- ??}??
- ??while((status?==?NOR_SUCCESS)?&&?(NumHalfwordToWrite?!=?0));??
- ????
- ??return?(status);???
- }??
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ??
- NOR_Status?NOR_ProgramBuffer(uint16_t*?pBuffer,?uint32_t?NumHalfwordToWrite)??
- {??
- ??uint32_t?lastloadedaddress?=?0x00;??
- ??uint32_t?currentaddress?=?0x00;??
- ??uint32_t?endaddress?=?0x00;??
- ????
- ??currentaddress?=?WriteAddr;??
- ??endaddress?=?WriteAddr?+?NumHalfwordToWrite?-?1;??
- ??lastloadedaddress?=?WriteAddr;??
- ????
- ??NOR_WRITE(ADDR_SHIFT(0x00555),?0x0055);????
- ????
- ??NOR_WRITE(ADDR_SHIFT(WriteAddr),?0x0025);??
- ??NOR_WRITE(ADDR_SHIFT(WriteAddr),?(NumHalfwordToWrite?-?1));??
- ????
- ??while(currentaddress?<=?endaddress)??
- ??{??
- ??????
- ????lastloadedaddress?=?currentaddress;??
- ???
- ????NOR_WRITE(ADDR_SHIFT(currentaddress),?*pBuffer++);??
- ????currentaddress?+=?1;???
- ??}??
- ??NOR_WRITE(ADDR_SHIFT(lastloadedaddress),?0x29);??
- ????
- ??return(NOR_GetStatus(Program_Timeout));??
- }??
- ?
- ?
- ?
- ?
- ??
- uint16_t?NOR_ReadHalfWord(uint32_t?ReadAddr)??
- {??
- ??NOR_WRITE(ADDR_SHIFT(0x00555),?0x00AA);???
- ??NOR_WRITE(ADDR_SHIFT(0x002AA),?0x0055);????
- ??NOR_WRITE((Bank1_NOR2_ADDR?+?ReadAddr),?0x00F0?);??
- ??return?(*(__IO?uint16_t?*)((Bank1_NOR2_ADDR?+?ReadAddr)));??
- }??
- ?
- ?
- ?
- ?
- ?
- ?
- ?
- ??
- void?NOR_ReadBuffer(uint16_t*?pBuffer,?uint32_t?ReadAddr,?uint32_t?NumHalfwordToRead)??
- {??
- ??NOR_WRITE(ADDR_SHIFT(0x0555),?0x0055);??
- ??NOR_WRITE((Bank1_NOR2_ADDR?+?ReadAddr),?0x00F0);??
- ??for(;?NumHalfwordToRead?!=?0x00;?NumHalfwordToRead--)???
- ??{??
- ??????
- ????*pBuffer++?=?*(__IO?uint16_t?*)((Bank1_NOR2_ADDR?+?ReadAddr));??
- ????ReadAddr?=?ReadAddr?+?2;???
- ??}????
- }??
- ?
- ?
- ?
- ?
- ??
- NOR_Status?NOR_ReturnToReadMode(void)??
- {??
- ??NOR_WRITE(Bank1_NOR2_ADDR,?0x00F0);??
- ??return?(NOR_SUCCESS);??
- }??
- ?
- ?
- ?
- ?
- ?
- ??
- NOR_Status?NOR_Reset(void)??
- {??
- ??NOR_WRITE(ADDR_SHIFT(0x00555),?0x00AA);???
- ??NOR_WRITE(ADDR_SHIFT(0x002AA),?0x0055);???
- ??NOR_WRITE(Bank1_NOR2_ADDR,?0x00F0);???
- ??return?(NOR_SUCCESS);??
- }??
- ?
- ?
- ?
- ?
- ?
- ??
- NOR_Status?NOR_GetStatus(uint32_t?Timeout)??
- {???
- ??uint16_t?val1?=?0x00,?val2?=?0x00;??
- ??NOR_Status?status?=?NOR_ONGOING;???
- ??uint32_t?timeout?=?Timeout;??
- ????
- ??while((GPIO_ReadInputDataBit(GPIOD,?GPIO_Pin_6)?!=?RESET)?&&?(timeout?>?0))???
- ??{??
- ????timeout--;??
- ??}??
- ??timeout?=?Timeout;??
- ????
- ??while((GPIO_ReadInputDataBit(GPIOD,?GPIO_Pin_6)?==?RESET)?&&?(timeout?>?0))?????
- ??{??
- ????timeout--;??
- ??}??
- ????
- ????
- ??while((Timeout?!=?0x00)?&&?(status?!=?NOR_SUCCESS))??
- ??{??
- ????Timeout--;??
- ??????
- ????val1?=?*(__IO?uint16_t?*)(Bank1_NOR2_ADDR);??
- ????val2?=?*(__IO?uint16_t?*)(Bank1_NOR2_ADDR);??
- ??????
- ????if((val1?&?0x0040)?==?(val2?&?0x0040))???
- ????{??
- ??????return?NOR_SUCCESS;??
- ????}??
- ????if((val1?&?0x0020)?!=?0x0020)??
- ????{??
- ??????status?=?NOR_ONGOING;??
- ????}??
- ????val1?=?*(__IO?uint16_t?*)(Bank1_NOR2_ADDR);??
- ????val2?=?*(__IO?uint16_t?*)(Bank1_NOR2_ADDR);??
- ??????
- ????if((val1?&?0x0040)?==?(val2?&?0x0040))???
- ????{??
- ??????return?NOR_SUCCESS;??
- ????}??
- ????else?if((val1?&?0x0020)?==?0x0020)??
- ????{??
- ??????return?NOR_ERROR;??
- ????}??
- ??}??
- ??if(Timeout?==?0x00)??
- ??{??
- ????status?=?NOR_TIMEOUT;??
- ??}???
- ????
- ??return?(status);??
- }??
- ?
- ?
- ??
- ?
- ?
- ??
- ?
- ?
- ??
- ?
- ?
- ??
- ?
- ?
- ????
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|