您的位置 首页 嵌入式

STM32的FSMC灵敏静态存储器控制器

FSMC(FlexihieStaticMemoryController)模块只适用于大容量产品。FSMC模块能够与同步或异步存储器和16位PC存储器卡接口,主…

  FSMC(Flexihie Static Memory Controller)模块只适用于大容量产品。

  FSMC模块可以与同步或异步存储器和16位PC存储器卡接口,首要将AHB传输信号转化到恰当的外部设备协议,满意拜访外部设备的时序要求。

  存储器接口包含:

  ① SRAM静态随机存储器

  ② ROM只读存储器

  ③ NOR闪存

  ④ PSRAM(4个存储块)

  ⑤ 两个NAND闪存块

  ⑥ 16位PC卡

  STM32之所以可以支撑NOR FLASH和NAND FLASH两类拜访方法彻底不同的存储器扩展,是因为FSMC内部实践包含NOR FLASH和NAND / PC Card两个操控器,别离支撑两种天壤之别的存储器拜访方法。在STM32内部,FSMC的一端经过内部高速总线AHB衔接到内核Cortex-M3,另一端则是面向扩展器的外部总线。内核对外部存储器拜访信号发送到AHB总线后,经FSMC转化为契合外部存储器通讯规约的信号,送到外部存储器相应的引脚,完成数据交互。FSMC起着桥梁作用,既能进行信号类型的转化,又能进行信号宽度和时序的调整,屏蔽掉不同存储类型的差异,使之对内核而言没有差异。

  FSMC模块框图如下:

       
  存储块外设地址映射(详细阐明请看数据手册,此处只用图表方法简略表明):
     

           
  下表为NOR/PSRAM存储块挑选:  

           
  三个存储块可用于NAND或PC:
        
  关于NAND闪存,空间可在低256K字节部分划分为三个区:
        
  时序参数:
  FSMC经过运用可编程的存储器时序参数寄存器,拓宽了可选用的外部存储器的速度规模。FSMC的NOR FLASH操控器支撑同步和异步突发两种拜访方法。
  选用同步突发拜访方法时,FSMC将体系时钟HCLK分频后,发送给外部存储器作为同步时钟信号FSMC_CLK。此刻需求设置的时刻参数有两个:CLK的分频系数和拜访中取得第1个数据所需求的等候推迟(DATLAT)。
  选用异步突发拜访方法时,FSMC首要设置3个时刻参数:地址树立时刻(ADDSET),数据树立时刻(DATAST)和地址坚持时刻(ADDHLD)。
  异步NOR FLASH时序形式2时刻参数核算公式如下:
         
  式中Twc和Trc为所选存储器芯片的写周期长度和读操作周期长度;Twp为所选存储器芯片的写信号继续长度。
  为到达更好的操控作用,还应考虑FSMC本身推迟问题,运用校对公式:
         
  式中TAVQV为所选存储器芯片拜访过程中,从地址有用至数据有用的时刻域;Tsu(Data_NE)为STM32特征参数,从数据有用到FSMC_NE失效时刻域,Ttv(A_NE)为STM32特征参数,从FSMC_NE有用至地址有用的时刻域。

  关于FSMC的其它装备这儿就不多说了,下面以TFT屏(ILI9325)的驱动举个比如。

  TFT_RS —— PE2/A23
  TFT_WR —— PD5/NWE
  TFT_RD —— PD4/NOE
  数据线衔接FSMC的数据接口,TFT屏背光运用PWM操控。
  例程如下:
#define TFT_Command ((uint32_t)0x60000000)
#define TFT_Data    ((uint32_t)0x61000000)   // FSMC_A23(16位) 留意16位与8位的地址核算方法不一样
                          // 8位地址 ——0x60800000
                          // 16位地址——0x61000000
/*——————————————————————————-*/
void TFT_IO_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStructure;

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5
            | GPIO_Pin_14 | GPIO_Pin_15// | GPIO_Pin_7
            | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;
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_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_Pin_2;
GPIO_Init(GPIOE, &GPIO_InitStructure);

}
/*——————————————————————————-*/
void TFT_FSMC_Configuration(void)
{
FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;
FSMC_NORSRAMTimingInitTypeDef p;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC , ENABLE);

TFT_IO_Configuration();

p.FSMC_AddressSetupTime = 1;
p.FSMC_AddressHoldTime = 0;
p.FSMC_DataSetupTime = 2;
p.FSMC_BusTurnAroundDuration = 0;
p.FSMC_CLKDivision = 0;
p.FSMC_DataLatency = 0;
p.FSMC_AccessMode = FSMC_AccessMode_B;

FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM1;   //扩展NORBANK的第1个子BANK
FSMC_NORSRAMInitStructure.FSMC_DataAddressMux = FSMC_DataAddressMux_Disable;  //不运用总线复用
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;   //扩展类型为SRAM
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;  // 16位总线宽度
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_WriteBurst = FSMC_WriteBurst_Disable;
FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct = &p;   //指向界说的BTR结构
FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct = &p;
FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure);

FSMC_NORSRAMCmd(FSMC_Bank1_NORSRAM1, ENABLE);
}

/*—————————————*/
void TFT_Write_com(u16 dat) //发送指令
{
  *(__IO uint16_t *) (TFT_Command)= dat;
}
/*—————————————*/
void TFT_Write_dat(u16 dat)// 发送数据
{
  *(__IO uint16_t *) (TFT_Data)= dat;
}

/*—————————————*/
u16 TFT_Read_dat(void)// 读数据
{
  return *(__IO uint16_t *) (TFT_Data);
}
/*—————————————*/
u16 TFT_ReadReg(u16 reg)
{
  *(__IO uint16_t *) (TFT_Command)= reg;
  return *(__IO uint16_t *) (TFT_Data);
}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qianrushi/272351.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部