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

【经验分享】STM32f746gdiscovery LTDC 驱动

[复制链接]
STMCU小助手 发布时间:2021-12-14 10:49
需要提前准备好SDRAM驱动,如果没有SDRAM可以进行纯色彩测试,底层时钟,IO操作相关看注释,我使用的是寄存器封装的。& B0 U6 l3 K* {  f' N: h+ @5 F

9 j7 D" M4 Y' n; }6 \; O
  1. /*************************************************************************************************************
    # R/ q% E: Q! I1 Q
  2. * 文件名                :        stm32f7_ltdc.c
    0 M" v5 J: N0 M4 t$ C6 i) T
  3. * 功能                        :        STM32F7 外部RGB LCD驱动+ T% h! {1 p6 ]7 s& c/ f
  4. * 创建时间                :        2019-09-12) l& [5 H- {/ A/ k2 g
  5. * 最后修改时间        :        2019-09-12
    - U7 }! U, P$ l7 E- z) V0 n6 O
  6. * 详细:        
    , Y0 D% k( g6 J, S& p# V! k, f
  7. *************************************************************************************************************/        
    " J# u  O* ^- {1 J4 {. C
  8. #include "stm32f7_ltdc.h"
    ( }8 m* h8 a, Q3 J
  9. #include "SYSTEM.H" ) P# ?, R( f( i
  10. #include "stm32f7_sdram.h"5 j" }' T, g  e6 K5 ~
  11. #include "DMA2D.h"
    * r8 p- Y& }' J: ~

  12. % V) j, j6 ?1 W
  13. # z: Z% k9 R$ X' ~, T
  14. u32 g_LTDC_BUFF_RGB888[2][LTDC_HEIGHT][LTDC_WIDTH]  __attribute__ ((at(Bank5_SDRAM_ADDR)));                //需要SDRAM支持,LCD帧缓冲区,RGB888格式
    3 w' l0 {/ l; w5 h" g
  15. % L/ c# [6 c9 _1 i

  16. 4 A- R( @9 J3 q
  17. //记录全局层配置信息
    $ G- G1 d+ B% A3 }, C
  18. typedef struct
    - R5 [" o6 W( |% U4 r& i" ?
  19. {, X3 L5 I. Y6 x$ b0 x- Y; p
  20.         u16 sx;                                        //层开始X坐标,从0开始
    % n% v" S. P7 u& z
  21.         u16 sy;                                        //层开始Y坐标,从0开始
    ' Z! |6 v  N( o# Y# \6 I! R5 D5 O
  22.         u16 width;                                //层宽度0 M( n& `& B) G, o- m# V
  23.         u16 height;                                //层高度
    + P2 ~/ w, M- `% V7 W" h+ ?
  24.         u32 *pFrameBuff;                //帧缓冲区指针,需要进行初始化
    * o2 B. _5 h  M
  25. }LTDC_LayerConfig;9 v5 n2 m' ?2 _) _/ q* P5 u& R4 |: D
  26. : R0 V/ K. L+ e5 P
  27. " N) R) N/ [( k% ~
  28. " t0 {9 Z* b" S4 G" K* {+ ]
  29. //全局的LTDC配置信息) Z5 }" R) v* Q) I8 y1 k
  30. typedef struct
    : [+ m$ O& j% W& m
  31. {" t  ~  H& o. A/ t" r5 x& k
  32.         u16 lcd_width;                                                //显示器宽度9 h0 E# W7 \# V$ ]$ B/ w
  33.         u16 lcd_height;                                                //显示器高度, k  Z" p# L5 P  x6 w+ B: f, [6 U
  34.         LTDC_LayerConfig LayerConfig[2];        //层信息) S# [. {, \. b2 T
  35. }LTDC_ConfigData;
    : h) ~# Z5 v1 U) k0 Z1 l

  36. : C5 |- o9 M" C' d$ w3 q- }
  37. 8 h. d6 {" O( h, N- P# F
  38. static LTDC_ConfigData sg_LTDC_ConfigData;        //记录全局的LCD配置
    . E- }( A/ I% e6 d! A! L3 a
  39. . j+ E# n7 a+ F5 R  \6 s
  40. - g9 B7 n$ c5 ?: ]* h
  41. //显示屏信息) j1 r$ {) G& |7 b* K# b
  42. typedef struct0 r3 w0 V' W$ g5 i# C- ~
  43. {
    6 x% @6 E5 |+ s  f
  44.         u16         Width;                //面板宽度,单位:像素) }% ~4 G, [. N! B4 A% b
  45.         u16         Height;                //面板高度,单位:像素
    , L! A3 W) R" Q9 G' s
  46.         u8          Thbp;                //水平后廊
    : {/ C" F0 V* N/ G, t
  47.         u8          Thfp;                //水平前廊
    , D7 o+ }3 m+ z: N- j
  48.         u8          Thw;                //水平同步宽度" V8 U( J) p% D% L0 K7 n5 e* j
  49.         u8          Tvbp;                //垂直后廊; C) D/ B  \5 A/ U/ V5 v( e
  50.         u8          Tvfp;                //垂直前廊
    ' k1 J, |; c7 I8 B5 W: w
  51.         u8          Tvw;                //垂直同步宽度
    : u$ Q9 H' A" T  o
  52.         u8          DCLK;                //时钟速度,MHz9 i; o+ C/ P5 A$ t- a- r6 O' n
  53.         
    5 \, h9 |+ f- t7 g9 ]
  54.         u8                HSPOL;                //水平同步极性,0:低电平有效;1:高电平有效
    ; o3 n8 \# @. S
  55.         u8                VSPOL;                //垂直同步极性,0:低电平有效;1:高电平有效+ ~+ z+ z- |! v7 S" b2 R
  56.         u8                DEPOL;                //数据使能极性,0:低电平有效;1:高电平有效  u( b& y9 G: Z  z" o
  57.         bool        PCPOL;                //像素时钟反向
    7 I6 F8 i" O% i  J
  58. }LTDC_INFO_TYPE;, C6 E& X0 O" I' @2 Z# m

  59. / W6 h" I; ~- G) O3 p. D9 B4 j
  60. & n3 }5 W* J6 u0 ^: ?, T9 m
  61. LTDC_INFO_TYPE DefaultLCD_Info =
    ! N' F/ e4 I0 s4 A3 s' g
  62. {) C" J! X" }2 w# H( U* e7 A
  63.         480,        //面板宽度,单位:像素5 T6 n- o1 F# e
  64.         272,        //面板高度,单位:像素
    2 `+ _3 s9 @( c( t+ c
  65.         41,                //水平后廊
    ; }2 ?1 Y4 D: {( v# I( K& b/ I; k
  66.         8,                //水平前廊
    % `1 }, ]) h' K* g8 m( ~1 i
  67.         2,                //水平同步宽度
    * K- o. p4 H, l# _" Y' j9 K! O* T+ u
  68.         2,                //垂直后廊
    6 X  Y, Y- e/ I9 n% J
  69.         4,                //垂直前廊
    7 z- Y0 \6 G7 r8 m3 }3 h
  70.         10,                //垂直同步宽度
    - k% B1 p* P  O. p& j3 B
  71.         9,                //时钟速度,MHz
    ; H  Y' [: X- T+ |7 c. O0 y$ ?! A, y6 ^
  72.         0,                //水平同步极性,0:低电平有效;1:高电平有效: d1 J+ F7 Z0 K% K6 S
  73.         0,                //垂直同步极性,0:低电平有效;1:高电平有效
    7 t' z" l9 M$ r3 c" e
  74.         1,                //数据使能极性,0:低电平有效;1:高电平有效
    ( A0 z) q8 `0 n
  75.         FALSE,        //像素时钟反向; j. |2 C& @! d* S+ L
  76. };
    * E% {  q3 `" o- @; q
  77. 2 G7 ~( D1 W  y+ R9 B2 r2 O
  78. bool LTDC_ClockInit(u16 ClockFreq);                                                        //STM32F4 LTDC时钟初始化
    3 @  }) l0 z3 _) I; ]

  79. / d) `* g, h  [( h0 x2 {
  80. & B8 q" D# s. M: O* k+ P0 B
  81. /*************************************************************************************************************************
    1 @4 l& u+ J  H
  82. * 函数        :                        void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha)
    - R( N! m7 o2 y, A0 Y
  83. * 功能        :                        LTDC 层窗口尺寸设置(会自动根据窗口尺寸以及像素格式设置帧缓冲区大小)  d' p1 U" z  y) y( t' v
  84. * 参数        :                        LayerIndex:层选择(0-1);sx,sy:起始坐标;width,height:宽度和高度. d. z* I( I" Z6 c6 d7 }
  85. * 返回        :                        无
    ' z0 {3 T# W2 g' Y
  86. * 依赖        :                        底层宏定义. }; `6 o& W7 X+ i0 E. I6 _
  87. * 作者        :                        <a href="mailto:cp1300@139.com">cp1300@139.com</a>0 Q! J3 K" O3 n9 T8 H  d$ ]
  88. * 时间        :                        2019-10-28, T* h/ o( f" e
  89. * 最后修改时间 :         2019-10-28
    0 ^% w# f/ E* L( s- w1 T
  90. * 说明        :                         不会使能层,不会更新层,只设置配置,需要刷新层配置后更新- _# z0 c: T4 O; F" }4 S
  91. *************************************************************************************************************************/
    . L; G, D  |3 c; K5 _# J: k$ B/ p
  92. void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha)
    3 s. ]# W3 e7 w, h+ g! w) k
  93. {) J- d* E9 H* ?
  94.         u32 temp;
    ! I* H; Z( g5 \; n1 H8 ^7 q
  95.         u8 pixformat=0;
    1 r( b+ f, s  l; o% J5 ~
  96.         
    9 Z& b! [- [( A
  97.         if(LayerIndex==0); w9 S& e* S* k
  98.         {, _$ t! E9 Z( g
  99.                 //基本配置1 \1 _5 Z, a- `6 A! ~
  100.                 LTDC_Layer1->CFBAR = FrameBuff;                                                                        //设置层颜色帧缓存起始地址
    ) [: z, z$ A7 k  T
  101.                 LTDC_Layer1->PFCR = LTDC_PIXEL_FORMAT;                                                        //设置层颜色格式) M: J' q* Y0 z! L2 r$ g) h
  102.                 LTDC_Layer1->CACR = Alpha;                                                                                //常数 Alpha,255分频;设置255,则不透明, z& Z$ {, G: F9 ~
  103.                 LTDC_Layer1->DCCR = 0x00;                                                                                //设置默认颜色:透明的黑色
    # D: j* r% h1 J. l: Q* _* Y
  104.                 LTDC_Layer1->BFCR = ((u32)6<<8)|7;                                                                //设置层混合系数& O2 h  m8 o7 s5 D
  105.                 //配置窗口
    7 R$ ~' x; {- O3 S6 m# a
  106.                 temp = (sx+width+((LTDC->BPCR&0X0FFF0000)>>16))<<16;
    # ^+ B! L  [' B9 n- l5 \5 Z  O
  107.                 LTDC_Layer1->WHPCR = (sx+((LTDC->BPCR&0X0FFF0000)>>16)+1)|temp;//设置行起始和结束位置
    0 f0 U; h9 ]& |/ b9 m
  108.                 temp = (sy+height+(LTDC->BPCR&0X7FF))<<16; $ s, z" [% r+ l5 G9 U$ X- r% n
  109.                 LTDC_Layer1->WVPCR = (sy+(LTDC->BPCR&0X7FF)+1)|temp;                        //设置列起始和结束位置
    " n% I7 m6 W; X- ~0 x" h
  110.                 pixformat = LTDC_Layer1->PFCR&0X07;                                                                //得到颜色格式
    9 M4 T5 k$ G- h7 o! \/ T9 z
  111.                 if(pixformat == 0)temp=4;                                                                                //ARGB8888,一个点4个字节: H7 [' h' u4 W, T
  112.                 else if(pixformat == 1)temp=3;                                                                        //RGB888,一个点3个字节
    6 M. w) v- o7 V; j
  113.                 else if(pixformat==5||pixformat==6)temp=1;                                                //L8/AL44,一个点1个字节
    2 v1 Q+ M$ E/ R2 O; Y8 d; F( n
  114.                 else temp=2;                                                                                                        //其他格式,一个点2个字节
      m5 Y: }, b5 ?3 |" \
  115.                 LTDC_Layer1->CFBLR = (width*temp<<16)|(width*temp+3);                        //帧缓冲区长度设置(字节为单位)
    ' W4 v( a8 o! P2 ~/ {/ q: I6 t
  116.                 LTDC_Layer1->CFBLNR = height;                                                                        //帧缓冲区行数设置        
    ! v8 L" A' x2 y& V; _3 `
  117.                
    / ^6 l$ j5 x7 E( o% p3 _' n! T
  118.                 //记录层窗口大小位置信息7 d8 F0 y+ k8 R: x% t2 z( i$ r7 Q5 N
  119.                 sg_LTDC_ConfigData.LayerConfig[0].sx = sx;               
    9 P/ i; k/ |( D/ @! _
  120.                 sg_LTDC_ConfigData.LayerConfig[0].sy = sy;        
    ' M" C" [, A7 V. ~/ ]$ f- Z. I
  121.                 sg_LTDC_ConfigData.LayerConfig[0].width = width;        $ i1 G& G, M: r- \7 t' u4 C
  122.                 sg_LTDC_ConfigData.LayerConfig[0].height = height;        
    ( Q2 R* T0 K! z' G, c2 b
  123.         }else) r8 P% X" P: X5 t
  124.         {
    ! f8 w5 n* {, K! K5 r
  125.                 //基本配置
    8 |  q) m4 H  ]% Z( s! U6 e2 Z
  126.                 LTDC_Layer2->CFBAR = FrameBuff;                                                                        //设置层颜色帧缓存起始地址
    3 N% i3 p% h0 p
  127.                 LTDC_Layer2->PFCR = LTDC_PIXEL_FORMAT;                                                        //设置层颜色格式
    ( ]! Z! f- i: _" O. k3 v
  128.                 LTDC_Layer2->CACR = Alpha;                                                                                //常数 Alpha,255分频;设置255,则不透明
    4 w. L, o" y3 u9 P
  129.                 LTDC_Layer2->DCCR = 0x00;                                                                                //设置默认颜色:透明的黑色  U- }! E* x" c2 r8 ?
  130.                 LTDC_Layer2->BFCR = ((u32)6<<8)|7;                                                                //设置层混合系数
    : L" I+ l5 ]: \: D
  131.                 //配置窗口
    + n4 \3 _5 {; J) E6 b
  132.                 temp = (sx+width+((LTDC->BPCR&0X0FFF0000)>>16))<<16;
    4 n; d0 Z# h9 T
  133.                 LTDC_Layer2->WHPCR = (sx+((LTDC->BPCR&0X0FFF0000)>>16)+1)|temp;        //设置行起始和结束位置
    & t- k: ]9 e0 N" K( U4 l
  134.                 temp = (sy+height+(LTDC->BPCR&0X7FF))<<16; 0 _7 C/ q  w) E4 p/ Z* z
  135.                 LTDC_Layer2->WVPCR = (sy+(LTDC->BPCR&0X7FF)+1)|temp;                        //设置列起始和结束位置9 z. e4 c' q& ~3 {5 w) k
  136.                 pixformat = LTDC_Layer2->PFCR&0X07;                                                                //得到颜色格式
    ! u. X- v! N2 j" z
  137.                 if(pixformat == 0)temp=4;                                                                                //ARGB8888,一个点4个字节
    4 }: l% F+ b0 N0 M: v
  138.                 else if(pixformat == 1)temp=3;                                                                        //RGB888,一个点3个字节
    7 e# _1 U9 Q* T
  139.                 else if(pixformat == 5||pixformat==6)temp=1;                                        //L8/AL44,一个点1个字节% i% k2 X- X0 ], H* R
  140.                 else temp = 2;                                                                                                        //其他格式,一个点2个字节
    2 y7 j; x+ [' B" q5 e; V3 a
  141.                 LTDC_Layer2->CFBLR = (width*temp<<16)|(width*temp+3);                        //帧缓冲区长度设置(字节为单位)
    9 G# {; O! H9 ?( P, N8 k3 `: Z
  142.                 LTDC_Layer2->CFBLNR = height;                                                                        //帧缓冲区行数设置        . n4 F4 T3 _' {8 s# K" Y
  143.                 . b+ v3 \3 _: V5 y2 K
  144.                 //记录层窗口大小位置信息$ K( A' L6 h/ Z) v# y1 A3 p
  145.                 sg_LTDC_ConfigData.LayerConfig[1].sx = sx;                : v! }% ?# D7 r% @# B, f0 G' q
  146.                 sg_LTDC_ConfigData.LayerConfig[1].sy = sy;        3 j2 \# }" G' G/ l9 j
  147.                 sg_LTDC_ConfigData.LayerConfig[1].width = width;        - B' |5 |* F8 d6 m
  148.                 sg_LTDC_ConfigData.LayerConfig[1].height = height;               
    / A+ S  O2 r4 }+ ?9 {3 \
  149.         }+ \2 Q1 ~" \# T* U
  150. }/ n# N5 U/ E% {
  151. ' @) p2 T8 {$ B9 Y
  152. 4 v4 l! t& X. l8 }: c

  153. : H5 |& f" T2 {5 L% j) Z' [0 S3 y
  154. /*************************************************************************************************************************1 \  h1 n$ t, m/ C0 q7 Q2 n
  155. * 函数        :                        void LTDC_Init(void)
    & D- {0 Y2 \) r7 }! p
  156. * 功能        :                        LTDC 接口初始化* _* Q/ Y$ Y4 V7 v( D) ]- f' ~
  157. * 参数        :                        无
    ) p* O8 n: @1 D& X* ?
  158. * 返回        :                        无
    * E3 [( U  q4 S2 ~, D
  159. * 依赖        :                        底层宏定义
    ( S( A: c$ L7 ^+ r
  160. * 作者        :                        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    0 ?: f' U4 \' O- w
  161. * 时间        :                        2019-09-08
    0 f% n" b: |& w: i
  162. * 最后修改时间 :         2019-09-08
      }# }2 ~3 O$ w0 @0 w' M6 S
  163. * 说明        :                         用于初始化STM32F7 LTDC 接口
    2 v" X! k  l# i* y* c
  164. *************************************************************************************************************************/  
    ) Y7 W' S" o9 [1 m
  165. void LTDC_Init(void)
    : T. ^2 V+ w$ F( p$ [, S& k$ z
  166. {
    . i/ W4 b( G2 Q" d( n2 j+ R1 N
  167.         u32 temp;- g8 D. P* D5 q2 L$ m
  168.         8 E- i/ E4 q2 U5 F2 ?8 U
  169.         SYS_DeviceClockEnable(DEV_LTDC, TRUE);        //LTDC时钟使能+ A- M4 ~/ }  b* v3 p! K  H
  170.         SYS_DeviceReset(DEV_LTDC);                                //STM32F7外设复位6 q+ o- s  }6 A$ P
  171.         SYS_DeviceClockEnable(DEV_GPIOE, TRUE);        //使能GPIOE时钟
    ( z& O  P/ b0 _* _. ~$ x9 D
  172.         SYS_DeviceClockEnable(DEV_GPIOG, TRUE);        //使能GPIOG时钟
    ) r, |. H2 Q  h. |( [
  173.         SYS_DeviceClockEnable(DEV_GPIOJ, TRUE);        //使能GPIOJ时钟( B/ T# e  Q9 [1 O3 K7 D* h
  174.         SYS_DeviceClockEnable(DEV_GPIOK, TRUE);        //使能GPIOK时钟
    + i& A0 u( R& a* y" L9 X% o
  175.         SYS_DeviceClockEnable(DEV_GPIOI, TRUE);        //使能GPIOI时钟2 y* X+ K8 ~4 g* V: X; F

  176. 1 O' L+ d# [, d- E
  177.         5 g/ u/ g$ z! ~- a
  178.         //初始化IO
    $ r* D- \8 H0 E( T4 ?9 J0 ^
  179.         SYS_GPIOx_Init(GPIOE, BIT4, AF_PP_OPU, SPEED_100M);                                                                                //PE40 H+ |  _% t1 R% }# a* V+ ~
  180.         SYS_GPIOx_Init(GPIOG, BIT12, AF_PP_OPU, SPEED_100M);                                                                        //PG12- q6 y4 p% Y# Z( A+ z/ g
  181.         SYS_GPIOx_Init(GPIOJ, 0Xffff&(~BIT12), AF_PP_OPU, SPEED_100M);                                                        //PJ0~11/13/14/15
    - G' r  ~3 z" }) V! z1 c
  182.         SYS_GPIOx_Init(GPIOK, BIT0|BIT1|BIT2|BIT4|BIT5|BIT6|BIT7, AF_PP_OPU, SPEED_100M);                //PK0/1/2/4/5/6/76 p& b8 }+ j6 T. ~! n
  183.         SYS_GPIOx_Init(GPIOI, BIT9|BIT10|BIT14|BIT15, AF_PP_OPU, SPEED_100M);                                        //PI9/10/14/15
    ( P% x+ `' _* i! F, V& ~
  184.         $ c! c& g* m: t. e
  185.         SYS_GPIOx_SetAF(GPIOE, 4, AF14_LTDC);                //PE4,AF14        2 B  J3 I- t$ X( T5 x+ p  O( x
  186.          SYS_GPIOx_SetAF(GPIOG, 12, AF14_LTDC);                //PG12,AF14        ; ]* y7 j) Z; ~6 z8 Y
  187.         SYS_GPIOx_SetAF(GPIOJ, 0, AF14_LTDC);                //PJ0,AF14( p: v5 U, u/ ]- U: r; z2 k
  188.         SYS_GPIOx_SetAF(GPIOJ, 1, AF14_LTDC);                //PJ1,AF14
    0 g& l6 B5 z; M' v$ H  _6 h
  189.         SYS_GPIOx_SetAF(GPIOJ, 2, AF14_LTDC);                //PJ2,AF14! [3 E# [. N8 w
  190.         SYS_GPIOx_SetAF(GPIOJ, 3, AF14_LTDC);                //PJ3,AF14
    7 E) z/ v5 J6 g! C- k% |  |
  191.         SYS_GPIOx_SetAF(GPIOJ, 4, AF14_LTDC);                //PJ4,AF14
    6 y) S* [( s: u' H6 D
  192.         SYS_GPIOx_SetAF(GPIOJ, 5, AF14_LTDC);                //PJ5,AF14
    ' s& b5 k, v* v( B" g
  193.         SYS_GPIOx_SetAF(GPIOJ, 6, AF14_LTDC);                //PJ6,AF14
    0 F4 `' N  V% i* \" V/ k
  194.         SYS_GPIOx_SetAF(GPIOJ, 7, AF14_LTDC);                //PJ7,AF14
    ; F1 F4 C1 J/ i9 c+ |
  195.         SYS_GPIOx_SetAF(GPIOJ, 8, AF14_LTDC);                //PJ8,AF14% h" H0 }9 N8 S" Q+ a
  196.         SYS_GPIOx_SetAF(GPIOJ, 9, AF14_LTDC);                //PJ9,AF14
    ( l4 W4 e; v7 P0 I
  197.         SYS_GPIOx_SetAF(GPIOJ, 10, AF14_LTDC);                //PJ10,AF14
    2 N+ |7 |' J* P8 T
  198.         SYS_GPIOx_SetAF(GPIOJ, 11, AF14_LTDC);                //PJ11,AF14
    $ J5 I" D! `2 y* |, {( ~
  199.         SYS_GPIOx_SetAF(GPIOJ, 13, AF14_LTDC);                //PJ13,AF140 L0 T4 Y3 Z* a
  200.         SYS_GPIOx_SetAF(GPIOJ, 14, AF14_LTDC);                //PJ14,AF14, {4 s+ G  b2 g8 I* Q5 G: C! f# ^
  201.         SYS_GPIOx_SetAF(GPIOJ, 15, AF14_LTDC);                //PJ15,AF14: Q" @+ B4 p; }) A' C
  202.         : n9 v# J( ?: Y$ ^
  203.         SYS_GPIOx_SetAF(GPIOK, 0, AF14_LTDC);                //PK0,AF14
    # u6 g  |( X( z( d6 Z5 H' [5 o
  204.         SYS_GPIOx_SetAF(GPIOK, 1, AF14_LTDC);                //PK1,AF14
    1 G7 ^" w3 i5 y0 u6 X7 U$ o
  205.         SYS_GPIOx_SetAF(GPIOK, 2, AF14_LTDC);                //PK2,AF14/ n4 W7 a8 b  c( r, [
  206.         SYS_GPIOx_SetAF(GPIOK, 4, AF14_LTDC);                //PK4,AF14
    ( i) i! e7 g: {# {" J' i' T
  207.         SYS_GPIOx_SetAF(GPIOK, 5, AF14_LTDC);                //PK5,AF140 d: I. \& t7 w+ C
  208.         SYS_GPIOx_SetAF(GPIOK, 6, AF14_LTDC);                //PK6,AF14# e9 w# a. x: M, ~" }7 R
  209.         SYS_GPIOx_SetAF(GPIOK, 7, AF14_LTDC);                //PK7,AF14$ U0 ^* r6 ~6 Y2 {5 i
  210.         ' F% h6 Y  w$ h2 z/ k4 R" w
  211.          SYS_GPIOx_SetAF(GPIOI, 9, AF14_LTDC);                //PI9,AF14
    3 O0 S8 @  [+ K; |8 X9 T9 h
  212.          SYS_GPIOx_SetAF(GPIOI, 10, AF14_LTDC);                //PI10,AF14
    $ W+ f" ^6 E+ u7 p, D8 Y! F
  213.         SYS_GPIOx_SetAF(GPIOI, 14, AF14_LTDC);                //PI14,AF14# G+ _: T/ G! h) I2 E6 N" O
  214.          SYS_GPIOx_SetAF(GPIOI, 15, AF14_LTDC);                //PI15,AF14
    ) o7 n+ u- z8 K- N3 u9 i, f
  215.         . x) V4 |9 H- H6 \& P: f( z8 n
  216.         LTDC_ClockInit(DefaultLCD_Info.DCLK);                 //设置像素时钟  9Mhz
    $ F7 M( g' T) w: M3 _7 X/ e
  217.         //设置LTDC 全局控制寄存器 (LTDC_GCR)4 Q6 ^. s( `) i5 ]  z
  218.         temp = 0;3 G- O+ E% u8 n& }
  219.         temp |= (DefaultLCD_Info.HSPOL&0x01) << 31;        //水平同步极性
    0 |% p) b$ X; ~) k, E- ^
  220.         temp |= (DefaultLCD_Info.VSPOL&0x01) << 30;        //垂直同步极性% ~+ `, g$ Y0 R; Y) @
  221.         temp |= (DefaultLCD_Info.DEPOL&0x01) << 29;        //数据使能极性& n3 V% W, Y4 v3 N# ~: P2 [8 g
  222.         temp |= (DefaultLCD_Info.PCPOL&0x01) << 28;        //像素时钟极性
    3 O9 C; i3 D  A5 L5 K' E. n9 }
  223.         LTDC->GCR = temp;+ J5 @3 a( o7 ^- j: K
  224.         //LTDC 后沿配置寄存器 (LTDC_BPCR)# E3 C& u* {' U5 ~  S  X4 \
  225.         temp = (DefaultLCD_Info.Tvw + DefaultLCD_Info.Tvbp - 1) << 0;        //这些位定义累加水平后沿宽度(水平同步像素加水平后沿像素减 1)。9 p9 j3 T, G( c6 m/ G* V
  226.         temp |= (DefaultLCD_Info.Thw + DefaultLCD_Info.Thbp - 1) << 16;        //这些位定义累加垂直后沿宽度(垂直同步行加垂直后沿行减 1)。
    ( s  r$ B% q! J: O1 s
  227.         LTDC->BPCR=temp;        8 K+ |& y+ M, H4 }: }/ E8 b4 h
  228.         : K7 C  C9 ?- h' _1 M6 d$ [
  229.         //LTDC 有效宽度配置寄存器 (LTDC_AWCR)
    ' v& z( C2 U; V! u* \" q
  230.         temp=(DefaultLCD_Info.Tvw+DefaultLCD_Info.Tvbp+DefaultLCD_Info.Height-1)<<0;        //累加有效高度=垂直脉宽+垂直后沿+垂直分辨率-1+ N( Z* Q' E* ?4 g6 s% q
  231.         temp|=(DefaultLCD_Info.Thw+DefaultLCD_Info.Thbp+DefaultLCD_Info.Width-1)<<16;        //累加有效宽度=水平脉宽+水平后沿+水平分辨率-15 L; y2 g5 K% Q6 c+ @4 e& K
  232.         LTDC->AWCR=temp;        
    : H0 \5 d" f* z: ]1 H) Z  c' v1 W% @
  233.         //LTDC 总宽度配置寄存器 (LTDC_TWCR)
    . }- Y5 e8 T, D' ]* j
  234.          temp=(DefaultLCD_Info.Tvw+DefaultLCD_Info.Tvbp+DefaultLCD_Info.Height+DefaultLCD_Info.Tvfp-1)<<0;        //总高度=垂直脉宽+垂直后沿+垂直分辨率+垂直前廊-13 C+ ~- ]( N6 k- I% T  D/ @
  235.         temp|=(DefaultLCD_Info.Thw+DefaultLCD_Info.Thbp+DefaultLCD_Info.Width+DefaultLCD_Info.Thfp-1)<<16;        //总宽度=水平脉宽+水平后沿+水平分辨率+水平前廊-1
    " V0 i/ n' V. {" g3 b; x3 K/ s
  236.         LTDC->TWCR=temp;                                ! ]) `7 u3 f" C" i, t) P  t8 f- ^
  237. % w/ t0 Y. ?) A/ u
  238.         //背景设置
    . v. ~2 K6 {! [+ t# r( b! `* x
  239.         LTDC->BCCR=0xffffff;                                //设置背景层颜色寄存器(RGB888格式)6 ~3 S/ o* `7 E
  240.         LTDC_Enable(TRUE);                                        //开启LTDC
    : C( k6 T3 I4 M9 L( a. Z: O$ T
  241.         //初始化层1
    4 L+ Y7 R: d* A) `/ \1 d
  242.         LTDC_SetLayerConfig(0, 0, 0, LTDC_WIDTH, LTDC_HEIGHT, (u32)g_LTDC_BUFF_RGB888[0], 255);
    + o, B3 V4 b6 @/ Y/ e" a, r- J
  243.         //初始化层2
    + [/ k- d9 d3 S7 K3 O
  244.         LTDC_SetLayerConfig(1, 0, 0, LTDC_WIDTH, LTDC_HEIGHT, (u32)g_LTDC_BUFF_RGB888[1], 255);
    . u( `8 h* C) W& E
  245.         LTDC_Clear(0, 0xFF000000);                        //清屏层1-不透明的黑色7 I, V8 u+ F, [# z+ C( }* W! z$ x' s
  246.         LTDC_Clear(1, 0x00000000);                        //清屏层2-透明的黑色) b8 W+ ^8 T- M) q9 _2 E5 m9 }
  247.         LTDC_LayerEnable(0, TRUE);                        //使能层1
    6 p4 i1 M) m: J
  248.         LTDC_LayerRefreshConfig();                        //LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)
    ( M9 b% \9 N/ ]$ y/ b" U
  249.         LCD_DispIoInit();                                        //初始化DISP引脚-启动显示
    % i- I# M/ w! q/ V! ~
  250. }
    ! O$ Q! g# \7 }- a' D" y
  251.   h" j! ?3 o1 c, q; H
  252. /*************************************************************************************************************************
    ) `( v7 c4 x8 h- Q
  253. * 函数                        :        void LTDC_LayerRefreshConfig(void)
    - N! z- C& L7 ?0 N4 ^. J" I0 p
  254. * 功能                        :        LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)" s3 R$ q& a4 J/ L
  255. * 参数                        :        无* B; C* |. C. p2 M% }* o
  256. * 返回                        :        无
    " E# ~4 S% P# h7 x$ T7 Z
  257. * 依赖                        :        底层宏定义
    1 k$ _, ^) Q9 e, L- j, x
  258. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>4 ]* Y; F  M  a! V* y: F  d7 T* |0 V
  259. * 时间                        :        2019-10-29* y. I7 L. a3 R* x& M0 y3 O# M  m8 |
  260. * 最后修改时间         :         2019-10-298 E1 [' @# z; P2 {( }1 L% b. ]
  261. * 说明                        :        修改层配置后必须重新加载,否则不会生效8 e2 o! h% |- L
  262. *************************************************************************************************************************/+ p0 ?& K+ O+ q$ w
  263. void LTDC_LayerRefreshConfig(void); o/ A% E* t0 V0 }6 f
  264. {
    ! \2 _8 _4 q0 @
  265.         LTDC->SRCR|=1<<0;                                                        //重新加载配置-必须重新加载,否则上面的层不会更新,折腾好久才发现,叫啥影子寄存器重载,也不说清楚
    ) l. y- A4 c- S2 o
  266. }) e1 D$ N. K: Q! t6 [- `
  267. / o$ k% @+ @3 l4 u! N  B
  268. /*************************************************************************************************************************
      a3 K5 S8 O# q( |* B9 n
  269. * 函数                        :        void LTDC_Enable(bool Enable)0 w0 q# B( q3 h+ ?+ M. b
  270. * 功能                        :        LTDC使能设置  V6 s. ?3 W! Q4 `1 c
  271. * 参数                        :        Enable:TRUE:使能;FALSE:失能
    . }) W. U: O. `/ x
  272. * 返回                        :        无
    ' {6 M2 l  Q1 b$ b# Y0 \
  273. * 依赖                        :        底层宏定义% R7 Z; C- }4 i5 Y
  274. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>  V' X  G3 L- m5 d) N
  275. * 时间                        :        2019-10-29) e) ^! _, H  F
  276. * 最后修改时间         :         2019-10-29
    - z. S5 N# |* \( I
  277. * 说明                        :        
    ( d) j# B) C( {3 S( b  f2 O
  278. *************************************************************************************************************************/8 C' l0 e1 ]' H
  279. void LTDC_Enable(bool Enable); V% R- I+ p. U6 a1 n! R5 s  Q
  280. {. c# D& E2 |; v9 w* r' V
  281.         if(Enable)
    # G1 V  M" Q1 O; d( D
  282.         {+ w' |+ b4 ~& K
  283.                 LTDC->GCR |= BIT0;                                        //打开LTDC1 z' C: ]" Z( m8 q
  284.         }
    + |  z3 r+ }. C3 Y. j" K  U; D
  285.         else$ i( A, s; p7 r3 u! J/ x7 s) ]: |
  286.         {
    3 a9 s/ Z5 v* @/ M7 u- n  A9 i
  287.                 LTDC->GCR &= ~BIT0;                                        //关闭LTDC
    6 X2 {: o- T& r5 n
  288.         }
    * b! [8 [/ J1 O
  289. }
      Z: x- T4 Q7 ]

  290. , X/ ^/ V+ @. w1 l, ~; R0 u9 u
  291. /*************************************************************************************************************************& F2 H2 d' d( o( k0 l. q
  292. * 函数                        :        void LTDC_LayerEnable(u8 LayerIndex, bool Enable)
    4 J* j% h; a3 C2 ^% [2 q
  293. * 功能                        :        LTDC 层使能设置: Y% g& C8 k+ M2 W9 Y  G! |
  294. * 参数                        :        LayerIndex:层选择0-1;Enable:TRUE:使能;FALSE:失能- z& L& V; h; n. K/ Z. C  i7 L& s' w% ]1 V
  295. * 返回                        :        无
    " b) E6 J7 s& e# U+ V" P; J' z% \
  296. * 依赖                        :        底层宏定义
    1 ~( C- t$ }; O# J$ [1 m
  297. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>) R  L* i; U) f5 T) Y6 O
  298. * 时间                        :        2019-10-29; d/ B  ~" g( u
  299. * 最后修改时间         :         2019-10-29
    * J  Y$ o( S4 {% l6 `0 s
  300. * 说明                        :        
    * Q; g4 I  ?2 L) R. Q5 b+ i
  301. *************************************************************************************************************************/
    2 |2 b% {( e" n/ P4 ~& Z+ H6 u7 r
  302. void LTDC_LayerEnable(u8 LayerIndex, bool Enable)
    0 J" p2 _+ Y& i) Q, ?! H0 ?8 M
  303. {
    % Z  ~4 P" b+ b6 v1 o5 F) v+ |
  304.         if(Enable)' R2 C: L; p# X/ S' G+ y
  305.         {
    - z& A3 ~* J- Z; [+ m  }, r5 E/ {6 k0 Z
  306.                 if(LayerIndex == 0)                                        //层11 I, \7 I" y. e4 m
  307.                 {
    ; G6 T5 G1 L# H$ A7 m& l" U
  308.                         LTDC_Layer1->CR |= BIT0;                //使能层1: m" ]' b3 W0 G3 q. Z4 Y/ f
  309.                 }
    8 n8 r  \, f5 w) G
  310.                 else
    5 J& l- f) a) `
  311.                 {
    1 L# w. T* c( L  a& `
  312.                         LTDC_Layer2->CR |= BIT0;                //使能层2
    ; D) c( F+ y2 I$ p: l
  313.                 }
    0 \3 Y, W9 k( W: k) I3 F6 g
  314.         }" X1 I+ y, s& {( k: x
  315.         else7 O2 f! N" q. }" V% j8 _
  316.         {* h* P+ x! ^' y; G0 M4 Y0 u
  317.                 if(LayerIndex == 0)                                        //层1
    1 J% ~, X$ M+ @7 u% D' L, [
  318.                 {. K' q5 i/ L' d! m
  319.                         LTDC_Layer1->CR &= ~BIT0;                //失能层1
    4 n2 M0 z+ R% Y1 U8 H
  320.                 }
    5 D7 }$ ~% Z3 f. u
  321.                 else
    8 F, q8 C! h/ R
  322.                 {
    $ v7 [, q, }" P" i: g; i' u
  323.                         LTDC_Layer2->CR &= ~BIT0;                //失能层21 s) c! t$ T  k; ?, E* _
  324.                 }
    $ ^0 \- G* t: }+ r
  325.         }0 K- T# T" u2 _9 G
  326. }
    7 e$ d# h; a6 u" h8 N! M# z! K' t
  327. 2 m$ A1 F0 F7 t* S0 I
  328. 1 d+ H3 K. V& {$ O1 ~0 g2 k! z/ \( t

  329. " N6 ?$ t/ i$ O5 l6 f4 H

  330. ; C. o1 ]/ M  C0 a1 e
  331. /*************************************************************************************************************************
    ) p0 ]" o- N' ^4 P5 w
  332. * 函数                        :        bool LTDC_ClockInit(u16 ClockFreq)                        
    & n! g3 k5 W& |# [
  333. * 功能                        :        STM32F7 LTDC时钟初始化" L% ^! M6 @; M) ]9 r6 ~! n: o
  334. * 参数                        :        ClockFreq:时钟频率,2-168MHZ
    ) c. J5 _. h3 C5 a7 E8 O( |* ~6 D
  335. * 返回                        :        是否设置成功
    0 v; g# }1 }; B- |. W) B) B3 Z9 x
  336. * 依赖                        :        底层宏定义
    " m# z+ x9 T' |+ ~) [- M% [7 m
  337. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    6 ^( \4 Q, t! Z+ s6 _: i) m! m
  338. * 时间                        :        2019-10-28. _) d% M0 J3 Y7 r8 h
  339. * 最后修改时间         :         2019-10-28
    & ~+ n1 C' G! k2 |. M  x
  340. * 说明                        :        输入时钟频率在系统主时钟初始化之后就会设置为1MHz,通过设置SAI PLL实现LTDC所需频率,VCO频率范围:49~432
    ' q; V6 m) W+ q. t0 j
  341. *************************************************************************************************************************/
    / d) L1 ~2 A' K( {
  342. bool LTDC_ClockInit(u16 ClockFreq)
    2 _2 |: {: b) Z0 Q) {9 B
  343. {
    7 A, ~$ v$ F( M$ L5 p% L: `1 x
  344.         u32 TimeOut = 0;
    $ c  i4 O7 _9 N3 ?
  345.         u32 VCO;
    9 q1 ~  @/ h9 o, c
  346.         u32 PLLSAIR;                //PLLSAICFGR[30:28]! t& r3 E3 P! h) U& h6 J3 l
  347.         u32 PLLSAIDIVR;                //DCKCFGR1[17:16]$ x0 B4 f, p7 P: f7 m. s. v
  348.         u32 temp;9 y) D( z. m& {* y% f6 E; F
  349.         
    * i9 V% ~1 X$ `. J, x
  350.         if(ClockFreq < 1)ClockFreq = 1;; t/ R0 c% d+ l# S# P9 G$ K( c
  351.         if(ClockFreq > 100) ClockFreq = 100;7 G$ J1 l8 ~0 i
  352.         1 m2 P9 T7 Z% V: G8 j
  353.         RCC->CR &= ~(1<<28);                                                //关闭SAI时钟 - V6 O! L9 D9 V  `6 m. \# \
  354.         TimeOut = 0;' N0 j4 ?& C' {/ a  x' h
  355.         while(RCC->CR&(1<<29))                                                //等待关闭成功7 ^2 Q" v' m: M; Y+ g
  356.         {
    2 D5 F1 h2 U% F+ s1 P7 j
  357.                 nop;0 I, T$ W2 \+ n& `# Y# {
  358.                 TimeOut ++;! \, a& J$ x, f9 ~  D! h, g3 s
  359.                 if(TimeOut > 0xFFFF) return FALSE;                //关闭超时
    9 R4 D6 C) F5 W0 ?% q7 A
  360.         }( L7 H- o4 E4 E2 e
  361.         //计算分频与VCO频率,通过PLLSAICFGR[30:28]可以设置2-7分频+ }- ~, B4 Y/ G) z
  362.         //通过PLLSAICFGR[17:16]可以设置00:2 01:4 10:8 11:16分频
    ' _4 m. i" O( f/ n1 p0 T/ c* z8 G
  363.         //通过PLLSAICFGR[14:6]可以设置为49-432MHz的VCO频率+ B" X; m: b2 `9 k2 R
  364.         if(ClockFreq <= 6)
    ! V  B/ T8 K) \0 n
  365.         {
    . W1 U! U4 |# p2 l0 S! n; P! k
  366.                 PLLSAIR = 4;        //4分频
    : {1 w( T0 B2 X
  367.                 PLLSAIDIVR = 3;        //16分频
    " ?9 ~/ K+ P, m  m
  368.                 VCO = ClockFreq * PLLSAIR * 16;                        //VCO范围:64-384;
      c6 k$ [- a6 U1 A
  369.         }
    ) I# T% f+ @# E1 L
  370.         else if(ClockFreq <= 13)# j: B5 t7 |& V8 s
  371.         {5 [+ K' }2 ^- T+ A
  372.                 PLLSAIR = 4;        //4分频
    + t+ T) N9 ?3 Q" P
  373.                 PLLSAIDIVR = 2;        //8分频
    1 U5 ]+ i: m* U* ^
  374.                 VCO = ClockFreq * PLLSAIR * 8;                        //VCO范围:224-416;6 p; x4 d2 {# z% h1 }  J8 R( t
  375.         }# R/ _) @' s8 n, ]/ U
  376.         else if(ClockFreq <= 26)
      n" z+ n- V0 ^& }. Y
  377.         {  p5 v/ x5 |% f; W1 o# X, G7 D- \
  378.                 PLLSAIR = 2;        //2分频
    8 i) Y' B. o* A: b5 h! D
  379.                 PLLSAIDIVR = 2;        //8分频6 w/ |2 x6 K, T! r9 E6 r. x
  380.                 VCO = ClockFreq * PLLSAIR * 8;                        //VCO范围:224-416;
    4 @! w3 R7 e# I6 s9 e! C7 F9 }
  381.         }
    . G. K0 U+ K, K
  382.         else if(ClockFreq <= 52)9 g, ]$ X; c* Q. N% F( V, o* ]0 x
  383.         {
    0 t* L% h2 `6 g9 F7 k& d1 ^
  384.                 PLLSAIR = 2;        //2分频
    ( R  ~7 E- }( O* e; l' M$ I& @
  385.                 PLLSAIDIVR = 1;        //4分频! @' p* y. L; ^8 _0 N9 ]
  386.                 VCO = ClockFreq * PLLSAIR * 4;                        //VCO范围:216-416;: Q, r6 X6 H3 b3 d" Z, w  h
  387.         }
    ) Z- K& k- q) m+ U
  388.         else if(ClockFreq <= 104)+ z- i6 t  l  P+ B) I- j9 S, N
  389.         {
    / M) Z5 v5 K" {3 k6 I4 P1 U
  390.                 PLLSAIR = 2;        //2分频
    , u9 }% Q' y- S, \
  391.                 PLLSAIDIVR = 0;        //2分频7 g% N$ y8 u7 u: E6 }
  392.                 VCO = ClockFreq * PLLSAIR * 2;                        //VCO范围:212-416;1 [2 ?. ^  h4 q* p' r3 _% z
  393.         }5 ?: t5 Y; \8 E# G
  394.         //设置PLLSAICFGR% u$ P. _& K: q3 r8 A  I
  395.         temp = RCC->PLLSAICFGR;" ~5 A! h# j/ }' k' Y
  396.         temp &= ~((3<<28) | (0x1FF<<6));                        //清除之前的设置/ {- \4 Q, x6 P+ H7 e, I
  397.         temp |= PLLSAIR << 28;                                                //设置分频PLLSAICFGR[30:28], A4 \1 {9 O& I- z5 U& [
  398.         temp |= VCO << 6;                                                        //设置VCO
    & p7 {$ [+ N% f
  399.         RCC->PLLSAICFGR = temp;: o3 x1 B* N6 y; ?
  400.         //设置DCKCFGR1" Q; L' E5 `0 E( ]( e
  401.         temp = RCC->DCKCFGR1;4 P) x" v3 l& m1 D0 F- v0 Y
  402.         temp &= ~(3<<16);                                                        //清除之前的设置; u3 |0 `3 R( h0 r/ B- {8 n
  403.         temp |= PLLSAIDIVR << 16;                                        //设置分频DCKCFGR1[17:16]2 Q1 s* Z( v( Z. ^* n1 e
  404.         RCC->DCKCFGR1 = temp;4 \7 \! o3 d9 p: Q& P
  405.         //启动时钟
    ' R2 R  C' A+ \) f+ {7 q' Y: c# O7 ?
  406.         RCC->CR |= 1<<28;                                                        //启动SAI时钟6 ], W3 E4 i0 j8 Y4 ?* t4 {
  407.         TimeOut = 0;, V* d# e' B5 ^4 P8 `8 [' u
  408.         while((RCC->CR&(1<<29)) == 0)                                //等待开启成功" ^! z# G/ \9 |( r( q; I% f/ C2 a  K
  409.         {
    $ Z! i" ~+ ]( a* u5 E* ?0 u3 D7 g
  410.                 nop;
    & O3 u1 G- ]0 M! r; u0 L8 Q- @
  411.                 TimeOut ++;3 f% M' r9 _$ O
  412.                 if(TimeOut > 0xFFFF) return FALSE;                //开启超时) P0 T# E3 y5 D6 z& ^- Z! }- s
  413.         }' H9 J# W( v& ^" x8 Q! k3 Y3 }' c
  414.         3 x) J. l9 U# Y! T9 Z4 q
  415.         return TRUE;6 U  A$ r' b- }6 ?: k: M+ L, `
  416. }: Y" u0 ?2 {2 h" n0 \; a$ F; A& V0 ]: ]

  417. $ K+ {& X; [! g0 x2 f. M1 _

  418. & _$ U: ~& j5 E
  419. /*************************************************************************************************************************
    + v4 d$ }3 f6 i: n7 b. P7 W
  420. * 函数                        :        void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color)        # {. i- a8 ^" A0 E6 E. {: Q6 [
  421. * 功能                        :        矩形填充(使用DMA2D)
    3 O( U! @5 P) r/ z2 \, W9 F( N
  422. * 参数                        :        LayerIndex:层选择0-1;sx,sy:开始坐标;ex,ey:结束坐标,color:需要填充的颜色
    * }# u3 [, ~# R  @4 g2 t
  423. * 返回                        :        无
    ! M. b) u& m2 X- {7 ?& s2 E& c: l" w
  424. * 依赖                        :        底层宏定义
    ! s* `$ G8 M5 e7 q( d- ?7 C
  425. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    ) H- i( c; D) F; B
  426. * 时间                        :        2019-10-303 ~. D( l# t" G
  427. * 最后修改时间         :         2019-10-30
    * B3 j. y: E7 F; j
  428. * 说明                        :        采用DMA2D实现
    ! i: z! C8 H% c/ @/ h4 d
  429. *************************************************************************************************************************/4 t# X5 `& b7 B# U1 N8 ]8 F
  430. void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color)
    : ?+ ~& S. U8 J/ R5 G2 W
  431. {5 S+ g2 g# ]  o3 H; Z0 `
  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进行单色填充
    & ~% E6 _4 i: X; u
  433.         DMA2D_WaitTransferComplete(500);                                                                                                                                                                                                                                //等待DMA2D传输完成* R+ C1 s: O' G" \4 G" @# X% T$ y
  434. }0 X" X3 E9 H4 N! C2 D7 \  Q' b8 T, j
  435. ' t4 b( e& ~" A2 E  G( }
  436. - v; D* F) d( K$ P! v
  437. /*************************************************************************************************************************. m* B' M8 C3 F. v
  438. * 函数                        :        void LTDC_Clear(u8 LayerIndex,u32 color); \! }1 K* `  Y" Y1 d, ]! i5 C
  439. * 功能                        :        清屏(使用DMA2D)+ k9 |# h. X+ ?
  440. * 参数                        :        LayerIndex:层选择0-1;color:需要填充的颜色
    0 N9 s! d7 ^1 G8 I4 U3 b
  441. * 返回                        :        无  o' W* {8 D- k% R# Z
  442. * 依赖                        :        底层宏定义: M' d$ y  y( T+ }
  443. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>5 }* W, u2 r4 L0 O6 u/ y" V
  444. * 时间                        :        2019-10-306 O, C, d- F' h1 {
  445. * 最后修改时间         :         2019-10-30% X( q- r, L* h$ K7 b$ v# u. `
  446. * 说明                        :        采用DMA2D实现0 O- ^8 x( d1 f( Q6 m
  447. *************************************************************************************************************************/7 i& v5 K; Z9 F; E% a! {0 q) _
  448. void LTDC_Clear(u8 LayerIndex,u32 color)
    + k8 p! _, {4 z8 h0 z) T
  449. {% s8 @0 l; [8 d! ~
  450.         DMA2D_FillColorToFGRAM((u32)&g_LTDC_BUFF_RGB888[LayerIndex][0][0], LTDC_WIDTH, LTDC_HEIGHT, 0,  DMA2D_COLOR_ARGB8888, color);                                        //DMA2D进行单色填充
    5 K  D5 K7 I# O' u
  451.         SYS_DelayMS(5);
    ) B3 n# C( f$ r! \
  452.         DMA2D_WaitTransferComplete(500);                                                                                                                                                                                                                                //等待DMA2D传输完成
    . Z: j2 J, u1 j. T0 G
  453. }0 O  q  b$ x& `
  454. : a" r* b+ R& _3 |' O9 p

  455. ' j( K( V* \) }2 P/ p  j
  456. /*************************************************************************************************************************3 r) l5 n% @* T0 x* L% ~% d
  457. * 函数                        :        void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr)
    4 k* `' H/ [' N1 I$ ~; S# J# t
  458. * 功能                        :        矩形图像填充(相同坐标范围传输,要求源图像与目标显示器分辨率一致,使用DMA2D)2 k" q6 [3 l' B) O, T
  459. * 参数                        :        LayerIndex:层选择0-1;sx,sy:开始坐标;ex,ey:结束坐标,ImageAddr:需要填充的图像地址# _+ F6 {% U+ c5 _. H$ A# E
  460. * 返回                        :        无9 Q' ]3 C% m* c4 d! {5 E* G: X
  461. * 依赖                        :        底层宏定义
    % m# @( z6 ~# v3 m4 g
  462. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    $ ^, r6 r1 t0 }7 R' Y8 S
  463. * 时间                        :        2019-10-30' u9 S8 B0 b2 ^2 O0 W) ~/ A) |
  464. * 最后修改时间         :         2019-10-30
    3 {$ U1 @5 g  T& X2 X: i: G0 H. p0 ]
  465. * 说明                        :        采用DMA2D实现,将源图像指定位置传输到现存,要求源图像与显存大小一致% F+ S! H2 A, x9 Y; X, h" J8 N* v
  466. *************************************************************************************************************************/
      `7 v3 n, a9 U! A9 U- O9 z$ ^1 L+ r5 ~
  467. void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr)) K- s: C" c) R
  468. {
      G. ]4 g" @) w& B2 _
  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进行矩形图形填充' o. W/ Q$ Y; }0 Y
  470.         DMA2D_WaitTransferComplete(500);
    % m- {6 ^8 F" `
  471. }
复制代码
  1. /*************************************************************************************************************' |; K1 p$ L. G+ \  }9 G9 b
  2. * 文件名                :        stm32f7_ltdc.h/ e; k) P" Q% n$ D+ V8 C$ G- V
  3. * 功能                        :        STM32F7 外部RGB LCD驱动
    3 u: M8 P6 |" D9 y+ ?' X8 h) S
  4. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>0 t0 }" x3 |; g: a' Z" c$ {+ L+ k
  5. * 创建时间                :        2019-09-12: S8 f& W* ]( p0 `- J2 C
  6. * 最后修改时间        :        2019-09-120 e! L" r% ^/ H; j( e
  7. * 详细:        9 X+ c* {5 P7 y3 q* u1 S3 K
  8. *************************************************************************************************************/                / ?/ b8 Q+ p1 D! f  t, n% o, x0 \
  9. #ifndef __STM32F7_LTDC_H_
    . _7 L% v; }7 D5 ]. G5 q) M
  10. #define        __STM32F7_LTDC_H_           " T, D7 {+ l, y; W) v. k
  11. #include "system.h"
    ' `  _8 |$ _6 d
  12. #include "DMA2D.h"
    5 q0 A. p" F; W6 K( S/ `& P

  13. 5 l) G" e* |( A0 A8 |
  14. #define LTDC_WIDTH                480
    % x" w' h" w+ K$ U  t
  15. #define LTDC_HEIGHT                2720 q- S2 j* O5 d" a) ^2 T

  16. 9 ]: h0 d1 z* w. N! t8 u0 d0 }
  17. 0 K$ @% b! i" S- A) \
  18. extern u32 g_LTDC_BUFF_RGB888[2][LTDC_HEIGHT][LTDC_WIDTH];
    * k* w9 V# [5 h  @$ e& l

  19. ) B7 g3 F. t7 |5 L% |
  20. //像素格式定义
    7 q" {- d0 s1 p' j$ B* ^: _
  21. typedef enum& n+ ]. f- I3 f; y: [4 ?
  22. {
    + I1 T$ V: n8 u) x
  23.         LTDC_ARGB8888         = 0,( U. u: A  u* M- A
  24.         LTDC_RGB888         = 1,4 V5 v) b/ `6 O; u) O. y
  25.         LTDC_RGB565         = 2,# ~% A: g5 s8 v) J! K
  26.         /*LTDC_ARGB1555         = 3,9 Z3 G2 ?5 H) ~  ^' Q
  27.         LTDC_ARGB4444         = 4,
    . Q3 l# E4 Q& |8 w9 |  L$ d* f
  28.         LTDC_L8                 = 5,        //8 位 Luminance
    / E: b2 w# ], Y3 W& M, T
  29.         LTDC_AL44                 = 6,        //4 位 Alpha,4 位 Luminance
    + f1 R+ N9 [5 v% V: W
  30.         LTDC_AL88                 = 7,        //8 位 Alpha,8 位 Luminance*/5 X0 y3 b& P4 y, S7 x. f" T
  31. }LTDC_PixelFormat;. X  [1 d. O' {
  32. #define LTDC_PIXEL_FORMAT                LTDC_ARGB8888                //选择ARGB8888格式
    2 ]9 f# m* f( z6 P1 h
  33. 9 ^1 Y: h  _' N% v: O( l
  34. ( h4 {6 Z7 \2 v8 {# d& |' B/ d

  35. & W" q6 E# V6 b( m

  36. 1 E' ?* q1 k9 e
  37. //画点函数32bit ARGB8888格式/ r/ M* u' O! t
  38. __inline void LTDC_DrawPoint(u8 LayerIndex, u16 Xpos,u16 Ypos,u32 ARGB8888_Color)
    ! h" t. a0 g1 C4 x) g; `: @
  39. {
    ! q: P4 a* N+ w+ f$ z
  40.         g_LTDC_BUFF_RGB888[LayerIndex][Ypos][Xpos] = ARGB8888_Color;
    " j# h1 k3 c. g0 |' y; X1 X$ S
  41. }; }. \3 C+ F$ t: d4 B

  42. 8 k( G8 P5 T; n6 o& `0 C
  43. //初始化DISP引脚2 r/ N) V3 |3 q; _' N- [
  44. __inline void LCD_DispIoInit(void)
    / S) K: D( N) m; X6 q9 o  v
  45. {. p( T/ Z: s+ a
  46.         SYS_GPIOx_Init(GPIOI, BIT12, OUT_PP, SPEED_25M);                                                                                                //PI12 LCD_DISP H:正常模式;L:低功耗                                                        
    # q/ Z4 o3 ?1 n% r5 A) E3 y2 c
  47.         PIout(12) = 1;                                                                                                                                                                        //DISP = H  2019-10-16:一直忽略将此引脚置为高电平,调试走了很多弯路9 D6 ?% }5 Z6 q; V: M6 D! k  X, h
  48. }/ \, P/ B7 w4 L) t
  49. # i% @( `/ l# l
  50. void LTDC_Enable(bool Enable);                                                                                                                                                //LTDC使能设置5 ^' ?5 S) Q, `" H) W
  51. void LTDC_Init(void);                                                                                                                                                                //LTDC 接口初始化
      W9 b. \- ^6 |9 z; _4 A
  52. void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha);//LTDC 层窗口尺寸设置! @' b' J. ~" |
  53. void LTDC_LayerEnable(u8 LayerIndex, bool Enable);                                                                                                        //LTDC 层使能设置
    8 l, c- O/ d/ h- V6 z0 s
  54. void LTDC_LayerRefreshConfig(void);                                                                                                                                        //LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)
    8 G! L! H/ p$ G% [; ^0 G

  55. ' I+ z  Y& I/ i( X& g% {' p! y5 x2 x
  56. //图形相关API3 m  i: e( S& e, U
  57. void LTDC_DrawPoint(u8 LayerIndex, u16 Xpos,u16 Ypos,u32 ARGB8888_Color);                                                        //画点函数32bit ARGB8888格式
    6 e. Q! D: l8 \! l
  58. void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color);                                                                //矩形填充(使用DMA2D)
    ; Q/ b! k  U% F2 m, m
  59. void LTDC_Clear(u8 LayerIndex,u32 color);                                                                                                                        //清屏(使用DMA2D)
    " }0 B0 p# }/ ]

  60. % \# |8 I* z9 {/ @
  61. void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr);//矩形图像填充(相同坐标范围传输,要求源图像与目标显示器分辨率一致,使用DMA2D)
复制代码

6 X& n3 w8 C& Z9 Y  ~# c; S
9 O6 G  q, N/ I0 O" J# I6 K/ i, V#endif //__STM32F7_LTDC_H_6 ]; F! A6 V7 x, [7 P) W" M4 c+ j

2 {2 \2 F- Q& R* e6 D! a' f* F
8 j3 w: h5 j! j  i) M7 G8 P3 I/ h
! z6 _; h9 T! }2 ~' J# H
收藏 评论0 发布时间:2021-12-14 10:49

举报

0个回答

所属标签

相似技术帖

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