前言:
从51学到STM32的FSMC 时候,我感觉很难,开始对着视频一顿猛刷,看的我雨里雾里。不知道这到底是个啥玩意。后来,慢慢往后学,我才顿悟了,说简单点,FSMC就是一个方便使用者来连接外挂设备的一个工具,比如你要用到TFTLCD彩屏,外扩的SRAM芯片,你当然可以用软件去配置引脚来模拟器件通信的时序,就像在51里面软件模拟IIC时序来驱动1302一样,但是这样无疑会很复杂,那么,为了方便使用,STM32就造出来个FSMC来硬件实现这个时序问题,你要做的就是配置寄存器即可。
1:FSMC的功能简介
灵活的静态存储控制器(FSMC),其主要用途:
将AHB数据通信事务转换为适当的外部器件协议
满足外部器件的访问时序要求
STM32的FSMC接口支持包括(连接静态存储器映射的器件)
静态随机访问存储器(SRAM):是随机存取存储器的一种,所谓“静态”,是指这种存储器只要保持通电,就可以一直保持数据
只读存储器(ROM):只读存储器,只读不可写,断电可以保持数据,更改数据只能在特定条件下
NOR Flash/OneNAND Flash:非易失闪存技术
PSRAM(4个存储区域):伪静态随机存储器
2:FSMC框图
FSMC包含四个主要模块:
AHB接口(包括FSMC配置寄存器)
NOR Flash/PSRAM 控制器
NAND Flash/PC卡控制器
外部器件接口
1:AHB接口:CPU和其他AHB总线主设备可通过该AHB从设备接口访问外部静态存储器,我们所访问的外部存储器一般是16或8位宽,而AHB是32位宽,所以用AHB去访问时。会划分成多个16或8位访问。
2:NOR Flash/PSRAM FSMC会生成适当的信号时序,以驱动以下类型的存储器
异步SRAM和ROM : 8位,16位,32位
PSRAM :异步模式,突发模式,复用或非复用
NOR Flash :异步模式或突发模式,复用或非复用
至于各种模式下引脚的定义,数据手册中都有详细的概述,不多说
3:NAND Flash/PC卡控制器 FSMC会生成相应的信号时序,用于驱动以下类型的设备
NAND Flash :8位,16位
16位PC卡兼容设备
4:外部器件接口
从FSMC的角度,外部存储器被划分为4个固定大小的存储区域,每个存储区域的大小位256M
存储区域1可连接多达4个NOR Flash或PSRAM存储器器件,带4个专用片选信号
存储区域2、3用于连接NAND Flash器件(每个存储区域一个器件)
存储区域4用于连接PC卡设备
Bank1也是我们最长使用的一个区
NOR/PSRAM地址映射:
Bank1的256M字节空间由28根地址线(HADDR[27:0])寻址,这里HADDR,是内部AHB地址总线,其中HADDR[25:0]来自外部存储器地址FSMC_A[25:0],而HADDR[26:27]对4个区进行寻址,详细的瞅数据手册,
这里有一个理解难点
当Bank1接的是16位宽度存储器的时候:HADDR[25:1]->FSMC_A[24:0]
当Bank1接的是8位宽度存储器的时候:HADDR[25:0]->FSMC_A[25:0]
why?
往下瞅
3:FSMC HADDR与FSMC_A 的地址问题
首先说一个前提:STM32 单片机的一个地址(如:0x2000 0000)对应的数据是一个字节
也就是说如果定义一个16位数组 u16 temp[5] 如果temp[0]对应的地址是0x0000 0000 那么temp[1]对应的地址是0x0000 0002 (地址是加2,因为前面说了,32一个地址对应一个字节,U16,是两个字节)、、
假设此时我们有一个 64K*8bit 的sram
那很简单 stm32的A0~A15 与存储器A0~A15连接 大家很容易理解
若此时是 64K*16bit 的sram
也就是此时sram的一个地址对应两个字节 但是stm32是一个地址一个字节 这就出现了对准的问题
如果我们的地址线依然是stm32A0~A15 和 存储器的A0~A15 连接
如果stm32要从sram中读取前面提到数组中的temp[1]
stm32会给出0x0000002(二进制地址0000000000000010b) 可是对于我们这个sram来说 读到却是temp[2],因为sram一个地址就是一个16位数据,这个地方好好想一下,于32来说,要挪两下,而16位的SRAM不同,只需要挪一下。
为了解决这个问题 我们只需要在给sram送地址时 右移一位 再送地址 即可(sram的一个地址对应stm32两个地址的数据)
比如读取0x0000002 右移一位(即除2)为0x0001(000000000000001b) 此时对应的就是temp[1]
此时会有另外一个问题 每次都右移一位 A0没用吗 也即只能读写偶地址的数据吗?
这也就是NBL0和NBL1的作用了 如果你要进行字节操作
如stm32发送地址0x0000001读取一个字节 右移一位对应的是sram地址0x0000处的16位数据 FSMC会根据AO 来控制NBLO和NBL1若为10 读取高字节数据
所以呢 偶字节读写时仅NBL0有效,奇字节读写时仅NBL1有效 低电平有效)
4:FSMC寄存器介绍
关于FSMC的一些访问模式,就不写了,太多了,可以去看数据手册
关于寄存器的描述,也不都贴出来,看数据手册比我这好多了,主要来说一下寄存器的组合
在ST官方库提供的寄存器定义里面,并没有定义FSMC_BCRx,FSMC_BTRx,FSMC_BWTRx等这些个单独的寄存器,而是进行了一些组合,规律如下
FSMC_BCRx和FSMC_BTRx,组合成BTCR[8]寄存器组,他们的对应关系如下:
BTCR[0]对应FSMC_BCR1
BTCR[1]对应FSMC_BTR1
BTCR[2]对应FSMC_BCR2
BTCR[3]对应FSMC_BTR2
BTCR[4]对应FSMC_BCR3
BTCR[5]对应FSMC_BTR3
BTCR[6]对应FSMC_BCR4
BTCR[7]对应FSMC_BTR4
FSMC_BWTRx则组合成BWTR[7]他们的对应关系如下:
BWTR[0]对应FSMC_BWTR1
BWTR[2]对应FSMC_BWTR2
BWTR[4]对应FSMC_BWTR3
BWTR[6]对应FSMC_BWTR4
BWTR[1]、BWTR[3]和BWTR[5]保留,没有用到。
#define FSMC_Bank1 ((FSMC_Bank1_TypeDef *) FSMC_Bank1_R_BASE)
typedef struct
{
__IO uint32_t BTCR[8]; /*!< NOR/PSRAM chip-select control register(BCR) and chip-select timing register(BTR), Address offset: 0x00-1C */
} FSMC_Bank1_TypeDef;
#define FSMC_Bank1E ((FSMC_Bank1E_TypeDef *) FSMC_Bank1E_R_BASE)
typedef struct
{
__IO uint32_t BWTR[7]; /*!< NOR/PSRAM write timing registers, Address offset: 0x104-0x11C */
} FSMC_Bank1E_TypeDef;
要访问这些寄存器,就要访问这些数组中的元素了,这个还是很好理解
上一篇:STM32_IIC
下一篇:STM32地址映射、位带操作
推荐阅读最新更新时间:2024-11-10 15:31
设计资源 培训 开发板 精华推荐
- LTC3624HMSE-23.3 3.3V 输出电压、2A 同步降压稳压器、同步至 500kHz、强制连续模式的典型应用
- 实用5口千兆交换机[带壳]
- LTC3892IUH 高效率、双路 5V/12V 输出同步降压型 DC/DC 控制器的典型应用电路
- ACS712
- PCA9617A电平转换Fm+ I2C总线中继器驱动短电缆典型应用
- AM2DM-1209DH60-NZ ±9 Vout、2W 双路输出 DC-DC 转换器的典型应用
- DER-538 - 使用InnoSwitch3-CE的25W高功率充电器
- MC33071DR2G 高顺从电压灌电流转换器的典型应用
- LTC2326-18、18 位、250ksps、伪差分输入 ADC 的典型应用
- 2017全国大学生电子设计竞赛-板球-源码