STM32学习之FSMC

2023-10-13 22:38
文章标签 学习 stm32 fsmc

本文主要是介绍STM32学习之FSMC,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

上一篇介绍了TFTLCD的基础知识,这一篇来看看,FSMC的基本原理。

学习资料来自:STM32F407最小系统板开发指南-库函数版本_V1.1.pdf
正点原子,感谢原子哥的开源奉献
正点原子资料下载中心

硬件:
STM32F407ZGT6
2.8 LCD MODULE
一个摄像头

注意:
共分为3篇:

  1. STM32学习之TFTLCD
  2. STM32学习之FSMC
  3. STM32学习之使用TFTLCD

如果仅仅想要实现,可以直接去看最后一篇的使用,前边的基础知识可以跳过

STM32单片机学习资料均来自 正点原子 ,仅用于学习,如有侵权请联系我删除
本博客内容原创,创作不易,转载请注明

本文链接

个人博客:https://ronglin.fun/?p=99
PDF链接:见博客网站
CSDN: https://blog.csdn.net/RongLin02/article/details/121446071

基础知识

STM32F407 或 STM32F417 系列芯片都带有 FSMC 接口,本人的芯片为 STM32F407ZGT6,是带有 FSMC 接口的。
FSMC,即灵活的静态存储控制器,能够与同步或异步存储器和 16 位 PC 存储器卡连接,STM32F4 的 FSMC 接口支持包括 SRAM、NAND FLASH、NOR FLASH 和 PSRAM 等存储器。

SRAM与TFTLCD

STM32F4 的 FSMC 将外部设备分为 2 类:NOR/PSRAM 设备、NAND/PC 卡设备。他们共用地址数据总线等信号,他们具有不同的 CS 以区分不同的设备,比如我们用到的 TFTLCD 就是用的 FSMC_NE4 做片选,其实就是将 TFTLCD 当成 SRAM 来控制。
这里介绍下为什么可以把 TFTLCD 当成 SRAM 设备用:
首先我们了解下外部 SRAM的连接,外部 SRAM 的控制一般有:地址线(如 A0~A18)、数据线(如 D0~D15)、写信号(WE)、读信号(OE)、片选信号(CS),如果 SRAM 支持字节控制,那么还有 UB/LB 信号。而 TFTLCD 的信号在前边有介绍,包括:RS、D0~D15、WR、RD、CS、RST 和 BL 等,其中真正在操作 LCD 的时候需要用到的就只有:RS、D0~D15、WR、RD 和 CS。其操作时序和 SRAM的控制完全类似,唯一不同就是 TFTLCD 有 RS 信号,但是没有地址信号。
TFTLCD 通过 RS 信号来决定传送的数据是数据还是命令,本质上可以理解为一个地址信号,比如我们把 RS 接在 A0 上面,那么当 FSMC 控制器写地址 0 的时候,会使得 A0 变为 0,对 TFTLCD 来说,就是写命令。而 FSMC 写地址 1 的时候,A0 将会变为 1,对 TFTLCD 来说,就是写数据了。这样,就把数据和命令区分开了,他们其实就是对应 SRAM 操作的两个连续地址。当然 RS 也可以接在其他地址线上, STM32F407 最小系统板是把 RS 连接在 A6 上面的。
STM32F4 的 FSMC 支持 8/16/32 位数据宽度,我们这里用到的 LCD 是 16 位宽度的,所以在设置的时候,选择 16 位宽就 OK 了。

映射原理

以下内容涉及到计算机组成原理中存储器的相关知识
我们再来看看 FSMC 的外部设备地址映像,STM32F4的 FSMC 将外部存储器划分为固定大小为 256M 字节的四个存储块,,如图 16.1.2.2 所示:
在这里插入图片描述
从上图可以看出,FSMC 总共管理 1GB 空间,拥有 4 个存储块(Bank),因为我们的屏幕需要 240*320*18/8 =172800 仅用到的是块 1即可,所以仅讨论块 1 的相关配置,其他块的配置,请参考《STM32F4xx 中文参考手册》第 32 章(1191 页)的相关介绍。
STM32F4 的 FSMC 存储块 1(Bank1)被分为 4 个区,每个区管理 64M 字节空间,每个区都有独立的寄存器对所连接的存储器进行配置。Bank1 的 256M 字节空间由 28 根地址线(HADDR[27:0])寻址。这 里 HADDR 是内 部 AHB 地址总 线,其 中 HADDR[25:0]来自外部存储器地址FSMC_A[25:0],而 HADDR[26:27]对 4 个区进行寻址。如表 16.1.2.1 所示:
在这里插入图片描述
表 16.1.2.1 中,我们要特别注意 HADDR[25:0]的对应关系:

  • 当 Bank1 接的是 16 位宽度存储器的时候:HADDR[25:1] -> FSMC_A[24:0]
  • 当 Bank1 接的是 8 位宽度存储器的时候:HADDR[25:0] -> FSMC_A[25:0]

这里为什么这样接,可以参考博客:https://www.cnblogs.com/tiange-137/p/11820412.html
不论外部接 8 位/16 位宽设备,FSMC_A[0]永远接在外部设备地址 A[0]。
这里,TFTLCD使用的是 16 位数据宽度,所以 HADDR[0]并没有用到,只有 HADDR[25:1]是有效的,对应关系变为:HADDR[25:1] -> FSMC_A[24:0],相当于右移了一位,这里请大家特别留意。
另外,HADDR[27:26]的设置,是不需要我们干预的,比如:当你选择使用 Bank1 的第三个区,即使用 FSMC_NE3 来连接外部设备的时候,即对应了 HADDR[27:26]=10,我们要做的就是配置对应第 3区的寄存器组,来适应外部设备即可。STM32F4 的 FSMC 各Bank配置寄存器如表 16.1.2.2所示:
在这里插入图片描述

控制寄存器

总述

对于 NOR FLASH 控制器,主要是通过 FSMC_BCRx、FSMC_BTRx 和 FSMC_BWTRx 寄存器设置(其中 x=1~4,对应 4 个区)。通过这 3 个寄存器,可以设置 FSMC 访问外部存储器的时序参数,拓宽了可选用的外部存储器的速度范围。
FSMC 的 NOR FLASH 控制器支持同步和异步突发两种访问方式。

  • 选用同步突发访问方式时,FSMC 将 HCLK(系统时钟)分频后,发送给外部存储器作为同步时钟信号 FSMC_CLK。此时需要的设置的时间参数有 2 个:
    1. HCLK 与 FSMC_CLK 的分频系数(CLKDIV),可以为 2~16 分频;
    2. 同步突发访问中获得第 1 个数据所需要的等待延迟(DATLAT)。
  • 对于异步突发访问方式,FSMC 主要设置 3 个时间参数:地址建立时间(ADDSET)、数据建立时间(DATAST)和地址保持时间(ADDHLD)。FSMC 综合了 SRAM/ROM、PSRAM 和 NOR Flash 产品的信号特点,定义了 4 种不同的异步时序模型。
    在这里插入图片描述
    选用不同的时序模型时,需要设置不同的时序参数,在实际扩展时,根据选用存储器的特征确定时序模型,从而确定各时间参数与存储器读/写周期参数指标之间的计算关系;利用该计算关系和存储芯片数据手册中给定的参数指标,可计算出 FSMC 所需要的各时间参数,从而对时间参数寄存器进行合理的配置。本章,我们使用异步模式 A(ModeA)方式来控制 TFTLCD

模式 A 支持独立的读写时序控制,这个对我们驱动 TFTLCD 来说非常有用,因为 TFTLCD在读的时候,一般比较慢,而在写的时候可以比较快,如果读写用一样的时序,那么只能以读的时序为基准,从而导致写的速度变慢,或者在读数据的时候,重新配置 FSMC 的延时,在读操作完成的时候,再配置回写的时序,这样虽然也不会降低写的速度,但是频繁配置,比较麻烦。而如果有独立的读写时序控制,那么我们只要初始化的时候配置好,之后就不用再配置,既可以满足速度要求,又不需要频繁改配置。

接下来我们讲解一下 Bank1 的几个控制寄存器

FSMC_BCRx

首先,我们介绍 SRAM/NOR 闪存片选控制寄存器:FSMC_BCRx(x=1~4),该寄存器各位描述如图 16.1.2.5 所示:
在这里插入图片描述
该寄存器我们在本章用到的设置有:EXTMOD、WREN、MWID、MTYP 和 MBKEN 这几
个设置,我们将逐个介绍。

  • EXTMOD:扩展模式使能位,也就是是否允许读写不同的时序,很明显,我们本章需要读写不同的时序,故该位需要设置为 1。
  • WREN:写使能位。我们需要向 TFTLCD 写数据,故该位必须设置为 1。
  • MWID[1:0]:存储器数据总线宽度。00,表示 8 位数据模式;01 表示 16 位数据模式;10 和 11 保留。我们的 TFTLCD 是 16 位数据线,所以设置 WMID[1:0]=01。
  • MTYP[1:0]:存储器类型。00 表示 SRAM、ROM;01 表示 PSRAM;10 表示 NOR FLASH;11保留。前面提到,我们把 TFTLCD 当成 SRAM 用,所以需要设置 MTYP[1:0]=00。
  • MBKEN:存储块使能位。这个容易理解,我们需要用到该存储块控制 TFTLCD,当然要使能这个存储块了。

FSMC_BTRx

我们看看 SRAM/NOR 闪存片选时序寄存器:FSMC_BTRx(x=1~4),该寄存器各位描述如图 16.1.2.6 所示
在这里插入图片描述
这个寄存器包含了每个存储器块的控制信息,可以用于 SRAM、ROM 和 NOR 闪存存储器。如果 FSMC_BCRx 寄存器中设置了 EXTMOD 位,则有两个时序寄存器分别对应(本寄存器)和写操作(FSMC_BWTRx 寄存器)。因为我们要求读写分开时序控制,所以 EXTMOD 是使能了的,也就是本寄存器是读操作时序寄存器,控制读操作的相关时序。本章我们要用到的设置有:
ACCMOD、DATAST 和 ADDSET 这三个设置。

  • ACCMOD[1:0]:访问模式。00 表示访问模式 A;01 表示访问模式 B;10 表示访问模式 C;11 表示访问模式 D,本章我们用到模式 A,故设置为 00。
  • DATAST[7:0]:数据保持时间。0 为保留设置,其他设置则代表保持时间为: DATAST 个 HCLK 时钟周期,最大为 255 个 HCLK 周期。对 ILI9341 来说,其实就是 RD 低电平持续时间,一般为 355ns。而一个 HCLK 时钟周期为 6ns 左右(1/168Mhz),为了兼容其他屏,我们这里设置 DATAST 为 60,也就是 60 个 HCLK 周期,时间大约是 360ns。
  • ADDSET[3:0]:地址建立时间。其建立时间为:ADDSET 个 HCLK 周期,最大为 15 个 HCLK周期。对 ILI9341 来说,这里相当于 RD 高电平持续时间,为 90ns,我们设置 ADDSET 为 15,即 15*6=90ns。

FSMC_BWTRx

我们再来看看 SRAM/NOR 闪写时序寄存器:FSMC_BWTRx(x=1~4),该寄存器各
位描述如图 16.1.2.7 所示:
在这里插入图片描述
该寄存器在本章用作写操作时序控制寄存器,需要用到的设置同样是:ACCMOD、DATAST和 ADDSET 这三个设置。这三个设置的方法同 FSMC_BTRx 一模一样,只是这里对应的是写操作的时序,ACCMOD 设置同 FSMC_BTRx 一模一样,同样是选择模式 A,另外 DATAST 和ADDSET 则对应低电平和高电平持续时间,对 ILI9341 来说,这两个时间只需要 15ns 就够了,比读操作快得多。所以我们这里设置 DATAST 为 2,即 3 个 HCLK 周期,时间约为 18ns。然后ADDSET 设置为 3,即 3 个 HCLK 周期,时间为 18ns。

至此,我们对 STM32F4 的 FSMC 介绍就差不多了,通过以上两个小节的了解,我们可以开始写 LCD 的驱动代码了。不过,这里还要给大家做下科普,在 MDK 的寄存器定义里面,并没有定义 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]保留,没有用到。
通过上面的讲解,通过对 FSMC 相关的寄存器的描述,大家对 FSMC 的原理有了一个初步的认识,如果还不熟悉的朋友,请一定要搜索网络资料理解 FSMC 的原理。只有理解了原理,使用库函数才可以得心应手。

库函数讲解

FSMC 初始化函数

总述

根据前面的讲解,初始化 FSMC 主要是初始化三个寄存器 FSMC_BCRx,FSMC_BTRx,FSMC_BWTRx,固件库提供了 3 个 FSMC 初始化函数初始化这三个参数,分别为

    FSMC_NORSRAMInit();FSMC_NANDInit();FSMC_PCCARDInit();

这三个函数分别用来初始化 4 种类型存储器。这里根据名字就很好判断对应关系。用来初始化NOR 和 SRAM 使用同一个函数 FSMC_NORSRAMInit()。我们使用的 FSMC 初始化函数为 FSMC_NORSRAMInit()。下面我们看看函数定义:

void FSMC_NORSRAMInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct);

这个函数只有一个入口参数,也就是 FSMC_NORSRAMInitTypeDef 类型指针变量,这个结构体的成员变量非常多,因为 FSMC 相关的配置项非常多。

typedef struct
{uint32_t FSMC_Bank;uint32_t FSMC_DataAddressMux;uint32_t FSMC_MemoryType;uint32_t FSMC_MemoryDataWidth;uint32_t FSMC_BurstAccessMode;uint32_t FSMC_AsynchronousWait;uint32_t FSMC_WaitSignalPolarity;uint32_t FSMC_WrapMode;uint32_t FSMC_WaitSignalActive;uint32_t FSMC_WriteOperation;uint32_t FSMC_WaitSignal;uint32_t FSMC_ExtendedMode;uint32_t FSMC_WriteBurst;FSMC_NORSRAMTimingInitTypeDef* FSMC_ReadWriteTimingStruct;FSMC_NORSRAMTimingInitTypeDef* FSMC_WriteTimingStruct;
}FSMC_NORSRAMInitTypeDef;

从这个结构体我们可以看出,前面有 13 个基本类型(unit32_t)的成员变量,这 13 个参数是用来配置片选控制寄存器 FSMC_BCRx
最后面还有两个SMC_NORSRAMTimingInitTypeDef 指针类型的成员变量。前面我们讲到,FSMC 有读时序和写时序之分,所以这里就是用来设置读时序和写时序的参数了, 也就是说,这两个参数是用来配置寄存器 FSMC_BTRxFSMC_BWTRx,后面我们会讲解到。
下面我们主要来看看模式 A
下的相关配置参数:

  • 参数 FSMC_Bank 用来设置使用到的存储块标号和区号,前面讲过,我们是使用的存储块 1 区号 4,所以选择值为 FSMC_Bank1_NORSRAM4
  • 参数 FSMC_MemoryType 用来设置存储器类型,我们这里是 SRAM,所以选择值为FSMC_MemoryType_SRAM
  • 参数 FSMC_MemoryDataWidth 用来设置数据宽度,可选 8 位还是 16 位,这里我们是 16 位数据宽度,所以选择值为 FSMC_MemoryDataWidth_16b
  • 参数 FSMC_WriteOperation 用来设置写使能,毫无疑问,我们前面讲解过我们要向 TFT 写数据,所以要写使能,这里我们选择 FSMC_WriteOperation_Enable
  • 参数 FSMC_ExtendedMode 是设置扩展模式使能位,也就是是否允许读写不同的时序,这里我们采取的读写不同时序,所以设置值为 FSMC_ExtendedMode_Enable
    其余参数可以参考中文参考手册了解相关参数的意思。

读写时序参数

接 下 来 我 们 看 看 设 置 读 写 时 序 参 数 的 两 个 变 量 FSMC_ReadWriteTimingStructFSMC_WriteTimingStruct,他们都是 FSMC_NORSRAMTimingInitTypeDef 结构体指针类型,这两个参数在初始化的时候分别用来初始化片选控制寄存器 FSMC_BTRx 和写操作时序控制寄存器 FSMC_BWTRx。 下面我们看看 FSMC_NORSRAMTimingInitTypeDef 类型的定义:

typedef struct
{uint32_t FSMC_AddressSetupTime;uint32_t FSMC_AddressHoldTime;uint32_t FSMC_DataSetupTime;uint32_t FSMC_BusTurnAroundDuration;uint32_t FSMC_CLKDivision;uint32_t FSMC_DataLatency;uint32_t FSMC_AccessMode;
}FSMC_NORSRAMTimingInitTypeDef;

这个结构体有 7 个参数用来设置 FSMC 读写时序。其实这些参数的意思我们前面在讲解 FSMC 的时序的时候有提到,主要是设计地址建立保持时间,数据建立时间等等配置,对于我们的实验中,读写时序不一样,读写速度要求不一样,所以对于参数 FSMC_DataSetupTime 设置了不同的值,大家可以对照理解一下。记住,这些参数的意义在前面讲解 FSMC_BTRx 和 FSMC_BWTRx 寄存器的时候都有提到,大家可以翻过去看看。

FSMC 使能函数

FSMC 对不同的存储器类型同样提供了不同的使能函数:

void FSMC_NORSRAMCmd(uint32_t FSMC_Bank, FunctionalState NewState);
void FSMC_NANDCmd(uint32_t FSMC_Bank, FunctionalState NewState);
void FSMC_PCCARDCmd(FunctionalState NewState);

这个就比较好理解,我们这里不讲解,我们是 SRAM,所以使用的是第一个函数。

总结

FSMC部分的知识比较枯燥和困难,和计算机组成原理中的存储器有很多联系,最后一篇是用 原子哥 的代码了,终于到实战部分了!未完待续,=w=

这篇关于STM32学习之FSMC的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/206324

相关文章

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

线性代数|机器学习-P36在图中找聚类

文章目录 1. 常见图结构2. 谱聚类 感觉后面几节课的内容跨越太大,需要补充太多的知识点,教授讲得内容跨越较大,一般一节课的内容是书本上的一章节内容,所以看视频比较吃力,需要先预习课本内容后才能够很好的理解教授讲解的知识点。 1. 常见图结构 假设我们有如下图结构: Adjacency Matrix:行和列表示的是节点的位置,A[i,j]表示的第 i 个节点和第 j 个