- void FSMC_NOR_Init(void)
- {
- FSMC_InitTypeDef FSMC_InitStructure;
- FSMC_NORSRAM_Bank_InitTypeDef FSMC_BankInitStructure;
- FSMC_NORSRAM_BankStructInit(&FSMC_BankInitStructure);
- FSMC_NORSRAMStructInit(&FSMC_InitStructure);
- RCC_AHB3PeriphClockCmd(RCC_AHB3ENR_FSMC, ENABLE);
- FSMC_BankInitStructure.FSMC_SMReadPipe = 0;
- FSMC_BankInitStructure.FSMC_ReadyMode = 0;
- FSMC_BankInitStructure.FSMC_WritePeriod = 15;
- FSMC_BankInitStructure.FSMC_WriteHoldTime = 3;
- FSMC_BankInitStructure.FSMC_AddrSetTime = 3;
- FSMC_BankInitStructure.FSMC_ReadPeriod = 15;
- FSMC_BankInitStructure.FSMC_DataWidth = FSMC_DataWidth_16bits;
- FSMC_NORSRAM_Bank_Init(&FSMC_BankInitStructure, \
- FSMC_NORSRAM_BANK1);
- FSMC_InitStructure.FSMC_Mode = FSMC_Mode_NorFlash;
- FSMC_InitStructure.FSMC_TimingRegSelect = FSMC_TimingRegSelect_0;
- FSMC_InitStructure.FSMC_MemSize = FSMC_MemSize_64MB;
- FSMC_InitStructure.FSMC_MemType = FSMC_MemType_FLASH;
- FSMC_InitStructure.FSMC_AddrDataMode = FSMC_AddrDataDeMUX;
- FSMC_NORSRAMInit(&FSMC_InitStructure);
- }
GPIO初始化
- void FSMC_GPIO_Init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_StructInit(&GPIO_InitStructure);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
- RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOB | RCC_AHBENR_GPIOC | \
- RCC_AHBENR_GPIOA | RCC_AHBENR_GPIOD | RCC_AHBENR_GPIOE | \
- RCC_AHBENR_GPIOF | RCC_AHBENR_GPIOG, ENABLE);
- GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_12); //NOE
- GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_12); //NWE
- GPIO_PinAFConfig(GPIOD, GPIO_PinSource6, GPIO_AF_12); //NWAIT
- GPIO_PinAFConfig(GPIOD, GPIO_PinSource11, GPIO_AF_12); //A16
- GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_12); //A17
- GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_12); //A18
- GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_12); //D0
- GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_12); //D1
- //省略部分代码
- GPIO_PinAFConfig(GPIOF, GPIO_PinSource0, GPIO_AF_12); //A0
- GPIO_PinAFConfig(GPIOF, GPIO_PinSource1, GPIO_AF_12); //A1
- GPIO_PinAFConfig(GPIOF, GPIO_PinSource2, GPIO_AF_12); //A2
- GPIO_PinAFConfig(GPIOF, GPIO_PinSource3, GPIO_AF_12); //A3
- //省略部分代码
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
- GPIO_Init(GPIOD, &GPIO_InitStructure);
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_FLOATING;
- GPIO_Init(GPIOD, &GPIO_InitStructure);
- //省略部分代码
- }
从选择的片选信号与FSMC外扩存储映像空间可以得出Bank2地址为0x64000000,使用该地址作为读写外部NOR Flash的基地址。
- #define NOR_FLASH_START_ADDR ((u32)0x64000000)
- #define NOR_FLASH_END_ADDR ((u32)0x67FFFFFF)
- //读一个半字
- u16 FSMC_NOR_ReadHalfWord(u32 ReadAddr)
- {
- NOR_WRITE(ADDR_SHIFT(0x00555), 0x00AA);
- NOR_WRITE(ADDR_SHIFT(0x002AA), 0x0055);
- NOR_WRITE((NOR_FLASH_START_ADDR + ReadAddr), 0x00F0 );
- /* exit autoselect (write reset command) */
- return (*(vu16*)((NOR_FLASH_START_ADDR + ReadAddr)));
- }
- //连续读一块半字数据
- void FSMC_NOR_ReadBuffer(u16* pBuffer, u32 ReadAddr, u32 NumHalfwordToRead)
- {
- NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
- NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
- NOR_WRITE((NOR_FLASH_START_ADDR + ReadAddr), 0x00F0);
- /* exit autoselect (write reset command) */
- for(; NumHalfwordToRead != 0x00; NumHalfwordToRead--) {
- // Read a Halfword from the NOR
- *pBuffer++ = *(vu16*)((NOR_FLASH_START_ADDR + ReadAddr));
- ReadAddr = ReadAddr + 2;
- }
- }
读写外部NOR Flash与读写外部SRAM的操作,地址寻址方式是一样的,但NOR Flash的写数据有较大的不同。
以单个Word编程为例,如下为写单个Word的流程图与实现代码:
- NOR_Status FSMC_NOR_WriteHalfWord(u32 WriteAddr, u16 Data)
- {
- NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
- NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
- NOR_WRITE(ADDR_SHIFT(0x0555), 0x00A0);
- NOR_WRITE((NOR_FLASH_START_ADDR + WriteAddr), Data);
- return (FSMC_NOR_GetStatus(Program_Timeout));
- }
通过MindMotion的官网下载MM32F3270 lib_Samples:
https://www.mindmotion.com.cn/products/mm32mcu/mm32f/mm32f_mainstream/mm32f3270/
工程路径如下:
~MM32F327x_Samples\LibSamples\FSMC\FSMC_NOR\
可以看到详细的样例与功能操作。