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

【经验分享】STM32f746gdiscovery LTDC 驱动

[复制链接]
STMCU小助手 发布时间:2021-12-14 10:49
需要提前准备好SDRAM驱动,如果没有SDRAM可以进行纯色彩测试,底层时钟,IO操作相关看注释,我使用的是寄存器封装的。3 w, k( [) g  F$ P) N$ A$ n8 n4 o
* C6 s" E% \# O! y  V) ~* v5 I
  1. /*************************************************************************************************************
    8 F5 P6 Q$ D- {; ]
  2. * 文件名                :        stm32f7_ltdc.c
    1 F2 A, S) @6 k9 H8 ^) V  |4 ^
  3. * 功能                        :        STM32F7 外部RGB LCD驱动
    % C* U6 w" z! A  B1 N
  4. * 创建时间                :        2019-09-12
    " `+ \7 Y( d8 X( }
  5. * 最后修改时间        :        2019-09-121 {. q& d% w, c1 R
  6. * 详细:        $ M# |8 `& p) @; ]' z* ^2 s6 t
  7. *************************************************************************************************************/        
    ( n% o* N9 C5 p- m3 @  b0 [) w. d
  8. #include "stm32f7_ltdc.h"
    1 V6 x0 I. j" z) A# s
  9. #include "SYSTEM.H"
    , P; [5 B3 q1 {$ N7 r* c
  10. #include "stm32f7_sdram.h"
    ; \5 ^4 h1 K" q3 w/ V" C% p
  11. #include "DMA2D.h") i8 d( A$ s. G$ L! V& h

  12. % k# X! _- ^7 m- K1 n  u( Y
  13. 4 b6 M% W  V0 ^8 t- e
  14. u32 g_LTDC_BUFF_RGB888[2][LTDC_HEIGHT][LTDC_WIDTH]  __attribute__ ((at(Bank5_SDRAM_ADDR)));                //需要SDRAM支持,LCD帧缓冲区,RGB888格式
    ! L0 p' `# z* D& Q* V, x
  15. 9 [7 B& ^8 f' E, A" |

  16. ( x1 L( O! e3 i0 L; L% g. h+ J5 ?9 |
  17. //记录全局层配置信息7 S7 q0 [2 B% y! g& v: V
  18. typedef struct) G/ l2 \6 M( X+ }
  19. {
    4 Y1 W5 p/ j! C: O; P) K
  20.         u16 sx;                                        //层开始X坐标,从0开始
    + e# Q) l( h; G+ C0 h( f
  21.         u16 sy;                                        //层开始Y坐标,从0开始
    * F: T4 s; `/ Q) L, ~9 C3 ?
  22.         u16 width;                                //层宽度5 G, g+ _; @  h
  23.         u16 height;                                //层高度3 ]6 @9 r' o$ S& {
  24.         u32 *pFrameBuff;                //帧缓冲区指针,需要进行初始化
    $ r) I( q# a4 [! \: o( l
  25. }LTDC_LayerConfig;+ p  D& L2 ]& a4 Q4 J% k

  26. " o8 S8 G0 i; g8 e

  27. ' }4 d! j, Q7 z+ g4 c
  28. ! a, M7 Y+ w! D! i& w
  29. //全局的LTDC配置信息3 }  @8 I/ E0 X7 s( ]1 z/ }
  30. typedef struct
    # N# p8 x/ J9 y  w6 L1 l( G
  31. {6 I' M' p/ s0 r
  32.         u16 lcd_width;                                                //显示器宽度6 G& p1 K7 P; M' E% N4 C
  33.         u16 lcd_height;                                                //显示器高度
    / U& I: J, \- I8 l3 t, X
  34.         LTDC_LayerConfig LayerConfig[2];        //层信息9 x" _" M+ @& ]1 V& z' i
  35. }LTDC_ConfigData;( a( S) A2 I# d! G+ `* S
  36. # F- b  N# F/ v* f6 s6 d6 _3 h
  37. 3 r6 r( ]0 o4 q8 \
  38. static LTDC_ConfigData sg_LTDC_ConfigData;        //记录全局的LCD配置6 t& G9 X( X+ G% f7 L; S
  39. & K2 V0 u! q# q
  40. $ C5 _8 U3 b& \% G) m* G
  41. //显示屏信息; g4 g  ^5 d- C, M% t
  42. typedef struct
    6 |; H1 V% D% G( G' @. k: T
  43. {
    " ?9 L7 i/ |: s
  44.         u16         Width;                //面板宽度,单位:像素$ A, M6 A, \( g% L% ^" J5 I6 ]- G
  45.         u16         Height;                //面板高度,单位:像素
    : ?0 h  n  {. k3 l  L( S
  46.         u8          Thbp;                //水平后廊( w( H& I+ ]2 d# y; Q
  47.         u8          Thfp;                //水平前廊2 ~! B! U/ b+ p. S. i
  48.         u8          Thw;                //水平同步宽度. \, D0 C: w9 P$ H5 d; B2 j
  49.         u8          Tvbp;                //垂直后廊: L6 d  b$ Z4 X# S, D
  50.         u8          Tvfp;                //垂直前廊1 b7 k0 K0 }3 D( ^5 l
  51.         u8          Tvw;                //垂直同步宽度" a& J) [9 g1 b# d6 Q8 `* q* H. x
  52.         u8          DCLK;                //时钟速度,MHz
    ' F/ ^. s; X/ w+ }1 r9 }  f  J
  53.         
    7 l5 u  B. G5 g7 M" r5 O1 x
  54.         u8                HSPOL;                //水平同步极性,0:低电平有效;1:高电平有效8 F" k6 M7 _( R( p- `# D6 W
  55.         u8                VSPOL;                //垂直同步极性,0:低电平有效;1:高电平有效
    ( |0 M& `1 k& m1 u$ }+ j( `) h
  56.         u8                DEPOL;                //数据使能极性,0:低电平有效;1:高电平有效
    * d0 J' y3 f) h# w/ f7 z
  57.         bool        PCPOL;                //像素时钟反向
    $ W3 R5 _: V. G& L7 @3 \
  58. }LTDC_INFO_TYPE;  Z/ g9 U# e( n5 B* M. l

  59. ! [7 r5 `* P5 m( n

  60. 7 \4 n7 a# `5 p( k
  61. LTDC_INFO_TYPE DefaultLCD_Info =
    ) r: l' b! Z: g. S" o& p$ t
  62. {8 P; ^+ H, h/ L+ F! x+ @7 r
  63.         480,        //面板宽度,单位:像素
    " m, o! q' I$ R* l0 o
  64.         272,        //面板高度,单位:像素* B: l% p1 K) A7 W( V4 p0 \
  65.         41,                //水平后廊
    0 Z) a  ~) ~# a$ k3 O% m
  66.         8,                //水平前廊$ {, B6 d/ H: K" N& W- c8 z
  67.         2,                //水平同步宽度
    ) I2 @. T1 D# B
  68.         2,                //垂直后廊
    9 |6 ?! h% N* @, Z
  69.         4,                //垂直前廊& M0 ]8 m* w4 c1 D9 X
  70.         10,                //垂直同步宽度. b  f+ A& s" P
  71.         9,                //时钟速度,MHz
    7 h! l5 V& v5 Z9 r% y4 K
  72.         0,                //水平同步极性,0:低电平有效;1:高电平有效
    : K: W# j+ D' U  i, [5 P
  73.         0,                //垂直同步极性,0:低电平有效;1:高电平有效
    3 d1 E8 j& w0 l; B4 G6 C# ]/ S
  74.         1,                //数据使能极性,0:低电平有效;1:高电平有效2 Q* l$ a/ I# J5 G2 ]: H
  75.         FALSE,        //像素时钟反向
    & l* M6 v1 z/ N! i/ Y
  76. };
    : S' }3 y: z9 A3 W( U

  77. 5 _7 w1 Q5 G9 _2 k
  78. bool LTDC_ClockInit(u16 ClockFreq);                                                        //STM32F4 LTDC时钟初始化  @. a4 q. @: l) l: C

  79. 5 i2 A! I# i% `. L  z- p8 ^5 T- P
  80. 6 Y' \% W) w" f' P4 i' K
  81. /*************************************************************************************************************************- B& i' i9 m- ]& R( Y% `2 w9 E
  82. * 函数        :                        void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha)8 X( b) Q# {5 c
  83. * 功能        :                        LTDC 层窗口尺寸设置(会自动根据窗口尺寸以及像素格式设置帧缓冲区大小)3 ]* n$ A) k  ~3 i7 d0 p
  84. * 参数        :                        LayerIndex:层选择(0-1);sx,sy:起始坐标;width,height:宽度和高度0 Y' ?0 Z9 v; ?- {' h. X3 P$ V, k
  85. * 返回        :                        无- n& x) y6 U6 N- t% [
  86. * 依赖        :                        底层宏定义8 ?- E4 ~8 Z+ }9 K- b
  87. * 作者        :                        <a href="mailto:cp1300@139.com">cp1300@139.com</a>$ q0 I! i0 \& V+ `2 H8 r' d
  88. * 时间        :                        2019-10-28) S* h/ [& Z) F# |( t1 b" T8 F, H
  89. * 最后修改时间 :         2019-10-28
    % W6 n9 [% U; @
  90. * 说明        :                         不会使能层,不会更新层,只设置配置,需要刷新层配置后更新
    3 B) Z$ M3 w0 \- }3 [4 E& D
  91. *************************************************************************************************************************/
    ( O) N* v, w* o) w; M
  92. void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha): |5 p8 `. r! ]
  93. {1 m9 Z. {% x* y7 ^/ ^; \" h' L
  94.         u32 temp;7 [- R1 N, m  {2 i" P/ P, L
  95.         u8 pixformat=0;
      ~, |# t/ Y. n, W( `
  96.         ) y4 s. b( h* P; A4 E- O
  97.         if(LayerIndex==0)
    + }: }$ W/ |2 H7 {1 R# g2 z5 y( S
  98.         {5 h3 l5 Y/ ~1 x
  99.                 //基本配置# {( j# Z& L0 V; p
  100.                 LTDC_Layer1->CFBAR = FrameBuff;                                                                        //设置层颜色帧缓存起始地址
    1 g: F2 W# }% `& D4 T' ~  S
  101.                 LTDC_Layer1->PFCR = LTDC_PIXEL_FORMAT;                                                        //设置层颜色格式
    ; W% Y+ j$ y5 y) U8 J. F
  102.                 LTDC_Layer1->CACR = Alpha;                                                                                //常数 Alpha,255分频;设置255,则不透明$ H! r( E" R9 G+ I' u9 p
  103.                 LTDC_Layer1->DCCR = 0x00;                                                                                //设置默认颜色:透明的黑色) b$ S$ V! B# N9 r$ B
  104.                 LTDC_Layer1->BFCR = ((u32)6<<8)|7;                                                                //设置层混合系数+ l1 ^, N- I" r- P
  105.                 //配置窗口
    1 c7 J/ ~9 J' w& A8 F- L' q) S
  106.                 temp = (sx+width+((LTDC->BPCR&0X0FFF0000)>>16))<<16;
    9 B5 }8 \9 P1 e' l* m0 F8 p
  107.                 LTDC_Layer1->WHPCR = (sx+((LTDC->BPCR&0X0FFF0000)>>16)+1)|temp;//设置行起始和结束位置
    2 Y8 d) W/ w* s) f' o% G+ r5 i
  108.                 temp = (sy+height+(LTDC->BPCR&0X7FF))<<16; 5 \) l' l. G9 o& `- U, ^) H
  109.                 LTDC_Layer1->WVPCR = (sy+(LTDC->BPCR&0X7FF)+1)|temp;                        //设置列起始和结束位置
    7 Q1 L' X; u9 d% q7 ^5 R7 w
  110.                 pixformat = LTDC_Layer1->PFCR&0X07;                                                                //得到颜色格式) f3 f; L; b0 V4 V4 S& i
  111.                 if(pixformat == 0)temp=4;                                                                                //ARGB8888,一个点4个字节. N. b. l% b8 {2 C+ r
  112.                 else if(pixformat == 1)temp=3;                                                                        //RGB888,一个点3个字节
    ) W8 S: m8 w4 ]* a$ d& ?
  113.                 else if(pixformat==5||pixformat==6)temp=1;                                                //L8/AL44,一个点1个字节
    3 E2 v& n& o# l2 b
  114.                 else temp=2;                                                                                                        //其他格式,一个点2个字节  o5 G* w0 b$ q1 I* m/ z  C. S
  115.                 LTDC_Layer1->CFBLR = (width*temp<<16)|(width*temp+3);                        //帧缓冲区长度设置(字节为单位)
    / R+ R* P+ W; L
  116.                 LTDC_Layer1->CFBLNR = height;                                                                        //帧缓冲区行数设置        3 n8 q& C& q4 Y  l
  117.                
    * K4 `2 Q  m% X9 ]" J5 ]
  118.                 //记录层窗口大小位置信息# E# {$ N2 U. k/ ^7 t
  119.                 sg_LTDC_ConfigData.LayerConfig[0].sx = sx;                # k% k  `7 G9 o, |- _6 `' _/ ~
  120.                 sg_LTDC_ConfigData.LayerConfig[0].sy = sy;        
    - E7 p+ N8 e* B. j6 ]$ V# e
  121.                 sg_LTDC_ConfigData.LayerConfig[0].width = width;        ( G; R% n  s4 l* o* m$ V& z
  122.                 sg_LTDC_ConfigData.LayerConfig[0].height = height;        
    ) x& @7 J5 w- S+ v5 q5 ]( |
  123.         }else
    1 M- N3 i+ F' p1 E; c! ^4 F
  124.         {# J* I- ?7 M1 j3 I+ R& W8 ^) t
  125.                 //基本配置- R1 l7 K8 G( r/ A, b
  126.                 LTDC_Layer2->CFBAR = FrameBuff;                                                                        //设置层颜色帧缓存起始地址
    . p- M' ^7 F9 C/ [( a; s
  127.                 LTDC_Layer2->PFCR = LTDC_PIXEL_FORMAT;                                                        //设置层颜色格式
    8 u8 J% ]1 R9 s$ U0 V( m
  128.                 LTDC_Layer2->CACR = Alpha;                                                                                //常数 Alpha,255分频;设置255,则不透明
    1 M4 h% ^3 @: J* z! b* d+ M( E
  129.                 LTDC_Layer2->DCCR = 0x00;                                                                                //设置默认颜色:透明的黑色, d, y1 c# p, p) E$ Y! d
  130.                 LTDC_Layer2->BFCR = ((u32)6<<8)|7;                                                                //设置层混合系数4 s3 H) D2 I) H
  131.                 //配置窗口; d$ X$ e5 G) B% I
  132.                 temp = (sx+width+((LTDC->BPCR&0X0FFF0000)>>16))<<16;
    ' V* C3 \6 u. a, i& g. i) h0 G$ X
  133.                 LTDC_Layer2->WHPCR = (sx+((LTDC->BPCR&0X0FFF0000)>>16)+1)|temp;        //设置行起始和结束位置   V4 o6 Y6 |! ~2 ]
  134.                 temp = (sy+height+(LTDC->BPCR&0X7FF))<<16;
    ' d7 D' o- x+ n$ n) M0 O
  135.                 LTDC_Layer2->WVPCR = (sy+(LTDC->BPCR&0X7FF)+1)|temp;                        //设置列起始和结束位置" g$ k: Z3 _, [+ F& U' o/ h& j- V
  136.                 pixformat = LTDC_Layer2->PFCR&0X07;                                                                //得到颜色格式
    . E' }( ?3 V% X4 V7 b$ t! x! j
  137.                 if(pixformat == 0)temp=4;                                                                                //ARGB8888,一个点4个字节
    ' j8 ]% }8 b3 f/ r/ v' m
  138.                 else if(pixformat == 1)temp=3;                                                                        //RGB888,一个点3个字节
    ) _) C; @' I9 |9 j+ R
  139.                 else if(pixformat == 5||pixformat==6)temp=1;                                        //L8/AL44,一个点1个字节3 _( ?7 t  O( N8 x! p& y
  140.                 else temp = 2;                                                                                                        //其他格式,一个点2个字节
    & e+ z5 u7 }. h$ Q! r! v
  141.                 LTDC_Layer2->CFBLR = (width*temp<<16)|(width*temp+3);                        //帧缓冲区长度设置(字节为单位)
    # x4 _5 B, X' j. L# Q0 \
  142.                 LTDC_Layer2->CFBLNR = height;                                                                        //帧缓冲区行数设置        
    # ^" O/ A+ u6 M9 `- {
  143.                
    8 ~5 W: b( Q. o; E5 v3 A9 I
  144.                 //记录层窗口大小位置信息3 M" r1 {+ W7 p6 d2 _
  145.                 sg_LTDC_ConfigData.LayerConfig[1].sx = sx;               
    7 w9 Y* H- Y" F( }, B6 ^2 x: _
  146.                 sg_LTDC_ConfigData.LayerConfig[1].sy = sy;        9 D' W: K' c) s2 q
  147.                 sg_LTDC_ConfigData.LayerConfig[1].width = width;        7 q( l5 X4 p$ I0 |7 F! ?
  148.                 sg_LTDC_ConfigData.LayerConfig[1].height = height;               
    6 p6 q* h; w% S( N" E5 L1 K
  149.         }+ O% H$ E. y4 E$ Y  |5 K
  150. }
    + I& X- U- b5 S, N
  151. % B: m3 |& r5 ^6 C
  152. ; k3 s; m( {3 p
  153. ( L- g# G, K) n4 i8 U1 ~/ |" ]" a- w6 W
  154. /*************************************************************************************************************************
    2 Q) j( g% {: y" N* |
  155. * 函数        :                        void LTDC_Init(void)
    . }3 }* M: r. I0 l: I
  156. * 功能        :                        LTDC 接口初始化4 L, A$ E  x" _, Q6 S, g* B) w) f
  157. * 参数        :                        无
    , [7 |% x% t3 a1 ]
  158. * 返回        :                        无; ^. r4 s" j# z( ~
  159. * 依赖        :                        底层宏定义" |. I# e) `! Z# _
  160. * 作者        :                        <a href="mailto:cp1300@139.com">cp1300@139.com</a>5 o: @9 q/ Y, Z" ~* }' V
  161. * 时间        :                        2019-09-08( y; V! S! u  I9 j9 g
  162. * 最后修改时间 :         2019-09-08/ y5 {: M; a6 ~; S' O7 v
  163. * 说明        :                         用于初始化STM32F7 LTDC 接口
    * S# N1 l% w$ h( S+ b  n
  164. *************************************************************************************************************************/  
    # [4 K5 ^! y; L
  165. void LTDC_Init(void)
    8 Z3 M  Z1 F: u- }4 d
  166. {  l+ n  t; N8 G  z
  167.         u32 temp;$ j9 S; Z4 A- G: R& A/ A
  168.         
    5 D$ d' g& k# Z3 _' z
  169.         SYS_DeviceClockEnable(DEV_LTDC, TRUE);        //LTDC时钟使能
    4 u0 `/ \( X' c5 n4 A+ ^8 X  q
  170.         SYS_DeviceReset(DEV_LTDC);                                //STM32F7外设复位5 S1 T  J, ~7 O4 t. A* u
  171.         SYS_DeviceClockEnable(DEV_GPIOE, TRUE);        //使能GPIOE时钟3 M! [5 m, `9 D2 n# L4 Z/ e. t
  172.         SYS_DeviceClockEnable(DEV_GPIOG, TRUE);        //使能GPIOG时钟7 _: D1 b6 }( s% q
  173.         SYS_DeviceClockEnable(DEV_GPIOJ, TRUE);        //使能GPIOJ时钟
    + ]- {# D9 \( z2 O  z
  174.         SYS_DeviceClockEnable(DEV_GPIOK, TRUE);        //使能GPIOK时钟: i% ^2 A# h) a4 {, M/ i* Y
  175.         SYS_DeviceClockEnable(DEV_GPIOI, TRUE);        //使能GPIOI时钟- C& r& f% y0 \$ k# x0 w

  176. # {+ b" H  g, t/ c, z0 O
  177.         4 U5 B! U5 v: }" }
  178.         //初始化IO7 M4 K/ s8 E$ y7 C- `0 X- M( ]
  179.         SYS_GPIOx_Init(GPIOE, BIT4, AF_PP_OPU, SPEED_100M);                                                                                //PE4. f* P6 N4 x4 {1 o/ q$ V
  180.         SYS_GPIOx_Init(GPIOG, BIT12, AF_PP_OPU, SPEED_100M);                                                                        //PG12
    * V, t& @" }& {5 U! d
  181.         SYS_GPIOx_Init(GPIOJ, 0Xffff&(~BIT12), AF_PP_OPU, SPEED_100M);                                                        //PJ0~11/13/14/15
    4 B" ~) i! q9 T* g) P! \
  182.         SYS_GPIOx_Init(GPIOK, BIT0|BIT1|BIT2|BIT4|BIT5|BIT6|BIT7, AF_PP_OPU, SPEED_100M);                //PK0/1/2/4/5/6/7
    5 P9 V, O) p7 G6 c( d
  183.         SYS_GPIOx_Init(GPIOI, BIT9|BIT10|BIT14|BIT15, AF_PP_OPU, SPEED_100M);                                        //PI9/10/14/15# |9 I( e' y+ M3 Y# Z, U
  184.         
    8 I. Y( ^$ F# c: Z. S  ^
  185.         SYS_GPIOx_SetAF(GPIOE, 4, AF14_LTDC);                //PE4,AF14        
    $ Q- C2 Q- R1 J  G1 a( Y
  186.          SYS_GPIOx_SetAF(GPIOG, 12, AF14_LTDC);                //PG12,AF14        
    4 b$ W$ S7 @6 [" U9 G: X
  187.         SYS_GPIOx_SetAF(GPIOJ, 0, AF14_LTDC);                //PJ0,AF14# A8 Z3 k% O; X: c6 V2 X% {
  188.         SYS_GPIOx_SetAF(GPIOJ, 1, AF14_LTDC);                //PJ1,AF144 g) V4 z. r. Z. O
  189.         SYS_GPIOx_SetAF(GPIOJ, 2, AF14_LTDC);                //PJ2,AF14
    ' X- C9 g4 q  C% @7 ?' }
  190.         SYS_GPIOx_SetAF(GPIOJ, 3, AF14_LTDC);                //PJ3,AF14
    ( @; e. p+ s. h) B
  191.         SYS_GPIOx_SetAF(GPIOJ, 4, AF14_LTDC);                //PJ4,AF149 d; w% w$ W2 B* h+ |8 T
  192.         SYS_GPIOx_SetAF(GPIOJ, 5, AF14_LTDC);                //PJ5,AF140 j. ?* W  I8 f1 }
  193.         SYS_GPIOx_SetAF(GPIOJ, 6, AF14_LTDC);                //PJ6,AF143 s7 p' ]: t, w5 ^% Y2 H
  194.         SYS_GPIOx_SetAF(GPIOJ, 7, AF14_LTDC);                //PJ7,AF14
    " S2 O) N% q$ r) |
  195.         SYS_GPIOx_SetAF(GPIOJ, 8, AF14_LTDC);                //PJ8,AF14
    % e# S9 B9 }$ G) }/ K. p2 n. x
  196.         SYS_GPIOx_SetAF(GPIOJ, 9, AF14_LTDC);                //PJ9,AF14
    : R* a" c- o: R
  197.         SYS_GPIOx_SetAF(GPIOJ, 10, AF14_LTDC);                //PJ10,AF14
    5 |* [8 Q5 @5 [% q8 {4 ^
  198.         SYS_GPIOx_SetAF(GPIOJ, 11, AF14_LTDC);                //PJ11,AF14- y: U/ a) @8 n/ f' A- p
  199.         SYS_GPIOx_SetAF(GPIOJ, 13, AF14_LTDC);                //PJ13,AF148 {8 y' y8 c2 c+ f
  200.         SYS_GPIOx_SetAF(GPIOJ, 14, AF14_LTDC);                //PJ14,AF145 y) K: S2 _/ P
  201.         SYS_GPIOx_SetAF(GPIOJ, 15, AF14_LTDC);                //PJ15,AF14! {5 y# D( d3 `6 {$ c2 A% g
  202.         ! C  ?' C) P7 c% x% c
  203.         SYS_GPIOx_SetAF(GPIOK, 0, AF14_LTDC);                //PK0,AF14% R- e. e3 j( n' r4 V" A
  204.         SYS_GPIOx_SetAF(GPIOK, 1, AF14_LTDC);                //PK1,AF14
    & A9 U9 M1 O: c' j7 y$ j* u
  205.         SYS_GPIOx_SetAF(GPIOK, 2, AF14_LTDC);                //PK2,AF14
    ) Q& e5 X0 [6 A9 B5 ?
  206.         SYS_GPIOx_SetAF(GPIOK, 4, AF14_LTDC);                //PK4,AF14% O* Y& C$ L6 x0 f
  207.         SYS_GPIOx_SetAF(GPIOK, 5, AF14_LTDC);                //PK5,AF14
    : H( V7 I( H- S4 i. K
  208.         SYS_GPIOx_SetAF(GPIOK, 6, AF14_LTDC);                //PK6,AF14
    5 u( u" E' |9 l' A7 _+ R' c
  209.         SYS_GPIOx_SetAF(GPIOK, 7, AF14_LTDC);                //PK7,AF14
    1 Q% B9 s: `& c! i" n1 T
  210.         
    4 c6 [) j0 b. Y! I0 f
  211.          SYS_GPIOx_SetAF(GPIOI, 9, AF14_LTDC);                //PI9,AF14
    7 [( f5 Z+ H- A/ Z( v' T8 O- |
  212.          SYS_GPIOx_SetAF(GPIOI, 10, AF14_LTDC);                //PI10,AF14
    # z: y* p* U( i! s% x
  213.         SYS_GPIOx_SetAF(GPIOI, 14, AF14_LTDC);                //PI14,AF14
    . y7 V1 m& D; g* l* V
  214.          SYS_GPIOx_SetAF(GPIOI, 15, AF14_LTDC);                //PI15,AF14
      Q' Z) c& b! G. o
  215.         3 `2 h0 Q5 u; l
  216.         LTDC_ClockInit(DefaultLCD_Info.DCLK);                 //设置像素时钟  9Mhz & ]% e+ ?8 ~" H& V
  217.         //设置LTDC 全局控制寄存器 (LTDC_GCR)
    0 _+ u, L* l  h- F; ^& X
  218.         temp = 0;
    $ c8 g; v$ D$ ?* J* q: F
  219.         temp |= (DefaultLCD_Info.HSPOL&0x01) << 31;        //水平同步极性
    & E0 N9 j, w$ g8 W
  220.         temp |= (DefaultLCD_Info.VSPOL&0x01) << 30;        //垂直同步极性% H+ l8 U/ G$ O7 j4 K# V: j
  221.         temp |= (DefaultLCD_Info.DEPOL&0x01) << 29;        //数据使能极性
    0 e4 o2 I0 t; h0 U: e
  222.         temp |= (DefaultLCD_Info.PCPOL&0x01) << 28;        //像素时钟极性
    1 q9 E5 v2 Y2 ?, q) D) W
  223.         LTDC->GCR = temp;
    " X, X& b: q' f5 U$ O
  224.         //LTDC 后沿配置寄存器 (LTDC_BPCR)- t; U/ h# K3 Y' ^: |
  225.         temp = (DefaultLCD_Info.Tvw + DefaultLCD_Info.Tvbp - 1) << 0;        //这些位定义累加水平后沿宽度(水平同步像素加水平后沿像素减 1)。# H/ Z. E7 g* z
  226.         temp |= (DefaultLCD_Info.Thw + DefaultLCD_Info.Thbp - 1) << 16;        //这些位定义累加垂直后沿宽度(垂直同步行加垂直后沿行减 1)。5 |3 B( U* l# _- X
  227.         LTDC->BPCR=temp;        # a, O5 M. M# }* \6 N
  228.         2 p) n/ x. ^2 |& i3 F' S
  229.         //LTDC 有效宽度配置寄存器 (LTDC_AWCR)# z1 y6 D3 J5 U
  230.         temp=(DefaultLCD_Info.Tvw+DefaultLCD_Info.Tvbp+DefaultLCD_Info.Height-1)<<0;        //累加有效高度=垂直脉宽+垂直后沿+垂直分辨率-1
    & m! F" L; Q" x/ C
  231.         temp|=(DefaultLCD_Info.Thw+DefaultLCD_Info.Thbp+DefaultLCD_Info.Width-1)<<16;        //累加有效宽度=水平脉宽+水平后沿+水平分辨率-1
    - C$ U& ^. g8 I7 o! B* K" z6 _9 ^
  232.         LTDC->AWCR=temp;        
    ! j* X' H+ F5 z& C. Y/ V
  233.         //LTDC 总宽度配置寄存器 (LTDC_TWCR). z5 U+ s! i0 N, b2 j& x& b  v9 m2 Z
  234.          temp=(DefaultLCD_Info.Tvw+DefaultLCD_Info.Tvbp+DefaultLCD_Info.Height+DefaultLCD_Info.Tvfp-1)<<0;        //总高度=垂直脉宽+垂直后沿+垂直分辨率+垂直前廊-1
    4 x' s) ]( N3 ^2 @
  235.         temp|=(DefaultLCD_Info.Thw+DefaultLCD_Info.Thbp+DefaultLCD_Info.Width+DefaultLCD_Info.Thfp-1)<<16;        //总宽度=水平脉宽+水平后沿+水平分辨率+水平前廊-1
    1 [7 ~( f, B3 z8 K: `5 N; ^
  236.         LTDC->TWCR=temp;                                
    $ d7 l. M2 J7 O: ^9 N

  237. 2 u" W0 _9 m1 d4 a/ h" b' ~$ Y
  238.         //背景设置
    % O* z( s; r  T# V8 y
  239.         LTDC->BCCR=0xffffff;                                //设置背景层颜色寄存器(RGB888格式)
    7 B# e  b0 n8 y1 r( V
  240.         LTDC_Enable(TRUE);                                        //开启LTDC% _5 T, Z5 M* y- {7 s! ?: [. d
  241.         //初始化层1' Z& c5 }, k1 f% I
  242.         LTDC_SetLayerConfig(0, 0, 0, LTDC_WIDTH, LTDC_HEIGHT, (u32)g_LTDC_BUFF_RGB888[0], 255);
    + J+ x% G8 [* A( J3 z
  243.         //初始化层23 u1 q9 n' H- h: \
  244.         LTDC_SetLayerConfig(1, 0, 0, LTDC_WIDTH, LTDC_HEIGHT, (u32)g_LTDC_BUFF_RGB888[1], 255);' I* K* ?% _3 R& a$ ^1 p" p' `( ?6 w
  245.         LTDC_Clear(0, 0xFF000000);                        //清屏层1-不透明的黑色: S! i8 {' d* _1 y5 A, Z& |9 @
  246.         LTDC_Clear(1, 0x00000000);                        //清屏层2-透明的黑色6 u: t( O: F2 U' q! Q6 ]1 B& s
  247.         LTDC_LayerEnable(0, TRUE);                        //使能层1
    , e& A6 R" r/ T" G) b. Q8 G& y  E7 C
  248.         LTDC_LayerRefreshConfig();                        //LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)
    1 |- b% V+ n& ]% T3 h% s2 e" K
  249.         LCD_DispIoInit();                                        //初始化DISP引脚-启动显示
      m+ E- U/ _0 |3 D' U
  250. }$ m7 j, u1 W" F

  251. ; a' j' X7 T8 a0 t% Y5 p
  252. /*************************************************************************************************************************6 s4 x7 @5 Y% Q( b; q
  253. * 函数                        :        void LTDC_LayerRefreshConfig(void)$ R: Y: |) }. h1 Y) T- f- ]
  254. * 功能                        :        LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)
    4 J. @2 `9 g+ Y- ~
  255. * 参数                        :        无
    * f3 |6 A# D2 A
  256. * 返回                        :        无
    ; ]9 k* i% s" @
  257. * 依赖                        :        底层宏定义
    % d. y* m: e( `5 L) x
  258. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    3 P; N( u/ @% _; E. y# B
  259. * 时间                        :        2019-10-299 K: p  {  z5 r
  260. * 最后修改时间         :         2019-10-29
    ! V& j7 M! h8 g0 ^: N! c
  261. * 说明                        :        修改层配置后必须重新加载,否则不会生效
    * Q4 p+ \7 W# M9 E3 P' e. Z
  262. *************************************************************************************************************************/
    / X) v2 {5 b$ a; x) b  A/ u
  263. void LTDC_LayerRefreshConfig(void)6 e% F; V' ]6 n9 v3 c9 y
  264. {
    8 t) l0 c: [, Q
  265.         LTDC->SRCR|=1<<0;                                                        //重新加载配置-必须重新加载,否则上面的层不会更新,折腾好久才发现,叫啥影子寄存器重载,也不说清楚5 t* \8 n+ f: P- m
  266. }
    ! Q$ k$ a1 I+ a( A' a7 I6 A

  267. 0 l! D# J7 F. R3 Z$ @8 R+ ?
  268. /*************************************************************************************************************************
    / V1 `0 P. K2 P  F' B4 F' y! h
  269. * 函数                        :        void LTDC_Enable(bool Enable)
    - f, J& \! r9 r$ ^
  270. * 功能                        :        LTDC使能设置- \, K. o/ I9 a/ l
  271. * 参数                        :        Enable:TRUE:使能;FALSE:失能3 W/ w4 H  L& Q8 S( q
  272. * 返回                        :        无
    0 o4 _/ l' T2 f, A
  273. * 依赖                        :        底层宏定义
    " n) {$ @) a5 i" c# o+ v5 {
  274. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    8 a2 ]# c, ^  Y) j6 e* f, v
  275. * 时间                        :        2019-10-295 c( J& t+ y9 O- l; R+ H4 B
  276. * 最后修改时间         :         2019-10-299 N0 V' N8 z' V# w8 F+ j9 s6 F4 X
  277. * 说明                        :        8 E& |* D8 h+ j$ Z# p. N
  278. *************************************************************************************************************************/! a% W% b0 ?2 E# N4 g+ l5 C- b/ L
  279. void LTDC_Enable(bool Enable)
    * I& n, z1 ~- ~& K! {5 s4 y7 o
  280. {2 |$ Q. ?5 y! d- s8 V
  281.         if(Enable)4 Z9 [% q+ A' u( U& G$ w8 ^
  282.         {; x6 @' y) W7 N) q" S: H% E
  283.                 LTDC->GCR |= BIT0;                                        //打开LTDC" X+ n9 ~2 ?% Q1 R* w
  284.         }) V8 C* d% R% q) k3 J, N+ R9 o9 `
  285.         else
    % y1 H" A5 i( j) s% K
  286.         {
    , u/ c; j( W7 @/ U
  287.                 LTDC->GCR &= ~BIT0;                                        //关闭LTDC* w: r2 P3 H* M* i2 Q- u
  288.         }9 F( g$ X# m6 N* k, n5 M* z9 f- m; n
  289. }* z+ D3 Q3 F9 `+ V. v' c4 I7 S
  290. . C4 a8 W' y# [. N
  291. /*************************************************************************************************************************1 h2 q, u7 Q. l$ R. e
  292. * 函数                        :        void LTDC_LayerEnable(u8 LayerIndex, bool Enable)
    * ^1 m' s' k4 |/ M8 F- l8 T0 z: d
  293. * 功能                        :        LTDC 层使能设置& l% W$ w. V5 |  R
  294. * 参数                        :        LayerIndex:层选择0-1;Enable:TRUE:使能;FALSE:失能/ d/ {  _' a) l' v5 q/ x% f5 z" F
  295. * 返回                        :        无
    3 s' o' V' v! N% ^8 ?
  296. * 依赖                        :        底层宏定义) b* p+ ]  ^3 S( |6 P
  297. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>, l4 ]$ S6 d. p6 Q6 Q
  298. * 时间                        :        2019-10-29
    ! v% A# t: s- K( x2 }' d1 H! `) ]7 y
  299. * 最后修改时间         :         2019-10-29% n' t1 x' j( U, P( Q/ Z. y
  300. * 说明                        :        
    & u( L1 L2 x& Y+ q6 w# S
  301. *************************************************************************************************************************/2 g8 ]5 d8 Q  y$ W' c7 `; i
  302. void LTDC_LayerEnable(u8 LayerIndex, bool Enable)
    & o8 L) @/ v" ~! v! Z. V
  303. {
    % D/ G  y5 c) w$ W6 ]: E$ C
  304.         if(Enable)# \* C7 d4 K* S: I  |
  305.         {
    7 D* L) {0 C# x$ i: m5 U: N0 {
  306.                 if(LayerIndex == 0)                                        //层16 w( o$ l* K1 Y2 o  O: e
  307.                 {7 n: T9 y# ?8 U% n; D) }, V; o# N. X
  308.                         LTDC_Layer1->CR |= BIT0;                //使能层12 V2 n7 e3 I" |% `
  309.                 }
    ' B& `" u% ]+ j
  310.                 else
    # ^! s1 R& r! u& P8 @% {1 ]
  311.                 {$ u: i, M5 \) }0 i( B: t  d
  312.                         LTDC_Layer2->CR |= BIT0;                //使能层2) F; e. w9 P3 w
  313.                 }
    * N9 l1 J* u, W1 z2 _9 g  f8 |
  314.         }
    % i: q5 E% s" d- A/ i
  315.         else, z! D/ J4 ~$ u& B+ k
  316.         {
    7 C3 N1 v( V8 N3 ~+ Z
  317.                 if(LayerIndex == 0)                                        //层1$ N. _  H3 b( k) Z9 _9 }
  318.                 {
    + d- S9 s) Y8 A
  319.                         LTDC_Layer1->CR &= ~BIT0;                //失能层1# ]) \7 F; J) ^  N& p5 K5 f
  320.                 }
    + ^, B5 o: p& r
  321.                 else
    4 D% X/ d% i, Y& u
  322.                 {; W' M/ u& D) `+ G; c
  323.                         LTDC_Layer2->CR &= ~BIT0;                //失能层2
    % P9 y& H' R* _9 B7 P- W& y: s. A
  324.                 }- V8 O/ O. J( B: i6 u0 i: b
  325.         }- g+ T3 O6 v* c8 h
  326. }
    7 h; C: H5 R- j5 W) c

  327. 0 ~- Y; R- p9 ~# T. P
  328. 4 d0 S/ s+ G1 C1 m  ]! E
  329. ' A" I/ {6 o8 p2 U0 R9 z+ Q4 f
  330. . a) ^; `) F- Z6 c; a3 j2 F
  331. /*************************************************************************************************************************2 E) z6 _8 a4 u/ O+ A
  332. * 函数                        :        bool LTDC_ClockInit(u16 ClockFreq)                        1 ~9 `7 @4 y0 w( z
  333. * 功能                        :        STM32F7 LTDC时钟初始化& j. }0 Y/ l6 [7 x( b! C+ F
  334. * 参数                        :        ClockFreq:时钟频率,2-168MHZ5 L8 g% I! H/ e+ \* g; g6 A* |/ E
  335. * 返回                        :        是否设置成功) }  W" j$ a) i
  336. * 依赖                        :        底层宏定义( [* Q! z5 K( i8 S4 k) \
  337. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    9 g/ V; c3 P: q' ~" I
  338. * 时间                        :        2019-10-28
    ! C; l/ p* c4 S; W
  339. * 最后修改时间         :         2019-10-28: v) I6 O# W( n; T9 `( P% Y& s
  340. * 说明                        :        输入时钟频率在系统主时钟初始化之后就会设置为1MHz,通过设置SAI PLL实现LTDC所需频率,VCO频率范围:49~4328 [: K, Z7 T( a  q+ q7 Y( U4 Z
  341. *************************************************************************************************************************/% n; k( V& o. \0 T
  342. bool LTDC_ClockInit(u16 ClockFreq)+ b2 n: Y, f6 n  k
  343. {
    ) ~+ B4 L1 R* U! M$ }7 Y6 ^
  344.         u32 TimeOut = 0;
    * G1 V7 G: b5 v' @& A9 z# d9 u* H
  345.         u32 VCO;
    ( F. i- I4 A$ m# s/ c6 B
  346.         u32 PLLSAIR;                //PLLSAICFGR[30:28]
    7 K) e' C- `- ^8 n
  347.         u32 PLLSAIDIVR;                //DCKCFGR1[17:16]- ~! o# v. G/ }1 v6 c6 z
  348.         u32 temp;
    $ ^' |7 ?/ o7 q% `
  349.         6 K1 c* Q, n" H# a2 h6 x. l
  350.         if(ClockFreq < 1)ClockFreq = 1;, y( y% r1 i9 i
  351.         if(ClockFreq > 100) ClockFreq = 100;- b4 }: h' A9 t- G0 A& o! X. F" D
  352.         ! d- y( O* P+ ]# W7 c- g
  353.         RCC->CR &= ~(1<<28);                                                //关闭SAI时钟 ( |2 ?! q0 |8 F- ^. ]
  354.         TimeOut = 0;
    % U( c7 M! k0 }+ V2 c
  355.         while(RCC->CR&(1<<29))                                                //等待关闭成功
    8 ]* v, ~; F  T9 z0 M; a' |; U) o' t
  356.         {( ?5 ]/ g) T5 ~. J
  357.                 nop;; W# U" b; u1 D$ x9 B; z1 W
  358.                 TimeOut ++;5 Q1 T1 U4 _4 r) c. S1 U
  359.                 if(TimeOut > 0xFFFF) return FALSE;                //关闭超时
    : `7 \$ E  L2 ~0 j. D' q, S' e
  360.         }
      }; l  g) @5 n0 W- f
  361.         //计算分频与VCO频率,通过PLLSAICFGR[30:28]可以设置2-7分频# \$ S' s5 ?! }
  362.         //通过PLLSAICFGR[17:16]可以设置00:2 01:4 10:8 11:16分频
    : U8 {- B6 Z) [  E& y
  363.         //通过PLLSAICFGR[14:6]可以设置为49-432MHz的VCO频率5 b$ f: {4 s! j! r
  364.         if(ClockFreq <= 6)* `& E) x  D4 u
  365.         {' v5 J; E5 }% R
  366.                 PLLSAIR = 4;        //4分频# B) t% a( I1 i& a4 z& ^6 B) _
  367.                 PLLSAIDIVR = 3;        //16分频# B# p( z9 z2 y  [" x0 k1 T/ |
  368.                 VCO = ClockFreq * PLLSAIR * 16;                        //VCO范围:64-384;
    0 k- A; J% W1 }( V0 H: z  w+ w: C$ H
  369.         }
    1 ]+ y! E- O4 ^) _9 H6 a" t! p
  370.         else if(ClockFreq <= 13)$ n) S9 w& I! z( W
  371.         {5 @/ v. h" q$ O+ E
  372.                 PLLSAIR = 4;        //4分频* T0 C+ Q. t9 ?! m
  373.                 PLLSAIDIVR = 2;        //8分频
    & [* i2 P/ B: t/ j4 \
  374.                 VCO = ClockFreq * PLLSAIR * 8;                        //VCO范围:224-416;
    9 m# p- Y& d) o/ t# q
  375.         }
    4 B# \* e, u$ B2 ~/ k8 n
  376.         else if(ClockFreq <= 26)" H% C" ^2 H9 H9 p7 \0 T& f% _
  377.         {& }+ d# U* @/ i" r% Q
  378.                 PLLSAIR = 2;        //2分频
    " Q8 r$ M7 g  s
  379.                 PLLSAIDIVR = 2;        //8分频) q( ?( E$ S5 G& w) O
  380.                 VCO = ClockFreq * PLLSAIR * 8;                        //VCO范围:224-416;6 Y' w7 o% j# G8 i+ c
  381.         }
    3 H7 ^" v9 F0 ^  D( l
  382.         else if(ClockFreq <= 52)( H' h9 A' u3 J/ `7 m2 E( p  X7 a3 P$ G
  383.         {8 o1 J, E! [; m: u& n
  384.                 PLLSAIR = 2;        //2分频
    $ n! {. m* }( s3 g
  385.                 PLLSAIDIVR = 1;        //4分频
    ' b( M. e- G0 ]. Y2 j, x0 a5 [
  386.                 VCO = ClockFreq * PLLSAIR * 4;                        //VCO范围:216-416;
    - ~& o2 m! Z6 W) I
  387.         }
    ) t3 C7 B% @0 y  O! N. }' C
  388.         else if(ClockFreq <= 104)  D( T3 U, v# q& D7 N
  389.         {
    4 h" k- s* n0 c. ~9 }. C6 A
  390.                 PLLSAIR = 2;        //2分频
    " k! w$ y# \9 v  c5 V$ n
  391.                 PLLSAIDIVR = 0;        //2分频3 s5 l# ?1 G: p* m& p4 I; Y, G
  392.                 VCO = ClockFreq * PLLSAIR * 2;                        //VCO范围:212-416;5 Q/ _. O5 T4 X1 D) D
  393.         }
    2 q6 Y' Q' |# z, h& Q- f8 N
  394.         //设置PLLSAICFGR
    9 R+ `' V  e& Z
  395.         temp = RCC->PLLSAICFGR;5 v- j: I: V+ D" x2 z0 H( A. j
  396.         temp &= ~((3<<28) | (0x1FF<<6));                        //清除之前的设置/ I, g. @, t1 b
  397.         temp |= PLLSAIR << 28;                                                //设置分频PLLSAICFGR[30:28]
    ! d0 H- A6 |: U+ ^0 C0 k- v- i2 R4 T
  398.         temp |= VCO << 6;                                                        //设置VCO
    $ \9 H0 _( q7 o% }$ A
  399.         RCC->PLLSAICFGR = temp;0 ^, z/ K8 E9 a5 `0 H& j
  400.         //设置DCKCFGR1. b2 `' }$ u. b. t9 [8 v8 ]6 Q; j0 ^
  401.         temp = RCC->DCKCFGR1;
    ! Q% D9 w) w  S  K( {' t
  402.         temp &= ~(3<<16);                                                        //清除之前的设置; {# n/ }2 w( _; K. F/ U
  403.         temp |= PLLSAIDIVR << 16;                                        //设置分频DCKCFGR1[17:16]5 W3 {$ k  K$ J& }6 Q- E
  404.         RCC->DCKCFGR1 = temp;
    7 {  p. G$ p/ \/ r  i
  405.         //启动时钟
    3 n$ h# P( \9 i- M* n
  406.         RCC->CR |= 1<<28;                                                        //启动SAI时钟
    6 ]: `* z3 v0 |8 m! E- k* ]
  407.         TimeOut = 0;
    ( x! {  Q7 s+ X
  408.         while((RCC->CR&(1<<29)) == 0)                                //等待开启成功: O! n9 h1 c' Y( A% Q* \
  409.         {
    4 k0 V* l  |: T) E$ ^
  410.                 nop;0 K: b, j; v/ a' |1 B
  411.                 TimeOut ++;
    ' d5 ^  p8 }- |
  412.                 if(TimeOut > 0xFFFF) return FALSE;                //开启超时5 ?) V9 l8 h, E
  413.         }
    ) E! [+ t+ e% p8 z) p
  414.         
    . o7 j$ \8 o7 P- R% a2 V1 R
  415.         return TRUE;
    , r4 D) z" w$ g; [# I" t! o! b6 q( S
  416. }4 m' E7 K$ g; G. c
  417. - \7 J6 a3 i. J
  418. 4 D& I' Q% g, U- x: g( w* g
  419. /*************************************************************************************************************************) U) F- p, M1 _+ e/ C7 z  d  _) q
  420. * 函数                        :        void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color)        
    1 v7 o* q2 E' G. F; R
  421. * 功能                        :        矩形填充(使用DMA2D)& j5 {+ d+ {  v" U& l/ [; b
  422. * 参数                        :        LayerIndex:层选择0-1;sx,sy:开始坐标;ex,ey:结束坐标,color:需要填充的颜色- h8 D6 A4 C; V
  423. * 返回                        :        无9 n5 o$ P2 W# P! O. ?, R
  424. * 依赖                        :        底层宏定义
    ! h9 g' m* [. \: X# E% U
  425. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    + M) \$ N* @3 m# y7 N
  426. * 时间                        :        2019-10-30& J& i; ~# ?: k
  427. * 最后修改时间         :         2019-10-30  {' b, E& {8 h2 p7 Z" _
  428. * 说明                        :        采用DMA2D实现3 R1 F* v0 E2 \. Z4 \! f
  429. *************************************************************************************************************************/
    6 V1 p8 f# t5 u3 E2 G( D
  430. void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color)& W4 ~2 G* U9 p) l. s/ d& S, d  [$ D
  431. {
    ( _) Q7 |3 ~. V# g3 i7 Z% l" i3 z
  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进行单色填充
    5 ~$ M* l. n7 ~  x  G% x
  433.         DMA2D_WaitTransferComplete(500);                                                                                                                                                                                                                                //等待DMA2D传输完成6 g2 `1 W5 ^/ H" V( G2 d7 e) e
  434. }
    1 @6 x4 ^* ?( Q
  435. & A! ?1 x; D( u# ~% L
  436. / _" |! f& k' Q5 \9 A$ `
  437. /*************************************************************************************************************************
    4 t: q/ H- G! K; g
  438. * 函数                        :        void LTDC_Clear(u8 LayerIndex,u32 color)
    1 D; i7 H& G- M% X0 S8 A" r
  439. * 功能                        :        清屏(使用DMA2D)9 m3 \; {+ w- m) v: N) F& A
  440. * 参数                        :        LayerIndex:层选择0-1;color:需要填充的颜色
    % Q% [% U8 H( A& D: s+ g4 z
  441. * 返回                        :        无
    3 J& Q$ }2 z1 a% q  f
  442. * 依赖                        :        底层宏定义; D3 g9 f/ R& s: z6 t9 M7 T! W
  443. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
      l6 S3 I- }4 p* o
  444. * 时间                        :        2019-10-302 O+ e3 P: ]9 I& E' Y: O
  445. * 最后修改时间         :         2019-10-300 J1 o, ~6 ?! b8 S2 v' ^7 ^
  446. * 说明                        :        采用DMA2D实现1 X4 v! m6 Q6 N& n) f
  447. *************************************************************************************************************************/
    ; E9 V! A+ W( Q5 r* x2 H
  448. void LTDC_Clear(u8 LayerIndex,u32 color)# k/ c) Z) ~* D) Z
  449. {
    ; @' E5 s7 b7 t# ]. v
  450.         DMA2D_FillColorToFGRAM((u32)&g_LTDC_BUFF_RGB888[LayerIndex][0][0], LTDC_WIDTH, LTDC_HEIGHT, 0,  DMA2D_COLOR_ARGB8888, color);                                        //DMA2D进行单色填充
    ) E& a8 J% h6 I; }( s9 m
  451.         SYS_DelayMS(5);% e' O) @6 u7 {, y
  452.         DMA2D_WaitTransferComplete(500);                                                                                                                                                                                                                                //等待DMA2D传输完成
    : B( d  Z: e* I' P. q5 [' g! |7 W
  453. }
    % ^- p5 o7 S5 q) J8 A: H2 i" Z

  454. 9 Y0 M3 @" y; _) T+ K; W7 ?3 V

  455. - [  K! {. g) ?4 Z- M0 ]( d
  456. /*************************************************************************************************************************1 Y* ^$ E' Z% r* b
  457. * 函数                        :        void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr)  {% N& l( `# v# a+ G1 a
  458. * 功能                        :        矩形图像填充(相同坐标范围传输,要求源图像与目标显示器分辨率一致,使用DMA2D)
    + z( f" _& F. T/ {6 W4 v9 _
  459. * 参数                        :        LayerIndex:层选择0-1;sx,sy:开始坐标;ex,ey:结束坐标,ImageAddr:需要填充的图像地址6 T' T8 ~- ]  [# x/ }
  460. * 返回                        :        无4 h) K" a7 }$ c$ h; u* }
  461. * 依赖                        :        底层宏定义
    8 z% q( R' Z' ?' }: c
  462. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>/ w( B& x6 I9 T( B& S% U0 s
  463. * 时间                        :        2019-10-30$ p, ^& \" V- _
  464. * 最后修改时间         :         2019-10-30' U0 e0 d" Z/ I( k
  465. * 说明                        :        采用DMA2D实现,将源图像指定位置传输到现存,要求源图像与显存大小一致
    + w& q& k) l8 n. r: O* y
  466. *************************************************************************************************************************/! m5 g9 [, P) l5 ~- M+ W" I
  467. void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr)* s' P8 ~/ i0 ?0 B/ o, m2 c
  468. {$ K" j/ x7 ~! p2 o5 n) q
  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进行矩形图形填充' `: ~1 ~" G, V% }
  470.         DMA2D_WaitTransferComplete(500);9 Q; w0 A( x* J  @. N. M
  471. }
复制代码
  1. /*************************************************************************************************************( v) _" C, m2 r* Z: ^  F
  2. * 文件名                :        stm32f7_ltdc.h
    1 x0 @3 {/ I8 M; Y* \0 I
  3. * 功能                        :        STM32F7 外部RGB LCD驱动  V$ C# W" i  {$ u* l$ V( v2 y
  4. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    / n# }( {7 ~1 T6 R9 W# S- A, O
  5. * 创建时间                :        2019-09-12
    ! _0 m5 y4 g1 \# |
  6. * 最后修改时间        :        2019-09-12
    & e7 P; ], z8 U& h; E4 }
  7. * 详细:        4 _# R- j1 t- Y, z
  8. *************************************************************************************************************/               
    + s% j9 {2 t. w6 U2 U0 O) q+ V% P
  9. #ifndef __STM32F7_LTDC_H_
    ( d/ N2 r- E: V' b+ j. g
  10. #define        __STM32F7_LTDC_H_           5 F& X+ R% C( m$ O1 L# Q: X* \
  11. #include "system.h"
    9 G$ m. Y9 }, r& S' O1 L
  12. #include "DMA2D.h"
    , Z1 T$ I6 k& i" l! A2 j& d

  13. & o2 M" V) V* t  K# h
  14. #define LTDC_WIDTH                4805 e$ F, D+ B, {: H5 w
  15. #define LTDC_HEIGHT                272! m7 o# c/ Y  i- b
  16. 1 `: F# Q, Y- L+ }2 Q1 j: h+ F

  17. 4 @2 U6 a0 j4 K* h
  18. extern u32 g_LTDC_BUFF_RGB888[2][LTDC_HEIGHT][LTDC_WIDTH];
    . \" D. `2 D9 L4 d* j3 g; X8 S5 k
  19. + O: N6 f: i, h& J7 q5 H
  20. //像素格式定义
    1 p6 [+ Q8 u- h- g( y: E
  21. typedef enum
    ; V% U, r% ~3 d8 R* A8 v9 G
  22. {
    . Z  v: n6 d" f
  23.         LTDC_ARGB8888         = 0,7 i: O  n% n/ B/ O% x5 a8 F9 R
  24.         LTDC_RGB888         = 1,2 |% j3 j, g3 |
  25.         LTDC_RGB565         = 2,7 H3 f) Q* J- |5 k" U
  26.         /*LTDC_ARGB1555         = 3,
    + f1 z9 J" E' u% ?1 T7 i+ D& L
  27.         LTDC_ARGB4444         = 4,. h! c. e( y' J
  28.         LTDC_L8                 = 5,        //8 位 Luminance
    , C2 H* v9 [. @2 C6 V) `/ a, l5 m
  29.         LTDC_AL44                 = 6,        //4 位 Alpha,4 位 Luminance+ h3 p9 ~3 [& U5 |9 F& ?* e, R! p; f
  30.         LTDC_AL88                 = 7,        //8 位 Alpha,8 位 Luminance*/2 k6 L8 \: q: D! y
  31. }LTDC_PixelFormat;- T7 K1 G5 N1 g% \5 C
  32. #define LTDC_PIXEL_FORMAT                LTDC_ARGB8888                //选择ARGB8888格式2 E5 a; q5 T: L

  33. - [$ J5 j. X) y- H

  34. 0 M: R; |; e" }
  35. 5 P: s" K9 G- \& W, x

  36. + L9 C' U2 u# R8 s  Q1 Z6 [. N; c
  37. //画点函数32bit ARGB8888格式; _& c6 }# t4 \  W
  38. __inline void LTDC_DrawPoint(u8 LayerIndex, u16 Xpos,u16 Ypos,u32 ARGB8888_Color)# I% J% l8 M+ d  s& I0 {9 v7 [( E
  39. {/ a0 Q7 B/ {" A+ \( L  W0 |
  40.         g_LTDC_BUFF_RGB888[LayerIndex][Ypos][Xpos] = ARGB8888_Color;
    ; G3 b8 h/ @0 d
  41. }/ p. T# ]/ y  y7 \

  42. * l2 C/ t  g/ [. |6 c
  43. //初始化DISP引脚9 W, \, M- \: ^' ?4 g
  44. __inline void LCD_DispIoInit(void)
    8 D0 C" a! ~& C* Y' Q
  45. {) \) o9 q& h, k- r! p* e
  46.         SYS_GPIOx_Init(GPIOI, BIT12, OUT_PP, SPEED_25M);                                                                                                //PI12 LCD_DISP H:正常模式;L:低功耗                                                        ) e  N) {% P$ y& U
  47.         PIout(12) = 1;                                                                                                                                                                        //DISP = H  2019-10-16:一直忽略将此引脚置为高电平,调试走了很多弯路4 C" N5 X5 S+ c  w. a2 u4 ]
  48. }' o4 O1 ^+ {3 L8 o0 w0 V( E
  49. / T+ X* |& a6 g
  50. void LTDC_Enable(bool Enable);                                                                                                                                                //LTDC使能设置
    0 ?5 {9 r, }2 T! u
  51. void LTDC_Init(void);                                                                                                                                                                //LTDC 接口初始化/ ^" x0 ?+ G8 y3 X  H
  52. void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha);//LTDC 层窗口尺寸设置7 Z; {; |( C" F6 K: X4 p. {4 l
  53. void LTDC_LayerEnable(u8 LayerIndex, bool Enable);                                                                                                        //LTDC 层使能设置
    7 T& K0 i7 g  x
  54. void LTDC_LayerRefreshConfig(void);                                                                                                                                        //LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)1 x$ E* l& C3 m2 B; `

  55. 6 B" I8 w' w4 E4 N7 u
  56. //图形相关API& s3 d( B) T$ M8 b) ~! r
  57. void LTDC_DrawPoint(u8 LayerIndex, u16 Xpos,u16 Ypos,u32 ARGB8888_Color);                                                        //画点函数32bit ARGB8888格式
    & @, @( [8 Q+ r) f
  58. void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color);                                                                //矩形填充(使用DMA2D)
    0 g4 a: [5 w) ]$ \* J) [
  59. void LTDC_Clear(u8 LayerIndex,u32 color);                                                                                                                        //清屏(使用DMA2D)) I& g# D5 j% i1 q% w" S

  60. 7 Q. r8 _9 O1 A( `2 Q5 I
  61. void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr);//矩形图像填充(相同坐标范围传输,要求源图像与目标显示器分辨率一致,使用DMA2D)
复制代码
) s* z/ I: z/ V, \
! u0 }" o( A+ M7 }$ o7 R7 E1 W
#endif //__STM32F7_LTDC_H_
1 G) ?6 h4 x$ ]! U, Q
  s5 E  M1 |( d- {) C
) l7 z+ z/ V2 B0 c0 H! x2 k
* F& ~) L( W. w0 c$ l% c4 w
收藏 评论0 发布时间:2021-12-14 10:49

举报

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