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

【经验分享】STM32f746gdiscovery LTDC 驱动

[复制链接]
STMCU小助手 发布时间:2021-12-14 10:49
需要提前准备好SDRAM驱动,如果没有SDRAM可以进行纯色彩测试,底层时钟,IO操作相关看注释,我使用的是寄存器封装的。) K( q& \/ f4 M: i6 |* s

9 i( L- F5 Z- M: H
  1. /*************************************************************************************************************
    / Y9 o: T8 |9 H- I; K: U- z
  2. * 文件名                :        stm32f7_ltdc.c1 r! Z' g/ @4 t7 d( d
  3. * 功能                        :        STM32F7 外部RGB LCD驱动
    3 u! A7 u* z2 {+ c
  4. * 创建时间                :        2019-09-120 a2 b/ K1 C! P! ?7 ?- k1 u
  5. * 最后修改时间        :        2019-09-12
    6 ], Y3 |: h8 s( C
  6. * 详细:        ( u& ^' k) [5 K" n  h6 g4 w
  7. *************************************************************************************************************/        
    ( N  @  H! E( r" ?2 e5 |! m, g. _' F$ K
  8. #include "stm32f7_ltdc.h"! J$ l; u( I# m$ v# X
  9. #include "SYSTEM.H" % j5 L" o8 f+ l3 L7 M8 {
  10. #include "stm32f7_sdram.h"' l1 Z) z+ {5 j" P- e
  11. #include "DMA2D.h"
    ; w6 h. [+ |! G, i2 m  m) @' w
  12. ! K; A' L/ R9 R1 q& O) |8 w0 x2 y

  13. : E  G4 y  U8 E' x
  14. u32 g_LTDC_BUFF_RGB888[2][LTDC_HEIGHT][LTDC_WIDTH]  __attribute__ ((at(Bank5_SDRAM_ADDR)));                //需要SDRAM支持,LCD帧缓冲区,RGB888格式1 V) l9 f/ W4 ^' m5 g
  15. 2 q9 @( f9 b( |3 A

  16. 1 T+ ~, g* L5 c* c& f  c& r
  17. //记录全局层配置信息1 [  Q! x$ j4 n! A4 C
  18. typedef struct, P+ c4 E) P- G+ ?0 z
  19. {9 g2 D# U9 l: ~: ]) [2 v# P
  20.         u16 sx;                                        //层开始X坐标,从0开始' {4 s  i: Y7 L% f* d, o7 ~  ]
  21.         u16 sy;                                        //层开始Y坐标,从0开始
    % y8 Z$ j! p' k  M* E. o: c
  22.         u16 width;                                //层宽度8 j5 _  O, l( J; K# \- z
  23.         u16 height;                                //层高度
    1 D) c- {* c' s- T* l5 e6 M1 C
  24.         u32 *pFrameBuff;                //帧缓冲区指针,需要进行初始化
    9 h. a& P+ |4 ?$ V1 J  F2 q# P
  25. }LTDC_LayerConfig;" O) S- @9 n- [$ _6 n% Q

  26. + i/ ]* j# M7 D7 \1 W( A

  27. / X9 n: D% P3 O# k

  28. 0 I+ ^/ C9 X8 l
  29. //全局的LTDC配置信息
    4 v" p3 Q6 M- {) d2 A- ^
  30. typedef struct
      g6 n# K2 Y9 U9 t/ I+ [  W
  31. {' |  d) f: v3 J
  32.         u16 lcd_width;                                                //显示器宽度# P# j/ h% D; g3 d9 j6 {
  33.         u16 lcd_height;                                                //显示器高度/ w6 p% k6 P' [; M  ^
  34.         LTDC_LayerConfig LayerConfig[2];        //层信息
    + _  l7 ~6 H8 [' Y* q# Z
  35. }LTDC_ConfigData;
    : K+ o2 q( \2 t9 P9 S) A% h
  36. & H* ]$ b2 O1 E' q5 q

  37.   A3 T7 x$ q2 S  j7 O8 m+ W
  38. static LTDC_ConfigData sg_LTDC_ConfigData;        //记录全局的LCD配置8 X1 ?' `$ v& M
  39. 9 u& G8 D( w, t; N3 T/ Y( @

  40. : d; k) W8 Y/ k5 h! S, A4 n9 ]% G
  41. //显示屏信息
    - w- {% y( b( ^5 P( E
  42. typedef struct$ z+ |$ f  b4 q/ ~$ ^
  43. {  G1 T2 R6 c% a/ B/ N
  44.         u16         Width;                //面板宽度,单位:像素
    8 v6 r) G- G! k9 w8 w
  45.         u16         Height;                //面板高度,单位:像素
    4 N+ K1 u6 U$ O
  46.         u8          Thbp;                //水平后廊
    0 f( H2 y0 Z9 N- z( c
  47.         u8          Thfp;                //水平前廊5 h7 N. n# W+ ^
  48.         u8          Thw;                //水平同步宽度) A# I9 r$ l8 j$ A( ?$ ~3 X7 `
  49.         u8          Tvbp;                //垂直后廊' Q6 ^. z! L- o: ~/ f
  50.         u8          Tvfp;                //垂直前廊( }/ z6 d  b0 D
  51.         u8          Tvw;                //垂直同步宽度
    : ?: P6 k* e+ Q3 J3 X3 E8 j
  52.         u8          DCLK;                //时钟速度,MHz2 |  q* q( P$ s/ h& k
  53.         
    6 W1 e8 `0 S" v1 ^
  54.         u8                HSPOL;                //水平同步极性,0:低电平有效;1:高电平有效
    ( P8 O& s% [0 t9 f' D7 W
  55.         u8                VSPOL;                //垂直同步极性,0:低电平有效;1:高电平有效
    $ g/ v- N9 q+ o; [/ ~, A4 o
  56.         u8                DEPOL;                //数据使能极性,0:低电平有效;1:高电平有效# f5 V8 D9 e+ J1 Z
  57.         bool        PCPOL;                //像素时钟反向
    1 P9 _& _! w& L! O% ^# ?
  58. }LTDC_INFO_TYPE;
    4 E5 b) c5 W; N  ^" T9 U

  59. # h9 B* j" k4 C) H6 h( H

  60. . \. `0 H2 G8 M" B
  61. LTDC_INFO_TYPE DefaultLCD_Info =6 W, G. F6 a# U
  62. {2 R5 U# O( u5 f- F
  63.         480,        //面板宽度,单位:像素
    $ k1 p- J9 D) P  n& F( ^
  64.         272,        //面板高度,单位:像素
    ' c9 ^9 G1 J# L1 T( J3 ^4 G
  65.         41,                //水平后廊
    ) t5 t7 T' `( D
  66.         8,                //水平前廊
    & H- v% `$ s9 B& @
  67.         2,                //水平同步宽度
    6 Y* g4 r$ Y5 L
  68.         2,                //垂直后廊
    1 o3 n+ Y& `: ]: W+ C( t1 C6 U8 S
  69.         4,                //垂直前廊
    . X$ b, m! W- P! I, Q9 B0 g* b
  70.         10,                //垂直同步宽度
    * N: F4 W4 b4 U" K& C
  71.         9,                //时钟速度,MHz
    6 p/ b( i: i  E! B0 ^' d" A
  72.         0,                //水平同步极性,0:低电平有效;1:高电平有效0 O: {5 u1 M' A- G  ]# r$ e6 Q
  73.         0,                //垂直同步极性,0:低电平有效;1:高电平有效
    6 v; C: i( L# B" r" t, s# F& t' a, X- b
  74.         1,                //数据使能极性,0:低电平有效;1:高电平有效, [3 A/ Q2 B* ^) S2 |  s5 k0 }/ s3 X
  75.         FALSE,        //像素时钟反向; ]% }3 ~; M1 ?. f
  76. };2 i- n5 g# E6 D4 c2 a" z
  77. 9 Y9 s, K; v" j
  78. bool LTDC_ClockInit(u16 ClockFreq);                                                        //STM32F4 LTDC时钟初始化3 g# l) P0 ?& g6 ?) }, K
  79. 0 |8 [0 L0 d2 K0 h
  80. 2 R1 B; [8 H( C
  81. /*************************************************************************************************************************! y  f; F1 ~+ P$ O( C/ F) N
  82. * 函数        :                        void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha)
    0 Z0 B; k0 W5 X, c- l
  83. * 功能        :                        LTDC 层窗口尺寸设置(会自动根据窗口尺寸以及像素格式设置帧缓冲区大小)
    6 I: S0 r' q3 A+ J+ D" [
  84. * 参数        :                        LayerIndex:层选择(0-1);sx,sy:起始坐标;width,height:宽度和高度( \' x4 Q+ K3 Q7 J* d
  85. * 返回        :                        无: m3 k5 [/ S/ a' {& Y
  86. * 依赖        :                        底层宏定义4 C5 N; }/ j% h- D/ `. x
  87. * 作者        :                        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    , Z% |  q& P8 B1 s8 A6 l0 G
  88. * 时间        :                        2019-10-28
    9 N: d( @* E; s0 r) g: E: Z
  89. * 最后修改时间 :         2019-10-28: n# I; g- e. H' V1 y; m, J
  90. * 说明        :                         不会使能层,不会更新层,只设置配置,需要刷新层配置后更新
    ' \& R: _' ^3 [2 T3 m
  91. *************************************************************************************************************************/ * L/ O& t& h( j  Z) d  V
  92. void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha)
    . J* W6 O4 @5 i9 _2 z5 P) n- S
  93. {) H' e# L! m/ C  d: y% B
  94.         u32 temp;
    - T6 b$ }2 @, Y6 y1 r; F
  95.         u8 pixformat=0; ! T: S9 ^8 l& ~3 l
  96.         * ]! L8 n% H9 z2 g6 W  O
  97.         if(LayerIndex==0)) ]) X, [/ k' x# E, h
  98.         {
    3 p5 G3 W' D4 A/ J9 S( h; I1 D% @
  99.                 //基本配置2 Z4 o& h9 P1 T3 v+ [
  100.                 LTDC_Layer1->CFBAR = FrameBuff;                                                                        //设置层颜色帧缓存起始地址
    & O2 _! s/ j; j* q$ S4 _
  101.                 LTDC_Layer1->PFCR = LTDC_PIXEL_FORMAT;                                                        //设置层颜色格式8 n- E- Z+ J, z* @; v
  102.                 LTDC_Layer1->CACR = Alpha;                                                                                //常数 Alpha,255分频;设置255,则不透明
    , M0 l. q/ v8 a+ K) b( w1 Y
  103.                 LTDC_Layer1->DCCR = 0x00;                                                                                //设置默认颜色:透明的黑色+ h4 k4 F/ T; L& T+ [
  104.                 LTDC_Layer1->BFCR = ((u32)6<<8)|7;                                                                //设置层混合系数
    4 e& e; Y8 N# w9 [0 k, v/ [& T3 a
  105.                 //配置窗口! \- m( d. X( z+ y! F
  106.                 temp = (sx+width+((LTDC->BPCR&0X0FFF0000)>>16))<<16;
    & k6 w2 j$ X! K$ I
  107.                 LTDC_Layer1->WHPCR = (sx+((LTDC->BPCR&0X0FFF0000)>>16)+1)|temp;//设置行起始和结束位置 " Q0 L* ?, q; _' _" M
  108.                 temp = (sy+height+(LTDC->BPCR&0X7FF))<<16; ; F( I4 b7 c- e* j: E& A$ O: a
  109.                 LTDC_Layer1->WVPCR = (sy+(LTDC->BPCR&0X7FF)+1)|temp;                        //设置列起始和结束位置
    / L% Y$ H4 z( z, a
  110.                 pixformat = LTDC_Layer1->PFCR&0X07;                                                                //得到颜色格式
    " r$ O4 v+ Y  r( [( P) B
  111.                 if(pixformat == 0)temp=4;                                                                                //ARGB8888,一个点4个字节2 ]# ^9 n' M# Z
  112.                 else if(pixformat == 1)temp=3;                                                                        //RGB888,一个点3个字节
    $ |! b- \/ o  I, V: T$ p
  113.                 else if(pixformat==5||pixformat==6)temp=1;                                                //L8/AL44,一个点1个字节
    ' \% z$ ]9 m8 m- c6 {* V, t& V
  114.                 else temp=2;                                                                                                        //其他格式,一个点2个字节
    8 F. A% H+ T0 \
  115.                 LTDC_Layer1->CFBLR = (width*temp<<16)|(width*temp+3);                        //帧缓冲区长度设置(字节为单位); n! u) r* a$ Y! p* o% t/ `$ C
  116.                 LTDC_Layer1->CFBLNR = height;                                                                        //帧缓冲区行数设置        
    ; W1 n0 L. L8 w" Q4 I4 [$ S
  117.                
    ( _& @9 [& P) p* l3 T
  118.                 //记录层窗口大小位置信息
    ! I- A' `3 F$ U1 T
  119.                 sg_LTDC_ConfigData.LayerConfig[0].sx = sx;                ' A3 Z' G/ f( W4 f
  120.                 sg_LTDC_ConfigData.LayerConfig[0].sy = sy;        2 }  F& e  M, [" F; z$ t4 s6 t! J3 P
  121.                 sg_LTDC_ConfigData.LayerConfig[0].width = width;        - Z4 B" _$ C/ `3 y: H8 [2 ]
  122.                 sg_LTDC_ConfigData.LayerConfig[0].height = height;        & @: H$ B+ H0 B" P8 t
  123.         }else
    8 f7 e' {& p8 S+ f: Q
  124.         {
    " s. \) K" @5 L; K% E
  125.                 //基本配置0 @6 W3 j( Q: V! [
  126.                 LTDC_Layer2->CFBAR = FrameBuff;                                                                        //设置层颜色帧缓存起始地址
    , R7 Y: s, {' I* F% P
  127.                 LTDC_Layer2->PFCR = LTDC_PIXEL_FORMAT;                                                        //设置层颜色格式
    8 s: O: z0 a% z; s: V' ?8 b& g
  128.                 LTDC_Layer2->CACR = Alpha;                                                                                //常数 Alpha,255分频;设置255,则不透明
    4 J$ e" Q4 ^1 W" h/ \
  129.                 LTDC_Layer2->DCCR = 0x00;                                                                                //设置默认颜色:透明的黑色* k* b" W, {3 w
  130.                 LTDC_Layer2->BFCR = ((u32)6<<8)|7;                                                                //设置层混合系数* L3 g  X- ]; g1 [
  131.                 //配置窗口
    , y4 }) S9 U) U' \9 m0 d
  132.                 temp = (sx+width+((LTDC->BPCR&0X0FFF0000)>>16))<<16; 0 o5 Y# h- a" [. W+ V9 M
  133.                 LTDC_Layer2->WHPCR = (sx+((LTDC->BPCR&0X0FFF0000)>>16)+1)|temp;        //设置行起始和结束位置
    # B; `5 E' H7 k% w
  134.                 temp = (sy+height+(LTDC->BPCR&0X7FF))<<16;
    9 i! v6 R+ N" {$ V5 n0 z
  135.                 LTDC_Layer2->WVPCR = (sy+(LTDC->BPCR&0X7FF)+1)|temp;                        //设置列起始和结束位置
    . x9 A9 n; y1 X. y8 k# |: M0 P' M6 F
  136.                 pixformat = LTDC_Layer2->PFCR&0X07;                                                                //得到颜色格式* W# p$ l. D+ D; q9 z2 u' I
  137.                 if(pixformat == 0)temp=4;                                                                                //ARGB8888,一个点4个字节4 H& |. s! S, E  y7 i* N0 Z& ]- B: J6 x) O
  138.                 else if(pixformat == 1)temp=3;                                                                        //RGB888,一个点3个字节# G- O# u1 |2 |% g
  139.                 else if(pixformat == 5||pixformat==6)temp=1;                                        //L8/AL44,一个点1个字节
    # }: C& v8 c+ y6 ]% {
  140.                 else temp = 2;                                                                                                        //其他格式,一个点2个字节
    " \# G7 W! g6 w8 u' o* ]- H
  141.                 LTDC_Layer2->CFBLR = (width*temp<<16)|(width*temp+3);                        //帧缓冲区长度设置(字节为单位), |' i% A9 D5 T9 j7 L% K1 C+ W" c
  142.                 LTDC_Layer2->CFBLNR = height;                                                                        //帧缓冲区行数设置        
    9 {% e- D' o9 j6 S: N, R0 p, @' d2 T
  143.                 8 d7 ]* M: q: n/ u# l0 |! H
  144.                 //记录层窗口大小位置信息# [2 i. j4 t1 T# z
  145.                 sg_LTDC_ConfigData.LayerConfig[1].sx = sx;               
    5 K: A7 q8 H& G8 F
  146.                 sg_LTDC_ConfigData.LayerConfig[1].sy = sy;        
    3 H0 X& v7 b' l+ L$ e$ Q
  147.                 sg_LTDC_ConfigData.LayerConfig[1].width = width;        ' `" U  P+ C% D0 \
  148.                 sg_LTDC_ConfigData.LayerConfig[1].height = height;               
    7 F6 D. {% |+ G: w2 \) f
  149.         }" X1 G0 M: d: N7 C
  150. }
    + x3 d6 w, u. ~% w

  151. ; @! P; X4 x, {: l8 T0 y
  152. - B  o, u8 v1 S' U4 L8 U- `
  153. 7 I2 d( o* ^6 D7 U5 }: N
  154. /*************************************************************************************************************************
    * {% W0 j) D8 ]' W6 v6 m) c& L/ t
  155. * 函数        :                        void LTDC_Init(void)
    3 \: v  b5 H) X! D
  156. * 功能        :                        LTDC 接口初始化
    3 H: C9 N0 ^- F5 \* S9 @) Y
  157. * 参数        :                        无1 b( F5 J" l. n3 O
  158. * 返回        :                        无
    & M- R, ^  u# w; c& X
  159. * 依赖        :                        底层宏定义0 R) |% }* N: G
  160. * 作者        :                        <a href="mailto:cp1300@139.com">cp1300@139.com</a>7 ]) w; Y' ~/ R
  161. * 时间        :                        2019-09-083 S7 g' F) U( v1 o
  162. * 最后修改时间 :         2019-09-08; F6 R1 l- J& h" J. e# W* [
  163. * 说明        :                         用于初始化STM32F7 LTDC 接口$ O7 ?4 z5 U6 q
  164. *************************************************************************************************************************/  - V4 q  X' q5 |) F. u* ?1 o
  165. void LTDC_Init(void)4 x! z# C, F6 a0 `6 R+ _
  166. {
    7 y8 _+ n( |3 K8 H
  167.         u32 temp;. _) s" e$ k4 s' F( [2 u
  168.         
    : U9 H/ F8 Q2 e3 W( n9 K, i5 `5 k
  169.         SYS_DeviceClockEnable(DEV_LTDC, TRUE);        //LTDC时钟使能, V7 c. R5 i( r- N8 I
  170.         SYS_DeviceReset(DEV_LTDC);                                //STM32F7外设复位) V  q/ n$ l7 y3 k
  171.         SYS_DeviceClockEnable(DEV_GPIOE, TRUE);        //使能GPIOE时钟
    : f1 }. G) `' |* I/ `
  172.         SYS_DeviceClockEnable(DEV_GPIOG, TRUE);        //使能GPIOG时钟$ `! O) t$ r' ^) s
  173.         SYS_DeviceClockEnable(DEV_GPIOJ, TRUE);        //使能GPIOJ时钟7 O$ E+ P% P+ ?5 O% w* x
  174.         SYS_DeviceClockEnable(DEV_GPIOK, TRUE);        //使能GPIOK时钟3 [% f$ g; g8 o* _9 r1 d- E
  175.         SYS_DeviceClockEnable(DEV_GPIOI, TRUE);        //使能GPIOI时钟
    ; [5 ]9 t8 g, R5 p1 l6 O3 q
  176. / C! J5 z7 S% `6 v7 h$ P6 \
  177.         
    ) T, i$ ^: v, `' g9 H
  178.         //初始化IO
    6 N( ^) H4 l! v( j$ h
  179.         SYS_GPIOx_Init(GPIOE, BIT4, AF_PP_OPU, SPEED_100M);                                                                                //PE4
    & `! k, v' k% k7 r" a3 `" U
  180.         SYS_GPIOx_Init(GPIOG, BIT12, AF_PP_OPU, SPEED_100M);                                                                        //PG120 u* \. ]# E) s9 W1 n# K+ n$ |
  181.         SYS_GPIOx_Init(GPIOJ, 0Xffff&(~BIT12), AF_PP_OPU, SPEED_100M);                                                        //PJ0~11/13/14/15
    : G& Y3 R" r! z0 _
  182.         SYS_GPIOx_Init(GPIOK, BIT0|BIT1|BIT2|BIT4|BIT5|BIT6|BIT7, AF_PP_OPU, SPEED_100M);                //PK0/1/2/4/5/6/7' a7 b0 ^) l4 r( m
  183.         SYS_GPIOx_Init(GPIOI, BIT9|BIT10|BIT14|BIT15, AF_PP_OPU, SPEED_100M);                                        //PI9/10/14/15  n# V  s0 m( K! c4 @
  184.         / }3 ]1 x9 G/ [- Z
  185.         SYS_GPIOx_SetAF(GPIOE, 4, AF14_LTDC);                //PE4,AF14        7 y7 X: T* B- X% e) }
  186.          SYS_GPIOx_SetAF(GPIOG, 12, AF14_LTDC);                //PG12,AF14        : A( }0 i4 G$ U, N+ j
  187.         SYS_GPIOx_SetAF(GPIOJ, 0, AF14_LTDC);                //PJ0,AF14
    $ j' `2 M* ~1 Z! m: `$ x/ t
  188.         SYS_GPIOx_SetAF(GPIOJ, 1, AF14_LTDC);                //PJ1,AF14
    , @# {% f% F% m$ j- O0 j6 z
  189.         SYS_GPIOx_SetAF(GPIOJ, 2, AF14_LTDC);                //PJ2,AF14
    . P& Z5 J$ {7 o! J" n
  190.         SYS_GPIOx_SetAF(GPIOJ, 3, AF14_LTDC);                //PJ3,AF146 ^4 I4 v9 `, e$ N1 n1 x- O- R
  191.         SYS_GPIOx_SetAF(GPIOJ, 4, AF14_LTDC);                //PJ4,AF14
    4 M  l& i  r! ]& P( X. Y# W
  192.         SYS_GPIOx_SetAF(GPIOJ, 5, AF14_LTDC);                //PJ5,AF14
    8 a1 W! G" {, B7 y( w4 p4 A
  193.         SYS_GPIOx_SetAF(GPIOJ, 6, AF14_LTDC);                //PJ6,AF14
    , O( j  S5 j/ [
  194.         SYS_GPIOx_SetAF(GPIOJ, 7, AF14_LTDC);                //PJ7,AF14
    3 y, I4 N( m, }3 {
  195.         SYS_GPIOx_SetAF(GPIOJ, 8, AF14_LTDC);                //PJ8,AF14- b9 z0 d" J4 c$ ~3 L! T
  196.         SYS_GPIOx_SetAF(GPIOJ, 9, AF14_LTDC);                //PJ9,AF14& G( \2 ]- @: F  }3 y; p  d
  197.         SYS_GPIOx_SetAF(GPIOJ, 10, AF14_LTDC);                //PJ10,AF14
    & {$ t% a, E) F
  198.         SYS_GPIOx_SetAF(GPIOJ, 11, AF14_LTDC);                //PJ11,AF14$ `2 H( b3 }1 k' L% d0 l
  199.         SYS_GPIOx_SetAF(GPIOJ, 13, AF14_LTDC);                //PJ13,AF14
    % O3 W' S+ d2 w: I
  200.         SYS_GPIOx_SetAF(GPIOJ, 14, AF14_LTDC);                //PJ14,AF14
    $ \: F4 q$ z2 U- t
  201.         SYS_GPIOx_SetAF(GPIOJ, 15, AF14_LTDC);                //PJ15,AF14
    & N# X& ?* I1 T. l; B
  202.         ! ?7 J' u" Y$ S( Z/ q1 H2 H
  203.         SYS_GPIOx_SetAF(GPIOK, 0, AF14_LTDC);                //PK0,AF142 M  J% s/ M, w) E: S9 X3 O
  204.         SYS_GPIOx_SetAF(GPIOK, 1, AF14_LTDC);                //PK1,AF148 P$ h% _; D: q3 f
  205.         SYS_GPIOx_SetAF(GPIOK, 2, AF14_LTDC);                //PK2,AF14
      H0 U1 T* A* K9 w, q+ Q
  206.         SYS_GPIOx_SetAF(GPIOK, 4, AF14_LTDC);                //PK4,AF14
    8 S- z: T+ s$ m: ]! k  u2 Y! m3 }
  207.         SYS_GPIOx_SetAF(GPIOK, 5, AF14_LTDC);                //PK5,AF14$ _. r5 b" N9 m4 i# q0 k/ T% Z9 |
  208.         SYS_GPIOx_SetAF(GPIOK, 6, AF14_LTDC);                //PK6,AF14
    , f# A! ]" n% Q" s, @- `. L
  209.         SYS_GPIOx_SetAF(GPIOK, 7, AF14_LTDC);                //PK7,AF14* x2 I! s6 t6 Q$ N' c+ O
  210.         5 z2 h( Y* \- N5 ~
  211.          SYS_GPIOx_SetAF(GPIOI, 9, AF14_LTDC);                //PI9,AF14) t/ v; Q# H1 y- Y$ ^5 A2 @
  212.          SYS_GPIOx_SetAF(GPIOI, 10, AF14_LTDC);                //PI10,AF14 . N* {+ A2 S1 K' \3 q1 y3 o
  213.         SYS_GPIOx_SetAF(GPIOI, 14, AF14_LTDC);                //PI14,AF14
    6 }) W: k$ N# m; {- }
  214.          SYS_GPIOx_SetAF(GPIOI, 15, AF14_LTDC);                //PI15,AF14
    1 t9 C( m1 L4 D& B9 e" ]7 x7 O7 n
  215.         
    7 ]( P  E- J- D
  216.         LTDC_ClockInit(DefaultLCD_Info.DCLK);                 //设置像素时钟  9Mhz
    2 F" u8 N% ~0 k, V5 Y/ @
  217.         //设置LTDC 全局控制寄存器 (LTDC_GCR): @  t, ]# I/ H3 _
  218.         temp = 0;) C  Y* O3 V5 {4 ]3 D. p9 g
  219.         temp |= (DefaultLCD_Info.HSPOL&0x01) << 31;        //水平同步极性
    " J" t9 c. p7 v* D" U
  220.         temp |= (DefaultLCD_Info.VSPOL&0x01) << 30;        //垂直同步极性8 v- G: l; C# C  u9 W2 `
  221.         temp |= (DefaultLCD_Info.DEPOL&0x01) << 29;        //数据使能极性: W. M5 Z0 r' Q- W- q" x! ?
  222.         temp |= (DefaultLCD_Info.PCPOL&0x01) << 28;        //像素时钟极性3 e+ ]" R  H# F& w2 I' K6 ^
  223.         LTDC->GCR = temp;& _! N6 c8 S# C: A
  224.         //LTDC 后沿配置寄存器 (LTDC_BPCR)$ j' c1 ?: ~* |( Z% s
  225.         temp = (DefaultLCD_Info.Tvw + DefaultLCD_Info.Tvbp - 1) << 0;        //这些位定义累加水平后沿宽度(水平同步像素加水平后沿像素减 1)。1 n5 ^8 B. }7 m* B
  226.         temp |= (DefaultLCD_Info.Thw + DefaultLCD_Info.Thbp - 1) << 16;        //这些位定义累加垂直后沿宽度(垂直同步行加垂直后沿行减 1)。
    , I( e' J3 X7 n+ n) a: a. |+ E
  227.         LTDC->BPCR=temp;        
    8 z* I0 U# t( a( B
  228.         ; v9 O! F" X/ ^5 L( J! K; ]( R
  229.         //LTDC 有效宽度配置寄存器 (LTDC_AWCR)1 i% \0 x' k8 y, q5 \" d
  230.         temp=(DefaultLCD_Info.Tvw+DefaultLCD_Info.Tvbp+DefaultLCD_Info.Height-1)<<0;        //累加有效高度=垂直脉宽+垂直后沿+垂直分辨率-13 ?' e& x0 {" I
  231.         temp|=(DefaultLCD_Info.Thw+DefaultLCD_Info.Thbp+DefaultLCD_Info.Width-1)<<16;        //累加有效宽度=水平脉宽+水平后沿+水平分辨率-1
    , A) R, w* N5 u
  232.         LTDC->AWCR=temp;        
    5 Z/ k/ E2 n) ?/ E0 E
  233.         //LTDC 总宽度配置寄存器 (LTDC_TWCR)0 q7 ^% ]6 G1 z5 ^- S$ [9 |4 p! [
  234.          temp=(DefaultLCD_Info.Tvw+DefaultLCD_Info.Tvbp+DefaultLCD_Info.Height+DefaultLCD_Info.Tvfp-1)<<0;        //总高度=垂直脉宽+垂直后沿+垂直分辨率+垂直前廊-1
    ( d! X9 V0 ~5 J" Z
  235.         temp|=(DefaultLCD_Info.Thw+DefaultLCD_Info.Thbp+DefaultLCD_Info.Width+DefaultLCD_Info.Thfp-1)<<16;        //总宽度=水平脉宽+水平后沿+水平分辨率+水平前廊-1
    $ ~6 C$ M* d2 V" E( w% |: {
  236.         LTDC->TWCR=temp;                                
    $ @: |: ^8 s, n* F' M6 W
  237. * P: v2 R. I. _% \1 S
  238.         //背景设置
    : @. |1 j5 U$ g  s9 q( ~( F
  239.         LTDC->BCCR=0xffffff;                                //设置背景层颜色寄存器(RGB888格式), ^& f" e1 y# v1 G7 V* e
  240.         LTDC_Enable(TRUE);                                        //开启LTDC
    ; o) A% ^9 E6 \  p. A& K
  241.         //初始化层1
    / R3 P# w8 t- P7 Z4 j
  242.         LTDC_SetLayerConfig(0, 0, 0, LTDC_WIDTH, LTDC_HEIGHT, (u32)g_LTDC_BUFF_RGB888[0], 255);
    . k2 c" E1 i" x" |$ L0 @0 R! ]
  243.         //初始化层2
    ( |$ ^" T1 I  C( ]# h& [
  244.         LTDC_SetLayerConfig(1, 0, 0, LTDC_WIDTH, LTDC_HEIGHT, (u32)g_LTDC_BUFF_RGB888[1], 255);6 F" o; P4 X/ x; ^  Y* N: s
  245.         LTDC_Clear(0, 0xFF000000);                        //清屏层1-不透明的黑色
    2 K) p  F) R! v# T+ y. [- e
  246.         LTDC_Clear(1, 0x00000000);                        //清屏层2-透明的黑色% }! k# @2 i9 S
  247.         LTDC_LayerEnable(0, TRUE);                        //使能层1
    0 I5 X, I& g! s; y+ L& B
  248.         LTDC_LayerRefreshConfig();                        //LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)
    $ j3 T0 x8 q  m' a+ |
  249.         LCD_DispIoInit();                                        //初始化DISP引脚-启动显示$ I7 \7 }4 p3 K/ [$ R# K5 R4 e
  250. }0 Z) c9 s( g& B* n! H4 W
  251. + s! O* s& @: M7 v" c
  252. /*************************************************************************************************************************
    # \- K! c9 Z; @# u* Z; ~
  253. * 函数                        :        void LTDC_LayerRefreshConfig(void)
    ! c  A# F' J* e0 K. T
  254. * 功能                        :        LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)
    ; ]! [* f/ ?& ^  P4 k& `0 E+ y
  255. * 参数                        :        无) f, @$ U1 c. q0 I  c* s
  256. * 返回                        :        无
    ( p" j' H3 @2 c4 A% o  `
  257. * 依赖                        :        底层宏定义
    , Y  K6 x( h& Q& g; |
  258. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    # c, i/ o3 h( U- h1 l/ Z; u& L
  259. * 时间                        :        2019-10-29
    ) _+ d: F$ n* c9 r8 M& z7 c
  260. * 最后修改时间         :         2019-10-29
    9 a# K$ n5 G+ O
  261. * 说明                        :        修改层配置后必须重新加载,否则不会生效, C& i$ N2 R4 d- }9 a& s
  262. *************************************************************************************************************************/
    " m6 a0 c9 @$ n% P" g* Z& T
  263. void LTDC_LayerRefreshConfig(void)0 f. z9 `( t  c/ h
  264. {
    + i/ ]) C! ^9 W: p8 b- W
  265.         LTDC->SRCR|=1<<0;                                                        //重新加载配置-必须重新加载,否则上面的层不会更新,折腾好久才发现,叫啥影子寄存器重载,也不说清楚
    7 G3 y- ^, }- }2 D: v
  266. }7 {# Q; m5 G: X
  267. 8 e# D. ]/ D/ L! d, P
  268. /*************************************************************************************************************************4 D2 P, w( i7 N7 i/ n
  269. * 函数                        :        void LTDC_Enable(bool Enable)
    % L' |1 G" ]. g: C
  270. * 功能                        :        LTDC使能设置4 z' @0 n: o. ?! s4 @+ \# n, o
  271. * 参数                        :        Enable:TRUE:使能;FALSE:失能; E% R9 p7 Z" |& C2 _) N
  272. * 返回                        :        无
    : E/ ^3 ~% S5 }" a5 \
  273. * 依赖                        :        底层宏定义
    " X# I; s7 ~9 f( r* F( m6 }
  274. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>7 o, ~5 x  k" @9 |: @0 m
  275. * 时间                        :        2019-10-29
    4 d% P! ]# b, G& ]! }( B( U
  276. * 最后修改时间         :         2019-10-29. H4 N+ t  z: M
  277. * 说明                        :        # n: T0 R9 y) L( [, u7 t6 R- Q
  278. *************************************************************************************************************************/3 m( S* s4 K( J
  279. void LTDC_Enable(bool Enable)" T+ y1 N' U" s# s! L7 C
  280. {
      Y, R6 w, H0 T# J6 M% A9 \4 @
  281.         if(Enable)& L- I3 w! A" L; ]' M
  282.         {3 W' s: H. b: n# C7 J2 {5 |
  283.                 LTDC->GCR |= BIT0;                                        //打开LTDC
    7 f4 N4 g1 A4 f# n6 }
  284.         }) C* W5 R3 F3 X# ^3 n
  285.         else
    - K* v: O, L0 m8 o$ H& y
  286.         {/ @. e. z6 G/ W5 e# X/ }: O. ~) q# q
  287.                 LTDC->GCR &= ~BIT0;                                        //关闭LTDC
    " T' q! u! ^) l4 F
  288.         }
    ) _! V3 T: h' X; o+ o
  289. }
    ( Q: {& Y: W3 ^/ A

  290. 9 O3 n" d+ W' P8 u
  291. /*************************************************************************************************************************
    # t" f0 H- l" F- W) O' d" B4 y5 I
  292. * 函数                        :        void LTDC_LayerEnable(u8 LayerIndex, bool Enable); s5 N. |/ s& P: x8 b
  293. * 功能                        :        LTDC 层使能设置1 V$ i, s$ S, z' V0 v2 C8 \' Q0 m3 n
  294. * 参数                        :        LayerIndex:层选择0-1;Enable:TRUE:使能;FALSE:失能
    / V3 B7 |; s+ U% R
  295. * 返回                        :        无& d. ?) I. n! E  N' k' |
  296. * 依赖                        :        底层宏定义
    - B: h- t* ?5 U! I
  297. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    . C4 P. Z2 A1 ?8 D3 u: a) `
  298. * 时间                        :        2019-10-29
    9 f) _) }9 j* O7 \' D5 p
  299. * 最后修改时间         :         2019-10-291 ?3 T4 L; j0 E. y
  300. * 说明                        :        
    0 z: E# }# G6 X. n8 u
  301. *************************************************************************************************************************/' k) ?! O  D  M2 P4 y! s: ^. J
  302. void LTDC_LayerEnable(u8 LayerIndex, bool Enable)
    9 r/ F$ _  {& i- r: `) L0 J0 v
  303. {
    4 E4 p% l4 B( `. |2 s
  304.         if(Enable)( b, R1 X$ v9 ~+ G, y( S* ]! |. `
  305.         {. A; @* S* ]: k% G8 s! v0 N
  306.                 if(LayerIndex == 0)                                        //层1( d6 O! ]5 j0 G4 I% k( o
  307.                 {
    . V* V8 T% B6 t* l
  308.                         LTDC_Layer1->CR |= BIT0;                //使能层18 t0 j% b: U$ F0 m2 n
  309.                 }
    " a" r* e+ W6 a4 R
  310.                 else
    " }9 ^& S; e6 N& ?8 o/ a1 K
  311.                 {7 J6 J3 Q4 q: @; t, ?  _% }
  312.                         LTDC_Layer2->CR |= BIT0;                //使能层2; h  C0 D/ u- @# P" h* ?$ k5 n( x
  313.                 }" X2 c! V; z. K0 k- g# l2 m
  314.         }" }7 m5 v/ O( F  C8 J! `. E
  315.         else
    . D6 w) h$ x& S' G; I9 c: {  G/ W
  316.         {# H- N. Z7 C0 g9 T) s, g' Z
  317.                 if(LayerIndex == 0)                                        //层1
    , y; y$ q) n2 \1 O4 m' ?- ]# z1 ~
  318.                 {
    $ O% T4 \/ P# X* S' F$ \
  319.                         LTDC_Layer1->CR &= ~BIT0;                //失能层1
    ) B* V. ]! z- k# H6 A. Y
  320.                 }. h0 i+ n/ F( D+ w& Z0 J& S  H2 i: f
  321.                 else; I1 U7 }; Z) F# o8 P
  322.                 {
    # k! L- K9 c8 p" l
  323.                         LTDC_Layer2->CR &= ~BIT0;                //失能层28 x: o9 b7 l6 B" D; d  _$ m# b/ I. y
  324.                 }/ s1 T# L  P1 l
  325.         }
    4 P- Y4 @3 h; T8 M
  326. }) Q7 o. ?: r. J( X5 q& v/ y
  327. # g& y$ s6 T1 b
  328. 2 p" M4 J* U' Y5 z" {2 X& r

  329. - J3 W4 D( }1 ]- c3 @, o

  330. & _; o( T; e- ], @
  331. /*************************************************************************************************************************7 v0 O; D4 c; w  Q8 W3 _9 Z$ g2 M
  332. * 函数                        :        bool LTDC_ClockInit(u16 ClockFreq)                        , U& \' A$ v# @# i1 z
  333. * 功能                        :        STM32F7 LTDC时钟初始化. h; b  \" M0 e" s) D
  334. * 参数                        :        ClockFreq:时钟频率,2-168MHZ
    8 t) O  q5 [: O# y
  335. * 返回                        :        是否设置成功
    3 B8 x/ `9 z- a2 F' A
  336. * 依赖                        :        底层宏定义
    * r, u' i% D5 `7 X0 C8 q/ h
  337. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    & ]* O, f0 G2 f- ~# p( X
  338. * 时间                        :        2019-10-28
    6 l  b9 L: L/ M6 Z8 B  ~0 I5 u
  339. * 最后修改时间         :         2019-10-286 a1 x* C4 @$ [) x+ d/ Z
  340. * 说明                        :        输入时钟频率在系统主时钟初始化之后就会设置为1MHz,通过设置SAI PLL实现LTDC所需频率,VCO频率范围:49~432
    # d8 Q$ a$ ?7 f* E
  341. *************************************************************************************************************************/
    , Q% L5 o- m, s1 ?
  342. bool LTDC_ClockInit(u16 ClockFreq)
    - W4 l9 J0 r* ^0 p% G+ |% ]
  343. {% Z* V# h% g$ p) z! `
  344.         u32 TimeOut = 0;
    - D: Y  ^7 p; L6 @
  345.         u32 VCO;
    & F9 y3 c  ]3 m2 f2 c' b
  346.         u32 PLLSAIR;                //PLLSAICFGR[30:28]5 F0 P# n8 H  z( G
  347.         u32 PLLSAIDIVR;                //DCKCFGR1[17:16]! e5 M1 K1 b& Q" p8 z) ^+ r8 q$ E
  348.         u32 temp;4 O- k# n- L+ {+ j
  349.         
    " g: K& Q* K* `
  350.         if(ClockFreq < 1)ClockFreq = 1;. A4 Y! N. i6 l$ s7 M7 v0 M
  351.         if(ClockFreq > 100) ClockFreq = 100;
    2 R1 y/ H2 x% [& n2 I: l. E& R- K
  352.         
    8 o2 ~" p- n4 A+ p: R
  353.         RCC->CR &= ~(1<<28);                                                //关闭SAI时钟
    2 i! E4 c2 X' g+ c
  354.         TimeOut = 0;6 m! f6 l) r- m' Q+ W5 e: f
  355.         while(RCC->CR&(1<<29))                                                //等待关闭成功
    - ?3 K9 C+ H* o. a$ y2 O* Q
  356.         {
    ! i+ O# G. A6 a; }) x/ F8 }
  357.                 nop;
    $ K/ F( Z2 ]% o  |( ^! l
  358.                 TimeOut ++;
    & u7 y) f7 d- E% F1 `
  359.                 if(TimeOut > 0xFFFF) return FALSE;                //关闭超时" m* B9 W) p& b( p3 n. g, o
  360.         }2 n1 B8 _% [( K! H- K, p) t' d, J, |
  361.         //计算分频与VCO频率,通过PLLSAICFGR[30:28]可以设置2-7分频* \- `. W* J6 s. k! W2 j
  362.         //通过PLLSAICFGR[17:16]可以设置00:2 01:4 10:8 11:16分频
    0 R9 r$ j! U2 D; o! A* n- v
  363.         //通过PLLSAICFGR[14:6]可以设置为49-432MHz的VCO频率
    5 U+ y5 ]6 s3 G8 c# V
  364.         if(ClockFreq <= 6)5 [- u$ U" n4 N5 h" x5 \
  365.         {& L) |0 B) h6 V6 v" O" \
  366.                 PLLSAIR = 4;        //4分频! ~$ Y8 i5 p0 Q- v  m
  367.                 PLLSAIDIVR = 3;        //16分频
    8 X5 ]2 K/ S& t8 j( H7 s
  368.                 VCO = ClockFreq * PLLSAIR * 16;                        //VCO范围:64-384;$ O7 Z, J# A8 }  r8 `9 l
  369.         }
    ' F$ C9 T# u4 L# o  b  g8 u& L0 Q; b6 j
  370.         else if(ClockFreq <= 13); T! T: _  K" S  V! K1 N. T
  371.         {" ~  E  B) Z8 k, L4 L# u# S2 }
  372.                 PLLSAIR = 4;        //4分频
    3 Z2 B- i' ^7 Q. T
  373.                 PLLSAIDIVR = 2;        //8分频
    4 L7 g9 u* r+ E* I3 O# L% B# J- ]
  374.                 VCO = ClockFreq * PLLSAIR * 8;                        //VCO范围:224-416;$ F" _! z) I: Q* ~0 R
  375.         }! O* H, u4 y+ H* q
  376.         else if(ClockFreq <= 26)# E. y! W' [- B' I  O% h' X
  377.         {1 ]4 a' H1 e! Q: ^) b1 B
  378.                 PLLSAIR = 2;        //2分频" i6 {" N; @# P: N$ E$ x: z
  379.                 PLLSAIDIVR = 2;        //8分频$ k3 ~: r# i" K2 V, S, x
  380.                 VCO = ClockFreq * PLLSAIR * 8;                        //VCO范围:224-416;
    , q. I! |( S" W0 j9 v2 e* _6 k
  381.         }
    ! S8 H# _9 ?7 f: q2 c
  382.         else if(ClockFreq <= 52)
    ; F4 j& m" U' I: ~5 n7 w5 [
  383.         {" s7 l) v3 p# t# A  k& p2 c
  384.                 PLLSAIR = 2;        //2分频
    % u$ _: k* n0 l8 f' k7 z
  385.                 PLLSAIDIVR = 1;        //4分频
    9 ^- f, y) B+ j
  386.                 VCO = ClockFreq * PLLSAIR * 4;                        //VCO范围:216-416;
    1 O4 ]" p) p' ?( y1 w" q
  387.         }
    9 e( M0 h; B' i! O# ^  `: o
  388.         else if(ClockFreq <= 104)
    * I* f& |! W+ }$ B6 A+ J, \
  389.         {
    / U2 y! w1 {/ |& F8 F, A) L; R
  390.                 PLLSAIR = 2;        //2分频' z# G! M6 \3 w  Z( x. G. a. k
  391.                 PLLSAIDIVR = 0;        //2分频$ t  m8 _! z4 z$ j9 `3 F- J
  392.                 VCO = ClockFreq * PLLSAIR * 2;                        //VCO范围:212-416;7 a8 g' K' Y" S% Y! ^4 z3 B
  393.         }
    2 h3 [5 {8 E0 l  A; {# X  z
  394.         //设置PLLSAICFGR  b! U( z7 v0 f% v7 ~! z
  395.         temp = RCC->PLLSAICFGR;( \1 F9 C2 X( i. S
  396.         temp &= ~((3<<28) | (0x1FF<<6));                        //清除之前的设置
    ; r2 Z1 _9 |5 `1 J
  397.         temp |= PLLSAIR << 28;                                                //设置分频PLLSAICFGR[30:28]3 O+ b  U0 a4 M' G  X
  398.         temp |= VCO << 6;                                                        //设置VCO. {/ F/ M( P$ N% t0 [
  399.         RCC->PLLSAICFGR = temp;
    ; m1 c% y1 O; `( O& g
  400.         //设置DCKCFGR1
    : Y# S& G# g+ C$ k* a" _
  401.         temp = RCC->DCKCFGR1;9 C7 T/ ?; Z/ ^
  402.         temp &= ~(3<<16);                                                        //清除之前的设置
      B# d! a7 _" T' U: w2 @3 ?$ x2 n8 F, X+ a
  403.         temp |= PLLSAIDIVR << 16;                                        //设置分频DCKCFGR1[17:16]* u+ i! c& M4 C( o+ [# t( m( l
  404.         RCC->DCKCFGR1 = temp;
    9 |- [8 I" ^3 m1 i. F3 V
  405.         //启动时钟( Z1 L2 v8 g$ D+ h9 y) R; n& E+ V
  406.         RCC->CR |= 1<<28;                                                        //启动SAI时钟
    * i; B8 s+ ]) g3 n4 e- T
  407.         TimeOut = 0;, h7 F( \: D9 [$ A( M
  408.         while((RCC->CR&(1<<29)) == 0)                                //等待开启成功" @! W' ]- [$ M& R9 p* p+ Y5 Z$ O5 h
  409.         {
    2 }  G6 n) T; @) P2 i% k& G8 U
  410.                 nop;2 V5 \3 `# r  C7 u; q# K8 F, |
  411.                 TimeOut ++;# z# ~- |' B6 E6 P( a' a( C
  412.                 if(TimeOut > 0xFFFF) return FALSE;                //开启超时
    4 t0 k2 L+ `" e& N4 H1 G+ b
  413.         }
    ; W  G! g! C2 |/ q( ~
  414.         * E! n7 M' o% X% G9 L% t
  415.         return TRUE;
    2 p3 Z1 M! G. R0 V! {7 c: b$ q
  416. }
    / s8 _# }8 p# t/ i& M6 Q. R
  417. 5 J( O% C5 b5 z+ e

  418. & F3 ^) f  f# M" |$ h6 D
  419. /*************************************************************************************************************************
    3 j3 C& \0 X: X" ?  I1 Z
  420. * 函数                        :        void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color)        + {5 _2 U3 ~+ M7 Y+ d
  421. * 功能                        :        矩形填充(使用DMA2D)5 r8 t6 s6 i+ D2 {6 Y" J+ P
  422. * 参数                        :        LayerIndex:层选择0-1;sx,sy:开始坐标;ex,ey:结束坐标,color:需要填充的颜色2 k# g2 e. R9 y( A9 @' D* R
  423. * 返回                        :        无% T; `- T" A) ^5 L- `- {: P
  424. * 依赖                        :        底层宏定义5 ~. j& D/ Q' C5 w9 K( g+ f
  425. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    2 Z) v, M$ K# K$ u
  426. * 时间                        :        2019-10-303 W* ^3 h" H- L/ e! D( o6 F) c% v! F
  427. * 最后修改时间         :         2019-10-30
    2 m  x/ @( X, {7 S0 e" Z
  428. * 说明                        :        采用DMA2D实现
    7 Q7 ^2 ^, I; m
  429. *************************************************************************************************************************/
    , @$ s( a1 _* i
  430. void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color): l- L; w2 V& h$ P5 a, [  s
  431. {6 y: m  Q: y- z+ c, {7 W- ~
  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进行单色填充3 M0 K; w& o* d% U, S2 p
  433.         DMA2D_WaitTransferComplete(500);                                                                                                                                                                                                                                //等待DMA2D传输完成+ Q" U8 Q: W; d, H1 E& e' P
  434. }
    5 X8 j% {9 c9 m9 v9 J3 O
  435. + x, X# S' \6 t, e' v: [
  436. 7 J) K: V( i- d$ p
  437. /*************************************************************************************************************************! ]! _5 H0 Z# z; P# }4 X2 w
  438. * 函数                        :        void LTDC_Clear(u8 LayerIndex,u32 color)
      L6 i; q" C. u! P+ }+ K( l% m
  439. * 功能                        :        清屏(使用DMA2D)( x9 i0 L# s- y3 {! j
  440. * 参数                        :        LayerIndex:层选择0-1;color:需要填充的颜色  I, ?: u2 U6 H% f
  441. * 返回                        :        无& K$ \% ^% i) N# d9 x
  442. * 依赖                        :        底层宏定义( R/ B5 ~) U+ ^  G) }
  443. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    0 @$ M; I, \- P! x2 K9 h8 O- t) B
  444. * 时间                        :        2019-10-30
    - W  n- K7 x; k8 U% x1 Z' Q9 |& s
  445. * 最后修改时间         :         2019-10-30
    * g! Q( t/ ]5 h  N3 k6 F% c) V
  446. * 说明                        :        采用DMA2D实现
    5 L& S  g9 [3 t9 T( h
  447. *************************************************************************************************************************/
    . k- h' h8 t0 a! _
  448. void LTDC_Clear(u8 LayerIndex,u32 color)" H; u% F) a8 n# N
  449. {/ W% ?% i; Y7 v1 r& F
  450.         DMA2D_FillColorToFGRAM((u32)&g_LTDC_BUFF_RGB888[LayerIndex][0][0], LTDC_WIDTH, LTDC_HEIGHT, 0,  DMA2D_COLOR_ARGB8888, color);                                        //DMA2D进行单色填充
      p: P! H/ v; X
  451.         SYS_DelayMS(5);8 M( b# M% i9 m2 a" `: H
  452.         DMA2D_WaitTransferComplete(500);                                                                                                                                                                                                                                //等待DMA2D传输完成0 j# _0 ^5 B' Y
  453. }
    : ?8 d( e2 i. u" h1 T2 [  C+ E. J

  454. , Y2 [; s+ s9 }9 {- W
  455. 0 l0 y% x2 n, W6 l) [3 ^$ Y1 z% a- m6 n
  456. /*************************************************************************************************************************
    . y$ Z2 }. a$ M# e9 U) [
  457. * 函数                        :        void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr)! ~4 l! {. h1 ]
  458. * 功能                        :        矩形图像填充(相同坐标范围传输,要求源图像与目标显示器分辨率一致,使用DMA2D)3 z3 s" b- m7 E* u6 f$ A: c
  459. * 参数                        :        LayerIndex:层选择0-1;sx,sy:开始坐标;ex,ey:结束坐标,ImageAddr:需要填充的图像地址
    8 [7 j7 W# y7 j, m  j% q$ r8 |
  460. * 返回                        :        无
    ! p, S1 T. q) P- t& H
  461. * 依赖                        :        底层宏定义
    , `7 b3 i- V, z& b1 q. p6 M
  462. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a># ?. b8 z1 ^/ {0 h1 f6 Z
  463. * 时间                        :        2019-10-30- p7 i0 y5 G' w5 m% z; S
  464. * 最后修改时间         :         2019-10-30" s8 ?! I' d3 o- Q" H' Y
  465. * 说明                        :        采用DMA2D实现,将源图像指定位置传输到现存,要求源图像与显存大小一致
    ( D' p) @3 Y( \# k/ D
  466. *************************************************************************************************************************/. T. u) q! D' Q- y1 O) j, x
  467. void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr)
    % T! w1 h& u4 B
  468. {
    ! A8 H* y5 }  i& g( s) d- |
  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进行矩形图形填充! L; R5 f; b5 Y3 @
  470.         DMA2D_WaitTransferComplete(500);
    ; L: {8 ?7 |. X: B$ A
  471. }
复制代码
  1. /*************************************************************************************************************
    . D$ c: m& \% j6 F7 T! G* H* R8 z* D
  2. * 文件名                :        stm32f7_ltdc.h
    7 g, W# l; P( x$ N4 k, a
  3. * 功能                        :        STM32F7 外部RGB LCD驱动
    + |, i" Z: l# p$ ], \
  4. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    7 q% B$ p2 K  s. p
  5. * 创建时间                :        2019-09-12( _2 b3 C: f5 l8 p
  6. * 最后修改时间        :        2019-09-12
    % x% l  a. E+ x5 @
  7. * 详细:        
    * S0 \! D. e# G* n3 {
  8. *************************************************************************************************************/                2 X, X: @. v! s! O$ O
  9. #ifndef __STM32F7_LTDC_H_0 g9 S1 b* ~8 }: L1 o% l
  10. #define        __STM32F7_LTDC_H_           
    ( m' \7 X2 P$ X" \* W% n7 L
  11. #include "system.h"4 S: r# j7 ~! W* B  x' p7 S: X
  12. #include "DMA2D.h"
    # m* E) f) x3 V2 b2 `$ t
  13. : n8 P+ l! m  X: b) ]
  14. #define LTDC_WIDTH                480
    : i" \0 b2 L4 u4 \; B5 O; P/ ^
  15. #define LTDC_HEIGHT                272
    1 Z& g" m* P: {2 |9 S  I
  16. & _. H) ^" G, j  i! ^
  17. 8 _& i" w- D) E3 p
  18. extern u32 g_LTDC_BUFF_RGB888[2][LTDC_HEIGHT][LTDC_WIDTH];- Z9 D6 P6 ]' D7 [" W* V6 q

  19. 1 s( o" E: Z; e9 A5 _/ A
  20. //像素格式定义: O$ B' w0 u2 X7 ~6 w
  21. typedef enum
    , g2 f4 H/ S3 G# J2 k; [
  22. {
    : N% }' y, y2 ?2 D
  23.         LTDC_ARGB8888         = 0,
    5 I2 k: Z( I2 ^! c. {. A
  24.         LTDC_RGB888         = 1,
    3 f* B) @! x; P& ~- V
  25.         LTDC_RGB565         = 2,# D6 B1 p( ?, Q) \: x; ?, v1 Z
  26.         /*LTDC_ARGB1555         = 3,% P# p. {& f, C+ K3 q* S
  27.         LTDC_ARGB4444         = 4,2 u/ [2 X/ }7 v0 h5 V. L
  28.         LTDC_L8                 = 5,        //8 位 Luminance0 l0 b8 o0 A& D0 S8 B) A) s2 B7 A
  29.         LTDC_AL44                 = 6,        //4 位 Alpha,4 位 Luminance# ^# Z1 g0 O- D' ^
  30.         LTDC_AL88                 = 7,        //8 位 Alpha,8 位 Luminance*/
    7 t5 V# d" V. Y9 g
  31. }LTDC_PixelFormat;' y2 _; e" y3 _2 c, _2 ~. H
  32. #define LTDC_PIXEL_FORMAT                LTDC_ARGB8888                //选择ARGB8888格式" H6 H% v& x$ ^' R" x8 n

  33. & k; h& F3 p) O
  34. 7 W8 _6 X# a$ [$ D0 \

  35. 1 G: L; T6 O- F$ L! c: E. q
  36. ; R& b0 _/ d4 N. F
  37. //画点函数32bit ARGB8888格式
    , i; J  G' l( K1 y
  38. __inline void LTDC_DrawPoint(u8 LayerIndex, u16 Xpos,u16 Ypos,u32 ARGB8888_Color)5 C4 l# C$ d6 P; a6 |+ ~) }( ~& H
  39. {/ f2 w2 f) l, n) \# _! o
  40.         g_LTDC_BUFF_RGB888[LayerIndex][Ypos][Xpos] = ARGB8888_Color;& s- ]! N& l" W! y, P! {( `1 F6 A7 k
  41. }" G/ w' Q/ n1 C/ l! ~% Y" d

  42. ( Q" K* Z+ p( b. K5 |# }
  43. //初始化DISP引脚% A1 w3 d3 R; \
  44. __inline void LCD_DispIoInit(void)0 k$ |; q- {* g% ]# t
  45. {
    ; f: f! Y3 D3 }2 v
  46.         SYS_GPIOx_Init(GPIOI, BIT12, OUT_PP, SPEED_25M);                                                                                                //PI12 LCD_DISP H:正常模式;L:低功耗                                                        
    % a+ J( o; X: B& U& |' i
  47.         PIout(12) = 1;                                                                                                                                                                        //DISP = H  2019-10-16:一直忽略将此引脚置为高电平,调试走了很多弯路$ @9 P! q# O3 s6 |, _
  48. }' z3 w3 d* Q+ c. w9 b3 D
  49. & F9 P$ p0 K9 y. f
  50. void LTDC_Enable(bool Enable);                                                                                                                                                //LTDC使能设置
    / P) Z5 B' o$ o
  51. void LTDC_Init(void);                                                                                                                                                                //LTDC 接口初始化
      w2 @% p3 b3 s4 q) f1 s" j
  52. void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha);//LTDC 层窗口尺寸设置) ]& {' Y1 l8 q& F% x# ~' @7 W
  53. void LTDC_LayerEnable(u8 LayerIndex, bool Enable);                                                                                                        //LTDC 层使能设置
    ( Q5 L0 n+ J1 G/ K% S! I- E
  54. void LTDC_LayerRefreshConfig(void);                                                                                                                                        //LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)9 O: {: Q- A4 i$ d

  55. 2 P  r) ~7 G: ^  X7 @  B  U
  56. //图形相关API5 |7 J! d8 V1 ^" ?& h. A" e4 `
  57. void LTDC_DrawPoint(u8 LayerIndex, u16 Xpos,u16 Ypos,u32 ARGB8888_Color);                                                        //画点函数32bit ARGB8888格式
    3 o- A* L/ }' G# W* y( i( {
  58. void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color);                                                                //矩形填充(使用DMA2D)) Z! p) E" I3 ?/ H! k
  59. void LTDC_Clear(u8 LayerIndex,u32 color);                                                                                                                        //清屏(使用DMA2D)
    8 r! B4 v) S& c6 w6 ]$ q

  60. " K# c- z* x( _0 ?
  61. void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr);//矩形图像填充(相同坐标范围传输,要求源图像与目标显示器分辨率一致,使用DMA2D)
复制代码
' H, s) g; b2 }" u/ d, v& s
3 q% q5 }+ I" X$ }5 b
#endif //__STM32F7_LTDC_H_/ o4 T" j) T+ o* n. a/ N
% p# b, y0 X1 y7 g

' `) s1 W$ {' F  P( _5 ?. c/ p) d4 I  @  z8 S
收藏 评论0 发布时间:2021-12-14 10:49

举报

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