你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】STM32实例-FSMC 配置步骤

[复制链接]
STMCU小助手 发布时间:2022-6-26 16:38
    介绍下如何使用库函数对 FSMC 进行配置。这个也是在编写程序中必须要了解的。具体步骤如下:(FSMC 相关库函数在 stm32f10x_fsmc.c 和stm32f10x_fsmc.h 文件中)
(1)FSMC 初始化
    FSMC 的初始化主要是配置 FSMC_BCRx, FSMC_BTRx,FSMC_BWTRx 这三个寄存器,固件库内提供了 3 个初始化函数对这些寄存器配置。FSMC 初始化库函数如下:
  1. FSMC_NORSRAMInit();# q+ i7 n  ^$ \8 R' l
  2. FSMC_NANDInit();3 n7 `3 ^' |& p' J6 B- H
  3. FSMC_PCCARDInit();
复制代码

) f1 p% G( E0 w# h0 k: H: V' B5 f
    这三个函数分别用来初始化 4 种类型存储器。这里根据名字就很好判断对
应关系。用来初始化 NOR 和 SRAM 使用同一个函数FSMC_NORSRAMInit()。所以我们之后使用的 FSMC 初始化函数为 FSMC_NORSRAMInit()。该初始化函数原型是:
  1. void FSMC_NORSRAMInit(FSMC_NORSRAMInitTypeDef*FSMC_NORSRAMInitStruct);
复制代码

- k/ q2 Z* n! y2 `+ [2 j) x
    这个函数只有一个参数,是一个结构体指针变量,结构体类型是FSMC_NORSRAMInitTypeDef,其内成员变量非常多,因为 FSMC 相关的配置项非常多。下面我们简单介绍下它的成员:
  1. typedef struct
    $ Y/ \# U4 a- M' s- S! S
  2. {& X+ }( Z4 L9 V- y! K- i( A
  3. uint32_t FSMC_Bank;9 ~, l6 J) A& g: m; B; u2 @
  4. uint32_t FSMC_DataAddressMux;
    ( W8 E  t9 u9 I3 @. \* o4 c
  5. uint32_t FSMC_MemoryType;
    3 ^# x+ g- G" \
  6. uint32_t FSMC_MemoryDataWidth;
    2 Z: q, h# V; o
  7. uint32_t FSMC_BurstAccessMode;3 f9 m: V; _/ C4 `
  8. uint32_t FSMC_AsynchronousWait;
      F, I% @* ~8 x* K# h* P8 u
  9. uint32_t FSMC_WaitSignalPolarity;! W1 C# M- `3 x  A) B
  10. uint32_t FSMC_WrapMode;' _  s+ Q% M- ^2 e: X8 T+ c
  11. uint32_t FSMC_WaitSignalActive;
    * r7 s, N5 j; H# _* O
  12. uint32_t FSMC_WriteOperation;
    3 `; [, N4 M/ e+ x# U
  13. uint32_t FSMC_WaitSignal;
    * }  o; L, x8 b! h; |) U
  14. uint32_t FSMC_ExtendedMode;. X  q( s- k3 e7 u/ _
  15. uint32_t FSMC_WriteBurst;
    ( c5 m9 `! k9 I: E- g
  16. FSMC_NORSRAMTimingInitTypeDef* FSMC_ReadWriteTimingStruct;
    / d( f5 i# P$ H: j+ v* f. n5 K
  17. FSMC_NORSRAMTimingInitTypeDef* FSMC_WriteTimingStruct;" Q% R3 l. C# d
  18. }FSMC_NORSRAMInitTypeDef;
复制代码
' ^1 U% {. W" U6 }" [* f1 |  ]
    从这个结构体我们可以看出,前面有 13 个基本类型( unit32_t)的成员
变量,这 13 个参数是用来配置片选控制寄存器 FSMC_BCRx。最后面还有两个SMC_NORSRAMTimingInitTypeDef 指针类型的成员变量。前面我们讲到,FSMC 有读时序和写时序之分,所以这里就是用来设置读时序和写时序的参数了,也就是说,这两个参数是用来配置寄存器 FSMC_BTRx 和 FSMC_BWTRx,后面我们会讲解到。下面我们就来看看这些成员:
FSMC_Bank:用来设置使用到的存储块标号和区号,本章实验我们是使用的
存储块 1 区号 4,所以选择值为 FSMC_Bank1_NORSRAM4。
FSMC_DataAddressMux:用于配置 FSMC 的数据线与地址线是否复用。FSMC支持数据与地址线复用或非复用两种模式。在非复用模式下 16 位数据线及 26位地址线分开始用;复用模式则低 16 位数据/地址线复用,仅对 NOR 和 PSRAM有效。在复用模式下,推荐使用地址锁存器以区分数据与地址。本实验使用FSMC模拟 8080 时序,仅使用一根地址线 A10 提供 8080 的 RS 信号,所以不需要复用,即设置为
  1. FSMC_DataAddressMux_Disable
复制代码

* b9 q! N  L0 f9 @
FSMC_MemoryType:用来设置FSMC外接的存储器类型, 可选类型为 NOR FLASH模式、PSARM 模式及 SRAM 模式。我们这里把 TFTLCD当做 SRAM 使用,所以选择值为 FSMC_MemoryType_SRAM。
FSMC_MemoryDataWidth:用来设置 FSMC 接口的数据宽度,可选择 8 位还是16 位, 这里我们是 16 位数据宽度, 所以选择值为 FSMC_MemoryDataWidth_16b。
FSMC_WriteOperation:用于配置写操作使能,如果禁止了写操作,FSMC 不会产生写时序,但仍可从存储器中读出数据。本实验需要向 TFTLCD内写数据,所以要写使能,配置为 FSMC_WriteOperation_Enable(写使能)。
FSMC_ExtendedMode:用于配置是否使用扩展模式,在扩展模式下,读时序和写时序可以使用独立时序模式。如读时序使用模式 A,写时序使用模式 B,这些 A、B、C、D 模式实际上差别不大,主要是在使用数据/地址线复用的情况下,FSMC 信号产生的时序不一样。
FSMC_BurstAccessMode:用于配置访问模式。FSMC 对存储器的访问分为异步模式和突发模式(同步模式)。在异步模式下,每次传送数据都需要产生一个确定的地址, 而突发模式可以在开始时提供一个地址之后, 把数据成组地连续写入。
    本实验使用异步模式 FSMC_BurstAccessMode_Disable。
    FSMC_WaitSignalPolarity(配置等待信号极性)、FSMC_WrapMode(配置是否使用非对齐方式)、FSMC_WaitSignalActive(配置等待信号什么时期产生)、FSMC_WaitSignal(配置是否使用等待信号)、FSMC_WriteBurst(配置是否允许突发写操作),这些成员均需要在突发模式开启后配置才有效。本实验使用的是异步模式,所以这些成员的参数没有意义。
FSMC_ReadWriteTimingStruct 和 FSMC_WriteTimingStruct:用于设置读写时序。这两个变量都是 FSMC_NORSRAMTimingInitTypeDef 结构体指针类型。这两个参数在初始化的时候分别用来初始化片选控制寄存器 FSMC_BTRx 和写操作时序控制寄存器 FSMC_BWTRx。                                FSMC_NORSRAMTimingInitTypeDef结构体如下:
  1. typedef struct
    $ h3 a9 h( r  a6 {& N
  2. {
    2 H6 J7 }: u! {7 @& O5 S
  3. uint32_t FSMC_AddressSetupTime;//地址建立时间# {& J% O0 Z$ p* [
  4. uint32_t FSMC_AddressHoldTime;//地址保持时间+ R/ Y) X0 v7 U7 d* Y* F
  5. uint32_t FSMC_DataSetupTime;//数据建立时间
    . ^$ p" p  ~( D. _- ]+ ~) T
  6. uint32_t FSMC_BusTurnAroundDuration;//总线恢复时间
    5 L. a0 `' t5 D  M( x4 y/ @" L
  7. uint32_t FSMC_CLKDivision;//时钟分频: m+ g% ]# V/ }7 f  H* L
  8. uint32_t FSMC_DataLatency;//数据保持时间/ ]  j% ?& ~6 ?# G
  9. uint32_t FSMC_AccessMode;//访问模式9 P+ i5 D  ]8 g! U* g- p  X* l* _
  10. }FSMC_NORSRAMTimingInitTypeDef;
复制代码
6 B; M5 K7 b. B0 d8 @4 s0 H  O
    这些成员主要用于设计地址建立保持时间,数据建立时间等配置,这些时间是由 HCLK 经过成员时钟分频得来的, 该分频值在成员 FSMC_CLKDivision(时钟分频)中设置,其中 FSMC_AccessMode(访问模式)成员的设置只在开启了扩展模式才有效,而且开启了扩展模式后,读时序和写时序的设置可以是独立的。本实验中我们需要读写速度不一样,所以开启了扩展模式并且对于参数FSMC_DataSetupTime 设置了不同的值。此结构体其实就是对 FSMC_BTRx 和FSMC_BWTRx 寄存器操作,大家可以查看中文参考手册寄存器说明。
    本实验中的时序设置是根据 R61509V3 的数据手册设置的, 调试的时候可以先把这些值设置得大一些,然后慢慢靠近数据手册要求的最小值,这样会取得比较好的效果。时序的参数设置对 LCD 的显示效果有一定的影响。
    了解结构体成员功能后,就可以进行配置,本章实验配置代码如下:
  1. FSMC_NORSRAMInitTypeDef FSMC_NORSRAMInitStructure;, k& o$ \5 E6 l6 A0 J
  2. FSMC_NORSRAMTimingInitTypeDef FSMC_ReadNORSRAMTiming;
    6 @9 Y5 \9 C$ z9 ~1 ]
  3. FSMC_NORSRAMTimingInitTypeDef FSMC_WriteNORSRAMTiming;; c* }* M6 w/ ^5 N
  4. FSMC_ReadTimingInitStructure.FSMC_AddressSetupTime = 0x01; // 地址建立时间(ADDSET)为2个HCLK 1/36M=27ns5 ^8 L+ w) {& n7 ?* [
  5. FSMC_ReadTimingInitStructure.FSMC_AddressHoldTime = 0x00; // 地址保持时间(ADDHLD)模式A未用到# ]5 E2 z0 B/ c5 N/ W
  6. FSMC_ReadTimingInitStructure.FSMC_DataSetupTime = 0x0f; // 数据保存时间为 16 个 HCLK,因为液晶驱动 IC 的读数据的时候,速度不能太快,尤其对 1289 这个 IC。" k2 H( `% [) K6 g- c9 k
  7. FSMC_ReadTimingInitStructure.FSMC_BusTurnAroundDuration = 0x00;# a2 S$ B( L2 Z2 e* v7 |- e
  8. FSMC_ReadNORSRAMTiming.FSMC_CLKDivision = 0x00;! Z  O: ]) j9 @' d" x" o
  9. FSMC_ReadNORSRAMTiming.FSMC_DataLatency = 0x00;
    ( `- q2 L8 x% \
  10. FSMC_ReadNORSRAMTiming.FSMC_AccessMode = FSMC_AccessMode_A;
    9 a. T1 J9 b1 Y) t
  11. //模式A
    3 y/ I% q3 r( R7 c% E' d! k# Z
  12. FSMC_WriteNORSRAMTiming.FSMC_AddressSetupTime =0x00; //地址建立时间(ADDSET)为1个HCLK
      M0 V. D- L/ D1 ^
  13. FSMC_WriteNORSRAMTiming.FSMC_AddressHoldTime = 0x00; //地址保持时间(A2 n4 W& }/ Q- e/ t
  14. FSMC_WriteNORSRAMTiming.FSMC_DataSetupTime = 0X03; //数据保存时间为 4 个 HCLK
    # b/ ?8 t5 |% l' x4 m! N! i3 T2 h/ g
  15. FSMC_WriteNORSRAMTiming.FSMC_BusTurnAroundDuration = 0x00;7 H# n5 w3 p4 F
  16. FSMC_WriteNORSRAMTiming.FSMC_CLKDivision = 0x00;
    * I5 [2 E. m7 u% e
  17. FSMC_WriteNORSRAMTiming.FSMC_DataLatency = 0x00;
    , R8 L+ M7 E+ a: V" j3 v
  18. FSMC_WriteNORSRAMTiming.FSMC_AccessMode = FSMC_AccessMode_A;9 d) H6 T* E0 G, h
  19. //模式A6 X5 y3 q) q1 Q. a
  20. FSMC_NORSRAMInitStructure.FSMC_Bank = FSMC_Bank1_NORSRAM4;// 这里我们使用 NE4 ,也就对应BTCR[6],[7]。
    7 U9 x3 _5 L7 w, P2 f' b
  21. FSMC_NORSRAMInitStructure.FSMC_DataAddressMux =0 c/ F1 D+ s5 g- [
  22. FSMC_DataAddressMux_Disable; // 不复用数据地址7 W. V1 j/ p$ d" f) x# f
  23. FSMC_NORSRAMInitStructure.FSMC_MemoryType=FSMC_MemoryType_SRAM;// FSMC_MemoryType_SRAM; //SRAM
    , q( m/ K. w/ ?& A* k! r' A5 o7 ?# U
  24. FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth =FSMC_MemoryDataWidth_16b;//存储器数据宽度为 16bit
    : L; a! C' R( \
  25. FSMC_NORSRAMInitStructure.FSMC_BurstAccessMode=FSMC_BurstAccessMode_Disable;// FSMC_BurstAccessMode_Disable;
    1 |% J2 g5 w1 X  P
  26. FSMC_NORSRAMInitStructure.FSMC_WaitSignalPolarity =FSMC_WaitSignalPolarity_Low;/ c0 ~: s- ?; u/ V) b
  27. FSMC_NORSRAMInitStructure.FSMC_AsynchronousWait=FSMC_AsynchronousWait_Disable;
    9 Q- Z8 B0 {$ }, o- d6 `/ [# J
  28. FSMC_NORSRAMInitStructure.FSMC_WrapMode = FSMC_WrapMode_Disable;$ w- m3 l9 d" r9 ?
  29. FSMC_NORSRAMInitStructure.FSMC_WaitSignalActive =FSMC_WaitSignalActive_BeforeWaitState;
    ( p; s2 O$ v7 a! K2 \5 o" e
  30. FSMC_NORSRAMInitStructure.FSMC_WriteOperation =FSMC_WriteOperation_Enable; // 存储器写使能8 Z, x) g! M" u" u# v. N
  31. FSMC_NORSRAMInitStructure.FSMC_WaitSignal =FSMC_WaitSignal_Disable;3 K2 X& G. M3 K) U: y: @1 y( f
  32. FSMC_NORSRAMInitStructure.FSMC_ExtendedMode =FSMC_ExtendedMode_Enable; // 读写使用不同的时序
    / o" |9 m2 \+ ^" z+ c
  33. FSMC_NORSRAMInitStructure.FSMC_WriteBurst =FSMC_WriteBurst_Disable;
    + j( ~3 Z/ ^" }6 m5 e* o- z* g
  34. FSMC_NORSRAMInitStructure.FSMC_ReadWriteTimingStruct =&FSMC_ReadNORSRAMTiming; //读写时序
      c9 _: X, O0 r' Z9 p1 l1 H
  35. FSMC_NORSRAMInitStructure.FSMC_WriteTimingStruct =&FSMC_WriteNORSRAMTiming; //写时序
    ( ]& h* E" |0 U6 I
  36. FSMC_NORSRAMInit(&FSMC_NORSRAMInitStructure); //初始化FSMC配置
复制代码

( N) J) k; z' W
(2)使能(开启)FSMC
    固件库提供了不同的库函数来初始化各种存储器, 同样也提供了不同类型的存储器使能函数,如下:
  1. void FSMC_NORSRAMCmd(uint32_t FSMC_Bank, FunctionalState NewState);
    & u3 V, U- c6 n: i1 [4 ]
  2. void FSMC_NANDCmd(uint32_t FSMC_Bank, FunctionalState NewState);% `: e9 V7 w. }' b7 p" K/ A0 G
  3. void FSMC_PCCARDCmd(FunctionalState NewState);
复制代码
    这 3 个函数支持不同种类的存储器,从函数名来看也非常好理解。我们把
4 }- @9 E( h3 ^: ?
TFTLCD当作 SRAM 使用,即使用第一个函数。该函数第一个参数用来选择存储器的区域,第二个参数用来使能或者失能。
    将以上几步全部配置好后,我们就可以使用 STM32F1 的 FSMC了。
" t! [, T+ W! G4 k
赞 收藏 评论0 发布时间:2022-6-26 16:38

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版