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

STM32L4使用SPI驱动TFTLCD

[复制链接]
STMCU小助手 发布时间:2022-8-27 14:53
在上新建工程的基础上添加使用SPI功能(新建工程见STM32使用LL库建立工程)  X5 C- Z- x' |' Z/ X5 b

  ^1 P7 `' r3 b3 p, u2 s7 S一、CubeMX的配置
4 o# p; v, h$ r  k) g3 t1、非SPI的LCD控制IO口的配置: P) B4 e% f$ u& L) T1 }* _( u4 j8 j
查看原理图可以看到,有5个引脚接在了MCU上,其中有两个SPI引脚,三个LCD控制引脚
+ ~9 W9 R5 N! |2 d/ \- y$ Y 2020011015195320.png
" c3 u. Y$ t" Z, X7 F; a' y0 N$ b( w4 r; J( \% A
其引脚对照表如下,所以我们先将PC6、PC7、PB15配置为通用IO推挽输出5 R% i. U  u5 c; x
0 B1 U7 {* _8 E  D  V
20200110153020937.png
5 M( p: p0 L+ x: H6 x
$ m; z2 P+ Q# k; V: \ 20200110153726935.png ) o2 L" n, k* `/ k/ z! L

. k' `3 g+ \( {) x9 u2、SPI的的配置8 E3 p+ W% g# w) A% d4 }8 f
MCU只需要通过SPI向LCD控制器发送命令/数据即可,所以只使用 SPI2 的 SCK 和 MOSI 引脚,将SPI2配置为主设备只发送模式,接下来开始配置SPI2接口:1 U5 F7 `- z) H" `' v5 S3 c6 g
2 K& u4 ?" Q* i0 y: V
首先将SPI2配置为只发送主设备模式8 n% W. a& i  E3 r( }6 e

3 `- U& l4 n! ?9 d1 f$ E4 ? 20200110154317851.png ' G; K0 S- a+ o) I$ `( p

1 {4 D* A# q: w8 j; T8 x5 Q可以看到,SPI2_SCK引脚默认为PB10,我们需要将其修改为PB13
: k/ ^. f' y% x0 |# s5 }& v
' Q* Q! s7 Z. M; s 20200110155915102.png
, v# ?1 [, \! @: T& C6 M2 O5 D8 [
然后对SPI的参数进行配置
9 n: _1 o! ~) u. @8 ?
3 X% t5 w1 i  {; g 2020011016032433.png
+ S6 h" P% R" D) T9 J* z* ]
* q. k3 a$ u( a7 E: w- B然后重要的是工程设置里,将HAL改成LL
6 E+ R# n/ v# M4 G7 t
) y" W5 a" n& K 20200110160609448.png
  V7 F* L+ E1 a0 W0 ^/ o
. a7 B% Y8 k% F- o7 W6 D5 L然后便可以生成代码' x, K  r8 g  n
: d% z1 c' q6 u7 _% D$ Z+ g9 D
20200110160627106.png
/ f8 f8 \2 b$ I+ o/ W$ s& k. Q
, L) R3 x: L6 b8 m; M$ O. F% L二、用户代码修改
9 t# c7 M  y1 h) i+ T将SPI初始化代码修改为如下,放入新建的spi.c文件/ `  r# p) v: _% T

* Z6 U; e; E5 z
  1. //SPI2初始化代码,配置成主设备只发送模式
    7 z0 n6 D9 a9 X$ K7 H( p
  2. void SPI2_Init(void), ?* a) t: `, P' i9 H, W( n) W, O
  3. {1 M+ j. c9 @. _. H, j( B
  4.         LL_SPI_InitTypeDef SPI_InitStruct;8 d3 G3 ]9 Q. j
  5.         LL_GPIO_InitTypeDef GPIO_InitStruct;
    ) F' o9 e/ W  E; |* M5 z4 @1 x

  6. 6 ]& f4 F1 O, o% o
  7.         LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);//使能GPIOB时钟, B) o9 e: x5 n# ?- K
  8.         LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC);//使能GPIOC时钟
    - r/ z- y; c: c$ e& L0 S
  9.         LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2);        //使能SPI2时钟( q4 [2 K1 k( I! t+ D) b) C

  10. - I* L' h: x6 z( G7 G
  11.         // **LCD控制GPIO配置 LCD_PWR->PB15        LCD_WR_RS PC6         LCD_RST->PC7        */
    ' B9 ]" `, t7 S1 W& Q8 U) o, e
  12.         GPIO_InitStruct.Pin = LL_GPIO_PIN_15;% T# U, b% D. l( i+ G6 N5 M
  13.         GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;
    6 K8 T" X6 B* y7 a! u
  14.         GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;9 k2 r! U/ v+ \2 O
  15.         GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;8 e( O$ u) A9 C8 Z2 \
  16.         GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
    " ?$ e( N) |0 n- z+ p+ W0 `
  17.         LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    " i! Q0 u& U; X! ?% k
  18.         LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_15);7 ]( m5 K1 |/ {% k/ ]0 H
  19. # o$ F) f. A1 k
  20.         GPIO_InitStruct.Pin = LL_GPIO_PIN_6|LL_GPIO_PIN_7;
    1 G- A4 B! G) j, }* w4 j
  21.         LL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    $ a1 \/ l$ [* p5 s  J
  22.         LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_6|LL_GPIO_PIN_7);. x7 O8 N: t: _" P- u& @+ j2 r
  23.         9 Y4 B" i) P/ _, O
  24.         // **SPI2 GPIO Configuration        PC3-> SPI2_MOSI                PB13-> SPI2_SCK */  j1 ~1 }% x1 ]; _
  25.         GPIO_InitStruct.Pin = LL_GPIO_PIN_13;. [( i# x- B" G; f+ i
  26.         GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
    2 ?# ?0 I$ p; T. [( A% w3 p* x* C6 _
  27.         GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;/ _9 d0 b$ ]7 G- t  J. Q( I" n2 @
  28.         GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
    & ?" q& W& s; y- Q
  29.         GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
    1 L8 C8 ?! V6 ]1 K5 }" l6 |8 @
  30.         GPIO_InitStruct.Alternate = LL_GPIO_AF_5;
    ( B/ ~4 @4 O8 v0 p/ P1 ?' K
  31.         LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    6 g3 {  W4 v+ N
  32.         & ]' k* D- i1 t* V- l1 J
  33.         GPIO_InitStruct.Pin = LL_GPIO_PIN_3;! T( l& _& x  n' z. g" @5 r. ?
  34.         LL_GPIO_Init(GPIOC, &GPIO_InitStruct);1 c* M' g$ x' \0 B3 x+ m; F5 S" Y# F: U

  35. & ]1 V' D; M1 Z# w5 e
  36.         /* SPI2 parameter configuration*/
    - `: |8 o- v& l$ e
  37.         SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX;        //全双工
    3 |. U4 F' ~6 E2 o/ G* ?6 N2 e
  38.         SPI_InitStruct.Mode = LL_SPI_MODE_MASTER;                                //主设备模式: T$ s! V* }# A2 c
  39.         SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT;                //8位数据宽度
    9 i3 I/ U5 `7 V
  40.         SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_HIGH;        //串行同步时钟的空闲状态为高电平* [) ]8 U2 i9 p, b
  41.         SPI_InitStruct.ClockPhase = LL_SPI_PHASE_2EDGE;                        //串行同步时钟的第二个跳变沿数据被采样& d  r/ c% w9 G" N/ S0 p
  42.         SPI_InitStruct.NSS = LL_SPI_NSS_SOFT;                                        //NSS信号由软件(使用SSI位)管理:内部NSS信号由SSI位控制
    ( t9 `8 L' `6 L1 H' C! U
  43.         SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV2;//定义波特率预分频的值:波特率预分频值为256
    ! e5 S; j0 }1 _7 R+ }1 M
  44.         SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST;                                //数据传输从MSB位开始
    # o  N- ]2 F5 D6 v$ C. Z. C0 T+ {
  45.         SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE;//关闭硬件CRC校验
    + g6 x- v' C8 U9 o: h9 H
  46.         SPI_InitStruct.CRCPoly = 7;                                                                //CRC值计算的多项式
    # X$ r$ k3 ^  W- C) O1 ~5 _
  47.         LL_SPI_Init(SPI2, &SPI_InitStruct);
    + {7 n" q% K3 \/ d

  48. " m! m' ]$ ~* x0 V7 V4 m) R% {
  49.         LL_SPI_SetStandard(SPI2, LL_SPI_PROTOCOL_MOTOROLA);                //SPI帧格式 为 SPI Motorola模式5 ~$ X0 K1 D4 ?! K3 U5 |
  50.         LL_SPI_DisableNSSPulseMgt(SPI2);                                                //关闭 NSS脉冲模式, t8 @( a: M. `% _2 S6 y& l

  51. / c  {% s# @. _0 X1 J
  52.         LL_SPI_Enable(SPI2);                //使能SPI2  S: ?9 A  D2 `1 d& T  _& g) d3 l
  53. }2 v; q$ y) F5 ~$ O' p- Y) w$ ]5 s2 q
  54. 4 V% j, i9 o+ f  t) N' m0 X( I2 Y
复制代码

8 `! ]; J" _4 k4 S; q/ J然后编写SPI2_WriteByte(u8 *TxData,u16 size)函数
( M- h1 d, k1 _& P$ _# w; N% v, F4 g9 N
  1. /**2 I7 V; g  O4 p7 M
  2. * @brief        SPI3 写入一个字节
    & K+ H" Q  K0 I& L' U
  3. * @param   TxData        要写入的字节) f' ]% ?) z. K  P3 F
  4. * @param   size        写入字节大小0 q9 n7 |6 H4 a  \' i) A
  5. * @return  u8                0:写入成功,其他:写入失败+ f% J' F( f+ \4 \' k8 s
  6. */
    : D4 L. b4 T+ O& a3 ?8 J  \+ D
  7. u8 SPI2_WriteByte(u8 *TxData,u16 size)  g$ [6 X" P/ ?, @! U
  8. {
    , k7 ]2 b2 u1 @, n* h
  9.         u8 retry=0;        " Z7 H+ S: W# u
  10.         u8 n=0;
    5 s2 h7 s0 N; {- {. u
  11.         for(n=0;n<size;n++)) z* O4 h4 R8 K* L+ H" q
  12.         {: @) t; G# V) O" J- V
  13.                 while (LL_SPI_IsActiveFlag_TXE(SPI2) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
    . z- I; i6 |! j$ W5 `' K+ d, n! A
  14.                 {! r% H+ A' x) B) j/ E' \5 x+ w
  15.                         retry++;& u7 X9 w0 b- U: M! C3 n# b
  16.                         if(retry>200)return retry;
    ! k* S( x3 L2 n+ ]; Z
  17.                 }                          + d* M+ a7 p) Y+ |
  18.                 LL_SPI_TransmitData8(SPI2, TxData[n]); //通过外设SPIx发送一个数据& K( }4 I2 ^# [# j. \# @! T, z
  19.         }! B# s( J# n. q( a3 ?
  20.         
      \8 Z. x, p. L- y' T" r; M
  21.         return 0;
    4 K! B& I( G& E# K, e! D) v
  22. }
复制代码
# F. Z7 o8 y8 r" l5 [& f  {
三、LCD代码移植
. X) A. m- q$ T: o. J" @7 L4 T6 {BearPi和正点原子的Pandora开发板使用的LCD是同一款,且模式配置也一样,所以既然有现成的代码,我们不妨copy一下,将lcd.c和lcd.h复制过来% H6 j! r5 r: ~
然后修改lcd.h里的LCD控制GPIO代码
* e) U- X* e1 c7 e! a. n6 L
, {* ^5 r" B7 A$ C4 S7 \
  1. /*
    4 A9 ^2 H, }; e8 H6 T" w. M; B, \; a
  2.         LCD_PWR:        PB15
      M# v; C# O1 J6 H  b: t
  3.         LCD_RST:        PC7
    ' R9 z: X. ~3 Y/ R
  4.         LCD_DC:                PC6
    7 K2 w/ y1 z) j+ u/ @$ T+ ]9 p
  5. */+ j8 V) u5 w; N+ o( \
  6. #define        LCD_PWR(n)                (n?LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_15):LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_15))
    8 a3 t5 [7 J# z
  7. #define        LCD_RST(n)                (n?LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_7 ):LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_7))
    $ Z' e  X2 e2 A$ `: w3 W
  8. #define        LCD_DC(n)                (n?LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_6 ):LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_6))5 ]* k+ {0 d$ B; I) `
复制代码
: c: A. U8 O4 m6 n% ~
将lcd.c里的LCD_Gpio_Init()代码删去,然后在LCD_Init()开头添加如下代码:
+ ]+ }7 y3 G/ K3 _' P* E& D  o
3 v, U; T/ b: o" W2 V$ |- n1 y
  1.     SPI2_Init();, Y2 \! y( A( W" X+ ]! [2 K6 g$ m1 l
  2.         : ~  a. v* C# I+ F9 Q
  3.     LCD_PWR(0);                //关闭显示
    . X1 z. o$ t: z( f) s) b: D
  4. $ `6 v. L# s' N" M
  5.     LCD_RST(0);
    % @5 _! J+ y2 p* e. y! S3 f
  6.     delay_ms(120);
    4 _5 k) z8 {( S$ F) I" M
  7.     LCD_RST(1);                //复位
复制代码
; r! [* t# \; M5 A# ]* K
在主函数里写入
3 S  i' w; R) G6 d7 Q- C' D9 D5 C' v1 R0 ^4 R9 ]/ S+ @0 @0 q
  1.         LCD_Init();                                //初始化LCD; `  C+ M  N& l  X& W. {1 l( p
  2.         # a5 Q# _2 V3 u5 G5 ?2 N
  3.         POINT_COLOR = RED;8 [+ R2 c  P# |; ^7 G
  4.         LCD_ShowString(0, 100, 240, 32, 32, "BearPi STM32L4");
复制代码

+ _5 l& e; K% F( @) |编译链接下载到开发板里,测试结果如下1 ~% f5 Y, S6 M$ J3 |
7 [# s! W0 ?( n! z0 T
2020011018350065.png * O8 a) ^5 ^, N1 x
+ p9 w% I- M: @* H( O1 _4 j  @
表明测试成功+ K* h, y$ ?7 g
————————————————9 V! M# n5 }& B4 h' |
转载:Willliam_william3 D- F# R0 O7 s) b$ s( @% C
: M# a. m0 w! `2 t1 K

* q' @4 k6 r# Q+ i- r+ K9 z: B1 Z
收藏 评论0 发布时间:2022-8-27 14:53

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版