STM32F1系列单片机有多种外设,外设配置方式比较一致,一般是使能外设所在GPIO口时钟、使能外设的时钟,在禁止外设的情况下配置外设的时序以及中断和DMA等。大部分的外设配置相对简单,但是FSMC接口因为配置比较复杂,往往让一些初学者一头雾水。本文记录了本人在STM32F103ZET6的FSMC接口配置调试TFT LCD屏相关注意事项。- t s1 i; y+ m( u$ l
1 FSMC接口GPIO配置- 1 r- Y# o5 v' s& X. E
- /** FSMC GPIOConfiguration
8 V- I, \! [) p4 b, B. K) q8 f - PF0 ------> FSMC_A0
5 |/ g N e" `3 q/ a8 ~ - ------> LCD_RS: 0: Reg,1:Data2 A* P8 p( L$ j' o3 Y v
- PE7 ------> FSMC_D48 p l1 t/ Y$ q" g4 C: K* Q
- PE8 ------> FSMC_D5
6 A J m# u6 E( }7 ?6 _0 | - PE9 ------> FSMC_D6$ }+ N9 y! b2 M
- PE10 ------> FSMC_D7. s6 o$ r9 c7 H; a! p
- PE11 ------> FSMC_D8
: \- k1 j$ f& C - PE12 ------> FSMC_D90 _" r- d' ^ B! g
- PE13 ------> FSMC_D10
7 B$ e* q9 I1 r) P: m - PE14 ------> FSMC_D11
; z; A" O: t6 F. f, Z' B. t C - PE15 ------> FSMC_D126 z- s8 G5 u4 ?) J: b. K0 ~
- PD8 ------> FSMC_D13
+ k4 t( B! A, |3 f - PD9 ------> FSMC_D14
" s/ e' X; }. n0 j! e/ n$ G - PD10 ------> FSMC_D15
9 m+ }; R7 J3 X, e5 I - PD14 ------> FSMC_D02 c' J* L4 Y7 H# J$ V( |( ?
- PD15 ------> FSMC_D1# s) y, U3 k9 G
- PD0 ------> FSMC_D2
; G& q6 U7 I. }0 d5 I; m+ p0 p - PD1 ------> FSMC_D3
* e6 m, G4 B- r& K; M& V) I - PD4 ------> FSMC_NOE
" p! w5 m, M: c, \9 R: m - ------> LCD_RD Default:1,Value:0 k- e3 `7 t0 K4 r' h
- PD5 ------> FSMC_NWE
5 k$ C5 |/ y' U6 w3 U - ------> LCD_WR Default:1,Value:0* L. a$ q0 L( d6 d. E# y0 k4 d" _
- PG12 ------> FSMC_NE4% ?& e* E4 R9 Z/ s4 N4 v
- ------>LCD_CS Default:1,Value:0
复制代码
6 `; I& J, m$ a' x; G2 初始化FSMC时序
# {) \$ ?; u+ s# g' D& ]- 9 e9 c& }- _; n1 F5 f4 ?
- /* FSMC initializationfunction */* z- W5 |- r4 z1 D" N* x9 Y: X% v
- FSMC_NORSRAM_TimingTypeDef Timing;
- L+ R2 H# x' G; ?. g% n# N - SRAM_HandleTypeDef hsram1;
4 H# @( s7 e# X4 x% E% ]- A
7 B. j7 y8 |+ t3 J/ {# j" P7 l, N% }- hsram1.Instance = FSMC_NORSRAM_DEVICE;
+ X& m- S& G( k3 o - hsram1.Extended =FSMC_NORSRAM_EXTENDED_DEVICE;
4 z" j, n: C: l7 ]. a - /* hsram1.Init */: `: I; c1 j* `. I7 i: M) s4 L
- hsram1.Init.NSBank = FSMC_NORSRAM_BANK4;
3 {: C9 o6 V! S5 N - hsram1.Init.DataAddressMux =FSMC_DATA_ADDRESS_MUX_DISABLE;( A3 y: Q! N9 Z; u6 C: J
- hsram1.Init.MemoryType=FSMC_MEMORY_TYPE_NOR;
' E0 P% ]6 X1 h1 N; E! h- D' W - hsram1.Init.MemoryDataWidth =FSMC_NORSRAM_MEM_BUS_WIDTH_16;5 x; }& C" F8 u2 v3 t$ Q$ I
- hsram1.Init.BurstAccessMode =FSMC_BURST_ACCESS_MODE_DISABLE;
$ i6 Y7 _5 O! X" y/ {* p - hsram1.Init.WaitSignalPolarity =FSMC_WAIT_SIGNAL_POLARITY_LOW;
0 u, f7 m2 a( W - hsram1.Init.WrapMode =FSMC_WRAP_MODE_DISABLE;
3 ?2 N, |0 `. l. _% G - hsram1.Init.WaitSignalActive =FSMC_WAIT_TIMING_BEFORE_WS;
. I9 d& p9 P7 V R0 Q+ P% k - hsram1.Init.WriteOperation =FSMC_WRITE_OPERATION_ENABLE;
9 A) H6 ~) F2 S) U# b - hsram1.Init.WaitSignal =FSMC_WAIT_SIGNAL_DISABLE;
6 E& u+ ~" e( T' k - hsram1.Init.ExtendedMode =FSMC_EXTENDED_MODE_DISABLE;
/ q9 K* S, Z+ _9 d8 P2 m - hsram1.Init.AsynchronousWait =FSMC_ASYNCHRONOUS_WAIT_DISABLE;
& f7 b* ~; x6 y# c. K - hsram1.Init.WriteBurst =FSMC_WRITE_BURST_DISABLE;0 z- t5 F8 f; b4 O0 J& B$ x& ~
- /* Timing */
% J5 B$ }* N" C5 B { - Timing.AddressSetupTime = 0x04;
3 z0 T: W2 r: i; k3 y - Timing.AddressHoldTime = 0x02;
4 A6 _6 c+ I. i5 c0 K$ N2 z - Timing.DataSetupTime = 0x08;
2 s, [3 K; F1 Q9 m3 d: n7 X z) { - Timing.BusTurnAroundDuration = 0x00;
/ v- a3 m2 }& c3 D- W+ _+ a - Timing.CLKDivision = 0x00;
& Q8 a* ?+ g1 Y - Timing.DataLatency = 0x00;2 _& K1 H# o |' X9 ^0 N; j
- Timing.AccessMode = FSMC_ACCESS_MODE_B; 后面数值决定读写屏快慢。
复制代码
( y6 z6 W$ W% D7 v- H w4 E- I* u6 q- b8 q; o, [
注意点:
7 s7 Q% B1 m D 1 因为STM32的地址是32bit的,数据是按照8bit组织的,如果lcd的数据选择8bit的话,地址A0就是正常的输出,如0x60000000输出A0=0; 0x6000 0001输出A0=1;对应数据是byte;如果lcd的数据选择16bit的话,地址A0就,如0x60000000输出A0=0; 而0x60000002对应A0=1;对应数据是word,也就是说每两个原来基于byte结构的地址对应一个地址线上实际的word长度的地址;
) M" Q! Q) J$ t% k( \6 A- * h: J1 P! S* R# i
- #define Bank1_LCD_D ((uint32_t)0x6C000002) //DispData ADDR
1 K/ l7 O2 y- O7 E6 | - #define Bank1_LCD_C ((uint32_t)0x6C000000) //DispReg ADDR* L8 m4 |. y: X! B6 I" p
3 x' J* D/ P7 b' Y- void LCD_WR_REG(uint16_t index)7 t) R/ k1 q$ X. E
- { *(__IOuint16_t *) (Bank1_LCD_C) = index;}7 l2 \& v( G5 @/ |2 @0 Q
- 6 ~, u+ n9 H- C |3 j+ j0 J; d" b- X
- uint16_t LCD_READ_DATA(void)
9 f9 c x/ [* X% E7 p! _' ? - { uint16_ta = 0;
3 Y, j, n3 A& X0 t' f - a=*(__IOuint16_t *) (Bank1_LCD_D); //L; z( c, {$ t2 K! x
- return a;0 R1 ?; Q' v# V
- }
复制代码 2 Image2LCD软件转换时注意扫描方式和数据位宽度,以及高低为顺序。
% Z: F0 ~( T: ~* J& Y- M& \
7 @. Z9 P* ^: P实际效果:6 E6 U" K* q( @! h( D& }+ A& p; e
9 d* B$ [# V9 Q. S# x2 g. w
" A, q" `3 x9 H3 [
8 Q' b7 O$ y* c9 p
|