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

STM32驱动ST7789V2 tft屏幕

[复制链接]
STMCU小助手 发布时间:2022-8-21 18:00
一 . 简介& J- Q4 H  r3 b
本次教程使用的是1.54寸240*240像素的tft屏幕,其接口协议为SPI协议。在使用的过程中仅需要四根数据即可驱动点亮屏幕。然后硬件使用的是STM32F103C8T6核心板,用的是SPI2。一般购买屏幕的话它们会提供对应的例程,直接拿过来修改即可。0 g5 s2 D* D5 B7 y

, ?2 z; i3 q& _$ y& d二. 屏幕的使用: @# v# @6 J, w
第一步肯定是引脚初始化,接口是SPI接口,所以也需要对SPI进行初始化(软件模拟SPI时序的话就不需要,硬件SPI需要),如果需要用到DMA进行加速的话,也需要对DMA进行初始化(不用DMA显示一副图片的速度比使用DMA的要慢上几倍,如果不显示图片的话可以不进行初始化)。* q& G3 Q  A0 P

4 S  j$ L9 Q  I- R  J1.屏幕引脚介绍:
: ]# M! v! P) K2 uDC: 写数据后命令控制,1为数据
0 o$ h! t, _5 D' p  V9 uCS:片选,低电平有效
4 L/ Y$ n# p" v9 X  oRES: 控制lCD重启4 S2 {" o: D/ y( T4 x
SDA:SPI的MOSI线
% c* Z8 \3 A" l. d/ ^7 QSCK:SPI的时钟线
4 n. i$ v; _; X, m( wBLK:控制LCD是否显示,不进行控制的话直接接高电平即可(这里直接接的高电平)
- p9 ]& J* K$ c2.引脚初始化
: a* g* ]' J( X' r% k, j这里除了SDA和SCK是SPI信号线需要进行复用之外,其他的都可以当做普通的IO进行初始化即可。查看手册可以知道SPI2的时钟映射到了GPIOB-Pin13,MOSI映射到了GPIOB-Pin15(一下子找不到了 ̄□ ̄||)。对其引脚进行复用初始化即可。
8 Y6 M8 ?- A: u3.SPI初始化  c7 h' s) y6 `5 \  ?  Y1 l
这里就直接上代码了
' z1 j3 o, l" x, t: h, z
  1.     SPI_InitTypeDef SPI_InitStructure;# I( U, P1 n+ J  S
  2.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE); //初始化SPI2端口时钟
    + N- ?. X5 [; r1 \( z; [: ^
  3.     SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;- X! w; y9 x0 [1 ~3 B- @+ q2 |4 h; o. u
  4.     SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;% I* D9 m7 z- ?5 ]% t. D3 |1 f" b
  5.     SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;; f# ^! G5 x% C  ~
  6.     SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
    5 r# O& i9 X: g5 @
  7.     SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;; o8 O5 J/ u" R# D7 @! b
  8.     SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;. ^' Q% U, o! J; o7 d: m; V
  9.     SPI_InitStructure.SPI_Direction = SPI_Direction_1Line_Tx;
    . Z- D: V  `% R' n* F6 L
  10.     SPI_InitStructure.SPI_CRCPolynomial = 7;
    0 \. ~! {6 U2 i% }6 n2 B  U
  11.     SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
    & e! b, ^! ?0 @2 y1 Y
  12.     SPI_Init(SPI2,&SPI_InitStructure);" Q: N( W7 _6 {3 h" w+ {
  13.     SPI_Cmd(SPI2,ENABLE);
复制代码

* H9 ~) }5 Y3 Z2 i4.DMA初始化
  M0 A3 n* y% \. q( g需要查看SPI2的Tx是使用的DMA1的那个通道,这个也需要查看手册。如下图,映射到的时候通道5,根据这个就可以进行初始化了。1 u( L* U) f' L# r
* J- q+ _1 @0 c
079514c7266542f6bd151bcd2b3a3a18.png
/ j/ ^+ \9 {4 y7 r- o! Q3 [' ]
% A3 X. \, U% E3 |6 l
  1. DMA_InitTypeDef DMA_InitStructure;
    ! h3 _4 H- X' Z& {. j
  2. 6 q6 _8 T$ q& C' T, K
  3.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
    , ]& k* A+ r) [. q$ ?

  4. 4 ^* C9 @1 E2 t) G9 g2 y
  5.     DMA_DeInit(DMA1_Channel5); : p. E. Y. V  W; v
  6.     DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32)&SPI2->DR;8 C" e- H3 x2 P9 C2 E
  7.     DMA_InitStructure.DMA_MemoryBaseAddr     = (uint32)buffer;    //发送数据的内存地址" ^6 z: i' n5 L, p2 m8 E
  8.     DMA_InitStructure.DMA_DIR                = DMA_DIR_PeripheralDST; //方向为内存到外设' }% a6 o1 S/ ~
  9.     DMA_InitStructure.DMA_BufferSize         = 480;   //数据大小
    - c9 s$ h* ~+ m- _# A( y
  10.     DMA_InitStructure.DMA_PeripheralInc      = DMA_PeripheralInc_Disable; //每发送一个外设地址不变  r2 |) [+ e- c2 f5 P- S* R9 I9 m
  11.     DMA_InitStructure.DMA_MemoryInc          = DMA_MemoryInc_Enable; //每发送一个内存地址加一# D* N) ?0 c, G0 v9 l
  12.     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;) L$ I" T6 z. H7 w% S
  13.     DMA_InitStructure.DMA_MemoryDataSize     = DMA_MemoryDataSize_Byte;6 [  o. I( d0 o, D- d4 {, |
  14.     DMA_InitStructure.DMA_Mode               = DMA_Mode_Normal;7 P4 ]' c3 N9 ?5 j, b7 m
  15.     DMA_InitStructure.DMA_Priority           = DMA_Priority_Medium;
    * M; [" }4 _4 r) N& U
  16.     DMA_InitStructure.DMA_M2M                = DMA_M2M_Disable;! [% d6 h0 ^4 S8 g$ t
  17.     DMA_Init(DMA1_Channel5,&DMA_InitStructure);
复制代码
# N) i( K) s) ^: S( N  {1 u
5.然后就是对LCD屏幕的初始化了,也就是配置对应的寄存器。这个可以拿卖家提供的直接拿来用就可以。
4 ^6 S+ V- B" E7 B这里我们就完成了所有的初始化工作了。
# |3 Y  ]& h' G3 W+ s1 }0 k
2 U% J  U( I2 z! E1. 设置数据地址范围
" d4 x  E( m' f每次发送显示数据的时候,需要设置显示范围,也就是行列的起始值。设置好范围,然后就发送对应大小的数据即可。其显示发送为从左往右,从上到下。
7 ?) F( L: f% i! C
& {# i" P; f( x9 w  b( ~2 g: b5 T fb58874c6f744d58ac68da63db9998e5.png 5 ?* ]2 z8 N: l
  1. 9 ?8 l* b: q8 |. b  K' T" Z. u
  2. //设置数据显示地址范围2 p% C$ |$ f3 M
  3. void LCD_Address_Set(uint16 x1,uint16 y1,uint16 x2,uint16 y2)
    * X- L8 [1 z3 j9 q: M
  4. {
    ' R! x8 T" s7 y% Q5 e; }" p! d; W
  5.     LCD_Write_Cmd(0x2a);//列地址设置+ G& E; P7 a; @9 ^$ C" ]/ ~
  6.     LCD_WriteDisplayData16(x1);# ~4 g4 i/ k/ b) T1 _
  7.     LCD_WriteDisplayData16(x2);, g: e" [; V, L8 R8 _( Y
  8.     LCD_Write_Cmd(0x2b);//行地址设置4 ^2 y* w# t: l" d
  9.     LCD_WriteDisplayData16(y1);
    1 Y1 f: I2 d' W* `
  10.     LCD_WriteDisplayData16(y2);5 D$ l$ J; `: b
  11.     LCD_Write_Cmd(0x2c);//储存器写5 \% l) |4 L$ i9 S% T) ]
  12. }
复制代码
3 p' i! N. m! S9 h9 T# L
2. 点亮LCD屏幕
7 l2 l+ m" l/ `6 ~6 r, R8 f1 V
  1. //LCD全亮$ n8 X; v4 Q; g$ V) |) a% A
  2. void LCDFullOn(uint16 Color)* s8 {0 R8 T9 ]. J; b
  3. {* L5 @5 L" X1 q/ T( e. E' w
  4.     uint16 i,j;          % ?# j- ~( t2 O& K" @
  5.         LCD_Address_Set(0,0,LCD_Width-1,LCD_Height-1);! {% M! V( E+ K
  6.     for(i=0;i<LCD_Width;i++)1 i, L% P6 q* E; V& k
  7.           { , a4 F+ f+ S, S
  8.                         for (j=0;j<LCD_Height;j++)
    6 g: j& D) q. M! _
  9.                                 {2 g1 \3 I" J# p$ L' q& e
  10.                                         LCD_WriteDisplayData16(Color);  v* _) t  R& ~; h7 l1 E  V
  11.                                 }      8 I! T2 h' F. s/ A- W% O
  12.           }" t$ q. J8 ^( W+ W( M( s
  13. }
复制代码
) X4 t! l0 s. h& l. Z2 K
3. 使用DMA搬运数据
9 g9 \! Q' {7 t! {1.对设置DMA搬运数据的大小并且使能
; T6 X' O& `% |7 L
  1. //spi2 DMA使能
    4 D' b4 C* d( [* g
  2. void SPI2DMA_Enable(void). _$ h* i& C7 e# @
  3. {
    * i- n( o# \! b  ~2 J
  4.     DMA_Cmd(DMA1_Channel5, DISABLE );    0 B) G) g6 W" A
  5.          DMA_SetCurrDataCounter(DMA1_Channel5,480);  //设置搬运数据的大小
    1 ?3 f; Y! z( b; D0 N4 r
  6.          DMA_Cmd(DMA1_Channel5, ENABLE);  6 }( i  P5 q" V  M. O/ C7 j
  7. }
复制代码
) w+ W% e2 [! F- b- G" n- Q9 W
2.开启DMA请求,且等待发送完成,清除标志位4 O- V5 k/ q# Q0 V  P# m9 Y
  1.   for(j = 0 ; j< 240 ; j++)- x8 U  j. x/ ]. @
  2.     {1 p' u- K7 Z$ z2 o: f" e" E, N
  3.         SPI_I2S_DMACmd(SPI2,SPI_I2S_DMAReq_Tx,ENABLE); 2 C4 B" \2 E5 d6 n- q  B3 Z$ [8 ?3 m
  4.             SPI2DMA_Enable();$ N1 E% c! b) U8 R) h3 r
  5.         while((DMA_GetFlagStatus(DMA1_FLAG_TC5)==RESET)); // 等待dma发送完成0 p  ?2 F$ U4 X8 R! v8 x9 ~3 W
  6.         DMA_ClearFlag(DMA1_FLAG_TC5);- k0 _8 b# ?0 k1 P  V
  7.     }
复制代码

- r$ c5 H' V# ^通过测试,可以明显看到使用DMA进行加速的显示效果要快很多。
9 [+ Y" ?$ Z$ a
  E  [# L6 X7 w: o0 d: y1 S# d1 `. h1 J8 R% n% i+ p1 b# U5 N# [! z
+ {' G$ }) ^6 ~
收藏 评论0 发布时间:2022-8-21 18:00

举报

0个回答

所属标签

相似分享

官网相关资源

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