请选择 进入手机版 | 继续访问电脑版

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

STM32L4使用SPI驱动TFTLCD

[复制链接]
STMCU小助手 发布时间:2022-8-27 14:53
在上新建工程的基础上添加使用SPI功能(新建工程见STM32使用LL库建立工程): v/ R5 z, [& p0 W  \/ C1 _

0 Y$ N  D0 D# U. t8 U/ T. V4 o7 h一、CubeMX的配置" p. L& l9 |) b
1、非SPI的LCD控制IO口的配置* Q0 p- y  c' x, L
查看原理图可以看到,有5个引脚接在了MCU上,其中有两个SPI引脚,三个LCD控制引脚8 }! F7 m# i; ~: ~9 Y7 V
2020011015195320.png 1 \! L) C' w6 E1 [

+ Q* i9 q' Y' ^$ x6 C其引脚对照表如下,所以我们先将PC6、PC7、PB15配置为通用IO推挽输出+ C: U" m' t/ q  f

3 ~0 U- R1 y! |# d 20200110153020937.png - n) Q) `8 D: C4 p& l4 ^+ ]

" s7 _! P. C+ R& }( o 20200110153726935.png , K+ w8 F& Y  |$ z" q, c

- L; {" y: T) `2、SPI的的配置4 c1 L" z  m: k1 D! c
MCU只需要通过SPI向LCD控制器发送命令/数据即可,所以只使用 SPI2 的 SCK 和 MOSI 引脚,将SPI2配置为主设备只发送模式,接下来开始配置SPI2接口:
* K  {3 Q. P3 P; q
+ i; |8 g9 B& R+ E首先将SPI2配置为只发送主设备模式- ?5 E1 V8 x$ O8 p0 n: L

- @( X/ O& O1 [! I7 G 20200110154317851.png ' H, `7 L  ?% o( [) {
' W% q1 \1 V3 `( T% t
可以看到,SPI2_SCK引脚默认为PB10,我们需要将其修改为PB13( y7 u6 E1 v9 G, f8 z1 s+ U! q# j8 M4 F$ W9 @

$ v0 Z5 m: r( D9 F' l( r" u 20200110155915102.png
9 i% P! t; O0 ?9 h5 s$ S6 _+ [5 i6 H; P# d
然后对SPI的参数进行配置
0 a8 m9 U9 n2 j$ p  `4 Q0 y7 h0 _) @) }0 g+ W/ L
2020011016032433.png
' Y% k+ y. C+ B) a7 W9 d6 A  r( ?5 ^; K: H
然后重要的是工程设置里,将HAL改成LL
9 N3 _8 q5 v8 p1 ]! l1 }+ j1 o# K* F
20200110160609448.png
& N2 ~* }. Z. S+ O9 d) S- O) c6 k1 R4 w+ C3 j" g" E3 p
然后便可以生成代码: n4 _( l. f* [5 D: t
5 B. X% q: J9 O4 z" P/ y( X. u
20200110160627106.png 8 t3 _3 o2 u2 B
# l4 r1 W" m9 A. O7 Z
二、用户代码修改9 P% s, ]$ o; T. q+ y
将SPI初始化代码修改为如下,放入新建的spi.c文件
! q5 e' ~# p. P1 V9 U& n/ f5 r$ j  C
  1. //SPI2初始化代码,配置成主设备只发送模式
    5 V8 v0 \5 b7 O5 }. i
  2. void SPI2_Init(void)
    & E0 n! F! j* P& J8 x1 `% ]# Y9 Y
  3. {) z5 v  N. ?; w2 z' ^" F2 Y6 V1 G( _
  4.         LL_SPI_InitTypeDef SPI_InitStruct;% E2 M( c/ d. a! z* N
  5.         LL_GPIO_InitTypeDef GPIO_InitStruct;( M- r' X3 h6 h) D! W) u

  6. 9 ~+ L# b! R/ e/ i. d# D
  7.         LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);//使能GPIOB时钟
    & H4 Q  z; h9 H0 I( f& r
  8.         LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC);//使能GPIOC时钟) r" \, N4 W2 Q& i4 @9 L: z0 A
  9.         LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2);        //使能SPI2时钟) [! L4 N/ M7 U! D5 a7 y: P* ]
  10. ! }* ]* K) M  r3 o4 ]
  11.         // **LCD控制GPIO配置 LCD_PWR->PB15        LCD_WR_RS PC6         LCD_RST->PC7        */
      f; U  U, a  J# }3 e- k* G
  12.         GPIO_InitStruct.Pin = LL_GPIO_PIN_15;5 r3 ~2 [4 y7 s; s1 t) J& G" {4 X
  13.         GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;9 G' o1 N3 U4 ?5 y! p; ~$ m- e7 F
  14.         GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;& {  l4 p0 I$ n2 d
  15.         GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
    ! W3 j! r- n- ]7 m; M
  16.         GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;0 o1 _" A+ X1 W$ P
  17.         LL_GPIO_Init(GPIOB, &GPIO_InitStruct);3 Z: O( l- b( ^- f- M
  18.         LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_15);
    : z, o' m+ O. m$ M4 D5 U' i

  19. % y/ i3 |6 j& c$ o# o/ O1 a8 W
  20.         GPIO_InitStruct.Pin = LL_GPIO_PIN_6|LL_GPIO_PIN_7;
    ( R" ?/ J; k* E
  21.         LL_GPIO_Init(GPIOC, &GPIO_InitStruct);3 c5 N) p- \' S& w* P
  22.         LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_6|LL_GPIO_PIN_7);
    : o3 ~9 }- i$ s; e: J9 j+ h5 D
  23.         ! P) }) R: H# `& s5 a" d4 e
  24.         // **SPI2 GPIO Configuration        PC3-> SPI2_MOSI                PB13-> SPI2_SCK */* ?9 c" G) U- ]- l( \
  25.         GPIO_InitStruct.Pin = LL_GPIO_PIN_13;
    " F$ y8 P7 ?; k/ T( M
  26.         GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;- q* X9 G0 K8 S  x# S0 u$ T' `
  27.         GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;& F: B' M3 \$ h3 J: |" E/ X
  28.         GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
    3 ^2 X2 D6 M6 H4 q, v
  29.         GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;+ u1 @$ A: U. L& ]! a4 T  p- b* R
  30.         GPIO_InitStruct.Alternate = LL_GPIO_AF_5;
    8 y/ K, s/ q, o+ x% W
  31.         LL_GPIO_Init(GPIOB, &GPIO_InitStruct);" s3 N; j+ U2 R; s6 W
  32.         
    : o. N( q0 M; {' O
  33.         GPIO_InitStruct.Pin = LL_GPIO_PIN_3;. I, }! u$ [8 P$ P% L0 t
  34.         LL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    ; [0 c1 T+ P1 ]# e

  35. 9 {6 Z+ W$ L% a. e3 g7 D
  36.         /* SPI2 parameter configuration*/* P5 I" b1 I, `: D$ ]2 ^+ J
  37.         SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX;        //全双工
    0 z/ p0 ^" Y8 ~: m
  38.         SPI_InitStruct.Mode = LL_SPI_MODE_MASTER;                                //主设备模式
    & I4 W  x: j4 i. k( Y5 A2 x1 g/ F
  39.         SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT;                //8位数据宽度( H: Y3 i- S  @& y! h( N7 j
  40.         SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_HIGH;        //串行同步时钟的空闲状态为高电平
    6 q5 M" {% a! h( N& {' Y0 l
  41.         SPI_InitStruct.ClockPhase = LL_SPI_PHASE_2EDGE;                        //串行同步时钟的第二个跳变沿数据被采样
    . J9 C8 a+ _  I
  42.         SPI_InitStruct.NSS = LL_SPI_NSS_SOFT;                                        //NSS信号由软件(使用SSI位)管理:内部NSS信号由SSI位控制. @, U' }2 S1 I* F. m+ N* n+ e
  43.         SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV2;//定义波特率预分频的值:波特率预分频值为256
    . e' T3 E) |3 |( p' H) H% Y$ C
  44.         SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST;                                //数据传输从MSB位开始% t; y9 {" Q' ]9 S. Y/ I
  45.         SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE;//关闭硬件CRC校验$ r9 s$ T; E, V
  46.         SPI_InitStruct.CRCPoly = 7;                                                                //CRC值计算的多项式
    ! p- ]  ~2 u# P' b' e
  47.         LL_SPI_Init(SPI2, &SPI_InitStruct);
      n5 F( c! N7 X  Q5 ~
  48. 0 V! p* z4 r1 f: p# l" Q
  49.         LL_SPI_SetStandard(SPI2, LL_SPI_PROTOCOL_MOTOROLA);                //SPI帧格式 为 SPI Motorola模式* j) G' |4 E5 d7 j( ~, W7 t  ?% u
  50.         LL_SPI_DisableNSSPulseMgt(SPI2);                                                //关闭 NSS脉冲模式+ A7 d: u& V: E1 l; H

  51. + b* R( y( ~7 |4 `
  52.         LL_SPI_Enable(SPI2);                //使能SPI2
    6 [% Z+ Q, S& l: K# e5 v
  53. }& Z9 s. Q  r; h
  54. ! k3 E7 ]+ j! P8 q* R
复制代码
# l. O$ j! W9 w7 |/ u6 w- U$ o0 f
然后编写SPI2_WriteByte(u8 *TxData,u16 size)函数; E' f0 S6 x" ]
" `5 ^% I7 K  n' m  `6 d1 \8 b# V
  1. /**: }/ o$ y; k; }2 l  p
  2. * @brief        SPI3 写入一个字节
    ! z) [8 m; O2 m# J8 q9 H1 ^' \$ J. i
  3. * @param   TxData        要写入的字节
    ; S& n% [  h" t  C$ i+ b. ]  r
  4. * @param   size        写入字节大小0 o  O& I9 q6 x$ y* G
  5. * @return  u8                0:写入成功,其他:写入失败5 C, b" f6 Z$ ~3 V4 `6 O5 W* E! e
  6. */
    + Z8 Z1 e5 b; ~, B9 j0 e
  7. u8 SPI2_WriteByte(u8 *TxData,u16 size); n' T/ ?3 W+ u" h! |
  8. {
    . L. ?' ^7 i3 e
  9.         u8 retry=0;        ( a9 B, v+ M7 O2 A, Y" v6 k: B6 p% m
  10.         u8 n=0;
    # o3 I- p! I$ o0 k+ y
  11.         for(n=0;n<size;n++)( ]" J& u* y7 o/ [6 x2 e2 r
  12.         {
    " P' w$ f  G% q0 X+ F6 J
  13.                 while (LL_SPI_IsActiveFlag_TXE(SPI2) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位) Q2 d* a8 F& T3 P' ^+ I
  14.                 {
    3 s2 ]- s+ J4 i/ F
  15.                         retry++;
    % F* l0 K0 C: Z) v. D
  16.                         if(retry>200)return retry;3 Z. f1 B" s: W
  17.                 }                          
    + P8 \# d0 Y% t1 @
  18.                 LL_SPI_TransmitData8(SPI2, TxData[n]); //通过外设SPIx发送一个数据
    8 i( x, }) u1 l; w* y* V( ^6 n
  19.         }
    * r' v1 J5 ]9 K* o/ X9 b( J4 @7 o
  20.         7 d9 }; A- n8 W3 U2 w; m# J( x$ \1 b: G
  21.         return 0;/ Z% z1 `+ ^1 B6 x1 H
  22. }
复制代码

) Z: y" V1 j! u三、LCD代码移植, I4 o* N2 J4 b8 g) {9 ~) {* ]
BearPi和正点原子的Pandora开发板使用的LCD是同一款,且模式配置也一样,所以既然有现成的代码,我们不妨copy一下,将lcd.c和lcd.h复制过来
/ x2 d; v, ]2 S: {" a然后修改lcd.h里的LCD控制GPIO代码
! F- d( ^( U$ l
7 S7 ]& l! j. o, t( L+ _
  1. /*0 k; w6 }+ x+ f5 z
  2.         LCD_PWR:        PB15
    4 Z! \: b! C7 X- U$ s7 ~
  3.         LCD_RST:        PC7+ h0 `2 U. x, I; }
  4.         LCD_DC:                PC6 2 D+ Q7 [" p- c5 Q7 t0 X: d
  5. */
    3 s* \0 ~( W- ^7 h
  6. #define        LCD_PWR(n)                (n?LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_15):LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_15))
    9 ^$ Y* m! t+ f
  7. #define        LCD_RST(n)                (n?LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_7 ):LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_7))
    + L- j* C4 R4 s- C
  8. #define        LCD_DC(n)                (n?LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_6 ):LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_6)); R% x: {  y6 Y0 E2 I1 n- U
复制代码

- f9 g: i9 D$ S" D将lcd.c里的LCD_Gpio_Init()代码删去,然后在LCD_Init()开头添加如下代码:# |% R& }: b" u) c% u4 Z/ d4 i

+ D# B5 e0 Y# I7 a' D8 l
  1.     SPI2_Init();
    ; o% z/ g" C+ l) k/ O5 x
  2.         # _8 z8 u% ]9 v. w6 w# |3 a) F
  3.     LCD_PWR(0);                //关闭显示4 G  _# |! @8 l' Z
  4. . ^( Z- z( C* D* U
  5.     LCD_RST(0);# K8 z" k" S7 q2 c8 F9 P3 b
  6.     delay_ms(120);
    6 R  q$ q/ D. y
  7.     LCD_RST(1);                //复位
复制代码

6 Z0 A% |! U+ p在主函数里写入7 x  }( O# D$ V' _

' b& z+ k% k4 L7 R% E  ^$ x
  1.         LCD_Init();                                //初始化LCD
    7 f+ f1 K2 V/ H9 ~2 ^! k4 F
  2.         4 C, Y, v+ e. r; A# ^
  3.         POINT_COLOR = RED;
    7 G; u0 m2 G+ X
  4.         LCD_ShowString(0, 100, 240, 32, 32, "BearPi STM32L4");
复制代码
! j" n3 N6 Y$ o- L2 K) F
编译链接下载到开发板里,测试结果如下4 g, e4 D! \. [3 l0 e
- m/ c  h: y* b# }  D) y3 B0 x- |" _
2020011018350065.png
9 X# ~0 l* v" H/ c0 I4 Y& F. W
9 S# e$ M* E0 W) S) W) S表明测试成功
# n1 A1 d) H7 s7 D————————————————8 g' D# k8 L$ x5 z4 S
转载:Willliam_william. l/ B4 y/ g0 g9 Q
# K. \. ?; f* _" k  J! X( r6 V

/ N! [( C; l2 X, l' n* a  R( r( c
收藏 评论0 发布时间:2022-8-27 14:53

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版