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

【经验分享】STM32f746gdiscovery LTDC 驱动

[复制链接]
STMCU小助手 发布时间:2021-12-14 10:49
需要提前准备好SDRAM驱动,如果没有SDRAM可以进行纯色彩测试,底层时钟,IO操作相关看注释,我使用的是寄存器封装的。
  W' p4 N% L! c5 R4 a
& C5 n+ k" m' q
  1. /*************************************************************************************************************
    0 T- Z! b- U" P+ C6 w  w
  2. * 文件名                :        stm32f7_ltdc.c3 c2 f' P1 q% q3 [) q
  3. * 功能                        :        STM32F7 外部RGB LCD驱动
    3 X, m+ g* b+ V+ N, {
  4. * 创建时间                :        2019-09-12- X) E" x2 m$ {& t, U
  5. * 最后修改时间        :        2019-09-12
    3 i+ A/ U# N1 ]
  6. * 详细:        
      j  |+ r$ [4 \
  7. *************************************************************************************************************/        1 @3 n  p$ x. \( G- ^
  8. #include "stm32f7_ltdc.h"
    * Q: T. y  q  {1 [0 z+ N
  9. #include "SYSTEM.H" % C2 R3 T5 U: k* G- Y( g0 s
  10. #include "stm32f7_sdram.h"% O  T' A+ k2 H* D) G. s6 H
  11. #include "DMA2D.h"
    9 \2 Y* g, Y3 W- l# Z! @
  12. 9 X4 T7 P* {& g) l) M
  13. 7 U' _) ]) N) j+ [+ n5 _
  14. u32 g_LTDC_BUFF_RGB888[2][LTDC_HEIGHT][LTDC_WIDTH]  __attribute__ ((at(Bank5_SDRAM_ADDR)));                //需要SDRAM支持,LCD帧缓冲区,RGB888格式
    4 t4 ~6 A( D8 w/ L

  15. + [/ ^# q% v  j8 h+ ^

  16. ; j% q' m+ B5 y5 C! [0 K. a/ T
  17. //记录全局层配置信息( F  a9 v, G; i& {  A( l$ a! e
  18. typedef struct# f$ S- ?0 Y* D3 m5 |, d( y
  19. {
    , |' l; @' B! [) e
  20.         u16 sx;                                        //层开始X坐标,从0开始/ c, g7 j# l$ X) u
  21.         u16 sy;                                        //层开始Y坐标,从0开始
    . l- Y$ }  S/ k
  22.         u16 width;                                //层宽度
    $ `0 w  R/ d: J. |3 m
  23.         u16 height;                                //层高度
    2 G- N8 M' _5 f, c
  24.         u32 *pFrameBuff;                //帧缓冲区指针,需要进行初始化' T4 {8 z% }4 @8 x
  25. }LTDC_LayerConfig;$ Q: X" C5 |6 A; z7 y

  26. 4 T% [7 Q/ ~9 v# L9 V& c

  27. 3 p# o2 j; \  d

  28. % N" m+ E! L7 Y6 |6 d2 X' F( H# N$ @
  29. //全局的LTDC配置信息
    3 B2 W& l5 D3 L% Q/ h: k
  30. typedef struct( E  {2 n+ t) v+ X# o5 [, ]3 H
  31. {9 C  d2 H* |# }0 m" c: a- E0 R
  32.         u16 lcd_width;                                                //显示器宽度: B* Z. g9 ?2 `: N9 l. j
  33.         u16 lcd_height;                                                //显示器高度
    , W  J1 l9 U1 C8 G
  34.         LTDC_LayerConfig LayerConfig[2];        //层信息
    7 q1 Y' R- ^8 P8 [& U4 a$ }
  35. }LTDC_ConfigData;5 ?# E$ a: w  L  o  i0 m4 O) r+ y

  36. ; C! K# H1 o/ ]6 j, p9 V" ^4 h
  37. 2 ~: Q* X1 V7 V& c: v5 U2 q# o$ `
  38. static LTDC_ConfigData sg_LTDC_ConfigData;        //记录全局的LCD配置& a- y6 H6 f8 C. f, [
  39. & E! |2 s' B# R( x9 C
  40. + @* x. s4 ^  K
  41. //显示屏信息2 q  H) A( m$ B, f: N8 e+ J
  42. typedef struct
    * ?2 }- R  g2 @+ F
  43. {
    $ @) R8 d; S1 A7 r
  44.         u16         Width;                //面板宽度,单位:像素
    5 y# J- O) a; Z/ K0 ?, M
  45.         u16         Height;                //面板高度,单位:像素
      r) S6 |0 q9 n5 s2 ]( {7 c
  46.         u8          Thbp;                //水平后廊2 ^  d# i( o- V& N5 V
  47.         u8          Thfp;                //水平前廊& }4 y$ Q8 K( a- E" [% U
  48.         u8          Thw;                //水平同步宽度
    , x. `; A$ n" r
  49.         u8          Tvbp;                //垂直后廊/ S+ \$ L. s! V& n! z& X
  50.         u8          Tvfp;                //垂直前廊9 B" c. k1 y' |3 }
  51.         u8          Tvw;                //垂直同步宽度
    % R  \7 @& ]! }3 @% {
  52.         u8          DCLK;                //时钟速度,MHz
    0 d1 h) ]/ R5 M. Z$ B8 i
  53.           q, {; m# D# p1 D' Q8 l
  54.         u8                HSPOL;                //水平同步极性,0:低电平有效;1:高电平有效
    , ]3 Y- c6 _/ r4 H+ }7 ^' D: o: h
  55.         u8                VSPOL;                //垂直同步极性,0:低电平有效;1:高电平有效
    6 l: g/ `5 l# V  x
  56.         u8                DEPOL;                //数据使能极性,0:低电平有效;1:高电平有效4 c4 [6 ^4 p) L
  57.         bool        PCPOL;                //像素时钟反向; m# S# k6 g) `2 V  G6 X
  58. }LTDC_INFO_TYPE;
      g4 l1 h  M  m/ O

  59. 3 a2 F: b; ]+ X7 W
  60. / z5 h: e# R0 z/ O
  61. LTDC_INFO_TYPE DefaultLCD_Info =
      V! t! A9 ?. I; n0 J1 O/ z& e! A
  62. {- L5 |" u5 M1 F8 H& }. ^
  63.         480,        //面板宽度,单位:像素
      f$ V% j- _: W$ B' B) W
  64.         272,        //面板高度,单位:像素
    & b$ h% u1 _6 T2 Z$ h1 U
  65.         41,                //水平后廊) U$ z! d& j. s: W
  66.         8,                //水平前廊1 O6 Y2 }+ i- b
  67.         2,                //水平同步宽度6 }; n$ [# H3 O! [
  68.         2,                //垂直后廊: ^/ z) y8 Y% x8 h# s* U2 \1 e
  69.         4,                //垂直前廊6 {5 Z8 O  v8 z$ o
  70.         10,                //垂直同步宽度) Q9 R7 s$ ^: ?& E% F+ {8 J! O# b
  71.         9,                //时钟速度,MHz
    " S2 `7 {. w: M! J3 C& G
  72.         0,                //水平同步极性,0:低电平有效;1:高电平有效0 T( I3 g# g7 B+ h1 y
  73.         0,                //垂直同步极性,0:低电平有效;1:高电平有效$ G# v1 y! _- w& L0 R
  74.         1,                //数据使能极性,0:低电平有效;1:高电平有效+ j% R5 `$ ?/ s
  75.         FALSE,        //像素时钟反向9 W- y! t7 K. }. J2 X
  76. };
    " z, S0 D( u4 |& z& C4 b( F
  77. 7 }2 `  {  m) }' [
  78. bool LTDC_ClockInit(u16 ClockFreq);                                                        //STM32F4 LTDC时钟初始化
    - e, S$ ]" u6 S6 Y

  79. ) h1 L( G! B1 \) p; M, @4 a
  80. ) N8 i6 s: h6 f. ]7 L( V9 R5 c; n
  81. /*************************************************************************************************************************
    * z/ w/ Z6 [' Y1 I
  82. * 函数        :                        void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha)  i+ C. }* B/ U8 Q4 t, L
  83. * 功能        :                        LTDC 层窗口尺寸设置(会自动根据窗口尺寸以及像素格式设置帧缓冲区大小)
    # Q3 k. a* J& ^
  84. * 参数        :                        LayerIndex:层选择(0-1);sx,sy:起始坐标;width,height:宽度和高度
    4 Z, D$ v9 T+ f8 V
  85. * 返回        :                        无
    ! ?+ A/ [1 d+ D% u3 I
  86. * 依赖        :                        底层宏定义
    4 G" ^: t6 Z5 _" [
  87. * 作者        :                        <a href="mailto:cp1300@139.com">cp1300@139.com</a>0 Y+ {  `2 S! R5 j1 }* m+ l. R/ a
  88. * 时间        :                        2019-10-28
    3 M7 y  I9 L8 T3 k- I7 ~
  89. * 最后修改时间 :         2019-10-28
    ! _' k0 r; V% B6 D: g* R
  90. * 说明        :                         不会使能层,不会更新层,只设置配置,需要刷新层配置后更新2 p' {9 @/ l8 j& d3 Y( f
  91. *************************************************************************************************************************/ ( @+ K1 t' y" r5 D; s
  92. void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha)
    5 U& U9 A5 q. \8 G6 s6 b1 z
  93. {
    $ V5 b; V: W! {  U7 k
  94.         u32 temp;/ A( {/ u, V6 t0 ~/ h. R  |4 K! }
  95.         u8 pixformat=0; : z6 u; h0 Q/ W
  96.         
    , c, s; v" _- N* D' @0 y- q
  97.         if(LayerIndex==0)( T; i+ m: f# H4 l: \4 v- c) O
  98.         {
    - P* V0 _; S; h  z. p$ O5 C- c
  99.                 //基本配置& N, ^' `0 ^8 a3 _4 l; Q6 x
  100.                 LTDC_Layer1->CFBAR = FrameBuff;                                                                        //设置层颜色帧缓存起始地址8 y" t9 R- B4 P- p. u
  101.                 LTDC_Layer1->PFCR = LTDC_PIXEL_FORMAT;                                                        //设置层颜色格式
    ' Y% ~7 z" H1 s4 c$ f; ]& Z7 t
  102.                 LTDC_Layer1->CACR = Alpha;                                                                                //常数 Alpha,255分频;设置255,则不透明  ?5 Q$ S* n4 V; Z! P$ r2 f
  103.                 LTDC_Layer1->DCCR = 0x00;                                                                                //设置默认颜色:透明的黑色
    5 I0 F0 h$ W7 T9 L- s
  104.                 LTDC_Layer1->BFCR = ((u32)6<<8)|7;                                                                //设置层混合系数, K3 W& C, J) v( c1 \/ K+ k' G8 O
  105.                 //配置窗口3 Z/ V! o$ ^) D6 _0 m
  106.                 temp = (sx+width+((LTDC->BPCR&0X0FFF0000)>>16))<<16;
    3 x; X/ N# X1 T% v+ r
  107.                 LTDC_Layer1->WHPCR = (sx+((LTDC->BPCR&0X0FFF0000)>>16)+1)|temp;//设置行起始和结束位置
    + t5 \' X6 E% y! H( I% S
  108.                 temp = (sy+height+(LTDC->BPCR&0X7FF))<<16;
    . N# _# K0 N$ I9 j0 \
  109.                 LTDC_Layer1->WVPCR = (sy+(LTDC->BPCR&0X7FF)+1)|temp;                        //设置列起始和结束位置7 b  B2 g- F( K# S' i) F, y
  110.                 pixformat = LTDC_Layer1->PFCR&0X07;                                                                //得到颜色格式2 F" Q* x/ h/ i# {7 n
  111.                 if(pixformat == 0)temp=4;                                                                                //ARGB8888,一个点4个字节& n+ ^6 K, U# a; g7 ?7 m
  112.                 else if(pixformat == 1)temp=3;                                                                        //RGB888,一个点3个字节8 W$ f% X' _# ?& h) o2 h4 }  r
  113.                 else if(pixformat==5||pixformat==6)temp=1;                                                //L8/AL44,一个点1个字节
    4 `; L! q# E' O6 X' N4 T
  114.                 else temp=2;                                                                                                        //其他格式,一个点2个字节
    9 j. T0 L# `  f9 T! A2 D( J. G' b
  115.                 LTDC_Layer1->CFBLR = (width*temp<<16)|(width*temp+3);                        //帧缓冲区长度设置(字节为单位)
    7 I7 [( O9 y8 K
  116.                 LTDC_Layer1->CFBLNR = height;                                                                        //帧缓冲区行数设置          c" N' A9 ^$ a" O1 q# ], v6 g
  117.                
    6 s* Q$ U$ T/ I
  118.                 //记录层窗口大小位置信息
    " ^8 H0 }, v) W
  119.                 sg_LTDC_ConfigData.LayerConfig[0].sx = sx;                ' I( _" ]9 p- y3 H! K
  120.                 sg_LTDC_ConfigData.LayerConfig[0].sy = sy;        + L9 {+ a6 t* b& {
  121.                 sg_LTDC_ConfigData.LayerConfig[0].width = width;        ( w% Z  h3 z" M1 Q/ t4 r
  122.                 sg_LTDC_ConfigData.LayerConfig[0].height = height;        
    - f% U. W7 T% F$ |2 K# r  T
  123.         }else
    ! m( E7 C* Q, p' H- }5 |! s
  124.         {
    ( |9 S: c' r1 e5 i* {
  125.                 //基本配置
    . g  E5 m# p/ N; b; Y
  126.                 LTDC_Layer2->CFBAR = FrameBuff;                                                                        //设置层颜色帧缓存起始地址
    + w2 i' ~% g8 q  \# ~
  127.                 LTDC_Layer2->PFCR = LTDC_PIXEL_FORMAT;                                                        //设置层颜色格式
    5 a7 l" R3 Q# `  l
  128.                 LTDC_Layer2->CACR = Alpha;                                                                                //常数 Alpha,255分频;设置255,则不透明7 d6 {+ M& _" V3 n7 x
  129.                 LTDC_Layer2->DCCR = 0x00;                                                                                //设置默认颜色:透明的黑色
    / ?0 b2 l: i7 \
  130.                 LTDC_Layer2->BFCR = ((u32)6<<8)|7;                                                                //设置层混合系数
    9 A$ v" l: n5 u  f
  131.                 //配置窗口( n7 X& v( Y1 d; {- r" V7 r, h1 @6 R
  132.                 temp = (sx+width+((LTDC->BPCR&0X0FFF0000)>>16))<<16; $ W# z2 V+ K8 v3 V2 g- r
  133.                 LTDC_Layer2->WHPCR = (sx+((LTDC->BPCR&0X0FFF0000)>>16)+1)|temp;        //设置行起始和结束位置 * E( Q1 D5 `. s
  134.                 temp = (sy+height+(LTDC->BPCR&0X7FF))<<16;
    1 I7 s; v$ Q: @+ Q  f8 E
  135.                 LTDC_Layer2->WVPCR = (sy+(LTDC->BPCR&0X7FF)+1)|temp;                        //设置列起始和结束位置' \$ s1 P* }5 s# f" n2 r
  136.                 pixformat = LTDC_Layer2->PFCR&0X07;                                                                //得到颜色格式- G: w6 g: m( m# w9 N9 Y% o6 y! d
  137.                 if(pixformat == 0)temp=4;                                                                                //ARGB8888,一个点4个字节
    * K9 W4 I, q; C" O: B; ?9 C
  138.                 else if(pixformat == 1)temp=3;                                                                        //RGB888,一个点3个字节
    6 C3 l7 G4 C. Z( s
  139.                 else if(pixformat == 5||pixformat==6)temp=1;                                        //L8/AL44,一个点1个字节
    % ^' |' x6 }, F$ U
  140.                 else temp = 2;                                                                                                        //其他格式,一个点2个字节, s; _" B# Y! t2 ~( H' E' R0 _7 I
  141.                 LTDC_Layer2->CFBLR = (width*temp<<16)|(width*temp+3);                        //帧缓冲区长度设置(字节为单位)- n* N# n0 \+ P5 K
  142.                 LTDC_Layer2->CFBLNR = height;                                                                        //帧缓冲区行数设置          Q* n% K5 p1 h5 S6 T
  143.                
    / ]& J* g; `3 r! y' |
  144.                 //记录层窗口大小位置信息
    - y2 j0 Z) H. w% ^( S- r
  145.                 sg_LTDC_ConfigData.LayerConfig[1].sx = sx;                - i0 X# T. r! z! U- O- G
  146.                 sg_LTDC_ConfigData.LayerConfig[1].sy = sy;        " f/ B8 ^, e" F( |, [, S
  147.                 sg_LTDC_ConfigData.LayerConfig[1].width = width;        
    - Z5 e# x# J! W4 a0 J( u' u
  148.                 sg_LTDC_ConfigData.LayerConfig[1].height = height;               
    % j, }6 U8 `+ @& \- k! e9 G5 J6 C
  149.         }1 \0 S3 T/ C# ~, v4 e0 L
  150. }- z* R/ X( G4 H& `5 p+ @  K

  151. $ l/ H, y! M5 T8 B* e2 g
  152. 2 w2 ]5 G# ?' _/ \, k: e

  153. 2 K% ?# P7 [+ `4 i! v
  154. /*************************************************************************************************************************
    0 n5 ~/ e! p, v  G
  155. * 函数        :                        void LTDC_Init(void)
    / {9 d0 W9 a+ ?4 s+ ~
  156. * 功能        :                        LTDC 接口初始化
    1 g& k& E5 t) m/ w
  157. * 参数        :                        无
      w. u) B$ w% y6 X) p
  158. * 返回        :                        无! J, B; O- @6 n+ {. r" C+ A
  159. * 依赖        :                        底层宏定义' u7 X9 b& \: g* h7 g; Z
  160. * 作者        :                        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    ) a. J' U5 D, W$ G1 O
  161. * 时间        :                        2019-09-089 C. i0 K4 k6 J( k! H: K
  162. * 最后修改时间 :         2019-09-081 T: C- U) L. C- n5 i, S
  163. * 说明        :                         用于初始化STM32F7 LTDC 接口# h8 ?1 X& Y% T7 ?
  164. *************************************************************************************************************************/  
    / {! a; j8 r0 p: n1 r+ {+ p. N+ \
  165. void LTDC_Init(void)$ Z" V$ e3 ?* m- d! R
  166. {
    0 J! t4 Z+ r8 l8 y
  167.         u32 temp;# D2 H" r# ~2 y- R9 N& u9 ~
  168.         
    & }. Q8 W) s8 a6 H, ?# v$ g* i
  169.         SYS_DeviceClockEnable(DEV_LTDC, TRUE);        //LTDC时钟使能
    4 P7 P/ r% C* \5 m2 t
  170.         SYS_DeviceReset(DEV_LTDC);                                //STM32F7外设复位2 C3 @8 Z/ o7 }9 c5 w
  171.         SYS_DeviceClockEnable(DEV_GPIOE, TRUE);        //使能GPIOE时钟. X. @( j5 [4 d! R1 m
  172.         SYS_DeviceClockEnable(DEV_GPIOG, TRUE);        //使能GPIOG时钟! H5 r% w3 x5 \4 p  l& t& w+ ?+ C
  173.         SYS_DeviceClockEnable(DEV_GPIOJ, TRUE);        //使能GPIOJ时钟
    ' ]5 b2 \6 h8 g. t0 R
  174.         SYS_DeviceClockEnable(DEV_GPIOK, TRUE);        //使能GPIOK时钟2 `& _6 I1 m- X' A. u) @$ s
  175.         SYS_DeviceClockEnable(DEV_GPIOI, TRUE);        //使能GPIOI时钟! M/ |0 W8 q, U2 {: L- |+ [0 C8 Y, x
  176. , P5 }# I. N! B; ~9 H' d1 Q
  177.         
    ; \2 O: Z; ^! k$ G4 z2 i3 ]& t5 z4 ~
  178.         //初始化IO
    " _( k( O% X5 @' H/ V2 N' I
  179.         SYS_GPIOx_Init(GPIOE, BIT4, AF_PP_OPU, SPEED_100M);                                                                                //PE4
    / W5 u' T2 ~6 c0 J
  180.         SYS_GPIOx_Init(GPIOG, BIT12, AF_PP_OPU, SPEED_100M);                                                                        //PG125 f9 b5 z# N( Q3 ~
  181.         SYS_GPIOx_Init(GPIOJ, 0Xffff&(~BIT12), AF_PP_OPU, SPEED_100M);                                                        //PJ0~11/13/14/155 N4 q; I0 E7 C" `9 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- \0 Y0 {4 |* Y# s: B; s% E/ m
  183.         SYS_GPIOx_Init(GPIOI, BIT9|BIT10|BIT14|BIT15, AF_PP_OPU, SPEED_100M);                                        //PI9/10/14/15
    & `$ c. d3 f1 J/ F
  184.         - ]1 @; C! s1 y+ V" g. w' k
  185.         SYS_GPIOx_SetAF(GPIOE, 4, AF14_LTDC);                //PE4,AF14        
    1 `1 U, J4 H1 Z6 s  ~8 S, Y3 |
  186.          SYS_GPIOx_SetAF(GPIOG, 12, AF14_LTDC);                //PG12,AF14        $ V+ K. G& u3 J% l
  187.         SYS_GPIOx_SetAF(GPIOJ, 0, AF14_LTDC);                //PJ0,AF14' Z& M% _5 Z, [) P) `
  188.         SYS_GPIOx_SetAF(GPIOJ, 1, AF14_LTDC);                //PJ1,AF14
    , m. e% {: T, c9 u$ B1 b
  189.         SYS_GPIOx_SetAF(GPIOJ, 2, AF14_LTDC);                //PJ2,AF14: K, I! O& u+ s5 i* w8 ~! T
  190.         SYS_GPIOx_SetAF(GPIOJ, 3, AF14_LTDC);                //PJ3,AF14) i  z$ e7 W: S" c! ^0 F
  191.         SYS_GPIOx_SetAF(GPIOJ, 4, AF14_LTDC);                //PJ4,AF14
    # p* {; I) J! e
  192.         SYS_GPIOx_SetAF(GPIOJ, 5, AF14_LTDC);                //PJ5,AF14
    % ?' H/ L  [2 v; v7 p( T( ], j
  193.         SYS_GPIOx_SetAF(GPIOJ, 6, AF14_LTDC);                //PJ6,AF149 A4 g  R+ F" [
  194.         SYS_GPIOx_SetAF(GPIOJ, 7, AF14_LTDC);                //PJ7,AF140 W  T. H. f; L. L% m7 q
  195.         SYS_GPIOx_SetAF(GPIOJ, 8, AF14_LTDC);                //PJ8,AF14
    ( N! i# _7 F5 _3 ]  \; ?( v
  196.         SYS_GPIOx_SetAF(GPIOJ, 9, AF14_LTDC);                //PJ9,AF14+ u1 O  p, T; O  ?3 q8 {0 T
  197.         SYS_GPIOx_SetAF(GPIOJ, 10, AF14_LTDC);                //PJ10,AF14
    8 y9 u- p# {! x$ G6 Y
  198.         SYS_GPIOx_SetAF(GPIOJ, 11, AF14_LTDC);                //PJ11,AF140 G  m" `% E/ h& \- N
  199.         SYS_GPIOx_SetAF(GPIOJ, 13, AF14_LTDC);                //PJ13,AF14
    2 F( Y9 w2 g9 X/ z2 a$ U" F/ m
  200.         SYS_GPIOx_SetAF(GPIOJ, 14, AF14_LTDC);                //PJ14,AF14
      h, t  ~1 a) g2 M
  201.         SYS_GPIOx_SetAF(GPIOJ, 15, AF14_LTDC);                //PJ15,AF14* ]1 [" i' B% x8 V
  202.         8 x) J" _+ h0 j, e! k/ W% e
  203.         SYS_GPIOx_SetAF(GPIOK, 0, AF14_LTDC);                //PK0,AF148 x. e7 D0 W  ]1 L) L8 r* d
  204.         SYS_GPIOx_SetAF(GPIOK, 1, AF14_LTDC);                //PK1,AF14
    , E. J3 o/ }- }7 U( |
  205.         SYS_GPIOx_SetAF(GPIOK, 2, AF14_LTDC);                //PK2,AF14
    ; u, K0 U0 ^* h
  206.         SYS_GPIOx_SetAF(GPIOK, 4, AF14_LTDC);                //PK4,AF146 L0 @4 n) D1 y  s1 w* V
  207.         SYS_GPIOx_SetAF(GPIOK, 5, AF14_LTDC);                //PK5,AF143 w& F, I4 f. f1 g2 i4 B
  208.         SYS_GPIOx_SetAF(GPIOK, 6, AF14_LTDC);                //PK6,AF14
    ( t; E8 u+ T. ^
  209.         SYS_GPIOx_SetAF(GPIOK, 7, AF14_LTDC);                //PK7,AF14& n4 Y3 T; F4 J! D  Z3 F4 D
  210.         & P0 j3 r5 N9 _. o3 Q
  211.          SYS_GPIOx_SetAF(GPIOI, 9, AF14_LTDC);                //PI9,AF14
    8 @" C* p& X; O) o
  212.          SYS_GPIOx_SetAF(GPIOI, 10, AF14_LTDC);                //PI10,AF14
    * k3 y& I0 p0 P
  213.         SYS_GPIOx_SetAF(GPIOI, 14, AF14_LTDC);                //PI14,AF14
    * Q' ^( o1 `# I6 i6 i2 ~. g
  214.          SYS_GPIOx_SetAF(GPIOI, 15, AF14_LTDC);                //PI15,AF14
    $ H. f, x7 O  ]
  215.         % ?6 c1 Q: T1 J1 m2 ~$ J
  216.         LTDC_ClockInit(DefaultLCD_Info.DCLK);                 //设置像素时钟  9Mhz
    0 u: o' o+ W" n! i; V
  217.         //设置LTDC 全局控制寄存器 (LTDC_GCR)$ H* k! u3 M; _" y
  218.         temp = 0;1 ^$ l2 t8 m5 E2 N
  219.         temp |= (DefaultLCD_Info.HSPOL&0x01) << 31;        //水平同步极性
    % m6 Q7 G; i* t) @: X6 t. R6 h
  220.         temp |= (DefaultLCD_Info.VSPOL&0x01) << 30;        //垂直同步极性! I1 A( G0 n: O1 m5 X
  221.         temp |= (DefaultLCD_Info.DEPOL&0x01) << 29;        //数据使能极性
    " i1 P/ Y2 I& J$ M( A# e" Y  O
  222.         temp |= (DefaultLCD_Info.PCPOL&0x01) << 28;        //像素时钟极性
    * W- L- ]; D6 g5 H: Y" P
  223.         LTDC->GCR = temp;7 J  [& \( d! ^% H/ r0 a
  224.         //LTDC 后沿配置寄存器 (LTDC_BPCR)
    4 u0 R" @( \0 e" m
  225.         temp = (DefaultLCD_Info.Tvw + DefaultLCD_Info.Tvbp - 1) << 0;        //这些位定义累加水平后沿宽度(水平同步像素加水平后沿像素减 1)。7 K$ P# c+ A+ N5 B( A* P
  226.         temp |= (DefaultLCD_Info.Thw + DefaultLCD_Info.Thbp - 1) << 16;        //这些位定义累加垂直后沿宽度(垂直同步行加垂直后沿行减 1)。
    . W4 x' i, G8 D7 i& P
  227.         LTDC->BPCR=temp;        
    . w1 B3 @+ H; r' @% O
  228.         
      X8 t2 o3 n1 P8 x
  229.         //LTDC 有效宽度配置寄存器 (LTDC_AWCR)
    ; `2 O, w" W: H& _$ v0 x
  230.         temp=(DefaultLCD_Info.Tvw+DefaultLCD_Info.Tvbp+DefaultLCD_Info.Height-1)<<0;        //累加有效高度=垂直脉宽+垂直后沿+垂直分辨率-1
    : e) g) ]; ]% e8 i/ b1 b* N7 x1 |
  231.         temp|=(DefaultLCD_Info.Thw+DefaultLCD_Info.Thbp+DefaultLCD_Info.Width-1)<<16;        //累加有效宽度=水平脉宽+水平后沿+水平分辨率-1! E: i% X& x5 m7 w- t7 C
  232.         LTDC->AWCR=temp;        
    - w) u9 C% j1 h. H; ?9 ^( u
  233.         //LTDC 总宽度配置寄存器 (LTDC_TWCR)
    : K9 S1 X7 L( @2 W) {2 _; Y! q4 ~
  234.          temp=(DefaultLCD_Info.Tvw+DefaultLCD_Info.Tvbp+DefaultLCD_Info.Height+DefaultLCD_Info.Tvfp-1)<<0;        //总高度=垂直脉宽+垂直后沿+垂直分辨率+垂直前廊-1  T+ ]+ A* ~. B1 s. r' L
  235.         temp|=(DefaultLCD_Info.Thw+DefaultLCD_Info.Thbp+DefaultLCD_Info.Width+DefaultLCD_Info.Thfp-1)<<16;        //总宽度=水平脉宽+水平后沿+水平分辨率+水平前廊-1
    " |* }" i7 j9 X4 O5 k' b. A
  236.         LTDC->TWCR=temp;                                - @+ V" D) P4 x4 \+ t- |$ Z

  237. 0 h1 A8 H1 {4 V4 e$ `
  238.         //背景设置
    6 c; |: q# N* u% S+ e9 Y
  239.         LTDC->BCCR=0xffffff;                                //设置背景层颜色寄存器(RGB888格式)5 ]1 S: _$ w/ G% B2 A
  240.         LTDC_Enable(TRUE);                                        //开启LTDC5 o- T0 Q. w9 E  ?$ }4 D8 K" b5 g
  241.         //初始化层14 C5 }% w; y6 B3 Q
  242.         LTDC_SetLayerConfig(0, 0, 0, LTDC_WIDTH, LTDC_HEIGHT, (u32)g_LTDC_BUFF_RGB888[0], 255);
    # n; {7 e* M* O& x, F1 c+ ?# y
  243.         //初始化层2/ I1 e  _; l. k, q8 d- U" R+ j& g
  244.         LTDC_SetLayerConfig(1, 0, 0, LTDC_WIDTH, LTDC_HEIGHT, (u32)g_LTDC_BUFF_RGB888[1], 255);* X4 \' h% K, u" @* T5 b& o
  245.         LTDC_Clear(0, 0xFF000000);                        //清屏层1-不透明的黑色
    6 Q9 x8 |- X  }# J( m6 V. z3 @6 |- Z
  246.         LTDC_Clear(1, 0x00000000);                        //清屏层2-透明的黑色' o7 ]% I5 s! l9 a6 b
  247.         LTDC_LayerEnable(0, TRUE);                        //使能层1
    1 H/ g7 a2 u4 B' h- h; H
  248.         LTDC_LayerRefreshConfig();                        //LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)
    ) S8 ~) L, h/ T' w8 V. r7 y
  249.         LCD_DispIoInit();                                        //初始化DISP引脚-启动显示2 @7 j- x4 v. B1 ?/ ~9 C$ B
  250. }
    # ?( k% r( H" v. o3 G# Y% |

  251. 9 a% R% @2 G4 q9 H
  252. /*************************************************************************************************************************
    2 h6 f3 i+ F. v& W2 u" F
  253. * 函数                        :        void LTDC_LayerRefreshConfig(void)
      \) D8 q! D7 z& O0 G3 T- X- f
  254. * 功能                        :        LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)0 Q$ u% `. C$ I3 X0 y7 z, A
  255. * 参数                        :        无% z! Z5 @* T8 ]! ]+ B3 Y
  256. * 返回                        :        无
    ; U0 u; x" y- @
  257. * 依赖                        :        底层宏定义# K2 g5 p: ?- _8 l5 Y4 }) l  z
  258. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>9 u4 c0 {8 b2 s) B) I
  259. * 时间                        :        2019-10-29& g) M9 x% r1 F: F$ Q& R
  260. * 最后修改时间         :         2019-10-29. d8 N8 ~# p0 F+ W
  261. * 说明                        :        修改层配置后必须重新加载,否则不会生效
    3 c7 {( C( K; [3 b2 g
  262. *************************************************************************************************************************/$ J# V. q0 D0 j& M4 ~, B% \/ w* u3 J
  263. void LTDC_LayerRefreshConfig(void)
    * e" ]' `4 c# w, B3 X' W
  264. {
    $ p( C4 }8 F0 T& ?3 O% @" X/ A4 c
  265.         LTDC->SRCR|=1<<0;                                                        //重新加载配置-必须重新加载,否则上面的层不会更新,折腾好久才发现,叫啥影子寄存器重载,也不说清楚
    " j/ k! v: _5 p+ j6 `( S+ g
  266. }
    ) X4 G/ h0 [3 v
  267. 7 ~: g/ r. R3 P( N  }. q
  268. /*************************************************************************************************************************
      |4 @) j" }& I  E( t9 i
  269. * 函数                        :        void LTDC_Enable(bool Enable)0 R% ^: F9 L; |6 q
  270. * 功能                        :        LTDC使能设置
    4 X( U+ N8 g5 j) ~2 \: c: z; e/ g
  271. * 参数                        :        Enable:TRUE:使能;FALSE:失能) |* M' X4 z" h2 h+ M
  272. * 返回                        :        无
    + k; p# J( |+ k$ Y
  273. * 依赖                        :        底层宏定义
    0 p  s' f" F/ ^6 J: W. K
  274. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>' u! s4 y: P# j
  275. * 时间                        :        2019-10-29
    $ C2 X. h/ X; J$ E
  276. * 最后修改时间         :         2019-10-29
    / g4 j8 h9 h  H8 ]+ y
  277. * 说明                        :        3 t! Z; Y' d1 n# Y; y
  278. *************************************************************************************************************************/6 j9 R' D+ U* A7 I3 H
  279. void LTDC_Enable(bool Enable)' ^3 T# Q7 t* I
  280. {
      r7 V8 R% B( z& M1 l) q% X
  281.         if(Enable)/ e; I* w. V  K5 g$ G9 |4 O
  282.         {
    0 l/ c3 w7 M+ G' s
  283.                 LTDC->GCR |= BIT0;                                        //打开LTDC1 e1 M  X& ?& P2 D
  284.         }$ y( R0 W+ w+ A$ i
  285.         else  s% ?* t' t9 f* m5 Q8 q/ e4 e7 m
  286.         {
    5 w! e3 J( G9 U& k+ V) [
  287.                 LTDC->GCR &= ~BIT0;                                        //关闭LTDC1 r6 ]( H% W8 e7 f
  288.         }' p) S0 m8 O% G/ {
  289. }& D' b$ b% j" r) u

  290. 1 t/ F8 B9 W. \: ]
  291. /************************************************************************************************************************** W0 a% \. T; P& n9 g( ?, h
  292. * 函数                        :        void LTDC_LayerEnable(u8 LayerIndex, bool Enable), _' `9 m$ O# Z' @
  293. * 功能                        :        LTDC 层使能设置
    - ]6 U' U8 V( v0 _
  294. * 参数                        :        LayerIndex:层选择0-1;Enable:TRUE:使能;FALSE:失能
    " c9 @: a) g4 S* f; U
  295. * 返回                        :        无7 q7 P3 p: C7 @8 V- e9 M" b
  296. * 依赖                        :        底层宏定义, |; c; c- Y/ m6 u3 b
  297. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    " E! N1 ?3 F7 \& k4 U" K
  298. * 时间                        :        2019-10-29
    2 s: W# v$ G8 y* }; ?
  299. * 最后修改时间         :         2019-10-29  \/ ^& K* {% p7 _# K4 s
  300. * 说明                        :        
    + n+ H5 |1 A8 ]+ @/ ^# L8 a
  301. *************************************************************************************************************************/5 t- j* M  X. ]: G7 t
  302. void LTDC_LayerEnable(u8 LayerIndex, bool Enable)
    $ }6 R1 t: r  J" R- [7 v
  303. {) s. h+ x  H) a+ t7 @& d
  304.         if(Enable)5 p( Q! G) j7 C/ D2 H. l
  305.         {) C7 N# d9 T. ~6 N, b& Q
  306.                 if(LayerIndex == 0)                                        //层1) y, s9 _3 e5 {& A+ ~$ H9 v
  307.                 {
    % p4 w' S0 y' y- {, \0 U, f
  308.                         LTDC_Layer1->CR |= BIT0;                //使能层1
    / T6 h5 P* k, Q7 R$ g% |
  309.                 }- X. j4 V" S& v" v1 F+ Y
  310.                 else; D6 [4 z9 P* }5 M7 J
  311.                 {
    - r. U) U0 Y1 E9 k, z
  312.                         LTDC_Layer2->CR |= BIT0;                //使能层2+ T$ l1 m" B8 H* a
  313.                 }0 z6 p5 W, ^% X0 D# T
  314.         }
    2 Z6 J. N& ?7 s; A3 b
  315.         else
    ( h9 ^2 [) g3 r! ]  ~* I' K
  316.         {
    + C3 t) T7 X  {
  317.                 if(LayerIndex == 0)                                        //层1
    6 b  R/ n( c. Q1 {2 m
  318.                 {
    ' L* E$ N: C2 H) ^
  319.                         LTDC_Layer1->CR &= ~BIT0;                //失能层1
    # P) ^' A* p  ?% p2 C; x: e
  320.                 }
    " h' T4 }! B1 B, l0 X* y0 b* n
  321.                 else
    - z7 o. p$ m+ S5 ^9 c/ X5 M! ?
  322.                 {' o) X4 T1 t/ ?+ H) y4 ^
  323.                         LTDC_Layer2->CR &= ~BIT0;                //失能层2' Z9 u2 M3 z. {6 E3 |
  324.                 }
    + N! m6 u1 |$ H8 u/ \; T
  325.         }
    0 M4 j1 c9 F/ N1 _6 p
  326. }
    4 R' E7 V# }/ ~7 D
  327. 1 G9 I* p' i; b! R
  328. ! S: k) e1 R. P6 h+ X: K- M

  329. - F7 A* v* l$ ~+ K+ H
  330. * S+ v6 e. u* |) O8 y2 h" n) I, q
  331. /*************************************************************************************************************************$ P9 U3 }  c% j
  332. * 函数                        :        bool LTDC_ClockInit(u16 ClockFreq)                        
    ( j5 L4 z7 m, G5 @3 W8 D; {  c" s
  333. * 功能                        :        STM32F7 LTDC时钟初始化( `2 I: }  ~# J1 z. e
  334. * 参数                        :        ClockFreq:时钟频率,2-168MHZ
    0 \' Y, H9 j# j0 c" F" l
  335. * 返回                        :        是否设置成功+ v. r+ q4 I4 |, f
  336. * 依赖                        :        底层宏定义
    . D7 G9 E6 Z$ C8 ]
  337. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>8 l: W9 L, J5 T# b
  338. * 时间                        :        2019-10-28
    . Q3 q/ [3 B4 Z
  339. * 最后修改时间         :         2019-10-287 g: v4 W. j3 F; F( N' N
  340. * 说明                        :        输入时钟频率在系统主时钟初始化之后就会设置为1MHz,通过设置SAI PLL实现LTDC所需频率,VCO频率范围:49~432
    8 T+ N3 j3 p/ B5 r2 {3 W  b" @
  341. *************************************************************************************************************************/1 a! g+ |$ E* x9 G0 s( Y2 R
  342. bool LTDC_ClockInit(u16 ClockFreq)2 V* ]' E) w, ?) h& M
  343. {8 U+ Y; W  N5 U! a" R9 v/ H
  344.         u32 TimeOut = 0;( H9 ^  ], g0 p! U/ e
  345.         u32 VCO;( A4 W" W3 {: W# d3 q( J
  346.         u32 PLLSAIR;                //PLLSAICFGR[30:28]
    . G1 X; {2 \. }. W( ^4 ?4 g
  347.         u32 PLLSAIDIVR;                //DCKCFGR1[17:16]
    2 z" L. L4 A# {
  348.         u32 temp;8 @. f5 E" y; V  E- |
  349.         
    $ e; c7 P1 F( y  \
  350.         if(ClockFreq < 1)ClockFreq = 1;9 |0 k+ G7 x6 U2 z" R+ B  L; r( G
  351.         if(ClockFreq > 100) ClockFreq = 100;
    & c3 u1 u  E0 B% y* G6 w2 V
  352.         $ M* |5 e5 x& ?* _: Q
  353.         RCC->CR &= ~(1<<28);                                                //关闭SAI时钟
    / @  n' n4 z% O! k
  354.         TimeOut = 0;
    ' h  l- ?. l# b1 H
  355.         while(RCC->CR&(1<<29))                                                //等待关闭成功
    7 N  f& y: O% X6 T( j# S
  356.         {5 Y% }1 y9 q# g
  357.                 nop;
    4 ^/ K% t- C- i
  358.                 TimeOut ++;
    * [+ r% M& x, \% P% C
  359.                 if(TimeOut > 0xFFFF) return FALSE;                //关闭超时
    / P3 w9 B) t3 L+ F, P
  360.         }5 ]' B7 O$ M5 }8 e* }  `
  361.         //计算分频与VCO频率,通过PLLSAICFGR[30:28]可以设置2-7分频! T' [8 E5 H9 _9 e  p
  362.         //通过PLLSAICFGR[17:16]可以设置00:2 01:4 10:8 11:16分频
    ) \7 d$ p* d( W6 a6 q+ F! ]
  363.         //通过PLLSAICFGR[14:6]可以设置为49-432MHz的VCO频率1 D# f8 }, j: p0 M% K
  364.         if(ClockFreq <= 6)
    2 ]; Z0 A) C8 Z2 {+ T2 t8 |+ Y
  365.         {: h; e4 T! O1 C5 y# u
  366.                 PLLSAIR = 4;        //4分频
    : L: E4 T! v" P: H
  367.                 PLLSAIDIVR = 3;        //16分频
    9 ?/ {. X0 A- K  j
  368.                 VCO = ClockFreq * PLLSAIR * 16;                        //VCO范围:64-384;1 Q. a1 l9 e& @$ K+ u0 n  ~
  369.         }- g! j- w3 D. n) |
  370.         else if(ClockFreq <= 13)
    : d2 [1 r7 u' E
  371.         {
    3 z3 X8 F0 f5 o; w. j
  372.                 PLLSAIR = 4;        //4分频1 V7 I2 c# J( }
  373.                 PLLSAIDIVR = 2;        //8分频; e% C: P9 }) h
  374.                 VCO = ClockFreq * PLLSAIR * 8;                        //VCO范围:224-416;3 `' ~  B, P  l; P% X  F
  375.         }- Q0 j- I$ ^* a5 G/ s6 A6 o
  376.         else if(ClockFreq <= 26)0 v( S8 T. c4 s4 J
  377.         {
    2 c$ c6 X( G2 D( d
  378.                 PLLSAIR = 2;        //2分频6 D% W6 G0 o0 F* X$ {
  379.                 PLLSAIDIVR = 2;        //8分频
    / L8 A6 W$ h$ B
  380.                 VCO = ClockFreq * PLLSAIR * 8;                        //VCO范围:224-416;% N# ^! i3 [$ B: \" q0 d5 b
  381.         }% f( u4 P# I1 |1 u0 J- i# h8 g: i+ u
  382.         else if(ClockFreq <= 52)- X( t3 ~+ [! S/ }* k9 @0 o  ~7 y) \
  383.         {
    ( _" J9 R2 i. x& D$ `
  384.                 PLLSAIR = 2;        //2分频
    9 F+ O7 r8 g$ {0 X7 c# s
  385.                 PLLSAIDIVR = 1;        //4分频
    4 o$ B- q( }0 h9 D4 T/ @2 g
  386.                 VCO = ClockFreq * PLLSAIR * 4;                        //VCO范围:216-416;
    1 ^% _: _! w$ x9 M. m4 {
  387.         }
    ; V% q. B. o& H9 g
  388.         else if(ClockFreq <= 104)( T  V, i% s% W6 {) H
  389.         {; T, o. o+ U& n# y; x) b
  390.                 PLLSAIR = 2;        //2分频( O7 c& ?& ~3 L' i
  391.                 PLLSAIDIVR = 0;        //2分频
    : H- B# x1 C; @+ F! T
  392.                 VCO = ClockFreq * PLLSAIR * 2;                        //VCO范围:212-416;3 `) d" E1 C  ?
  393.         }& G4 G( S% D. g+ v9 Q
  394.         //设置PLLSAICFGR1 }8 `9 g! Y9 d+ K' d1 @
  395.         temp = RCC->PLLSAICFGR;, W8 K6 ~: s  B5 @( [" I* V3 J
  396.         temp &= ~((3<<28) | (0x1FF<<6));                        //清除之前的设置( O1 p$ Z( [. e" }4 y; V* _. p0 F
  397.         temp |= PLLSAIR << 28;                                                //设置分频PLLSAICFGR[30:28]
    1 G$ _; H9 o$ g: q) d+ I2 K
  398.         temp |= VCO << 6;                                                        //设置VCO! {0 Q' R- m1 q3 x/ `, u% S. c
  399.         RCC->PLLSAICFGR = temp;
    . X( P8 M2 n, }) M9 @
  400.         //设置DCKCFGR1* L& N2 x. |* k- E: [
  401.         temp = RCC->DCKCFGR1;# ~( S( D3 U( V4 U
  402.         temp &= ~(3<<16);                                                        //清除之前的设置& n$ q0 w! }4 f
  403.         temp |= PLLSAIDIVR << 16;                                        //设置分频DCKCFGR1[17:16]! d3 S7 @1 ]( r1 K9 `
  404.         RCC->DCKCFGR1 = temp;
    7 P. \' W- x+ B. B* B
  405.         //启动时钟  j0 K! |: a: M, y5 E
  406.         RCC->CR |= 1<<28;                                                        //启动SAI时钟" L2 l- }: ~. k# Y% s8 c
  407.         TimeOut = 0;; u# e# b" _, u# Q5 G. R+ l
  408.         while((RCC->CR&(1<<29)) == 0)                                //等待开启成功% U9 Z$ N! y2 V( ~$ g
  409.         {
    - ~+ P. a. E; N6 r5 _
  410.                 nop;3 J4 l; i  ]' ]
  411.                 TimeOut ++;. M$ G/ o" W/ [% X+ b
  412.                 if(TimeOut > 0xFFFF) return FALSE;                //开启超时! j2 k! S8 Q1 ~
  413.         }* u  [3 Y  f0 G: R! t  i0 _
  414.         ) W) D- _- [; C) D" e
  415.         return TRUE;8 \! c! x- I# Q' f: t/ K/ I
  416. }
    6 ~& f. s* m5 f' T/ |
  417. 2 z1 f' G4 i( z$ Y' H6 `+ U
  418. ( \+ P1 C# V+ m5 i; x# X9 k5 f
  419. /*************************************************************************************************************************
    , k7 o/ R( \# B( O+ q8 S
  420. * 函数                        :        void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color)        . w; ?" G. P$ l7 \9 ]6 M: c
  421. * 功能                        :        矩形填充(使用DMA2D)
    # E4 q7 {% N9 ]( b4 Y+ _
  422. * 参数                        :        LayerIndex:层选择0-1;sx,sy:开始坐标;ex,ey:结束坐标,color:需要填充的颜色
    , B3 m( g; H2 p/ [5 B% k9 x- w4 m
  423. * 返回                        :        无5 s2 W. Q/ J+ l! j, a3 f$ S
  424. * 依赖                        :        底层宏定义
    5 d  F. w+ C7 T  _
  425. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    $ _! y; B- b0 a" I1 x& O+ J
  426. * 时间                        :        2019-10-30( D6 H/ J/ u: b) h
  427. * 最后修改时间         :         2019-10-30
    # v+ K9 @2 V" n. J
  428. * 说明                        :        采用DMA2D实现% C6 E% Z7 ^- x; A6 R
  429. *************************************************************************************************************************/
    . |$ o! X! H) W7 Q
  430. void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color)' U# L2 N! r& P/ |. `
  431. {- Q, F/ ^; n: X9 L# e
  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进行单色填充8 h$ k. j7 {/ s
  433.         DMA2D_WaitTransferComplete(500);                                                                                                                                                                                                                                //等待DMA2D传输完成
    . x" I, R  F# z. N* D
  434. }
    : `" r  Y  O" ]0 h+ }$ _
  435. % G! w9 V% r- N

  436. 4 t, i4 C7 w/ |; p6 C5 m- y
  437. /*************************************************************************************************************************8 p4 y# y  f. g' e% e7 H3 e" _
  438. * 函数                        :        void LTDC_Clear(u8 LayerIndex,u32 color)
    7 o: W# P" q, S% r6 M9 G$ c1 Z
  439. * 功能                        :        清屏(使用DMA2D)
    ! t+ w: B4 i. Y) I7 x# L  `! f
  440. * 参数                        :        LayerIndex:层选择0-1;color:需要填充的颜色
    - ~  I7 A/ x  c/ o
  441. * 返回                        :        无: ]' U9 @9 o7 l4 Q4 I
  442. * 依赖                        :        底层宏定义/ s7 c- m/ N0 v0 g
  443. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    5 c5 f! i' A/ m
  444. * 时间                        :        2019-10-300 m6 {. m8 ~0 s/ ]* ^8 d
  445. * 最后修改时间         :         2019-10-30
    6 {6 @5 A2 h5 T7 P
  446. * 说明                        :        采用DMA2D实现
    % F5 ?: p# U. {5 e
  447. *************************************************************************************************************************/* C7 B8 O% S9 Q7 ]
  448. void LTDC_Clear(u8 LayerIndex,u32 color)
    ! ^& E* z' a% i! X# `
  449. {
    0 A, v( A9 {5 M( ~1 T
  450.         DMA2D_FillColorToFGRAM((u32)&g_LTDC_BUFF_RGB888[LayerIndex][0][0], LTDC_WIDTH, LTDC_HEIGHT, 0,  DMA2D_COLOR_ARGB8888, color);                                        //DMA2D进行单色填充3 n* s" U2 M' b% X7 b& }
  451.         SYS_DelayMS(5);
    # Q+ l4 A/ u8 L$ Y" n2 f
  452.         DMA2D_WaitTransferComplete(500);                                                                                                                                                                                                                                //等待DMA2D传输完成3 ?8 C! W' Z- x2 W; _
  453. }
    ' ]) z& n1 Q  t2 [$ b9 M+ ?

  454. + r8 W& l6 F3 o/ U: J
  455. $ Y' S2 ^  s' R* n' s1 d+ S7 N
  456. /*************************************************************************************************************************- {8 i6 |& ?0 u. b6 o7 k% ]6 m/ X8 f
  457. * 函数                        :        void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr)
    / q" x. m6 A4 \: b; j5 p' g
  458. * 功能                        :        矩形图像填充(相同坐标范围传输,要求源图像与目标显示器分辨率一致,使用DMA2D)/ P6 G& y% W0 X  {) d$ T3 N, J% n# M
  459. * 参数                        :        LayerIndex:层选择0-1;sx,sy:开始坐标;ex,ey:结束坐标,ImageAddr:需要填充的图像地址$ G! V2 G7 _) a" q( v3 Z9 I8 x
  460. * 返回                        :        无, }; n0 P- I& N- \9 |
  461. * 依赖                        :        底层宏定义$ K: Y: P. t# B7 f8 n
  462. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>% [! @0 ~* x3 a, D
  463. * 时间                        :        2019-10-30
    , m2 p8 I6 N+ R/ G+ J9 l/ S- Q6 `( E
  464. * 最后修改时间         :         2019-10-30/ K& R& l( ]. D7 H5 T  Y  i
  465. * 说明                        :        采用DMA2D实现,将源图像指定位置传输到现存,要求源图像与显存大小一致
    5 g( s+ c; K9 b6 l
  466. *************************************************************************************************************************/" h$ y# i7 ~% e  z' ~6 y. j+ y
  467. void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr)
    $ T+ x5 L  D  m- {% l4 \6 W0 N
  468. {0 A& K/ n* ], i4 R2 E! O4 c4 v
  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进行矩形图形填充
    5 J+ w5 Q1 ~! Z* F7 O
  470.         DMA2D_WaitTransferComplete(500);! I# x6 \* D4 ~) K
  471. }
复制代码
  1. /*************************************************************************************************************
    5 v+ n. D6 L2 {, }& k  K( Y/ R
  2. * 文件名                :        stm32f7_ltdc.h" K2 R" z' H7 F3 \% T; ~/ h
  3. * 功能                        :        STM32F7 外部RGB LCD驱动
    ) g9 g- W  F8 U6 S
  4. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    9 _6 c, ~$ B; j8 S. K5 j
  5. * 创建时间                :        2019-09-12
    ; C1 g$ E) i) f8 ^
  6. * 最后修改时间        :        2019-09-12
    & g  j) _* m- _7 u. W$ D
  7. * 详细:        
    ( |, _' C" z3 E# W
  8. *************************************************************************************************************/                4 A* t& g9 Y' v1 \, z0 B
  9. #ifndef __STM32F7_LTDC_H_
    ! U, i. U% v. o' M2 s
  10. #define        __STM32F7_LTDC_H_           
    9 F8 L$ f0 g& Z) d- t3 U% y! ?
  11. #include "system.h"
    ( g4 f& l0 w8 x* A" ]
  12. #include "DMA2D.h"
    & Z* U' \7 K! P  k4 z. a; L& s
  13. ( C9 |+ l1 o! w" _& _3 _
  14. #define LTDC_WIDTH                480
    % t/ ]# ~' U7 M; r' l
  15. #define LTDC_HEIGHT                272
    ! ]/ Z- b$ |7 Q# Z

  16. * [/ `- n) a& Z7 ^) J' L, g0 f

  17. * Y/ H, q" Z) m+ }
  18. extern u32 g_LTDC_BUFF_RGB888[2][LTDC_HEIGHT][LTDC_WIDTH];
    5 \8 z7 V- r+ k" ]3 d4 e  x
  19. : u) x+ z5 x' d4 N) |' M  s' f
  20. //像素格式定义
    7 a4 K! Z( k9 Q5 L% Q
  21. typedef enum! d% x2 f. O. Y) \* a
  22. {- Q7 A9 n1 C& N
  23.         LTDC_ARGB8888         = 0,, o9 J: S$ n' ~' c0 D9 @( X/ I
  24.         LTDC_RGB888         = 1,
    ! m# L. s# [( w
  25.         LTDC_RGB565         = 2,
    $ c$ _' O# k( `: |& l
  26.         /*LTDC_ARGB1555         = 3,
    ) Z6 ]& @. |% X# V# r3 Y  p$ Y
  27.         LTDC_ARGB4444         = 4,2 n, ?. s6 V; V9 F4 F$ ~2 v9 H
  28.         LTDC_L8                 = 5,        //8 位 Luminance" I: w, x3 M' L
  29.         LTDC_AL44                 = 6,        //4 位 Alpha,4 位 Luminance
    0 O7 n; w" }' [" P  b1 `
  30.         LTDC_AL88                 = 7,        //8 位 Alpha,8 位 Luminance*/
    $ H8 g% x9 a/ b) r
  31. }LTDC_PixelFormat;
    . R  M6 m% Y% `6 O5 k
  32. #define LTDC_PIXEL_FORMAT                LTDC_ARGB8888                //选择ARGB8888格式
    # y3 ?% v6 u* ]3 A, X& ^2 @

  33. 2 o% m& \2 _7 j) G6 w" D; t

  34. ! z& e( E5 I& X5 a0 c$ v( n
  35. ; G9 @  {  g: Q& [2 O
  36. 1 H- z# C+ W: k0 W
  37. //画点函数32bit ARGB8888格式
    4 u) x5 g% @. Z% @1 W. A
  38. __inline void LTDC_DrawPoint(u8 LayerIndex, u16 Xpos,u16 Ypos,u32 ARGB8888_Color)& x" u! A) \8 ]
  39. {
    - W. ~- V5 q$ ~/ G2 a& g
  40.         g_LTDC_BUFF_RGB888[LayerIndex][Ypos][Xpos] = ARGB8888_Color;
    ! I& a0 Z2 p* Y
  41. }: ]) O6 I, e. l* X" `$ T+ B8 l: f

  42. % |$ Q6 d4 G; X0 e. g5 h
  43. //初始化DISP引脚% J6 Z: I' U0 x# s$ f5 B! p
  44. __inline void LCD_DispIoInit(void)
    ' i, R* [7 d- ]& @1 _
  45. {
    # o" B9 ~3 Y( F4 D  r
  46.         SYS_GPIOx_Init(GPIOI, BIT12, OUT_PP, SPEED_25M);                                                                                                //PI12 LCD_DISP H:正常模式;L:低功耗                                                        . F1 o8 i- u% k
  47.         PIout(12) = 1;                                                                                                                                                                        //DISP = H  2019-10-16:一直忽略将此引脚置为高电平,调试走了很多弯路
    ! w+ J% K- s% @6 {- Y- _. E
  48. }/ w) a* m" q' _9 f# Y3 n

  49. . k: g) Z( m+ g* V0 C
  50. void LTDC_Enable(bool Enable);                                                                                                                                                //LTDC使能设置
    9 P2 I$ m( i6 z& z- n# {9 w
  51. void LTDC_Init(void);                                                                                                                                                                //LTDC 接口初始化
    4 t( B3 R: s! S3 M& f/ m( r# K
  52. void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha);//LTDC 层窗口尺寸设置
    , o. |! K: e# ]# c' ~
  53. void LTDC_LayerEnable(u8 LayerIndex, bool Enable);                                                                                                        //LTDC 层使能设置
    ' A2 o5 |4 @: W/ t+ V
  54. void LTDC_LayerRefreshConfig(void);                                                                                                                                        //LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)
    0 ~( H. O8 Z9 e* c3 }5 _1 S
  55. : L# }; U/ g7 ~8 ]. |
  56. //图形相关API: m4 Z9 Z5 m$ {# {9 d
  57. void LTDC_DrawPoint(u8 LayerIndex, u16 Xpos,u16 Ypos,u32 ARGB8888_Color);                                                        //画点函数32bit ARGB8888格式" Y/ z5 x& Z" R7 n
  58. void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color);                                                                //矩形填充(使用DMA2D)
    " p$ E& k4 S: F4 {& ~
  59. void LTDC_Clear(u8 LayerIndex,u32 color);                                                                                                                        //清屏(使用DMA2D)
    1 G! T8 W" c& P+ K8 u8 }. |
  60. 3 z. w- Q: @" x
  61. void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr);//矩形图像填充(相同坐标范围传输,要求源图像与目标显示器分辨率一致,使用DMA2D)
复制代码

8 e# H' n1 L7 n' y, L  v+ g5 A8 b2 ~/ |3 x* S3 n
#endif //__STM32F7_LTDC_H_
& \$ R9 [7 }6 R9 K# f% X2 Y& v
7 I* x9 q2 d% t* y) B" O$ L2 {1 M! k- _# Y3 v- c. g0 j$ ]* H+ Y

: K* G1 s/ V- F$ o
收藏 评论0 发布时间:2021-12-14 10:49

举报

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