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

STM32L4使用SPI驱动TFTLCD

[复制链接]
STMCU小助手 发布时间:2022-8-27 14:53
在上新建工程的基础上添加使用SPI功能(新建工程见STM32使用LL库建立工程)
7 D. D/ W5 a; I4 h0 A/ B# q$ m% @) J, P8 Y' t8 v0 r
一、CubeMX的配置  ]5 I/ F. X* z0 W/ l+ \  h; f
1、非SPI的LCD控制IO口的配置
) g/ `8 K' V4 h: z( m& Y+ a; O查看原理图可以看到,有5个引脚接在了MCU上,其中有两个SPI引脚,三个LCD控制引脚
9 W! p8 M5 W8 h 2020011015195320.png
6 g' D! J3 n% w% X8 F
9 X$ u1 a$ X( P1 l) f# c其引脚对照表如下,所以我们先将PC6、PC7、PB15配置为通用IO推挽输出, ?4 D7 D. Q) {0 n; h+ b! t! I

( T& N9 Q5 H* t# j% m* U6 O) l! M 20200110153020937.png
/ c3 p( s$ s# o/ ~* g7 @
8 M1 _2 U: @$ Q1 a" s 20200110153726935.png 6 W; l9 v1 H) J4 k
+ b% u( v" L! m: q! @* x
2、SPI的的配置
0 A# P( w4 n( K- _  W+ u( H) T& cMCU只需要通过SPI向LCD控制器发送命令/数据即可,所以只使用 SPI2 的 SCK 和 MOSI 引脚,将SPI2配置为主设备只发送模式,接下来开始配置SPI2接口:
# \  n( `/ p9 C5 D, `$ ~- j# a9 y6 N; u, D* Y* o1 y0 w0 ~& h
首先将SPI2配置为只发送主设备模式
# @' b3 v) h* s; U7 l4 r5 y4 n  ]) I" j' G
20200110154317851.png
2 S" t+ \4 F- F, m3 q9 ]+ k* P+ H% r' A0 r& d4 q$ y% F
可以看到,SPI2_SCK引脚默认为PB10,我们需要将其修改为PB13) J, p  _2 \9 C6 v1 p

7 s7 _3 O0 l- b: X( ?1 T. c2 L 20200110155915102.png : r9 |% D7 @  A: l9 W
1 R' g4 a, L( h' m, U( o
然后对SPI的参数进行配置
& w* f  ?4 U. I1 t8 Z! J+ s( x( U9 i: g
2020011016032433.png - _+ l+ C* B) L4 B! `# |# c
, A- [0 G5 i% O2 A: P- Q+ x' x8 O
然后重要的是工程设置里,将HAL改成LL
% q. S" k* |( l7 y, P
: y! w" C$ C7 E; m0 Z 20200110160609448.png " g) [- W# M  t) ]9 |
* e( }" [1 o" M6 @
然后便可以生成代码3 l" w$ }$ G* N7 o' ]

1 s: B# E. |" C/ \/ U) G9 w 20200110160627106.png
5 ]5 N/ G- ^  f! y, ~( H3 d! H1 m/ v9 X2 w& I* {
二、用户代码修改
: g9 g% k* \, T( W1 V将SPI初始化代码修改为如下,放入新建的spi.c文件0 f0 k. m& K5 H2 Y1 P) J( R5 m
& S& G0 n  Z8 _0 z5 A  z
  1. //SPI2初始化代码,配置成主设备只发送模式* {- C/ ?+ V! M4 d; A
  2. void SPI2_Init(void)
    - s# m, Q# v  w) k5 K
  3. {
    # i' r* }) N9 l7 r1 l" B
  4.         LL_SPI_InitTypeDef SPI_InitStruct;
    0 E4 x4 l% x, Q, G
  5.         LL_GPIO_InitTypeDef GPIO_InitStruct;! z0 g8 D% i  p

  6. ! X3 c/ @1 t+ B' e) `
  7.         LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);//使能GPIOB时钟2 G- b4 p3 U+ G: T' b
  8.         LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC);//使能GPIOC时钟
    4 i* }# d; Q% L% r
  9.         LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2);        //使能SPI2时钟9 J8 i0 q* |1 Y' d0 j7 N
  10. , y( [, n7 |" y, K
  11.         // **LCD控制GPIO配置 LCD_PWR->PB15        LCD_WR_RS PC6         LCD_RST->PC7        */
    4 J6 I# J8 p) f
  12.         GPIO_InitStruct.Pin = LL_GPIO_PIN_15;
    + ?3 `( [/ D: h* G
  13.         GPIO_InitStruct.Mode = LL_GPIO_MODE_OUTPUT;! t& a8 f* r1 y: i. L0 L' d4 I
  14.         GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_LOW;
    3 I8 j  ]' p3 }- [* \
  15.         GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;& b( o8 T" c/ ]7 \
  16.         GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
    1 C* f; P  Q) z- V5 g
  17.         LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    2 V9 N: R! {' x8 W% m7 q
  18.         LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_15);# N" \" D! y5 p

  19. ; `2 `) O- c) E' p8 U; q' E7 |
  20.         GPIO_InitStruct.Pin = LL_GPIO_PIN_6|LL_GPIO_PIN_7;3 n5 C; a' ~6 M; I* N) T
  21.         LL_GPIO_Init(GPIOC, &GPIO_InitStruct);
    * b0 f. F2 ^; [- A* N- V! b
  22.         LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_6|LL_GPIO_PIN_7);: Y4 D% M+ N% [3 ?$ V/ a" C
  23.         . g7 Y1 j) a5 b% E/ i
  24.         // **SPI2 GPIO Configuration        PC3-> SPI2_MOSI                PB13-> SPI2_SCK */0 d7 ?& y( I) s2 l
  25.         GPIO_InitStruct.Pin = LL_GPIO_PIN_13;8 v" |" A) b/ N0 e4 @6 G% E
  26.         GPIO_InitStruct.Mode = LL_GPIO_MODE_ALTERNATE;
    0 U1 a' T( o. D; ]2 Z3 R6 `- V7 `
  27.         GPIO_InitStruct.Speed = LL_GPIO_SPEED_FREQ_VERY_HIGH;8 w! o7 e4 Y5 {$ F2 k
  28.         GPIO_InitStruct.OutputType = LL_GPIO_OUTPUT_PUSHPULL;' d  ~2 Q8 Z2 u" o
  29.         GPIO_InitStruct.Pull = LL_GPIO_PULL_NO;
    - a, N. Z- B7 c+ B1 b: _6 ~
  30.         GPIO_InitStruct.Alternate = LL_GPIO_AF_5;
    5 s: P- }, @0 ]' p( C1 {' `2 W
  31.         LL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    2 L" C" q, H6 m6 Y% W& Y1 r4 k( l; `3 w
  32.         3 r$ K( M# v* y, c
  33.         GPIO_InitStruct.Pin = LL_GPIO_PIN_3;3 d: _& x7 Z1 }
  34.         LL_GPIO_Init(GPIOC, &GPIO_InitStruct);, S$ u' X; U  t+ V# Y# t& ]

  35. " b0 D9 q" S3 B1 j
  36.         /* SPI2 parameter configuration*/
    6 ?- B  K! i+ x; j- }. m! j
  37.         SPI_InitStruct.TransferDirection = LL_SPI_FULL_DUPLEX;        //全双工
    ) ]& u( a- T- f
  38.         SPI_InitStruct.Mode = LL_SPI_MODE_MASTER;                                //主设备模式
    9 B6 [% y8 I* D2 ]; r# H" V
  39.         SPI_InitStruct.DataWidth = LL_SPI_DATAWIDTH_8BIT;                //8位数据宽度
    ; y$ P* b$ H/ P3 c9 h  G
  40.         SPI_InitStruct.ClockPolarity = LL_SPI_POLARITY_HIGH;        //串行同步时钟的空闲状态为高电平0 r4 Q; J2 `' Y5 d% y# _. L
  41.         SPI_InitStruct.ClockPhase = LL_SPI_PHASE_2EDGE;                        //串行同步时钟的第二个跳变沿数据被采样
      `9 ^( [& o! _) O& K/ L
  42.         SPI_InitStruct.NSS = LL_SPI_NSS_SOFT;                                        //NSS信号由软件(使用SSI位)管理:内部NSS信号由SSI位控制
    1 r# E$ y8 j( ]' X# ~
  43.         SPI_InitStruct.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV2;//定义波特率预分频的值:波特率预分频值为256
    ) |+ `8 p% W# v3 l
  44.         SPI_InitStruct.BitOrder = LL_SPI_MSB_FIRST;                                //数据传输从MSB位开始' Q0 Z- \8 ?) c! g: e& f! k* N
  45.         SPI_InitStruct.CRCCalculation = LL_SPI_CRCCALCULATION_DISABLE;//关闭硬件CRC校验0 s7 o+ b" L% C  M" _  D2 y5 R& U
  46.         SPI_InitStruct.CRCPoly = 7;                                                                //CRC值计算的多项式' @6 g0 x) }9 b
  47.         LL_SPI_Init(SPI2, &SPI_InitStruct);5 p; E' Z5 r' ^( Z% K
  48. $ S: E  O$ g, B+ y
  49.         LL_SPI_SetStandard(SPI2, LL_SPI_PROTOCOL_MOTOROLA);                //SPI帧格式 为 SPI Motorola模式# |, p( B) b7 N; o
  50.         LL_SPI_DisableNSSPulseMgt(SPI2);                                                //关闭 NSS脉冲模式# O% e$ `7 G0 S6 j& L2 p+ x$ q% b

  51. 4 M, o9 X) T9 a  e+ C
  52.         LL_SPI_Enable(SPI2);                //使能SPI2
    # n4 g, w1 M) @% }% D# D
  53. }9 e2 b3 T% }+ e$ k

  54. $ N( s) ]- w& i- a& O) M
复制代码
/ O$ {' B5 h, ]( E
然后编写SPI2_WriteByte(u8 *TxData,u16 size)函数( @: z: c" x. a* b; j. ^

. l" O/ x& l3 Y0 \
  1. /**
    ! W/ W! \3 _* I* w9 U5 N; }! b. j& `
  2. * @brief        SPI3 写入一个字节/ X$ T8 e1 K) c$ A9 L
  3. * @param   TxData        要写入的字节( t6 b7 y; K- m) h  w" b
  4. * @param   size        写入字节大小
    2 w$ ?' G) q8 C; q4 R
  5. * @return  u8                0:写入成功,其他:写入失败
    $ X# A* E( z! S4 W) w8 y8 k
  6. */  |+ @; s7 h  J7 p9 g
  7. u8 SPI2_WriteByte(u8 *TxData,u16 size)9 t9 {4 i* g+ c4 x
  8. {6 m* A& x# i- n2 v6 w0 I
  9.         u8 retry=0;        
    " c  t8 Y( }( @
  10.         u8 n=0;
    * }' f: I! D. k* }4 F7 A# Y
  11.         for(n=0;n<size;n++)6 _! o5 w& }' a
  12.         {; D: z/ r1 ^3 ~9 \' y
  13.                 while (LL_SPI_IsActiveFlag_TXE(SPI2) == RESET) //检查指定的SPI标志位设置与否:发送缓存空标志位
    ( ^6 M$ M9 i; T! J) V8 \
  14.                 {5 m* L( B1 ~( B
  15.                         retry++;, j6 B6 P) s9 J; M3 U0 ~& R
  16.                         if(retry>200)return retry;
    . l: N2 d) Z( p, C$ f( g
  17.                 }                          
    9 X* m# E' t0 Q# P9 h+ N, V
  18.                 LL_SPI_TransmitData8(SPI2, TxData[n]); //通过外设SPIx发送一个数据
    & z  z7 J! v1 {
  19.         }6 |, d: t$ M0 ^6 l& S
  20.         . Z" k7 Q; N$ W$ L& d% L
  21.         return 0;
    : L  I' @9 \  c1 q! ?; \% m
  22. }
复制代码
8 s$ p, c* C( r2 U( M
三、LCD代码移植
, B$ B4 U. f8 `( t- h7 tBearPi和正点原子的Pandora开发板使用的LCD是同一款,且模式配置也一样,所以既然有现成的代码,我们不妨copy一下,将lcd.c和lcd.h复制过来8 {8 O7 [7 T$ v6 J
然后修改lcd.h里的LCD控制GPIO代码+ h4 b& L; q; ~$ \: l2 g! {

4 K2 w/ p% ]  Z8 E  O
  1. /*6 z, X2 r# h) ^; @
  2.         LCD_PWR:        PB150 S& ?. V: r, n% w" w( I) B
  3.         LCD_RST:        PC7, N8 [& v/ e2 R  M9 p4 s% H! M( k
  4.         LCD_DC:                PC6 5 @. [: }/ U) K/ X; Y) \2 ~; V
  5. *// P* G" W0 H9 U& y3 n: W! f
  6. #define        LCD_PWR(n)                (n?LL_GPIO_SetOutputPin(GPIOB, LL_GPIO_PIN_15):LL_GPIO_ResetOutputPin(GPIOB, LL_GPIO_PIN_15))& {+ D+ d8 {$ b0 K8 d
  7. #define        LCD_RST(n)                (n?LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_7 ):LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_7))- ]" i/ u& P" V0 m: {
  8. #define        LCD_DC(n)                (n?LL_GPIO_SetOutputPin(GPIOC, LL_GPIO_PIN_6 ):LL_GPIO_ResetOutputPin(GPIOC, LL_GPIO_PIN_6))
    ( O2 q( m' }. b' }2 {3 z
复制代码

5 q" j" Q8 Y% ?3 ~" A0 O8 p将lcd.c里的LCD_Gpio_Init()代码删去,然后在LCD_Init()开头添加如下代码:
* j* I' w) \6 q' i
: |) f4 E! |; h" `  o0 K; p
  1.     SPI2_Init();
    ) K+ ~) M+ @3 F" ?& {
  2.         
    # x7 T/ T- R7 W/ d0 o" |( d
  3.     LCD_PWR(0);                //关闭显示
    3 K0 F4 D* k+ B: O# w

  4. . F/ S4 I1 z& N
  5.     LCD_RST(0);9 u* {: `1 O5 [. r+ V: J
  6.     delay_ms(120);
    3 l7 I  {+ g% t7 Q
  7.     LCD_RST(1);                //复位
复制代码
! S7 n# S; C# O
在主函数里写入
# \. k$ G9 C* Y' o2 |
. j3 F5 g6 y8 y+ [& ^8 D6 R
  1.         LCD_Init();                                //初始化LCD4 Z) u2 w0 [2 r' Q5 c
  2.         9 H$ N+ s5 ]" O6 s/ i
  3.         POINT_COLOR = RED;1 w  Q4 v) n2 t" \2 `6 P
  4.         LCD_ShowString(0, 100, 240, 32, 32, "BearPi STM32L4");
复制代码

! \2 N+ q0 T% P: f, |编译链接下载到开发板里,测试结果如下
! i( K& H4 p( H9 B% l
5 f7 L0 t- ?( I4 P5 t$ S! k 2020011018350065.png 0 v/ n$ K4 j! f' q

+ c9 ^; J" O; z0 a: F; a表明测试成功
9 b# j! u) T8 z9 s6 k' ?) `4 N  I————————————————
; ]" P4 y7 e: v# Z! r" @; A1 X转载:Willliam_william% U( F3 [. y2 Y9 d% ~9 p5 }: b
1 Q, A' }; X* g1 n3 n! `
% A! o- k/ P; }* k/ P1 c
收藏 评论0 发布时间:2022-8-27 14:53

举报

0个回答

所属标签

相似分享

官网相关资源

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