[MM32软件] FSMC非复用方式控制NOR Flash的程序设计

[复制链接]
 楼主| mutable 发表于 2021-12-17 15:03 | 显示全部楼层 |阅读模式
根据配置的接口电路配置GPIO初始化程序与FSMC初始化程序。
  1. void FSMC_NOR_Init(void)
  2. {
  3.     FSMC_InitTypeDef  FSMC_InitStructure;
  4.     FSMC_NORSRAM_Bank_InitTypeDef  FSMC_BankInitStructure;

  5.     FSMC_NORSRAM_BankStructInit(&FSMC_BankInitStructure);
  6.     FSMC_NORSRAMStructInit(&FSMC_InitStructure);
  7.     RCC_AHB3PeriphClockCmd(RCC_AHB3ENR_FSMC, ENABLE);

  8.     FSMC_BankInitStructure.FSMC_SMReadPipe    = 0;
  9.     FSMC_BankInitStructure.FSMC_ReadyMode     = 0;
  10.     FSMC_BankInitStructure.FSMC_WritePeriod   = 15;
  11.     FSMC_BankInitStructure.FSMC_WriteHoldTime = 3;
  12.     FSMC_BankInitStructure.FSMC_AddrSetTime   = 3;
  13.     FSMC_BankInitStructure.FSMC_ReadPeriod    = 15;
  14.     FSMC_BankInitStructure.FSMC_DataWidth     = FSMC_DataWidth_16bits;
  15.     FSMC_NORSRAM_Bank_Init(&FSMC_BankInitStructure, \
  16.     FSMC_NORSRAM_BANK1);

  17.     FSMC_InitStructure.FSMC_Mode = FSMC_Mode_NorFlash;
  18.     FSMC_InitStructure.FSMC_TimingRegSelect = FSMC_TimingRegSelect_0;
  19.     FSMC_InitStructure.FSMC_MemSize = FSMC_MemSize_64MB;
  20.     FSMC_InitStructure.FSMC_MemType = FSMC_MemType_FLASH;
  21.     FSMC_InitStructure.FSMC_AddrDataMode = FSMC_AddrDataDeMUX;
  22.     FSMC_NORSRAMInit(&FSMC_InitStructure);
  23. }
GPIO初始化
  1. void FSMC_GPIO_Init(void)
  2. {
  3.     GPIO_InitTypeDef GPIO_InitStructure;
  4.     GPIO_StructInit(&GPIO_InitStructure);
  5.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
  6.     RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOB | RCC_AHBENR_GPIOC | \
  7.     RCC_AHBENR_GPIOA | RCC_AHBENR_GPIOD | RCC_AHBENR_GPIOE | \
  8.     RCC_AHBENR_GPIOF | RCC_AHBENR_GPIOG, ENABLE);

  9.     GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_12);  //NOE
  10.     GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_12);  //NWE
  11.     GPIO_PinAFConfig(GPIOD, GPIO_PinSource6, GPIO_AF_12);  //NWAIT
  12.     GPIO_PinAFConfig(GPIOD, GPIO_PinSource11, GPIO_AF_12); //A16
  13.     GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_12); //A17
  14.     GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_12); //A18
  15.     GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_12); //D0
  16.     GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_12); //D1
  17.     //省略部分代码
  18.     GPIO_PinAFConfig(GPIOF, GPIO_PinSource0, GPIO_AF_12);  //A0
  19.     GPIO_PinAFConfig(GPIOF, GPIO_PinSource1, GPIO_AF_12);  //A1
  20.     GPIO_PinAFConfig(GPIOF, GPIO_PinSource2, GPIO_AF_12);  //A2
  21.     GPIO_PinAFConfig(GPIOF, GPIO_PinSource3, GPIO_AF_12);  //A3
  22.     //省略部分代码
  23.     GPIO_InitStructure.GPIO_Pin  =  GPIO_Pin_All;
  24.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  25.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  26.     GPIO_Init(GPIOD, &GPIO_InitStructure);

  27.     GPIO_InitStructure.GPIO_Pin  =  GPIO_Pin_6;
  28.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  29.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_FLOATING;
  30.     GPIO_Init(GPIOD, &GPIO_InitStructure);

  31.     //省略部分代码

  32. }
从选择的片选信号与FSMC外扩存储映像空间可以得出Bank2地址为0x64000000,使用该地址作为读写外部NOR Flash的基地址。
  1. #define NOR_FLASH_START_ADDR       ((u32)0x64000000)
  2. #define NOR_FLASH_END_ADDR         ((u32)0x67FFFFFF)
  3. //读一个半字
  4. u16 FSMC_NOR_ReadHalfWord(u32 ReadAddr)
  5. {
  6.     NOR_WRITE(ADDR_SHIFT(0x00555), 0x00AA);
  7.     NOR_WRITE(ADDR_SHIFT(0x002AA), 0x0055);
  8.     NOR_WRITE((NOR_FLASH_START_ADDR + ReadAddr), 0x00F0 );
  9. /* exit autoselect (write reset command) */
  10.     return (*(vu16*)((NOR_FLASH_START_ADDR + ReadAddr)));
  11. }
  12. //连续读一块半字数据
  13. void FSMC_NOR_ReadBuffer(u16* pBuffer, u32 ReadAddr, u32 NumHalfwordToRead)
  14. {
  15.     NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
  16.     NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
  17.     NOR_WRITE((NOR_FLASH_START_ADDR + ReadAddr), 0x00F0);
  18. /* exit autoselect (write reset command) */
  19.     for(; NumHalfwordToRead != 0x00; NumHalfwordToRead--) {
  20.         // Read a Halfword from the NOR
  21.         *pBuffer++ = *(vu16*)((NOR_FLASH_START_ADDR + ReadAddr));
  22.         ReadAddr = ReadAddr + 2;
  23.     }
  24. }

读写外部NOR Flash与读写外部SRAM的操作,地址寻址方式是一样的,但NOR Flash的写数据有较大的不同。


以单个Word编程为例,如下为写单个Word的流程图与实现代码:

1935661bc36255e964.png

  1. NOR_Status FSMC_NOR_WriteHalfWord(u32 WriteAddr, u16 Data)
  2. {
  3.     NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
  4.     NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
  5.     NOR_WRITE(ADDR_SHIFT(0x0555), 0x00A0);
  6.     NOR_WRITE((NOR_FLASH_START_ADDR + WriteAddr), Data);

  7.     return (FSMC_NOR_GetStatus(Program_Timeout));
  8. }

通过MindMotion的官网下载MM32F3270 lib_Samples:

https://www.mindmotion.com.cn/products/mm32mcu/mm32f/mm32f_mainstream/mm32f3270/

工程路径如下:

~MM32F327x_Samples\LibSamples\FSMC\FSMC_NOR\

可以看到详细的样例与功能操作。










七毛钱 发表于 2021-12-17 16:44 来自手机 | 显示全部楼层
学习学习
您需要登录后才可以回帖 登录 | 注册

本版积分规则

72

主题

598

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部

72

主题

598

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部