STM32F1系列单片机有多种外设,外设配置方式比较一致,一般是使能外设所在GPIO口时钟、使能外设的时钟,在禁止外设的情况下配置外设的时序以及中断和DMA等。大部分的外设配置相对简单,但是FSMC接口因为配置比较复杂,往往让一些初学者一头雾水。本文记录了本人在STM32F103ZET6的FSMC接口配置调试TFT LCD屏相关注意事项。1 j% L( d, w0 Z# b7 n/ ^7 c- o# |1 z
1 FSMC接口GPIO配置- * r6 Y* a& c W& m4 k6 A0 f
- /** FSMC GPIOConfiguration
( m. F' U$ f0 c; H( A+ Q6 | - PF0 ------> FSMC_A0
1 M. Y2 X/ X- `8 { - ------> LCD_RS: 0: Reg,1:Data1 P9 _3 }) I4 o& y( G
- PE7 ------> FSMC_D4+ ?1 J3 ^0 d j& A2 f
- PE8 ------> FSMC_D59 z2 S5 i& I, j4 b3 S' E M+ u
- PE9 ------> FSMC_D6/ _6 I- o3 h% `) O0 V' {* ~5 ?( C
- PE10 ------> FSMC_D7, Y% z4 _; K6 y1 `' T& t- D7 y
- PE11 ------> FSMC_D8, m A* @5 a& k. R
- PE12 ------> FSMC_D9
4 {# P$ H: \( b4 V" L - PE13 ------> FSMC_D10$ s( S1 w, ^& q2 j2 ^( |
- PE14 ------> FSMC_D11& S. X0 _! F9 Q
- PE15 ------> FSMC_D12: k8 c6 o/ ` z+ }+ n, M: x
- PD8 ------> FSMC_D13: \# R/ Q* n; R# J
- PD9 ------> FSMC_D14$ k0 m$ i+ _ ]0 u
- PD10 ------> FSMC_D15, `$ b9 Y4 |: f0 ~1 m( v
- PD14 ------> FSMC_D03 Q+ K0 _& n0 n6 O
- PD15 ------> FSMC_D1* ^: Z* C: N5 o# D+ g( F$ v
- PD0 ------> FSMC_D2
! M* f; G* x8 o/ `- m - PD1 ------> FSMC_D3# C6 w: Z. l2 W' o' S( q6 L
- PD4 ------> FSMC_NOE: S/ u3 Y- }, s
- ------> LCD_RD Default:1,Value:0 9 t" y/ f( t3 y' O" M3 x. w9 @
- PD5 ------> FSMC_NWE4 G% `8 n7 N% d3 G& h' j( O$ y
- ------> LCD_WR Default:1,Value:06 h: ~# T9 U% D& z6 @8 U2 P H7 U
- PG12 ------> FSMC_NE40 z( K( z4 [: A W8 x, o0 f. l
- ------>LCD_CS Default:1,Value:0
复制代码
) {7 t2 P: P# H3 ?8 g, Y' y* D2 初始化FSMC时序& ^: j0 F/ r8 A% o: M0 f; T: q
- * J, d# Q6 k1 D# G" D9 g
- /* FSMC initializationfunction */
6 y& w# C' ~6 r( B7 n - FSMC_NORSRAM_TimingTypeDef Timing;
6 A6 v7 \" B& n6 l" a* a - SRAM_HandleTypeDef hsram1;2 m* f0 _% t* |' s0 z6 [
9 \+ C% J4 {0 f4 F/ T( I- hsram1.Instance = FSMC_NORSRAM_DEVICE;
0 M: c# `: j" D - hsram1.Extended =FSMC_NORSRAM_EXTENDED_DEVICE;4 j2 `+ @ c6 d/ Y
- /* hsram1.Init */% |# X j7 [ g, V2 Y6 N
- hsram1.Init.NSBank = FSMC_NORSRAM_BANK4;1 Q7 T! Z- ^6 W* r6 C2 y
- hsram1.Init.DataAddressMux =FSMC_DATA_ADDRESS_MUX_DISABLE;5 T" C: E1 g* b0 L2 ?
- hsram1.Init.MemoryType=FSMC_MEMORY_TYPE_NOR;7 P, }$ ]3 L( N" _+ B
- hsram1.Init.MemoryDataWidth =FSMC_NORSRAM_MEM_BUS_WIDTH_16;
$ M$ l" y" F! V- e - hsram1.Init.BurstAccessMode =FSMC_BURST_ACCESS_MODE_DISABLE; v4 e4 U- Q' f) g6 i
- hsram1.Init.WaitSignalPolarity =FSMC_WAIT_SIGNAL_POLARITY_LOW;* a0 A% ~! N8 \% T
- hsram1.Init.WrapMode =FSMC_WRAP_MODE_DISABLE;# T3 V2 y7 Y$ Y3 O. R* \! B/ N
- hsram1.Init.WaitSignalActive =FSMC_WAIT_TIMING_BEFORE_WS;0 y' O- F* T' b* J5 U" }
- hsram1.Init.WriteOperation =FSMC_WRITE_OPERATION_ENABLE;. A4 h8 l1 ^9 G" {6 Y# ~$ {
- hsram1.Init.WaitSignal =FSMC_WAIT_SIGNAL_DISABLE;
* O7 G( V [6 t" } - hsram1.Init.ExtendedMode =FSMC_EXTENDED_MODE_DISABLE;2 W2 P7 K' F1 r0 V" ]
- hsram1.Init.AsynchronousWait =FSMC_ASYNCHRONOUS_WAIT_DISABLE;
9 s( ]+ W: N; T6 h - hsram1.Init.WriteBurst =FSMC_WRITE_BURST_DISABLE;
4 ^0 `2 a! v5 i" \' N - /* Timing */ k1 U" _* B" t
- Timing.AddressSetupTime = 0x04;
9 n9 f. H \6 n6 r8 A5 w - Timing.AddressHoldTime = 0x02;+ V' a2 J# R3 ]0 U! Y8 z
- Timing.DataSetupTime = 0x08;8 v) ]( P( f% p- f1 T
- Timing.BusTurnAroundDuration = 0x00;
4 n7 s- |- \& F/ s a8 S; M" J - Timing.CLKDivision = 0x00;, H6 [8 ?9 P/ g2 e1 b. n% h+ x
- Timing.DataLatency = 0x00;
, P0 T0 d: d# R3 F - Timing.AccessMode = FSMC_ACCESS_MODE_B; 后面数值决定读写屏快慢。
复制代码
/ E, F4 n2 W% Z5 H& Q( ?" i0 Y& \" S( u6 U
注意点:- 5 Z1 i6 o: E" U+ H" O
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长度的地址;& T/ v0 v6 i2 K9 L* {* O/ K
1 I$ e% ], g$ G1 p- #define Bank1_LCD_D ((uint32_t)0x6C000002) //DispData ADDR F6 F% o% {5 I+ N) J
- #define Bank1_LCD_C ((uint32_t)0x6C000000) //DispReg ADDR; I* v" Z2 W# l( P W
- * i \6 U7 }& j
- void LCD_WR_REG(uint16_t index)
2 f, n( y. U2 f; G) B - { *(__IOuint16_t *) (Bank1_LCD_C) = index;}
$ ? k( t }( M - 1 U9 N: z5 B$ |: q" d/ D
- uint16_t LCD_READ_DATA(void)
- d/ Z7 f9 C/ `) E; P - { uint16_ta = 0;* ]) h$ p1 l g. H
- a=*(__IOuint16_t *) (Bank1_LCD_D); //L5 ]3 a' Q/ W; u. Y9 e! k, x {
- return a;
1 B" Q5 q# }7 |2 ]) e - }
复制代码 2 Image2LCD软件转换时注意扫描方式和数据位宽度,以及高低为顺序。7 D2 {. m2 @" \. O' ^
0 G9 m5 S# ?' }3 b2 ~8 D实际效果:
. e+ {8 u% z2 _# j6 R
t: I8 e( `$ L
% M! {+ X, D, |% y* c9 e
C5 S/ R" L" k0 N# T) c* T) T/ } |