问题:; l' E3 T5 o' {4 U
在合计智能穿戴应用的时候,为了更好的用户体验和丰富的人机交互界面,需要更多的存储(RAM 和 FLASH)来存储自定义的图片资源 ;由于可穿戴类的产品体积都非常小,因此 FLASH&PSRAM集成在一起的 MCP 存储芯片是一个不错的选择.
' h% ?* m M# R. Z3 l7 o* N我们的 STM32 FMC 外设是可以支持 MCP 存储芯片的,而且只需要简单的配置就可以实现MCP 的访问.
: s# H i7 `/ Y1 r5 R' ` d0 V1 K: V; p2 o9 T4 r
3 q+ q5 h+ @" ~# {( N4 o. C调研:
b, L; E" {8 |& V) S下面介绍使用 STM32CubeMX 配置 MCP 驱动的过程,我们使用 STM32F429+MX69V28F64 举例说明:
1 ^6 G _2 ?" j5 q w& R0 d
' t: V' C4 _# x2 s1 [$ L一、配置过程:
1 Z' ]% m; n( j4 H5 w6 o7 q8 F1.MX69V28F64 的总线结构和 PIN 定义:
+ T: Z! k8 V" d( b4 @! N- j! _8 ~0 r; ~! b, z- M8 J
" C- N3 y1 Z5 {9 r
7 q: v+ |0 t% O* B) w0 p Q
# ?8 L3 g7 @7 R) r# j- ?; Y
0 i5 T: V! _' X# a: Z2.下面我们使用 STM32CubeMX 来配置 MCP 接口:
; I( L: |3 v3 C) O; pa.新建 STM32F429ZIYx 的工程,在 FMC 根据 MCP 芯片来配置 FMC 的参数:; ]1 h4 s5 h8 w3 r
$ I: v* J( z7 P, m- j
! @6 h* t* l* t- R B1 |- G. ^
' i0 d& M+ F& p/ j# {9 o
b.在 configuration 选项卡中配置 FMC 的详细参数,
5 J- N4 M4 H; X* s( P
" Z1 c" ~( j4 `3 J7 k+ P& X+ { ~
8 S Y* G6 H# e: N: ]
* Z3 K) x4 _3 A4 Y' H3 Mc.根据 MX69V28F64 datasheet 中对时间的要求来更改 NOR/PSRAM timing 的参数:
+ s4 {& X/ c" A) P% a( M0 r& u7 o Q8 C
5 G& I. \$ @2 s1 J% ~0 J- p9 m+ F2 i) d/ q, Y9 X* O
c.配置完成后,生成代码,FMC 主要初始化如下:8 ^+ i$ r4 @9 u r
- /* FMC initialization function */" S+ D3 p! J5 s4 p
- void MX_FMC_Init(void)+ u' \3 v; I1 Y' i
- {0 M6 \- N. y8 Q6 O
- FMC_NORSRAM_TimingTypeDef Timing;
; A: s& R! ?0 | u9 k# ]* w - /** Perform the SRAM1 memory initialization sequence5 A2 \! o6 d! l) h1 j
- *// t2 q; \% S, h
- hsram1.Instance = FMC_NORSRAM_DEVICE;
d1 k' K; y4 L( X5 D - hsram1.Extended = FMC_NORSRAM_EXTENDED_DEVICE;& h) d$ }3 {1 |: j' V
- /* hsram1.Init */0 x: b" |2 w3 k9 X
- hsram1.Init.NSBank = FMC_NORSRAM_BANK1;
0 `$ L* `7 x" O' Z& o- v - hsram1.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_ENABLE;4 J+ d. g# I4 z/ Z
- hsram1.Init.MemoryType = FMC_MEMORY_TYPE_PSRAM;6 \+ c7 D% v: K- V5 M
- hsram1.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16;
" ?3 N& f1 O* h) Y - hsram1.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;
) a8 x2 ]) _6 m+ p5 F - hsram1.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_HIGH;
9 E( m8 d4 [5 x" N5 I - hsram1.Init.WrapMode = FMC_WRAP_MODE_DISABLE;
( T7 u% p( p( l1 D6 `! q. | - hsram1.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;
) {' d- k( O$ m - hsram1.Init.WriteOperation = FMC_WRITE_OPERATION_DISABLE;; @9 o4 W6 o; `2 {3 _
- hsram1.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;4 R8 a1 }9 ]& b1 @ S
- hsram1.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;* M1 ]9 m3 I- y) d N
- hsram1.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_ENABLE;
1 x2 }+ O, W4 `) v( S- r - hsram1.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;
0 n0 ~* O$ E( d& c - hsram1.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;7 k6 [; i0 \# Q- s. N
- /* Timing */$ Y' U- j& O) _1 c; [
- Timing.AddressSetupTime = 2;/ d I* _; [' b8 x* I) W
- Timing.AddressHoldTime = 2;
1 Z9 ]% Q( A5 g. v0 L* K! r; k - Timing.DataSetupTime = 6;
& R& ^& Q# j7 V - Timing.BusTurnAroundDuration = 0;
# g2 C+ z. h6 |* @9 D+ l: E& z - Timing.CLKDivision = 16;
z; b+ G( @. B9 {# \/ D6 B - Timing.DataLatency = 17;2 f! L: i# \% Q( P( ?9 w" ] q( u
- Timing.AccessMode = FMC_ACCESS_MODE_A;
) F5 G0 V! z2 v - /* ExtTiming */5 z9 C- _9 m, j8 v- A
- HAL_SRAM_Init(&hsram1, &Timing, NULL);
' Y, S7 a G O7 L: @2 x$ Z - /** Perform the NOR2 memory initialization sequence
7 z+ O6 g& ]$ s3 k - */0 z- f* D& L u! ^1 _2 Q
- hnor2.Instance = FMC_NORSRAM_DEVICE;& w R) m' R% y( [
- hnor2.Extended = FMC_NORSRAM_EXTENDED_DEVICE;
3 E! c0 Z' L/ P5 c5 {. t - /* hnor2.Init */
- ~) n. b) ]- Q2 l' G- |! E - hnor2.Init.NSBank = FMC_NORSRAM_BANK2;
z& h5 k# r! Q! J. ]+ O% V) ]! n - hnor2.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_ENABLE;
2 G' E$ ]# e/ u' S' J, ~ - hnor2.Init.MemoryType = FMC_MEMORY_TYPE_NOR;, E* M. r4 i, h' y1 r. S% {: E
- hnor2.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16;
* ~; n) ?7 x b; I; } - hnor2.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE;/ U; M8 k8 K/ e$ y; R3 L. l+ F! G
- hnor2.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW;% h6 u; ]/ @; P; j7 j# ?; P
- hnor2.Init.WrapMode = FMC_WRAP_MODE_DISABLE;
, f6 U6 \9 D! S4 T# M; c6 U9 B - hnor2.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS;2 e# G( n/ I; O$ h, D
- hnor2.Init.WriteOperation = FMC_WRITE_OPERATION_DISABLE;- U: s/ W: Y9 M7 l- \0 {: v* F
- hnor2.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE;
$ V# u. Y5 p; ?4 _' } - hnor2.Init.ExtendedMode = FMC_EXTENDED_MODE_DISABLE;; J4 {* @- ]2 \/ s
- hnor2.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE;1 T5 U* t' S% L4 |' Z( y% d
- hnor2.Init.WriteBurst = FMC_WRITE_BURST_DISABLE;( J3 N0 x% h3 j. P" r; d: A% q
- hnor2.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ONLY;# c$ U% @3 `0 D7 a1 o
- /* Timing */
5 b0 {: e: Y; x* d+ B2 } - Timing.AddressSetupTime = 5;
/ v, L+ }9 O. {3 C - Timing.AddressHoldTime = 15;
0 l: f) p4 }; i - Timing.DataSetupTime = 7;3 L% \$ @ u3 I6 P7 D7 p6 @
- Timing.BusTurnAroundDuration = 2;
8 f0 z% u% k( H - Timing.CLKDivision = 16;
- X: H* T) q) E% p - Timing.DataLatency = 17;
5 W& v* n+ D1 S3 M3 v - Timing.AccessMode = FMC_ACCESS_MODE_A; p5 h$ ?' I9 ], R8 r5 w: h _
- /* ExtTiming */
- i; \% B$ N( h) G9 ^* N) n0 J. g - HAL_NOR_Init(&hnor2, &Timing, NULL);8 n5 p& ~; v8 U# t: ~
- }
复制代码 2 h6 I F/ D# x9 v) L' q( x
二、软件如何使用:
3 h- `5 W! h" x& U9 a用户在编写软件的时候,直接访问 FMC Bank1 的分区地址即可,FMC 外设会生成读写MCP 芯片的时序.
S4 c! L" u: b/ D+ @+ W5 Y7 @) R2 Z1 ^+ {4 s0 F% j
; R2 w, L2 U9 u& Q
8 m, Y; L) P' M' a, k1 y
8 l2 k. ]+ j3 N& l1 Q8 s5 Q6 b1 g3 q8 T
$ {' K8 h+ s& L7 H+ g5 O1 | |