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

【经验分享】STM32f746gdiscovery LTDC 驱动

[复制链接]
STMCU小助手 发布时间:2021-12-14 10:49
需要提前准备好SDRAM驱动,如果没有SDRAM可以进行纯色彩测试,底层时钟,IO操作相关看注释,我使用的是寄存器封装的。
4 F0 C0 a2 W& Z! j/ z5 t1 W9 j
5 q0 v8 ?5 L" Z
  1. /*************************************************************************************************************
    . q8 a# A: x5 b% H- u! v1 ]! W
  2. * 文件名                :        stm32f7_ltdc.c
    6 e, m( @/ [3 l+ ?( c1 f* y  F, t
  3. * 功能                        :        STM32F7 外部RGB LCD驱动
    , N% g2 n, O2 j  H' z8 z5 O; t
  4. * 创建时间                :        2019-09-124 }( `" w* K, q4 Z  D5 i$ y
  5. * 最后修改时间        :        2019-09-12
    / E( k' K& u6 e" Z, z, K9 ]. X
  6. * 详细:        
    ' J+ i9 O+ j6 T: `! {% d
  7. *************************************************************************************************************/        - Z5 d3 c6 M  s5 y2 ?: _) X
  8. #include "stm32f7_ltdc.h"0 ]2 ~* A* F* V" \- J; Z. i
  9. #include "SYSTEM.H" / L# M2 p( H8 ?2 [7 \; o
  10. #include "stm32f7_sdram.h"* ~; a. \" u/ K: a! }
  11. #include "DMA2D.h"5 \- L! H) H& C9 m8 e, N
  12. 8 _& s3 P. e" O+ I5 X* h

  13.   L: U/ M1 }" [) e+ i. L  _2 J
  14. u32 g_LTDC_BUFF_RGB888[2][LTDC_HEIGHT][LTDC_WIDTH]  __attribute__ ((at(Bank5_SDRAM_ADDR)));                //需要SDRAM支持,LCD帧缓冲区,RGB888格式1 H: Z, ]$ ^/ K: F) A# H, V9 t# c
  15. , J; O) e2 F! k

  16. ; ~+ F! y' O+ @" _( C
  17. //记录全局层配置信息
    , l2 |7 s7 g+ H) ~( g! z! `
  18. typedef struct
    & |) ^6 v6 f4 H. A' j0 {  d. R  C
  19. {0 K. h+ z+ j% \$ S
  20.         u16 sx;                                        //层开始X坐标,从0开始9 V! B5 u4 G2 Y8 I! R. I
  21.         u16 sy;                                        //层开始Y坐标,从0开始
    : A- p# k+ }( {5 @3 J
  22.         u16 width;                                //层宽度, v! K! S2 M* m* K6 I. D$ A
  23.         u16 height;                                //层高度
    - _5 k3 H4 e6 s. m; v. T
  24.         u32 *pFrameBuff;                //帧缓冲区指针,需要进行初始化# t1 C% {  S9 ?3 Z: W$ H
  25. }LTDC_LayerConfig;3 w* ~1 b  |" r

  26. 9 ]: Q" w- m! G( z3 N; w

  27. . r3 m+ I- b5 J' x/ C" h2 W$ M

  28. & y6 K0 P/ F0 Q' M- d- Y
  29. //全局的LTDC配置信息
    : G+ d* b( X* m$ p. ]5 r" l
  30. typedef struct
    * K5 s  d4 ~/ \
  31. {3 a* Z4 C9 G1 g- f! d
  32.         u16 lcd_width;                                                //显示器宽度
    1 H: b& R7 Z( F, _0 B* U
  33.         u16 lcd_height;                                                //显示器高度
    6 h+ M6 T$ w6 Q( F
  34.         LTDC_LayerConfig LayerConfig[2];        //层信息- y4 ]( s; s/ q  y# A7 `* w2 y
  35. }LTDC_ConfigData;
    ! G; ^, Q$ p' h8 E  ?& k
  36. ) M+ w0 a  ^; e

  37. ! H0 I0 f+ }/ T
  38. static LTDC_ConfigData sg_LTDC_ConfigData;        //记录全局的LCD配置4 j, d$ ~$ k3 C0 `3 {

  39. : o6 u8 s4 v8 G' `* T
  40. + P8 Q9 O. }& t* k
  41. //显示屏信息
    4 |$ x9 R4 ~, a4 r, T
  42. typedef struct6 F6 y7 j+ @" ^+ U. E
  43. {
    4 l, Y+ N. q' T5 @" Q/ [
  44.         u16         Width;                //面板宽度,单位:像素( Y& J+ x1 K8 `. Z+ v+ t% B
  45.         u16         Height;                //面板高度,单位:像素
    : ~5 E; y& i" h6 h
  46.         u8          Thbp;                //水平后廊
    5 A: j$ ~0 v' r! c( B% T  R5 o
  47.         u8          Thfp;                //水平前廊
    . T6 p* j- T- e  G7 s' Z+ Q
  48.         u8          Thw;                //水平同步宽度
    " Q" ^4 I* p, }( a5 M
  49.         u8          Tvbp;                //垂直后廊6 Y( i% l1 Z3 o8 G
  50.         u8          Tvfp;                //垂直前廊
    , k  O9 P  v" C
  51.         u8          Tvw;                //垂直同步宽度' S% T/ k( w! q  s
  52.         u8          DCLK;                //时钟速度,MHz
    4 [. }' M+ l% x& S$ d
  53.         8 u( H' i4 |+ ]% K9 Y# Y
  54.         u8                HSPOL;                //水平同步极性,0:低电平有效;1:高电平有效; X% A6 ~4 X6 a; @/ T& _- w( {
  55.         u8                VSPOL;                //垂直同步极性,0:低电平有效;1:高电平有效9 C$ G, v* |# u3 f! ?! s, @
  56.         u8                DEPOL;                //数据使能极性,0:低电平有效;1:高电平有效: F; B7 Z3 c/ P$ `+ D3 K
  57.         bool        PCPOL;                //像素时钟反向- o6 Q+ T$ F) o" p! @
  58. }LTDC_INFO_TYPE;) p8 o2 U3 P. v( c7 B) U

  59. 4 v$ m3 S7 G6 ]( g$ w
  60. / N( ?5 B4 [8 p& i# S1 O+ @, @" B7 U
  61. LTDC_INFO_TYPE DefaultLCD_Info =
    2 Z$ W$ F4 \1 l  B
  62. {) F, u3 n! h- k8 F
  63.         480,        //面板宽度,单位:像素3 `4 `( `3 C. _, v6 Q$ E* s
  64.         272,        //面板高度,单位:像素
    3 D% n# J) ?* |# }& Y% Y
  65.         41,                //水平后廊. w( S' b8 w, P( s; Y
  66.         8,                //水平前廊8 W( M" Z" O0 u. J0 h+ A3 A
  67.         2,                //水平同步宽度
    . O# Z! k- Z# i4 H6 N0 j. ?7 m
  68.         2,                //垂直后廊' ?' o  J, B) B6 |) V3 @7 L2 A
  69.         4,                //垂直前廊
    5 f7 \1 d: n& s: _  W$ j
  70.         10,                //垂直同步宽度) a/ @5 e" m3 z4 q; h8 h
  71.         9,                //时钟速度,MHz
    8 E, D8 D& p( P) _* b
  72.         0,                //水平同步极性,0:低电平有效;1:高电平有效
    , w8 ?5 c6 s( }( J( `+ ^
  73.         0,                //垂直同步极性,0:低电平有效;1:高电平有效
    . d, f# R$ R0 L% a1 y# Q
  74.         1,                //数据使能极性,0:低电平有效;1:高电平有效; S" M. _$ j! E7 _1 N% ?4 s3 t; s7 s
  75.         FALSE,        //像素时钟反向
    7 c" z. m# i0 ~9 `" p: V* O* L
  76. };
    9 P# T2 L0 n5 x
  77. , [0 @! z) p. G9 L0 o) A! ]
  78. bool LTDC_ClockInit(u16 ClockFreq);                                                        //STM32F4 LTDC时钟初始化
    6 [/ p1 l& T: Z: z3 b9 i

  79. : d) {& i, e! E% ?; [7 v% S

  80. 7 k: ?; Q+ j, k  j6 W: w( ^
  81. /*************************************************************************************************************************
    : L6 A. w7 y4 k1 u% C4 h
  82. * 函数        :                        void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha)
    * N8 ?# B8 h$ i$ @* h2 U3 R
  83. * 功能        :                        LTDC 层窗口尺寸设置(会自动根据窗口尺寸以及像素格式设置帧缓冲区大小)7 u% W; q9 c: y# M2 |. n& O& F
  84. * 参数        :                        LayerIndex:层选择(0-1);sx,sy:起始坐标;width,height:宽度和高度* l( w' V! [: [( d6 a
  85. * 返回        :                        无# j0 u* I6 ]6 z* X. z
  86. * 依赖        :                        底层宏定义$ K0 b9 `5 I' I2 _6 H1 Z
  87. * 作者        :                        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    / r. B% v  ~" C# ^* Z- M6 L- o" t
  88. * 时间        :                        2019-10-28( }5 q7 K: r4 \" Z8 N- c
  89. * 最后修改时间 :         2019-10-285 s1 l7 O' E, O3 {
  90. * 说明        :                         不会使能层,不会更新层,只设置配置,需要刷新层配置后更新( m+ j; O. x  K" P0 a
  91. *************************************************************************************************************************/
    ; U* a; s6 F2 b0 Q
  92. void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha)
    / a: p1 F1 e* D% C/ ^3 f% J
  93. {
    $ H5 M- S2 y* z' F: b; `$ B8 }# I
  94.         u32 temp;) D* A: J4 N$ P0 o' F4 r, i( X
  95.         u8 pixformat=0; " o7 [, d' Y# T7 Y! J0 \
  96.         
    2 h" _( D& O! K4 {
  97.         if(LayerIndex==0)
    9 c4 y  K2 _- V7 y
  98.         {, L+ _. l8 S3 Z" f
  99.                 //基本配置/ U6 u( G% s2 {/ |/ T  D' H4 k
  100.                 LTDC_Layer1->CFBAR = FrameBuff;                                                                        //设置层颜色帧缓存起始地址& Q4 v, {" H/ _2 [  s
  101.                 LTDC_Layer1->PFCR = LTDC_PIXEL_FORMAT;                                                        //设置层颜色格式0 k* Q" i6 U8 e, _* }
  102.                 LTDC_Layer1->CACR = Alpha;                                                                                //常数 Alpha,255分频;设置255,则不透明
    7 p: C, I0 J8 }/ i/ \, ~
  103.                 LTDC_Layer1->DCCR = 0x00;                                                                                //设置默认颜色:透明的黑色0 _7 F8 P8 [* [1 K" U8 E) q
  104.                 LTDC_Layer1->BFCR = ((u32)6<<8)|7;                                                                //设置层混合系数
    - z5 X" X. C' n7 F8 P5 B
  105.                 //配置窗口
    2 \5 p/ w2 ]$ t: B
  106.                 temp = (sx+width+((LTDC->BPCR&0X0FFF0000)>>16))<<16;
    * M! ]2 B9 N" L0 D( K, c
  107.                 LTDC_Layer1->WHPCR = (sx+((LTDC->BPCR&0X0FFF0000)>>16)+1)|temp;//设置行起始和结束位置
    8 Z% v! Z5 G( p0 m9 d4 g
  108.                 temp = (sy+height+(LTDC->BPCR&0X7FF))<<16; + _4 [5 @2 z: \/ W, t
  109.                 LTDC_Layer1->WVPCR = (sy+(LTDC->BPCR&0X7FF)+1)|temp;                        //设置列起始和结束位置
    1 e! H, d& |& `" C; x
  110.                 pixformat = LTDC_Layer1->PFCR&0X07;                                                                //得到颜色格式+ r! x: r% n/ Z) e2 F6 _3 T% U
  111.                 if(pixformat == 0)temp=4;                                                                                //ARGB8888,一个点4个字节) T8 ]! A3 _( r0 r
  112.                 else if(pixformat == 1)temp=3;                                                                        //RGB888,一个点3个字节
    * v# Z; a3 |- j; u5 Y, a
  113.                 else if(pixformat==5||pixformat==6)temp=1;                                                //L8/AL44,一个点1个字节
    % [+ Z3 @3 O  J: K; _$ f( V* v  X- P
  114.                 else temp=2;                                                                                                        //其他格式,一个点2个字节
    * a' j8 b& }" U& u% D- c
  115.                 LTDC_Layer1->CFBLR = (width*temp<<16)|(width*temp+3);                        //帧缓冲区长度设置(字节为单位)1 h* V( X( ^2 {+ X" E4 M4 c
  116.                 LTDC_Layer1->CFBLNR = height;                                                                        //帧缓冲区行数设置        
    4 h  ]8 n* i7 N$ `# l9 |+ j
  117.                 . U+ m: ~$ I  y2 o9 g* E
  118.                 //记录层窗口大小位置信息
    / M- \6 e/ ?7 a6 a# {+ |* j
  119.                 sg_LTDC_ConfigData.LayerConfig[0].sx = sx;                4 t4 E$ H. d; ?6 [  y, p* g% b
  120.                 sg_LTDC_ConfigData.LayerConfig[0].sy = sy;        
    & R  u5 `: _. @/ e. N- w% @* z& X
  121.                 sg_LTDC_ConfigData.LayerConfig[0].width = width;        
    + x1 a$ r) s# E& J+ R
  122.                 sg_LTDC_ConfigData.LayerConfig[0].height = height;        - o5 i# Q% a5 F
  123.         }else
    7 F8 U/ `9 o& {3 H
  124.         {
    . L) z' q/ q9 s; y, M! i; o
  125.                 //基本配置
    5 I# R4 U. |0 V5 n1 t) w
  126.                 LTDC_Layer2->CFBAR = FrameBuff;                                                                        //设置层颜色帧缓存起始地址
    " }# L+ w& T) y) y7 H
  127.                 LTDC_Layer2->PFCR = LTDC_PIXEL_FORMAT;                                                        //设置层颜色格式% o: h; i3 C5 f1 T* r
  128.                 LTDC_Layer2->CACR = Alpha;                                                                                //常数 Alpha,255分频;设置255,则不透明' R* X3 m* v: Y( C
  129.                 LTDC_Layer2->DCCR = 0x00;                                                                                //设置默认颜色:透明的黑色* O4 p' ]7 j* f7 l$ V
  130.                 LTDC_Layer2->BFCR = ((u32)6<<8)|7;                                                                //设置层混合系数
    5 y: h: I& ?" l  \
  131.                 //配置窗口& s- r  l2 k1 V9 A
  132.                 temp = (sx+width+((LTDC->BPCR&0X0FFF0000)>>16))<<16;
      C5 I, `3 X  b6 W1 b. @" G+ _
  133.                 LTDC_Layer2->WHPCR = (sx+((LTDC->BPCR&0X0FFF0000)>>16)+1)|temp;        //设置行起始和结束位置
    , L: d7 l  Q) f/ i% a
  134.                 temp = (sy+height+(LTDC->BPCR&0X7FF))<<16;
    5 H4 r: \! |- p; u' F* ]7 I  a
  135.                 LTDC_Layer2->WVPCR = (sy+(LTDC->BPCR&0X7FF)+1)|temp;                        //设置列起始和结束位置
    ) t% y# T5 c. T7 a2 a
  136.                 pixformat = LTDC_Layer2->PFCR&0X07;                                                                //得到颜色格式# {% K. @4 ?6 k: S! i4 {) a
  137.                 if(pixformat == 0)temp=4;                                                                                //ARGB8888,一个点4个字节1 K7 Y! h5 i* c8 \
  138.                 else if(pixformat == 1)temp=3;                                                                        //RGB888,一个点3个字节9 C: Y0 L% s& h1 `$ l
  139.                 else if(pixformat == 5||pixformat==6)temp=1;                                        //L8/AL44,一个点1个字节
    8 a# o3 |: }+ ?6 p8 h1 g
  140.                 else temp = 2;                                                                                                        //其他格式,一个点2个字节$ H8 Z! j" P3 v
  141.                 LTDC_Layer2->CFBLR = (width*temp<<16)|(width*temp+3);                        //帧缓冲区长度设置(字节为单位)/ n+ y& \3 a6 o/ T) O" L. _
  142.                 LTDC_Layer2->CFBLNR = height;                                                                        //帧缓冲区行数设置        . Y- ~; I2 A9 M7 u+ z
  143.                
    4 h4 i% G* C' G1 {; S0 }
  144.                 //记录层窗口大小位置信息6 u. u) }3 ?: U' |
  145.                 sg_LTDC_ConfigData.LayerConfig[1].sx = sx;               
    3 \2 ^3 @: q9 u5 x$ f
  146.                 sg_LTDC_ConfigData.LayerConfig[1].sy = sy;        
    - U% c5 V* S( m
  147.                 sg_LTDC_ConfigData.LayerConfig[1].width = width;        / n% m- X  {# P: |7 t
  148.                 sg_LTDC_ConfigData.LayerConfig[1].height = height;               
    3 @6 F3 I3 g7 G1 H" R# q
  149.         }' X5 ]& D4 S6 i) \* T
  150. }  V, x5 i1 E! F+ c
  151. % _% ]: O7 m( A) T. a. d+ x
  152. ! ~) N5 X1 R6 B
  153.   [# m6 N% b2 p. y( I6 D9 N
  154. /*************************************************************************************************************************: k! r7 j- H, }% L- W: Q* E6 k
  155. * 函数        :                        void LTDC_Init(void)
    ( y' K9 c6 A0 r' v" B( y6 y
  156. * 功能        :                        LTDC 接口初始化( l/ V1 v' l# m( d" Q$ C1 S8 [% z  d  ^; O
  157. * 参数        :                        无
    0 F+ f8 a* _6 p8 t6 M
  158. * 返回        :                        无
    5 V, b/ U. H& J; g8 n
  159. * 依赖        :                        底层宏定义
    ( r2 W6 \- c) W
  160. * 作者        :                        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    0 ]) D- [4 F! t! g
  161. * 时间        :                        2019-09-08! i* m" \2 |6 r( L/ O
  162. * 最后修改时间 :         2019-09-08
    - Y! R8 y7 P  t8 D7 A9 T+ c
  163. * 说明        :                         用于初始化STM32F7 LTDC 接口
    & A$ W) @$ J- u* C, k( i
  164. *************************************************************************************************************************/  
    . T! D$ Z6 s  c5 j. q
  165. void LTDC_Init(void)# {: s" Z4 v, y" g& O
  166. {
    * p/ C. u* H( H. o- a, Q
  167.         u32 temp;
    4 z# q+ y) q& S6 d' b; {" e
  168.         
      _3 }4 E' }, R. {
  169.         SYS_DeviceClockEnable(DEV_LTDC, TRUE);        //LTDC时钟使能) j6 E6 A" E) a% N
  170.         SYS_DeviceReset(DEV_LTDC);                                //STM32F7外设复位
    ( G. x. |6 F+ L+ b7 C* V7 z$ ^3 ?
  171.         SYS_DeviceClockEnable(DEV_GPIOE, TRUE);        //使能GPIOE时钟6 `% @+ I4 i# A/ m$ s+ ]
  172.         SYS_DeviceClockEnable(DEV_GPIOG, TRUE);        //使能GPIOG时钟' @. G0 |- f0 p. V0 j
  173.         SYS_DeviceClockEnable(DEV_GPIOJ, TRUE);        //使能GPIOJ时钟
    ' p; p! d$ R& W5 G% `
  174.         SYS_DeviceClockEnable(DEV_GPIOK, TRUE);        //使能GPIOK时钟
    : j6 I6 o" Z3 ]* B+ ~$ k
  175.         SYS_DeviceClockEnable(DEV_GPIOI, TRUE);        //使能GPIOI时钟' C: a5 V0 f! b
  176. / m7 d& E- E; }
  177.         
    - r- s& u1 x% Y9 c# k
  178.         //初始化IO; w) p$ w% s" O6 H
  179.         SYS_GPIOx_Init(GPIOE, BIT4, AF_PP_OPU, SPEED_100M);                                                                                //PE4" U. C2 o6 O5 B% p+ w
  180.         SYS_GPIOx_Init(GPIOG, BIT12, AF_PP_OPU, SPEED_100M);                                                                        //PG12
    ; {2 q/ x7 h8 p5 }
  181.         SYS_GPIOx_Init(GPIOJ, 0Xffff&(~BIT12), AF_PP_OPU, SPEED_100M);                                                        //PJ0~11/13/14/15! J2 ^( p8 g4 `* H% w4 A4 i
  182.         SYS_GPIOx_Init(GPIOK, BIT0|BIT1|BIT2|BIT4|BIT5|BIT6|BIT7, AF_PP_OPU, SPEED_100M);                //PK0/1/2/4/5/6/7
    ' l9 w0 b% j" X* V5 X/ s/ C
  183.         SYS_GPIOx_Init(GPIOI, BIT9|BIT10|BIT14|BIT15, AF_PP_OPU, SPEED_100M);                                        //PI9/10/14/15% a0 e) y3 W$ o) g8 b0 B* d
  184.         / u0 Q' J& @4 G/ V
  185.         SYS_GPIOx_SetAF(GPIOE, 4, AF14_LTDC);                //PE4,AF14        * c* `' \' z- I8 D$ `
  186.          SYS_GPIOx_SetAF(GPIOG, 12, AF14_LTDC);                //PG12,AF14        
    8 C7 R. {; }' p
  187.         SYS_GPIOx_SetAF(GPIOJ, 0, AF14_LTDC);                //PJ0,AF14
    # d( }/ z2 W- [" Y* c% {& B3 Z
  188.         SYS_GPIOx_SetAF(GPIOJ, 1, AF14_LTDC);                //PJ1,AF14
    $ u' A. d) z2 J' G' m5 c7 G
  189.         SYS_GPIOx_SetAF(GPIOJ, 2, AF14_LTDC);                //PJ2,AF149 D5 @' F+ P' o: ~# j9 z1 ^% a
  190.         SYS_GPIOx_SetAF(GPIOJ, 3, AF14_LTDC);                //PJ3,AF147 b" Q6 F6 U0 m! X, I/ k7 q
  191.         SYS_GPIOx_SetAF(GPIOJ, 4, AF14_LTDC);                //PJ4,AF148 U2 Z; s3 R# `; w
  192.         SYS_GPIOx_SetAF(GPIOJ, 5, AF14_LTDC);                //PJ5,AF14
    : `. N6 s1 M% N; M; O' `+ d
  193.         SYS_GPIOx_SetAF(GPIOJ, 6, AF14_LTDC);                //PJ6,AF14$ J, N( m% }( v% `  z
  194.         SYS_GPIOx_SetAF(GPIOJ, 7, AF14_LTDC);                //PJ7,AF14
    0 G# s- a% N6 |( i* ~- t
  195.         SYS_GPIOx_SetAF(GPIOJ, 8, AF14_LTDC);                //PJ8,AF14
    + _) Y3 T5 p# M- a0 I8 K- w2 ]
  196.         SYS_GPIOx_SetAF(GPIOJ, 9, AF14_LTDC);                //PJ9,AF14
    / C8 G4 D% t, [
  197.         SYS_GPIOx_SetAF(GPIOJ, 10, AF14_LTDC);                //PJ10,AF14
    2 C( Y$ q/ o% E* F" F: r
  198.         SYS_GPIOx_SetAF(GPIOJ, 11, AF14_LTDC);                //PJ11,AF14+ j) r4 o& ?  `9 f
  199.         SYS_GPIOx_SetAF(GPIOJ, 13, AF14_LTDC);                //PJ13,AF14
    ' I) \5 {" O7 R7 b' p  G
  200.         SYS_GPIOx_SetAF(GPIOJ, 14, AF14_LTDC);                //PJ14,AF14
    - c2 Q' W/ x. e9 T4 v
  201.         SYS_GPIOx_SetAF(GPIOJ, 15, AF14_LTDC);                //PJ15,AF14
    ; `/ g1 P1 W/ @; o2 x
  202.         ) [7 a: c; ^/ o$ a! D6 o
  203.         SYS_GPIOx_SetAF(GPIOK, 0, AF14_LTDC);                //PK0,AF14; ]9 ?0 |2 \4 u& F+ t" u$ y
  204.         SYS_GPIOx_SetAF(GPIOK, 1, AF14_LTDC);                //PK1,AF144 g" \: b* U8 H. d3 A. l$ N/ M
  205.         SYS_GPIOx_SetAF(GPIOK, 2, AF14_LTDC);                //PK2,AF14
    7 S. F% x* j& C0 `' `2 @& I) R9 r) s
  206.         SYS_GPIOx_SetAF(GPIOK, 4, AF14_LTDC);                //PK4,AF14
    1 A' ^4 b8 W+ \+ C
  207.         SYS_GPIOx_SetAF(GPIOK, 5, AF14_LTDC);                //PK5,AF14
    ' K# A- o# O2 K; c1 R% }  f$ h
  208.         SYS_GPIOx_SetAF(GPIOK, 6, AF14_LTDC);                //PK6,AF145 S8 a' }2 K9 p0 b( d1 v0 f8 L9 x+ u
  209.         SYS_GPIOx_SetAF(GPIOK, 7, AF14_LTDC);                //PK7,AF148 R* h4 j. ]- I7 }
  210.         - X0 _: {9 S$ K
  211.          SYS_GPIOx_SetAF(GPIOI, 9, AF14_LTDC);                //PI9,AF14: N- e. {- |0 k# i) e6 `' ]
  212.          SYS_GPIOx_SetAF(GPIOI, 10, AF14_LTDC);                //PI10,AF14
    8 i6 a/ x: r5 v4 x
  213.         SYS_GPIOx_SetAF(GPIOI, 14, AF14_LTDC);                //PI14,AF14  t7 z9 Q& h' g0 d
  214.          SYS_GPIOx_SetAF(GPIOI, 15, AF14_LTDC);                //PI15,AF14
    9 n3 z2 c: |6 N% a6 q
  215.         
    2 _8 z7 G! j1 z4 `
  216.         LTDC_ClockInit(DefaultLCD_Info.DCLK);                 //设置像素时钟  9Mhz ! A' h9 ^6 t9 M  i! U
  217.         //设置LTDC 全局控制寄存器 (LTDC_GCR). U9 s/ y8 r9 R& R8 ]
  218.         temp = 0;
    8 s. M: W. l' N2 E
  219.         temp |= (DefaultLCD_Info.HSPOL&0x01) << 31;        //水平同步极性$ Q# g/ c/ @, t$ O& a  c$ L  K5 f' W
  220.         temp |= (DefaultLCD_Info.VSPOL&0x01) << 30;        //垂直同步极性
    6 e4 r7 _' L# |4 i
  221.         temp |= (DefaultLCD_Info.DEPOL&0x01) << 29;        //数据使能极性
    7 H7 P  j3 Y/ n) J& `/ h/ _
  222.         temp |= (DefaultLCD_Info.PCPOL&0x01) << 28;        //像素时钟极性
    / ~/ W$ K# p' ^
  223.         LTDC->GCR = temp;. `' p# v' b3 }. P
  224.         //LTDC 后沿配置寄存器 (LTDC_BPCR)
    + }7 ]8 Y' ?4 N; ?3 |
  225.         temp = (DefaultLCD_Info.Tvw + DefaultLCD_Info.Tvbp - 1) << 0;        //这些位定义累加水平后沿宽度(水平同步像素加水平后沿像素减 1)。' A4 y5 D  c* g# u) C
  226.         temp |= (DefaultLCD_Info.Thw + DefaultLCD_Info.Thbp - 1) << 16;        //这些位定义累加垂直后沿宽度(垂直同步行加垂直后沿行减 1)。4 s/ c9 B/ r; l" @
  227.         LTDC->BPCR=temp;        4 _0 T7 \3 Y$ t" N# Y8 i9 c
  228.         # C. N6 r2 H: p0 K
  229.         //LTDC 有效宽度配置寄存器 (LTDC_AWCR)7 O5 {2 t+ [! I: J' Z" k& b; X$ F
  230.         temp=(DefaultLCD_Info.Tvw+DefaultLCD_Info.Tvbp+DefaultLCD_Info.Height-1)<<0;        //累加有效高度=垂直脉宽+垂直后沿+垂直分辨率-1/ r: n  Z  J7 {3 l2 M* r
  231.         temp|=(DefaultLCD_Info.Thw+DefaultLCD_Info.Thbp+DefaultLCD_Info.Width-1)<<16;        //累加有效宽度=水平脉宽+水平后沿+水平分辨率-1
    7 z1 u1 @& `- g6 _2 g4 h( Q+ H' i
  232.         LTDC->AWCR=temp;          }3 ?0 Y7 X  m5 L8 a; [# H
  233.         //LTDC 总宽度配置寄存器 (LTDC_TWCR)
    5 Q! o6 H5 l. L3 D7 _2 a
  234.          temp=(DefaultLCD_Info.Tvw+DefaultLCD_Info.Tvbp+DefaultLCD_Info.Height+DefaultLCD_Info.Tvfp-1)<<0;        //总高度=垂直脉宽+垂直后沿+垂直分辨率+垂直前廊-1& R- p! n9 D4 Q" P) p
  235.         temp|=(DefaultLCD_Info.Thw+DefaultLCD_Info.Thbp+DefaultLCD_Info.Width+DefaultLCD_Info.Thfp-1)<<16;        //总宽度=水平脉宽+水平后沿+水平分辨率+水平前廊-19 v" k& [7 ~$ ~/ o1 B6 M
  236.         LTDC->TWCR=temp;                                
    ; v9 a: c$ g9 v" L/ w- ^5 O

  237. % v7 U9 G) M& G2 c. ?6 O( R
  238.         //背景设置
    5 E2 T/ c; a9 K, ^: @- G: ?# j
  239.         LTDC->BCCR=0xffffff;                                //设置背景层颜色寄存器(RGB888格式)
    " {2 v) i( K1 o# o0 K# z! q* x9 R
  240.         LTDC_Enable(TRUE);                                        //开启LTDC$ a) Q: T0 X9 m1 s
  241.         //初始化层1: q  v! L/ j( i$ u0 U2 A
  242.         LTDC_SetLayerConfig(0, 0, 0, LTDC_WIDTH, LTDC_HEIGHT, (u32)g_LTDC_BUFF_RGB888[0], 255);& |1 R- N: w8 U/ W) B* C/ }
  243.         //初始化层2& u/ x" N% X2 C5 d
  244.         LTDC_SetLayerConfig(1, 0, 0, LTDC_WIDTH, LTDC_HEIGHT, (u32)g_LTDC_BUFF_RGB888[1], 255);
    + H1 T5 B2 }$ H
  245.         LTDC_Clear(0, 0xFF000000);                        //清屏层1-不透明的黑色, B6 Z- O7 j- f% S
  246.         LTDC_Clear(1, 0x00000000);                        //清屏层2-透明的黑色
    8 e/ C1 w4 P9 r& @* S! w
  247.         LTDC_LayerEnable(0, TRUE);                        //使能层12 Q- N1 [& j( A" H# |
  248.         LTDC_LayerRefreshConfig();                        //LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)
    " c2 p* Q0 F( v+ `! b$ @
  249.         LCD_DispIoInit();                                        //初始化DISP引脚-启动显示
    8 H! x9 q" L1 ?* O9 b5 ^+ f
  250. }
    ! Z4 @' u. }( a0 d; |6 O+ X) f

  251. 0 c5 e( K% H( b' o* t( k9 o3 _
  252. /*************************************************************************************************************************3 d: }0 K5 c$ ]
  253. * 函数                        :        void LTDC_LayerRefreshConfig(void)
      a' S; q; t6 n8 Q6 y
  254. * 功能                        :        LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)
      S5 N- Q, T4 |3 Q! @! n' q
  255. * 参数                        :        无. A# q& h1 ~2 x9 {
  256. * 返回                        :        无
    1 g* s8 |4 q0 w/ v( G* L' e  g- c
  257. * 依赖                        :        底层宏定义
    ! \% w1 t; B$ W9 q( u
  258. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    5 [: u$ F, p: w2 L( k. f8 y' M
  259. * 时间                        :        2019-10-29
    : K2 M, W- x; W3 y
  260. * 最后修改时间         :         2019-10-29
    6 ~1 c- Q+ Q6 Z0 u
  261. * 说明                        :        修改层配置后必须重新加载,否则不会生效) u' q$ d5 z& q
  262. *************************************************************************************************************************/* E7 H; P8 Q  R  y/ W
  263. void LTDC_LayerRefreshConfig(void)
    6 b- ]0 q6 ~) {  n
  264. {  {8 y: B. l9 i9 X3 y" I
  265.         LTDC->SRCR|=1<<0;                                                        //重新加载配置-必须重新加载,否则上面的层不会更新,折腾好久才发现,叫啥影子寄存器重载,也不说清楚  ~8 n( d! Q3 ]( o2 S3 c
  266. }% C* j0 J1 L8 {; R6 O" g, \) ]
  267. ' k$ k' j+ G  x+ A4 F& G5 x
  268. /*************************************************************************************************************************8 }, G+ ^  }9 j  m- J4 v
  269. * 函数                        :        void LTDC_Enable(bool Enable)
    , E# S8 A- z/ i2 T3 @
  270. * 功能                        :        LTDC使能设置
    * ?: D+ X5 Z, j% ~- u6 Z
  271. * 参数                        :        Enable:TRUE:使能;FALSE:失能
    5 c! x/ j" ]1 u% y
  272. * 返回                        :        无
    2 C" u1 ~6 W0 y4 W
  273. * 依赖                        :        底层宏定义, C2 t: r4 F1 V
  274. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>; e* M$ x! }% w# `6 i; `
  275. * 时间                        :        2019-10-29  U& D; w1 b1 j" _
  276. * 最后修改时间         :         2019-10-29
    6 }3 M# X3 O9 n5 S- Z
  277. * 说明                        :        8 n4 J. j. \& s4 y- ]3 _
  278. *************************************************************************************************************************/3 u2 u! b6 |* l, Q3 L* s
  279. void LTDC_Enable(bool Enable)  [+ I1 J4 A2 B3 a
  280. {
    : U- l0 ~! W& S$ E
  281.         if(Enable)
    7 ?9 U  {0 a/ p0 Q+ ~$ q* {, {- J
  282.         {
    9 W1 U5 E3 x. b8 \: F3 f2 V9 P- |
  283.                 LTDC->GCR |= BIT0;                                        //打开LTDC) c8 j. D6 X7 n
  284.         }: y; _; y% `# c2 k' B
  285.         else, Z& z1 y3 v  n( ]7 r2 ^9 w
  286.         {! I+ Y3 T/ H4 u: |8 }
  287.                 LTDC->GCR &= ~BIT0;                                        //关闭LTDC
    4 E; o' q! w9 \$ k; @
  288.         }) r/ p* o  @' `( Y: n/ Y6 }
  289. }
    ' o. a, w$ C" Q& J! M

  290. 6 ?$ }$ j% a: A; Q8 v  ?
  291. /*************************************************************************************************************************
    8 _# H: {% ~, N% c& c0 C: t
  292. * 函数                        :        void LTDC_LayerEnable(u8 LayerIndex, bool Enable): M; t: I3 P. `: F" t# \
  293. * 功能                        :        LTDC 层使能设置: w! i. L: i7 }
  294. * 参数                        :        LayerIndex:层选择0-1;Enable:TRUE:使能;FALSE:失能$ p  j6 z% u# `
  295. * 返回                        :        无
    , N. y, T/ Z% Z( x! v5 P* X' @' C0 _$ m
  296. * 依赖                        :        底层宏定义
    1 Q2 h! p. V2 I) w9 }1 L4 R- a7 N
  297. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    9 u$ b! }7 {4 N3 h  l) K& F2 a
  298. * 时间                        :        2019-10-29
    % s; J! d1 }8 @3 r
  299. * 最后修改时间         :         2019-10-291 Y3 A* ^7 Z' e% ]0 A2 T
  300. * 说明                        :        
    7 t* s/ e* ~; ?/ @! t0 D7 ~# F
  301. *************************************************************************************************************************/
    $ J" ?+ x$ O7 ?. @/ m& t
  302. void LTDC_LayerEnable(u8 LayerIndex, bool Enable)9 l2 G8 M0 [5 O+ S4 i% D+ j% v1 ?
  303. {$ M, W* h! l5 W+ \$ j$ A% C
  304.         if(Enable)4 P! e& w# T& Z: h* u( [! g
  305.         {, C) _* l7 r6 f8 g7 w
  306.                 if(LayerIndex == 0)                                        //层1& r) y! i8 ~2 t8 y- X/ {! p
  307.                 {" N+ y* Z+ e) a, _* r
  308.                         LTDC_Layer1->CR |= BIT0;                //使能层13 W* K2 K" Z0 m# j
  309.                 }3 S  E+ w" p) b& Q
  310.                 else" G) k; O7 k# m# S  Y  W# I
  311.                 {
    & m7 [* B$ L8 T' V4 K% I
  312.                         LTDC_Layer2->CR |= BIT0;                //使能层2
    # p: b/ K0 p  v2 B
  313.                 }
    7 L* H5 d2 @' j1 P
  314.         }
    " y7 Y3 G. f- d
  315.         else1 x) V% m0 Z8 o( ~; i
  316.         {: W8 \9 r7 w- @6 D
  317.                 if(LayerIndex == 0)                                        //层1  E$ H" E, j# |6 P# Y* v. V3 `
  318.                 {
    - U  ^6 H; @' w9 j
  319.                         LTDC_Layer1->CR &= ~BIT0;                //失能层1! N) {9 ^- Q" z3 V  y2 ?
  320.                 }
    9 I3 U* t. Y! K% T# b4 }* C3 y( t
  321.                 else
    6 K5 C( O. p! b- t& z
  322.                 {, J+ `! g0 U. R; b# e
  323.                         LTDC_Layer2->CR &= ~BIT0;                //失能层2
    . x" _; O! r9 ]* z3 @$ f4 }
  324.                 }7 {; ^1 A5 |  `- ~; U) W0 _
  325.         }* W6 {! a3 x/ q0 g
  326. }) i0 H  C' F" P5 A& l
  327. ( D. R" H: W. S+ D+ O( b; J
  328. ! L8 D4 y( j3 B! S9 {+ G7 O

  329. / J0 H' L8 Q- T2 d9 o- g
  330. 2 d, K, |$ i/ C
  331. /*************************************************************************************************************************$ v: B# S; ?$ s3 @' h9 P
  332. * 函数                        :        bool LTDC_ClockInit(u16 ClockFreq)                        
    6 [3 |1 W9 D8 _9 V' B# ]) E" Z! W
  333. * 功能                        :        STM32F7 LTDC时钟初始化. d0 _7 |( D) K; Q& V4 v& L
  334. * 参数                        :        ClockFreq:时钟频率,2-168MHZ) C) [, W! w  W* m/ t$ A2 v9 {
  335. * 返回                        :        是否设置成功
    1 c) L9 m/ ^, W& r
  336. * 依赖                        :        底层宏定义
    ! Q* c' j8 }; P4 w+ |6 y7 f7 B
  337. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    ; |$ _9 g: R# `( P
  338. * 时间                        :        2019-10-28$ j$ s3 A% r5 I7 v9 c0 E2 R- l
  339. * 最后修改时间         :         2019-10-28* i* H4 x5 f  a" o
  340. * 说明                        :        输入时钟频率在系统主时钟初始化之后就会设置为1MHz,通过设置SAI PLL实现LTDC所需频率,VCO频率范围:49~432$ E0 j1 c# \  a+ E/ i; G4 }9 f1 B
  341. *************************************************************************************************************************/
    3 g! g  U4 @% b9 o
  342. bool LTDC_ClockInit(u16 ClockFreq)  b' B2 i4 G9 G) o* o
  343. {
    5 b9 J5 S- \5 W, {
  344.         u32 TimeOut = 0;2 Z% Y0 ]/ I7 m- `5 K6 O- l
  345.         u32 VCO;
    3 Q5 f; t. m) _/ v; B! b
  346.         u32 PLLSAIR;                //PLLSAICFGR[30:28]
    2 i. n! b2 Y7 v8 w
  347.         u32 PLLSAIDIVR;                //DCKCFGR1[17:16]1 q8 m& n" R0 {2 ]7 j4 r5 Z, o
  348.         u32 temp;5 C/ O- w" s2 b& j* y
  349.         0 ]' v# _, m4 {( P
  350.         if(ClockFreq < 1)ClockFreq = 1;6 ?! O$ ?4 g$ J/ ?1 V7 f# C, T
  351.         if(ClockFreq > 100) ClockFreq = 100;/ d4 B1 b7 o8 |2 p, v( _
  352.         
    8 @2 m: A  U: D( e: f
  353.         RCC->CR &= ~(1<<28);                                                //关闭SAI时钟   @$ ]  V) s7 d4 C2 s9 o' G
  354.         TimeOut = 0;
    & ]; B# b: U; F( @. n; J
  355.         while(RCC->CR&(1<<29))                                                //等待关闭成功1 k& K5 v+ I$ ^8 f$ F$ Y# x0 Q
  356.         {
      m3 i) v/ Y9 L, G& i
  357.                 nop;
    / d% h2 W( x+ h1 M1 p
  358.                 TimeOut ++;8 A8 h* N% v6 l7 V
  359.                 if(TimeOut > 0xFFFF) return FALSE;                //关闭超时
    - V4 J5 q9 y% i, d. T2 v
  360.         }( [% ^2 M9 w0 i: Q
  361.         //计算分频与VCO频率,通过PLLSAICFGR[30:28]可以设置2-7分频4 {" i, x4 c' \% I
  362.         //通过PLLSAICFGR[17:16]可以设置00:2 01:4 10:8 11:16分频
    & o! R0 w  J# M6 A0 o9 f/ I
  363.         //通过PLLSAICFGR[14:6]可以设置为49-432MHz的VCO频率
    - S5 i, _; G& }3 {
  364.         if(ClockFreq <= 6)
    , ~$ Z9 v: E$ d7 ]
  365.         {
    ' z' e8 u& C3 C
  366.                 PLLSAIR = 4;        //4分频
    $ ?4 B8 J9 [/ \- O3 z- K& a5 G
  367.                 PLLSAIDIVR = 3;        //16分频
    ' F  ^' T0 `* O  U3 Z
  368.                 VCO = ClockFreq * PLLSAIR * 16;                        //VCO范围:64-384;8 K9 l( I/ b3 V; D5 r2 L
  369.         }' z4 P: d4 a2 f- z7 h2 q; R2 j/ r
  370.         else if(ClockFreq <= 13)* ^1 @; G9 Z* z0 ?
  371.         {% E" R% _5 b0 B) W4 {
  372.                 PLLSAIR = 4;        //4分频
    1 g9 k: W: W/ B5 W3 v5 N7 ?3 e
  373.                 PLLSAIDIVR = 2;        //8分频! Y0 @4 l3 |$ L1 h  u  Z8 ~8 Q% @
  374.                 VCO = ClockFreq * PLLSAIR * 8;                        //VCO范围:224-416;: T: i% c* n- c$ Q  ]9 D$ U9 ^6 H) K
  375.         }( s! R0 M3 E2 T: }- S1 a$ I
  376.         else if(ClockFreq <= 26)  j. Z1 Y/ y  ^. B2 J$ r. @
  377.         {9 h) e. v' b. X0 G6 s) j
  378.                 PLLSAIR = 2;        //2分频
    ! B( V( N: u3 f# {- J8 p
  379.                 PLLSAIDIVR = 2;        //8分频
    / I1 }% O& f8 C: a& P
  380.                 VCO = ClockFreq * PLLSAIR * 8;                        //VCO范围:224-416;7 {3 c7 M- h! f% B
  381.         }
    9 }* M/ u: e) G; s9 J
  382.         else if(ClockFreq <= 52)
    & @5 D% o+ s; \0 H' J
  383.         {2 g% Z9 y* Q) O6 ^
  384.                 PLLSAIR = 2;        //2分频' x  j! S' L) [5 K/ W* w- \1 D
  385.                 PLLSAIDIVR = 1;        //4分频- Q( s# K7 L6 F$ c8 U7 r
  386.                 VCO = ClockFreq * PLLSAIR * 4;                        //VCO范围:216-416;
    + t- j7 w& I) P  `
  387.         }/ d. O) r1 D' b( r5 K* @. [
  388.         else if(ClockFreq <= 104)6 R# x% y. _* }4 ?: R5 o" j
  389.         {5 L5 p5 m  {/ h- P2 u! }
  390.                 PLLSAIR = 2;        //2分频" F3 ?6 _1 i5 C4 t
  391.                 PLLSAIDIVR = 0;        //2分频
    0 h* _. I' C/ A- i" {/ ^4 u
  392.                 VCO = ClockFreq * PLLSAIR * 2;                        //VCO范围:212-416;
    4 y! X$ f+ x/ V" {
  393.         }( g( @8 v/ {2 [
  394.         //设置PLLSAICFGR
    ; c& w: x8 s) Y9 p
  395.         temp = RCC->PLLSAICFGR;; V# k! T1 n' z/ C0 d1 D
  396.         temp &= ~((3<<28) | (0x1FF<<6));                        //清除之前的设置
    5 p0 F* l& p: z: T- t2 H
  397.         temp |= PLLSAIR << 28;                                                //设置分频PLLSAICFGR[30:28]0 S' E0 ]/ o# d2 P) C# ^
  398.         temp |= VCO << 6;                                                        //设置VCO/ p. A& }7 E; N: q) Y
  399.         RCC->PLLSAICFGR = temp;/ E9 @( a5 w" {
  400.         //设置DCKCFGR16 q7 M: g1 j* l2 Q$ H3 w9 U' c
  401.         temp = RCC->DCKCFGR1;7 c, F4 S; |$ E2 P: f' Y
  402.         temp &= ~(3<<16);                                                        //清除之前的设置& P4 c  U+ ~% [. I
  403.         temp |= PLLSAIDIVR << 16;                                        //设置分频DCKCFGR1[17:16]
    - N) U/ R, `5 U
  404.         RCC->DCKCFGR1 = temp;* g& `+ h& R3 L4 [! U/ J
  405.         //启动时钟
    ! F! j2 Z- p8 G% F! m* W
  406.         RCC->CR |= 1<<28;                                                        //启动SAI时钟/ ~( K4 _0 D, R+ P* W) p
  407.         TimeOut = 0;# ^1 J* b3 q1 k( E1 J
  408.         while((RCC->CR&(1<<29)) == 0)                                //等待开启成功7 @5 J0 T0 H- ~' _0 V
  409.         {7 H9 j  n: N9 y0 m! N- ?- ^
  410.                 nop;3 ~1 s; o5 I' F% u2 p
  411.                 TimeOut ++;
    7 d: M8 [: L3 j1 `, `& ~
  412.                 if(TimeOut > 0xFFFF) return FALSE;                //开启超时
    ) r1 o3 K, f. O! `
  413.         }1 }% Q) \2 v" K8 {
  414.         
    , x3 ]2 [, g, R. A% B: b' r
  415.         return TRUE;8 }: [, S: C& d: E
  416. }
    ! u; k8 U% W  B* i

  417. ) m8 E8 B3 \- n! B

  418. * }6 C3 d. d' v* r
  419. /*************************************************************************************************************************0 V4 \# b! c, L. r" ~8 u! D
  420. * 函数                        :        void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color)        " p, E, G5 e7 e6 m4 e& B) `
  421. * 功能                        :        矩形填充(使用DMA2D)
    ) Q/ v) J$ ~5 W* q2 H' I, l2 {' O  F
  422. * 参数                        :        LayerIndex:层选择0-1;sx,sy:开始坐标;ex,ey:结束坐标,color:需要填充的颜色
    & q) W/ A6 i% g9 t1 x) m3 N' _
  423. * 返回                        :        无
    $ b2 b  P0 ~: N$ K! c
  424. * 依赖                        :        底层宏定义
    ! H" @- e2 d: }+ }( y
  425. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    - K8 J% Q. k* |: ?
  426. * 时间                        :        2019-10-307 h0 x7 ^1 f, |0 {; S$ y9 ^/ k
  427. * 最后修改时间         :         2019-10-30
    % b+ u; p6 y; H( C, p9 T- v4 W( k
  428. * 说明                        :        采用DMA2D实现2 Q1 ?, {7 b# g' a1 |6 e
  429. *************************************************************************************************************************/: b. V  m! v8 f: j! m/ h7 A: k! ]1 ^
  430. void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color)
    ) l, v. V% [# X7 ^/ k2 E; r5 V4 A
  431. {
    6 i  T. e/ ^: J# U9 Q) q
  432.         DMA2D_FillColorToFGRAM((u32)&g_LTDC_BUFF_RGB888[LayerIndex][sy][sx], ex-sx+1, ey-sy+1, LTDC_WIDTH-(ex-sx+1),  DMA2D_COLOR_ARGB8888, color);                //DMA2D进行单色填充
    4 T  m4 y, T7 r
  433.         DMA2D_WaitTransferComplete(500);                                                                                                                                                                                                                                //等待DMA2D传输完成5 _( ^+ T5 v$ S; j$ E1 Q+ r
  434. }4 n; g7 i. M7 ]) J
  435.   b% j  R% V0 M9 b  z! G- C
  436. ' r. }( ?. P* x) B1 H! h
  437. /*************************************************************************************************************************
    ! l7 W- G* g. W
  438. * 函数                        :        void LTDC_Clear(u8 LayerIndex,u32 color)) I0 @8 ?( \# v
  439. * 功能                        :        清屏(使用DMA2D)" W+ ~6 j. j# }$ s2 V) W
  440. * 参数                        :        LayerIndex:层选择0-1;color:需要填充的颜色
    ! ^" ^, R( n) F+ Z  P) l# R2 Z
  441. * 返回                        :        无
    6 o& ]) E3 w" w9 J' \
  442. * 依赖                        :        底层宏定义
    5 R1 \7 e7 M6 X; R7 G/ \) ]; e/ K) }
  443. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    ' t2 ]' i3 S6 R# o
  444. * 时间                        :        2019-10-30
    ! g+ F* d- J2 c
  445. * 最后修改时间         :         2019-10-306 I6 l, Y, g8 ?# |; c
  446. * 说明                        :        采用DMA2D实现4 \5 N; S% P2 w; G- n5 Y; `
  447. *************************************************************************************************************************/
    $ ?0 f6 C4 d  p4 d+ u0 G' x# M! C
  448. void LTDC_Clear(u8 LayerIndex,u32 color)
    0 h& }" N# C1 P' i8 K/ w/ [# J
  449. {
    % q, R" }* w  O! H
  450.         DMA2D_FillColorToFGRAM((u32)&g_LTDC_BUFF_RGB888[LayerIndex][0][0], LTDC_WIDTH, LTDC_HEIGHT, 0,  DMA2D_COLOR_ARGB8888, color);                                        //DMA2D进行单色填充
    ) A+ r, ?) D, }2 ~% v
  451.         SYS_DelayMS(5);3 E7 p  \* q: P. l' d
  452.         DMA2D_WaitTransferComplete(500);                                                                                                                                                                                                                                //等待DMA2D传输完成! S$ f9 S( f9 k* V
  453. }+ I, `9 C5 u/ Z/ F$ f

  454.   _* R. h5 R( G% A5 _, z7 a2 F( F

  455. 6 Q3 O% j4 q$ ~  y
  456. /*************************************************************************************************************************, t( e' a. F% y
  457. * 函数                        :        void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr)1 {( |0 Z' N8 [5 w3 q- Y9 T  O
  458. * 功能                        :        矩形图像填充(相同坐标范围传输,要求源图像与目标显示器分辨率一致,使用DMA2D)
    ' C" d# a: x5 P; e: z) @4 m8 x
  459. * 参数                        :        LayerIndex:层选择0-1;sx,sy:开始坐标;ex,ey:结束坐标,ImageAddr:需要填充的图像地址
    : m9 o/ S  u% \+ k5 n
  460. * 返回                        :        无
    2 M/ L% h; |+ k  h* n3 f. a
  461. * 依赖                        :        底层宏定义
    ( `' _5 `$ `) j, ?2 Q& Q/ F  k
  462. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    6 G/ M2 o* a# O+ b% i6 {
  463. * 时间                        :        2019-10-309 W% u5 R+ F: h- h- |
  464. * 最后修改时间         :         2019-10-308 w) k$ W" G- G' W( ^, m. U0 r
  465. * 说明                        :        采用DMA2D实现,将源图像指定位置传输到现存,要求源图像与显存大小一致
    * Q' l3 I' e5 g
  466. *************************************************************************************************************************/* M8 Y% s3 s+ q; Z$ |+ D. z7 k# l" Z
  467. void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr)/ |. S; ~: I% M$ \: |* V
  468. {% X1 b3 O4 @) o' C' ^  A3 m' H/ [
  469.         DMA2D_FillImageToFGRAM(ImageAddr+sy*LTDC_WIDTH+sx, (u32)&g_LTDC_BUFF_RGB888[LayerIndex][sy][sx], ex-sx+1, ey-sy+1, LTDC_WIDTH-(ex-sx+1), LTDC_WIDTH-(ex-sx+1), DMA2D_COLOR_ARGB8888);//DMA2D进行矩形图形填充% c  s, u8 p4 ]9 ?7 \5 n
  470.         DMA2D_WaitTransferComplete(500);+ [4 D: i" i' U+ p" b! s
  471. }
复制代码
  1. /*************************************************************************************************************
    3 L* D* Q6 ^- \  e4 h
  2. * 文件名                :        stm32f7_ltdc.h
    ' w" ?& `4 \; ?9 `, t. f
  3. * 功能                        :        STM32F7 外部RGB LCD驱动$ U- z# e/ e9 p' A: D  ]! n( ^
  4. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>6 O. U9 z8 k% A/ T( O) \
  5. * 创建时间                :        2019-09-12
    ; D6 |+ _+ @3 ~2 r. s
  6. * 最后修改时间        :        2019-09-12
    % G. L0 b% ~  \1 U5 P8 R
  7. * 详细:        
    $ h0 o7 ?1 S, P, I2 x0 V; `+ S
  8. *************************************************************************************************************/               
    : D1 n" ]; Q8 |+ U1 H
  9. #ifndef __STM32F7_LTDC_H_
    % I6 D3 |: J$ g6 f8 w& R1 o% w$ ~
  10. #define        __STM32F7_LTDC_H_           2 B! \8 V! a" T  I% t$ N; O, c; P" [
  11. #include "system.h"( H0 E! h( L& n, O6 ^! h: \9 Q
  12. #include "DMA2D.h"8 V0 ~7 h' f/ M* t8 U
  13. ( `! u2 v. S4 [. _; O
  14. #define LTDC_WIDTH                4808 m6 N: ~' F$ K8 ?& X! C7 ?9 |
  15. #define LTDC_HEIGHT                272: q) Y4 m' t& A& r2 @

  16. ! s* T8 `' w+ D( u1 q

  17. 4 S, p* S/ m# e& i; y
  18. extern u32 g_LTDC_BUFF_RGB888[2][LTDC_HEIGHT][LTDC_WIDTH];
    ( Z7 A" ^/ k' L

  19.   {8 U( P& }7 n8 X
  20. //像素格式定义) m% H% g$ R6 ~. w* m: D
  21. typedef enum
    $ ^. X# d# p# s! u, }  Q1 p& v% S; s; W
  22. {
    $ g: B' v1 S! B" f$ X/ u( I7 d
  23.         LTDC_ARGB8888         = 0,; q. \1 ?" `7 v' B+ q
  24.         LTDC_RGB888         = 1,5 x: z: T5 s. [& ]; K* v- }1 X: Y
  25.         LTDC_RGB565         = 2,5 }& V) E0 c) Q, f  u8 ^
  26.         /*LTDC_ARGB1555         = 3,
    # P4 W& Z- k% i+ f- L
  27.         LTDC_ARGB4444         = 4,
    ; K! j8 m3 {, s
  28.         LTDC_L8                 = 5,        //8 位 Luminance
    3 ~/ D" ~7 D; x1 B
  29.         LTDC_AL44                 = 6,        //4 位 Alpha,4 位 Luminance
    ; R% D+ F1 W" P% H* m
  30.         LTDC_AL88                 = 7,        //8 位 Alpha,8 位 Luminance*/. h; p4 A9 }& X% o: k3 S
  31. }LTDC_PixelFormat;4 m5 n: y; d. {4 h: e1 h# n
  32. #define LTDC_PIXEL_FORMAT                LTDC_ARGB8888                //选择ARGB8888格式
    . _9 h, t. J# A! @0 }

  33. $ D. j8 {, s8 ~2 B
  34. / |! Y6 R% k- }
  35. 5 F9 N5 x' X& V; F
  36. : c1 |; O; N0 S0 r
  37. //画点函数32bit ARGB8888格式" A3 G( a" p- a$ g7 a
  38. __inline void LTDC_DrawPoint(u8 LayerIndex, u16 Xpos,u16 Ypos,u32 ARGB8888_Color)  f& F  s- d8 {
  39. {. U/ J) ]4 A! \  M6 @5 ^
  40.         g_LTDC_BUFF_RGB888[LayerIndex][Ypos][Xpos] = ARGB8888_Color;  A+ A5 E/ H" V
  41. }
    6 |/ w6 p5 z4 v& O, [" B4 ?8 c
  42. 2 k, ~6 r& q) @3 Y1 y
  43. //初始化DISP引脚( m1 U: }: o7 M" o
  44. __inline void LCD_DispIoInit(void)
    9 |2 |, k  J! o) a0 B6 x' U
  45. {
    ' y" v5 t1 l1 ~, L4 |% o$ }
  46.         SYS_GPIOx_Init(GPIOI, BIT12, OUT_PP, SPEED_25M);                                                                                                //PI12 LCD_DISP H:正常模式;L:低功耗                                                        
    : i, H2 U& R2 r4 w" ^& o
  47.         PIout(12) = 1;                                                                                                                                                                        //DISP = H  2019-10-16:一直忽略将此引脚置为高电平,调试走了很多弯路
    9 q  H' m& ^  S8 X1 T, ~2 [
  48. }, o$ I, Y  i2 y. @

  49. 2 _/ ?: K( U/ y6 y
  50. void LTDC_Enable(bool Enable);                                                                                                                                                //LTDC使能设置
    + K( S) q9 Y1 e/ ^6 m7 X- d$ k
  51. void LTDC_Init(void);                                                                                                                                                                //LTDC 接口初始化8 v8 t9 R, e/ M% n. u: p
  52. void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha);//LTDC 层窗口尺寸设置
    3 y6 ~+ X1 f* {# a+ D9 m( Z
  53. void LTDC_LayerEnable(u8 LayerIndex, bool Enable);                                                                                                        //LTDC 层使能设置5 c( P7 G- Q( p5 |
  54. void LTDC_LayerRefreshConfig(void);                                                                                                                                        //LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)9 x: Y+ {+ _/ j3 n% _+ Z9 y
  55. : z- s# ]$ Y1 Y
  56. //图形相关API0 G& g+ j8 c& w+ h! l
  57. void LTDC_DrawPoint(u8 LayerIndex, u16 Xpos,u16 Ypos,u32 ARGB8888_Color);                                                        //画点函数32bit ARGB8888格式
    # D( s! v+ u& y
  58. void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color);                                                                //矩形填充(使用DMA2D)8 y( H: S9 N2 ]+ j( @! v! k7 N0 l
  59. void LTDC_Clear(u8 LayerIndex,u32 color);                                                                                                                        //清屏(使用DMA2D)
    : N, C' c. i! ]6 e0 r! D1 @
  60. 2 E2 Y4 X, U- ]3 I6 b1 Q0 ^
  61. void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr);//矩形图像填充(相同坐标范围传输,要求源图像与目标显示器分辨率一致,使用DMA2D)
复制代码

. e4 T' ~" }+ @8 M
( `. i; w$ F& F& m#endif //__STM32F7_LTDC_H_
( v+ }6 m- G/ g( \6 ]/ b4 \
( i6 z( I/ |! {% T# v* v  a6 T7 o
) ^- p# u. S! E0 k, O' ^6 S& _: {1 y9 @. W6 d0 I
收藏 评论0 发布时间:2021-12-14 10:49

举报

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