1.0野火指南者lcd中FSMC的使用

本文详细介绍了FSMC的功能,包括其静态存储器接口(SRAM,ROM,NOR,PSRAM)、AHB接口的作用、外部设备地址映像、不同时序模式以及在CubeMX中的配置步骤,还涉及了GPIO初始化。重点展示了如何通过FSMC控制外部存储器并与CPU通信。
摘要由CSDN通过智能技术生成

目录

一.FSMC功能描述

     2.FSMC具有的静态存储器接口包括   :

二.FSMC框图

2.AHB 接口:

3.引脚作用:

三.外部设备地址映像

四.FSMC时序:

五.CubeMX配置FSMC的初始化过程:​编辑

六.FSMC初始化代码:



一.FSMC功能描述

     1.FSMC:灵活的静态存储器控制器 (可以控制扩展的内存).

     2.FSMC具有的静态存储器接口包括   :

                                        ─  静态随机存储器(SRAM)

                                       ─  只读存储器(ROM)

                                       ─  NOR闪存

                                       ─  PSRAM(4个存储器块)

      (FSMC通过接口与相应的内存模块连接就可以控制相应的内存模块。)


二.FSMC框图

1.在野火指南者lcd的应用中只使用NOR/PSRAM信号和公用信号的引脚。

2.AHB 接口:

 AHB接口为内部CPU和其它总线控制设备访问外部静态存储器提供了通道。
AHB操作被转换到外部设备的操作。当选择的外部存储器的数据通道是16或8位时,在AHB上的
32位数据会被分割成连续的16或8位的操作。
AHB时钟(HCLK)是FSMC的参考时钟。

(通俗理解:CPU通过AHB跟FSMS建立通信,FSMS又可以连接外部存储器,AHB上的数据位可以是8位,16位和32位,外部存储器接收或发送数据是固定的,FSMS可以对数据进行拼接和分割)

3.引脚作用:

NOR/PSRAM引脚作用
FSMC信号名称          信号方向       功能
NE[X]          输出片选,x = 1...4
NL(=NADV)            输出锁存使能(某些NOR闪存器件命名该信号为地址有效,NADV)
NBL[1]            输出高字节使能(存储器信号名称为:NUB)
NBL[0]          输出低字节使能(存储器信号名称为:NLB
CLK           输出时钟(同步突发模式使用)

             

公用引脚作用
FSMC信号名称          信号方向       功能
A[25:0]         输出     地址总线
D[15:0]      输入/输出     双向数据总线
NOE      输出     输出使能
NWE     输出     写使能
NWAIT     输入X闪存要求FSMC等待的信号,X=NOR,PSRAM...

三.外部设备地址映像

1.从FSMC的角度看,可以把外部存储器划分为固定大小为256M字节的四个存储块

● 存储块1用于访问最多4个NOR闪存或PSRAM存储设备。这个存储区被划分为4个
NOR/PSRAM区并有4个专用的片选。

● 存储块2和3用于访问NAND闪存设备,每个存储块连接一个NAND闪存。

● 存储块4用于访问PC卡设备

每一个存储块上的存储器类型是由用户在配置寄存器中定义的

(野火指南者lcd中只用到了块1)

FSMC存储块:

FSMC通过时序来控制内存。


四.FSMC时序:

1.FSMC 外设支持输出多种不同的时序以便于控制不同的存储器,它具有 ABCD 四种模式,下面
仅针对控制异步 NOR FLASH 使用的模式 B 进行讲解。

                                      FSMC 读 NOR FLASH 的时序图:

FSMC 写 NOR FLASH 的时序图:

2.野火指南者lcd中利用了, FSMC 模拟 8080 时序:

                      FSMC 模式 B 时序与 8080 时序对比

对比 FSMC NOR/PSRAM 中的模式 B 时序与 ILI9341 液晶控制器芯片使用的 8080 时
序可发现,这两个时序是十分相似的 (除了 FSMC 的地址线 A 和 8080 的 D/CX 线,可以说是完全一样)

1. 对于 FSMC 和 8080 接口,前四种信号线都是完全一样的,仅仅是 FSMC 的地址信号线 A[25:0] 与8080 的数据/命令选择线 D/CX 有区别。而对于 D/CX 线,它为高电平的时候表示数值,为低电平的时候表示命令,如果能使用 FSMC 的 A 地址线根据不同的情况产生对应的电平,那么就完
全可以使用 FSMC 来产生 8080 接口需要的时序了。 

2.把 FSMC 的 A0 地址线 (也可以使用其它 A1/A2 等地址线) 与ILI9341 芯片 8080 接口的 *D/CX 信号线连接 ,那么当 A0 为高电平时 (即 D/CX 为高电平),数据线 D[15:0] 的信号会被 ILI9341 理解为数值,若 A0 为低电平时 (即 D/CX 为低电平),传输的信号则会被理解为命令


液晶屏的信号线及 8080 时序:

 液晶屏引出的信号线说明:

这些信号线即 8080 通讯接口,X 的表示低电平有效,通讯的内容主要包括命令和显存数据.

1. 写命令时序由片选信号 CSX 拉低开始,对数据/命令选择信号线 D/CX 也置低电平表示写入的是命令地址,以写信号 WRX 为低读信号RDX 为高表示数据传输方向为写入,同时,在数据线 D[17:0](或 D[15:0]) 输出命令地址,在第二个传输阶段传送的是命令的参数,所以 *D/CX 要置高电平 *,表示写入的是数据,数据是某些指令带有的参数。

2.当需要把像素数据写入 GRAM 时,过程很类似,把片选信号 CSX 拉低后,再把数据/命令选择信号线 D/CX 置为高电平,这时由 D[17:0] 传输的数据则会被 ILI9341 保存至它的 GRAM 中。


  • 五.CubeMX配置FSMC的初始化过程:


 

六.FSMC初始化代码:

1.FSMC初始化配置函数 :

void MX_FSMC_Init(void)
{

  FSMC_NORSRAM_HandleTypeDef hsram1;

  SRAM_TimingTypeDef Timing = {0};

  /** 执行SRAM1内存初始化顺序*/
  hsram1.Instance = FSMC_NORSRAM_DEVICE;                                     //基地址
  hsram1.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;              //扩展模式寄存器地址


  /* hsram1.Init */
  hsram1.Init.NSBank = FSMC_NORSRAM_BANK1;                     //设置要控制的块区域
  hsram1.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE;    //设置地址总线与数据总线是否复用
  hsram1.Init.MemoryType =  FSMC_MEMORY_TYPE_NOR  ;               //设置存储器的类型
  hsram1.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16;   //设置存储器的数据宽度
  hsram1.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE;  //设置是否支持突发访问模式
  hsram1.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW;//设置等待信号的极性
  hsram1.Init.WrapMode = FSMC_WRAP_MODE_DISABLE;                 //设置是否支持对齐的突发模式
  hsram1.Init.WaitSignalActive = FSMC_WAIT_TIMING_BEFORE_WS;     //配置等待信号在等待前有效还是等待期间有效
  hsram1.Init.WriteOperation = FSMC_WRITE_OPERATION_ENABLE;      //设置是否写使能
  hsram1.Init.WaitSignal = FSMC_WAIT_SIGNAL_DISABLE;             //设置是否使能等待状态插入
  hsram1.Init.ExtendedMode = FSMC_EXTENDED_MODE_DISABLE;         //设置是否使能扩展模式
  hsram1.Init.AsynchronousWait = FSMC_ASYNCHRONOUS_WAIT_DISABLE; //设置是否使能等待信号
  hsram1.Init.WriteBurst = FSMC_WRITE_BURST_DISABLE;             //设置是否使能写突发操作


  /* 时间设置 */
  Timing.AddressSetupTime = 15;           //地址建立时间
  Timing.AddressHoldTime =15;            //地址保持时间
  Timing.DataSetupTime = 255;             //数据建立时间
  Timing.BusTurnAroundDuration = 10;      //总线转换周期
  Timing.CLKDivision = 16;                //时钟分频因子
  Timing.DataLatency = 2;                //数据延迟时间
  Timing.AccessMode = FSMC_ACCESS_MODE_A;
  /* ExtTiming */

  if (HAL_SRAM_Init(&hsram1, &Timing, NULL) != HAL_OK)
  {
    Error_Handler( );
  }

  /** 断开NADV
  */

  __HAL_AFIO_FSMCNADV_DISCONNECTED();
}


2.FSMC_GPIO初始化函数 :

static uint32_t FSMC_Initialized = 0;

/* FSMC初始化硬件层配置函数 */
static void HAL_FSMC_MspInit(void){
   
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if (FSMC_Initialized) {
    return;
  }
  FSMC_Initialized = 1;

  /* 使能时钟 */
  __HAL_RCC_FSMC_CLK_ENABLE();
  __HAL_RCC_GPIOE_CLK_ENABLE();
  __HAL_RCC_GPIOD_CLK_ENABLE();

  /** FSMC GPIO配置
  PE7   ------> FSMC_D4
  PE8   ------> FSMC_D5
  PE9   ------> FSMC_D6
  PE10   ------> FSMC_D7
  PE11   ------> FSMC_D8
  PE12   ------> FSMC_D9
  PE13   ------> FSMC_D10
  PE14   ------> FSMC_D11
  PE15   ------> FSMC_D12
  PD8   ------> FSMC_D13
  PD9   ------> FSMC_D14
  PD10   ------> FSMC_D15
  PD11   ------> FSMC_A16
  PD14   ------> FSMC_D0
  PD15   ------> FSMC_D1
  PD0   ------> FSMC_D2
  PD1   ------> FSMC_D3
  PD4   ------> FSMC_NOE
  PD5   ------> FSMC_NWE
  PD7   ------> FSMC_NE1
 
  */
  /* GPIO_Init结构体 */
  GPIO_InitStruct.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_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

  /* GPIO_Init结构体 */
  GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
                          |GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1
                          |GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);


  /*配置GPIO引脚 : 
    PD12------>LCD_BL    //控制背光
  */
  GPIO_InitStruct.Pin = GPIO_PIN_12;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  /*配置GPIO引脚 : 
     PE1 ------>LCD_RST  //控制复位
  */
  GPIO_InitStruct.Pin = GPIO_PIN_1;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_PULLUP ;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
}

以上代码我存放在Gitee上:驱动模块: 平常练习中对一些,代码模块化处理icon-default.png?t=N7T8https://gitee.com/xuji-group_0/driver-module.git

文件名为FSMC. 

  • 30
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值