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

【经验分享】STM32f746gdiscovery LTDC 驱动

[复制链接]
STMCU小助手 发布时间:2021-12-14 10:49
需要提前准备好SDRAM驱动,如果没有SDRAM可以进行纯色彩测试,底层时钟,IO操作相关看注释,我使用的是寄存器封装的。4 v: g, j8 J9 A2 j

, j, O# ~5 u7 [
  1. /*************************************************************************************************************
    # y+ Y/ c7 {" y  w- N: S
  2. * 文件名                :        stm32f7_ltdc.c
    % D6 _+ @6 V& ?4 t+ E! |& F
  3. * 功能                        :        STM32F7 外部RGB LCD驱动- y! k1 ?8 r7 ?
  4. * 创建时间                :        2019-09-12
    5 t9 I. a, Z! Q# d# A# X0 F9 g
  5. * 最后修改时间        :        2019-09-12: r: g0 R, }4 N" Y* l: c+ A/ e- z, I
  6. * 详细:        6 F1 q# f1 p+ c# S
  7. *************************************************************************************************************/        9 \! Q9 W: Y! A# b! p8 F3 X. \9 _; f
  8. #include "stm32f7_ltdc.h"5 A! a$ p& N7 l) Q
  9. #include "SYSTEM.H"
    6 o% d' |! l3 t8 b) Z/ @" b0 X
  10. #include "stm32f7_sdram.h"  P9 F/ j1 i' z/ M$ L$ v7 @* D8 Q
  11. #include "DMA2D.h"
    " u3 [  N+ x- b+ I* u

  12. 1 d8 C  t- W3 e$ P/ k

  13. 7 n+ ]% q% G1 u& t- g" H. `% v7 {3 J/ {. U
  14. u32 g_LTDC_BUFF_RGB888[2][LTDC_HEIGHT][LTDC_WIDTH]  __attribute__ ((at(Bank5_SDRAM_ADDR)));                //需要SDRAM支持,LCD帧缓冲区,RGB888格式9 M+ c" Q5 I( Y' M( r1 ~. x

  15. ; g/ M$ a0 U% ?* H% \$ S' S

  16. * b. J( ?; |' i- E  c3 d
  17. //记录全局层配置信息
    $ q8 _( H! y) u/ \( i. z
  18. typedef struct
    ; C) S" j+ ]0 x$ o+ t# P
  19. {9 s. }' v- Z. e# C8 q
  20.         u16 sx;                                        //层开始X坐标,从0开始. f  v; k: R' _% [
  21.         u16 sy;                                        //层开始Y坐标,从0开始
      G" Z* \2 y! {" l
  22.         u16 width;                                //层宽度
    ! b% z9 K5 Y& `$ Z) f" R$ a
  23.         u16 height;                                //层高度
      K( _4 v) u3 u
  24.         u32 *pFrameBuff;                //帧缓冲区指针,需要进行初始化
    . q, Q: u( I2 q! z' n
  25. }LTDC_LayerConfig;: G3 V: o8 T, n7 C
  26. , r! n. a! A, q+ x

  27. . n; f  L6 C, U& t& A2 B
  28. ! c$ L& u! W- I" Z/ B/ T$ G
  29. //全局的LTDC配置信息% b3 g1 [( n/ m/ p3 `
  30. typedef struct0 ?8 p! h/ ]0 @% k/ Y9 u! s8 Q
  31. {* E7 b9 E0 L" r5 _2 H6 \0 }- ^
  32.         u16 lcd_width;                                                //显示器宽度
    ! i3 a! D: I  y8 U# W- H( j+ L* I
  33.         u16 lcd_height;                                                //显示器高度
    9 D# d3 n6 P& M" a
  34.         LTDC_LayerConfig LayerConfig[2];        //层信息
    3 P- R' _+ |' q9 F3 W
  35. }LTDC_ConfigData;  X% D3 I8 O7 z) B7 }; T" e

  36. # b+ A$ g/ v4 N1 W1 I  X, E

  37. # f7 Y0 W" ?8 T, N" J1 k
  38. static LTDC_ConfigData sg_LTDC_ConfigData;        //记录全局的LCD配置
    % K. \5 p3 O/ {! H1 U' v: z8 C
  39. + \) r( M$ P) s
  40. ; F0 V0 {0 A9 G3 V- R' b8 j
  41. //显示屏信息
    ! X$ w) X2 U0 M$ r! x( U
  42. typedef struct& |( ]" m: j/ A0 h. p9 s# f4 L
  43. {$ A& n3 E* s9 K3 @7 q! I
  44.         u16         Width;                //面板宽度,单位:像素& v4 m! t+ ]/ B5 T1 m
  45.         u16         Height;                //面板高度,单位:像素
    % W! O' W1 R4 L8 w. P
  46.         u8          Thbp;                //水平后廊& s- H7 E8 P7 q( I
  47.         u8          Thfp;                //水平前廊
    - ~8 z2 |3 U' }7 w
  48.         u8          Thw;                //水平同步宽度; ?4 ?) B% g9 J3 Y0 c" ]% Y
  49.         u8          Tvbp;                //垂直后廊! c2 ?, w# A$ S- v. i% N' T& N
  50.         u8          Tvfp;                //垂直前廊$ h8 r6 k. w/ }1 C3 i% \6 O  ]
  51.         u8          Tvw;                //垂直同步宽度
    0 [" Q7 K5 f! h# S5 V
  52.         u8          DCLK;                //时钟速度,MHz& Y- X& D5 p5 t& u1 y
  53.         
    7 D, E, _: U" Y/ r+ y  b
  54.         u8                HSPOL;                //水平同步极性,0:低电平有效;1:高电平有效& q% S3 H4 [/ X4 B2 A) t. t
  55.         u8                VSPOL;                //垂直同步极性,0:低电平有效;1:高电平有效
    ' F! r4 e9 j7 j; C
  56.         u8                DEPOL;                //数据使能极性,0:低电平有效;1:高电平有效9 d0 P% \! P  ~
  57.         bool        PCPOL;                //像素时钟反向$ B2 ]8 j1 y+ k+ T; @9 q, B
  58. }LTDC_INFO_TYPE;
    5 a' E) g# u8 Y7 C, s/ T( J3 B
  59. , X8 f( S6 S  F# N, C

  60. & c9 l' |. o8 X
  61. LTDC_INFO_TYPE DefaultLCD_Info =2 n1 f/ P! h& i! i
  62. {" O: e3 K5 N1 ^2 a0 |+ ?$ Y" N
  63.         480,        //面板宽度,单位:像素
    ' i4 T& y3 {1 n2 |9 m
  64.         272,        //面板高度,单位:像素
    ) j1 G, J9 u8 Z/ ~# W. |( t
  65.         41,                //水平后廊6 Z, |9 ]9 b! {  |0 |
  66.         8,                //水平前廊
    & r- {# M) i  L7 d
  67.         2,                //水平同步宽度, v3 i7 C. m; Q: M/ B) ~9 a
  68.         2,                //垂直后廊; y, @" Y3 n0 a! m( N3 H8 c* R" o
  69.         4,                //垂直前廊
    4 O) ]3 q7 h' }/ g% F
  70.         10,                //垂直同步宽度! t' G# _( D7 \
  71.         9,                //时钟速度,MHz
    4 {5 O8 ]) C, k
  72.         0,                //水平同步极性,0:低电平有效;1:高电平有效& j/ w$ {* o& R2 ]4 h/ f. r9 @5 R2 s
  73.         0,                //垂直同步极性,0:低电平有效;1:高电平有效
    8 r2 d" S9 N8 s# G
  74.         1,                //数据使能极性,0:低电平有效;1:高电平有效
    $ o$ C; I6 ]) U& m# j4 [
  75.         FALSE,        //像素时钟反向
    7 y! |) \( ^( q" H5 @
  76. };# q# D% [6 [+ c( j2 G2 R
  77. " Y$ X+ }9 }$ S7 z2 }5 a2 T8 y
  78. bool LTDC_ClockInit(u16 ClockFreq);                                                        //STM32F4 LTDC时钟初始化
    7 e: K7 }; H" c7 H

  79. 0 {3 b  z" D2 z2 R& X
  80. / t+ p# B* y6 |
  81. /*************************************************************************************************************************
    * i1 q3 o  b  {1 X1 n$ X. c
  82. * 函数        :                        void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha)1 ^0 H4 h$ k* R$ \, i
  83. * 功能        :                        LTDC 层窗口尺寸设置(会自动根据窗口尺寸以及像素格式设置帧缓冲区大小), W5 A) {/ Q2 w- ?, W, }
  84. * 参数        :                        LayerIndex:层选择(0-1);sx,sy:起始坐标;width,height:宽度和高度  `* u0 h( c- m+ z: ^
  85. * 返回        :                        无
    ' ]2 w' s+ a( z, K
  86. * 依赖        :                        底层宏定义+ y9 x" G% {" d
  87. * 作者        :                        <a href="mailto:cp1300@139.com">cp1300@139.com</a>' w( \; @$ q/ h+ J+ S- l
  88. * 时间        :                        2019-10-28
    2 I: Z8 H) r0 }2 d- D4 Z* y
  89. * 最后修改时间 :         2019-10-286 ]- A4 y$ s" ]( A
  90. * 说明        :                         不会使能层,不会更新层,只设置配置,需要刷新层配置后更新, J, \0 S1 @" N! V
  91. *************************************************************************************************************************/ ! s& D6 X* h8 B* U) S% O* G3 R
  92. void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha)' p# q3 R' Y7 B, ^2 o) ]- R! P. R
  93. {
    - t9 J  Z  \' Q' D
  94.         u32 temp;
    : Z2 h3 B; o. P4 |, ]
  95.         u8 pixformat=0; ; i1 E8 r  [; p- o0 i
  96.         3 O5 t' M$ ~8 w5 i' ]
  97.         if(LayerIndex==0)( _3 O8 x5 M' q2 O" O2 x
  98.         {- L. i2 \. f2 F8 n, h
  99.                 //基本配置, }7 B/ s4 z1 h5 r( x
  100.                 LTDC_Layer1->CFBAR = FrameBuff;                                                                        //设置层颜色帧缓存起始地址$ ^, f9 j) |. j
  101.                 LTDC_Layer1->PFCR = LTDC_PIXEL_FORMAT;                                                        //设置层颜色格式. @% a7 R# g1 v
  102.                 LTDC_Layer1->CACR = Alpha;                                                                                //常数 Alpha,255分频;设置255,则不透明
    ; t; C; k9 s7 P+ ~7 f
  103.                 LTDC_Layer1->DCCR = 0x00;                                                                                //设置默认颜色:透明的黑色
    % N! v3 O- m! z9 D# ]9 V- ?
  104.                 LTDC_Layer1->BFCR = ((u32)6<<8)|7;                                                                //设置层混合系数
    $ d6 \" X' T$ m
  105.                 //配置窗口
    & D5 W% R6 G/ Z+ i3 D3 c
  106.                 temp = (sx+width+((LTDC->BPCR&0X0FFF0000)>>16))<<16;
    5 O$ l8 ~0 m; \, J. H
  107.                 LTDC_Layer1->WHPCR = (sx+((LTDC->BPCR&0X0FFF0000)>>16)+1)|temp;//设置行起始和结束位置 , [# l; Z/ F; V+ a
  108.                 temp = (sy+height+(LTDC->BPCR&0X7FF))<<16;
    6 f7 }) e: k) C: {) H
  109.                 LTDC_Layer1->WVPCR = (sy+(LTDC->BPCR&0X7FF)+1)|temp;                        //设置列起始和结束位置' R3 U$ D, q6 s
  110.                 pixformat = LTDC_Layer1->PFCR&0X07;                                                                //得到颜色格式
    % R. B1 W; X6 G' x0 t  L
  111.                 if(pixformat == 0)temp=4;                                                                                //ARGB8888,一个点4个字节  D% B3 A/ ~( U+ _5 h/ [) i
  112.                 else if(pixformat == 1)temp=3;                                                                        //RGB888,一个点3个字节0 \9 t( i$ i% P" K3 c, I
  113.                 else if(pixformat==5||pixformat==6)temp=1;                                                //L8/AL44,一个点1个字节
    6 ^9 D  X; ?+ U4 H
  114.                 else temp=2;                                                                                                        //其他格式,一个点2个字节, N2 K' o9 f6 @6 L
  115.                 LTDC_Layer1->CFBLR = (width*temp<<16)|(width*temp+3);                        //帧缓冲区长度设置(字节为单位)
    - E8 m5 f7 ]3 S3 D3 G' X* \
  116.                 LTDC_Layer1->CFBLNR = height;                                                                        //帧缓冲区行数设置        % `, B9 A# |: K& L2 w
  117.                   m8 q' B" B  M# f% L
  118.                 //记录层窗口大小位置信息
    - R: B5 w2 ]% o% x% {: y/ U, Z5 G8 P* l
  119.                 sg_LTDC_ConfigData.LayerConfig[0].sx = sx;               
      @$ t8 e$ D2 q( F  c/ t, Q3 g1 T! v
  120.                 sg_LTDC_ConfigData.LayerConfig[0].sy = sy;        
    / X3 O; U) I; u4 g
  121.                 sg_LTDC_ConfigData.LayerConfig[0].width = width;        
    * f6 h8 ]. S& G* b. E/ f* u; l! A
  122.                 sg_LTDC_ConfigData.LayerConfig[0].height = height;        
    ' ~5 ]) o$ {! V" I8 `
  123.         }else
    ! _& ^1 x: c& R7 f8 [# z0 [" w) J5 u
  124.         {
    # b+ F+ u) B, w1 K
  125.                 //基本配置6 V, a3 F# ^8 P8 _5 e9 F
  126.                 LTDC_Layer2->CFBAR = FrameBuff;                                                                        //设置层颜色帧缓存起始地址' W5 g" y0 S" {: D
  127.                 LTDC_Layer2->PFCR = LTDC_PIXEL_FORMAT;                                                        //设置层颜色格式5 g/ E) H* A1 c5 P' A
  128.                 LTDC_Layer2->CACR = Alpha;                                                                                //常数 Alpha,255分频;设置255,则不透明: r: m7 c6 W3 ^; h
  129.                 LTDC_Layer2->DCCR = 0x00;                                                                                //设置默认颜色:透明的黑色
    : W2 \1 Q$ a' |! C: [
  130.                 LTDC_Layer2->BFCR = ((u32)6<<8)|7;                                                                //设置层混合系数
    7 u0 }1 S9 @' a% ?% X  i, y
  131.                 //配置窗口: k) ?! u, x" f9 i5 C& W: Q5 N
  132.                 temp = (sx+width+((LTDC->BPCR&0X0FFF0000)>>16))<<16;
    ( G# @, n- `3 n, L/ G
  133.                 LTDC_Layer2->WHPCR = (sx+((LTDC->BPCR&0X0FFF0000)>>16)+1)|temp;        //设置行起始和结束位置 - n; G- b5 E4 E& h0 v1 [% _& B
  134.                 temp = (sy+height+(LTDC->BPCR&0X7FF))<<16;
    : B# n* X! h: N( P* W) _% b( u
  135.                 LTDC_Layer2->WVPCR = (sy+(LTDC->BPCR&0X7FF)+1)|temp;                        //设置列起始和结束位置& F4 p* W- t+ J  }5 E+ s- t6 s
  136.                 pixformat = LTDC_Layer2->PFCR&0X07;                                                                //得到颜色格式
    " C' j% A3 {# H/ x7 z
  137.                 if(pixformat == 0)temp=4;                                                                                //ARGB8888,一个点4个字节5 ?) W' d- S: ~& T  q& }! v8 _' p
  138.                 else if(pixformat == 1)temp=3;                                                                        //RGB888,一个点3个字节
    1 |9 r6 L  i. y& t5 C0 }6 R
  139.                 else if(pixformat == 5||pixformat==6)temp=1;                                        //L8/AL44,一个点1个字节5 E* o) U2 C, D' ?: o7 q  y
  140.                 else temp = 2;                                                                                                        //其他格式,一个点2个字节% q, }$ B/ K2 h' _: i2 _) _
  141.                 LTDC_Layer2->CFBLR = (width*temp<<16)|(width*temp+3);                        //帧缓冲区长度设置(字节为单位)
    4 I6 H* _( K% G  S
  142.                 LTDC_Layer2->CFBLNR = height;                                                                        //帧缓冲区行数设置        
      P( n3 l# Y+ D. V* p
  143.                
    , p7 _) ~# i. C2 O  v- H# O, c' p
  144.                 //记录层窗口大小位置信息
    ) {3 ^* |0 h, E9 G/ E
  145.                 sg_LTDC_ConfigData.LayerConfig[1].sx = sx;               
    ' a) p! {, C4 z
  146.                 sg_LTDC_ConfigData.LayerConfig[1].sy = sy;        . s# H5 {$ A$ D, n/ |8 C: g: o
  147.                 sg_LTDC_ConfigData.LayerConfig[1].width = width;        
    # g' u: K3 }1 m/ R, q
  148.                 sg_LTDC_ConfigData.LayerConfig[1].height = height;               
    4 T' D$ q9 z3 R  B2 f9 y: e" k
  149.         }5 M6 V! ]$ }7 Z( ^
  150. }
    + j) i9 J1 [$ T; }

  151. * N+ c! Y- `0 p% b! i9 b& K* T6 E7 t: Q
  152. ' ?, _2 y8 A/ J2 m- v0 Z$ p# s. f/ M
  153. 8 j4 L, \* C# ?8 E
  154. /*************************************************************************************************************************
    - h/ G" b5 r9 \5 D  J) W  I8 Z
  155. * 函数        :                        void LTDC_Init(void)& I, _  H* k/ m+ d" x
  156. * 功能        :                        LTDC 接口初始化
    * V( d9 i+ E! c+ D) M) q
  157. * 参数        :                        无+ _" q7 }, k! q0 s5 C
  158. * 返回        :                        无3 H, J; N1 J: a6 \
  159. * 依赖        :                        底层宏定义3 }- k' a" _8 [
  160. * 作者        :                        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    ( I  P# {/ g/ s4 F* c+ ]. A
  161. * 时间        :                        2019-09-08
    9 R, L. U# L6 N- @# Y: B
  162. * 最后修改时间 :         2019-09-086 z- x5 Q, e4 S/ |& s1 ]
  163. * 说明        :                         用于初始化STM32F7 LTDC 接口
    9 q8 H1 i! S. {  W( Q" g
  164. *************************************************************************************************************************/  
    9 d* p' Z, K& x6 m% p% e! n+ q4 e
  165. void LTDC_Init(void)+ [0 z9 ^( b0 X' U) w6 n5 c1 ]- N
  166. {0 ~0 |2 {; T3 U* A) B$ V
  167.         u32 temp;, e# B" r) q& y1 p
  168.         5 [. w1 u0 @. [* r0 ~: n4 f& B
  169.         SYS_DeviceClockEnable(DEV_LTDC, TRUE);        //LTDC时钟使能
    " v6 g8 }2 L2 K/ e! j
  170.         SYS_DeviceReset(DEV_LTDC);                                //STM32F7外设复位$ W4 x; @" n; S) O* E! _
  171.         SYS_DeviceClockEnable(DEV_GPIOE, TRUE);        //使能GPIOE时钟
    6 J4 [- e; X2 @# I0 c
  172.         SYS_DeviceClockEnable(DEV_GPIOG, TRUE);        //使能GPIOG时钟
    , i1 r8 F2 m; X+ p5 o+ f- g
  173.         SYS_DeviceClockEnable(DEV_GPIOJ, TRUE);        //使能GPIOJ时钟7 K, c  c; q6 S: {
  174.         SYS_DeviceClockEnable(DEV_GPIOK, TRUE);        //使能GPIOK时钟
    5 X: r! P% P/ c# g7 W3 ?' {2 G
  175.         SYS_DeviceClockEnable(DEV_GPIOI, TRUE);        //使能GPIOI时钟: D8 f$ Q; F8 j$ b* J: Q

  176. 0 Q* _, N/ S7 r% ]* F; j
  177.         # ]( S( Z0 U; I. C0 b+ E+ H# ^
  178.         //初始化IO
    7 ^: ?! L# i7 @5 S8 J
  179.         SYS_GPIOx_Init(GPIOE, BIT4, AF_PP_OPU, SPEED_100M);                                                                                //PE4
    ! L% S0 r$ ^" \' F1 W, X# J
  180.         SYS_GPIOx_Init(GPIOG, BIT12, AF_PP_OPU, SPEED_100M);                                                                        //PG12
    " ]. i, c' ]  k! |8 U; K, F# }
  181.         SYS_GPIOx_Init(GPIOJ, 0Xffff&(~BIT12), AF_PP_OPU, SPEED_100M);                                                        //PJ0~11/13/14/15% \4 v1 }4 O% s! r7 k% `7 X, S
  182.         SYS_GPIOx_Init(GPIOK, BIT0|BIT1|BIT2|BIT4|BIT5|BIT6|BIT7, AF_PP_OPU, SPEED_100M);                //PK0/1/2/4/5/6/7
      a3 s& l+ n  U% ~
  183.         SYS_GPIOx_Init(GPIOI, BIT9|BIT10|BIT14|BIT15, AF_PP_OPU, SPEED_100M);                                        //PI9/10/14/15
    , J; r; I3 i- P% _
  184.         
    7 D- F5 `" f6 U+ L! U2 X
  185.         SYS_GPIOx_SetAF(GPIOE, 4, AF14_LTDC);                //PE4,AF14        
    0 j9 _& @* B! x
  186.          SYS_GPIOx_SetAF(GPIOG, 12, AF14_LTDC);                //PG12,AF14        & J2 S# _1 a, n; ~2 S! M9 j
  187.         SYS_GPIOx_SetAF(GPIOJ, 0, AF14_LTDC);                //PJ0,AF14# B7 _6 v# Y% o8 N/ z6 n
  188.         SYS_GPIOx_SetAF(GPIOJ, 1, AF14_LTDC);                //PJ1,AF14
    $ K5 L% q8 W6 p9 G& R
  189.         SYS_GPIOx_SetAF(GPIOJ, 2, AF14_LTDC);                //PJ2,AF14
    7 N' Z5 M0 \/ H; L' |
  190.         SYS_GPIOx_SetAF(GPIOJ, 3, AF14_LTDC);                //PJ3,AF14( W( [; q3 m0 ^, s8 E
  191.         SYS_GPIOx_SetAF(GPIOJ, 4, AF14_LTDC);                //PJ4,AF14
    / M( g" M' B+ }5 \- w+ G
  192.         SYS_GPIOx_SetAF(GPIOJ, 5, AF14_LTDC);                //PJ5,AF14  A8 k# n- j* y: ~& l* j6 A" ~# R
  193.         SYS_GPIOx_SetAF(GPIOJ, 6, AF14_LTDC);                //PJ6,AF14
    , D9 F+ v" }+ C  N. a/ {
  194.         SYS_GPIOx_SetAF(GPIOJ, 7, AF14_LTDC);                //PJ7,AF14
    1 J; {1 ~* K8 u) C* Q
  195.         SYS_GPIOx_SetAF(GPIOJ, 8, AF14_LTDC);                //PJ8,AF14
    8 S+ A! a& Z6 {+ n+ l
  196.         SYS_GPIOx_SetAF(GPIOJ, 9, AF14_LTDC);                //PJ9,AF14& v) ]' B5 S, O. x: u4 h, u
  197.         SYS_GPIOx_SetAF(GPIOJ, 10, AF14_LTDC);                //PJ10,AF14
    ! n) y" p) a' g: e' k" x, z% [2 Y
  198.         SYS_GPIOx_SetAF(GPIOJ, 11, AF14_LTDC);                //PJ11,AF14% X2 e( s2 `! |4 c8 l/ i
  199.         SYS_GPIOx_SetAF(GPIOJ, 13, AF14_LTDC);                //PJ13,AF14( U3 R5 o& e7 k0 C( }
  200.         SYS_GPIOx_SetAF(GPIOJ, 14, AF14_LTDC);                //PJ14,AF148 |' o6 u. b' C' l8 J
  201.         SYS_GPIOx_SetAF(GPIOJ, 15, AF14_LTDC);                //PJ15,AF14
    4 e# n" Y* K! }7 a2 R
  202.         
    8 K  A6 \9 w/ ]6 H
  203.         SYS_GPIOx_SetAF(GPIOK, 0, AF14_LTDC);                //PK0,AF14* ?% V1 ]: N- {; M
  204.         SYS_GPIOx_SetAF(GPIOK, 1, AF14_LTDC);                //PK1,AF14. ^. n/ m) Z5 [$ Z$ r' e
  205.         SYS_GPIOx_SetAF(GPIOK, 2, AF14_LTDC);                //PK2,AF14' E3 h( _" U: Z
  206.         SYS_GPIOx_SetAF(GPIOK, 4, AF14_LTDC);                //PK4,AF14
    7 L* v) f- A5 V7 q- B; }1 t. z
  207.         SYS_GPIOx_SetAF(GPIOK, 5, AF14_LTDC);                //PK5,AF14( j2 Z) H) m6 i
  208.         SYS_GPIOx_SetAF(GPIOK, 6, AF14_LTDC);                //PK6,AF14& n/ J7 k  ]# e) Z
  209.         SYS_GPIOx_SetAF(GPIOK, 7, AF14_LTDC);                //PK7,AF142 T% v1 `, h& p: K
  210.         7 L3 _. n- {7 g7 R0 h
  211.          SYS_GPIOx_SetAF(GPIOI, 9, AF14_LTDC);                //PI9,AF14' \5 }6 H, m, j# I  \+ q4 I( K( B- c8 R
  212.          SYS_GPIOx_SetAF(GPIOI, 10, AF14_LTDC);                //PI10,AF14 / @3 ?0 Z- c. }! f9 i( m' q- r
  213.         SYS_GPIOx_SetAF(GPIOI, 14, AF14_LTDC);                //PI14,AF14) C; J* C& N/ ]' x
  214.          SYS_GPIOx_SetAF(GPIOI, 15, AF14_LTDC);                //PI15,AF14 * |9 L. |4 R8 R3 ]/ p$ O
  215.         
    , O2 A5 ^/ r0 c
  216.         LTDC_ClockInit(DefaultLCD_Info.DCLK);                 //设置像素时钟  9Mhz
    % ?/ K0 Y$ [8 s! _- Q, k
  217.         //设置LTDC 全局控制寄存器 (LTDC_GCR)$ |: z0 @" K5 K1 ^
  218.         temp = 0;
    7 j! Z6 Q4 Z* ]1 T. h6 Z4 Z- ]8 C% j
  219.         temp |= (DefaultLCD_Info.HSPOL&0x01) << 31;        //水平同步极性6 D  e" I% x" b! g; g
  220.         temp |= (DefaultLCD_Info.VSPOL&0x01) << 30;        //垂直同步极性
    " ]6 O2 D1 ~) T" Y  h- ~5 l7 N
  221.         temp |= (DefaultLCD_Info.DEPOL&0x01) << 29;        //数据使能极性
    " m- t" d6 z+ s) f" b
  222.         temp |= (DefaultLCD_Info.PCPOL&0x01) << 28;        //像素时钟极性
    " c( c8 \' L8 g" V2 V, a
  223.         LTDC->GCR = temp;8 A% \0 O# C9 h8 U3 I% s
  224.         //LTDC 后沿配置寄存器 (LTDC_BPCR)
    , N) d+ K( m+ C# c* k
  225.         temp = (DefaultLCD_Info.Tvw + DefaultLCD_Info.Tvbp - 1) << 0;        //这些位定义累加水平后沿宽度(水平同步像素加水平后沿像素减 1)。) K# X* {0 H- R+ ~6 o3 `
  226.         temp |= (DefaultLCD_Info.Thw + DefaultLCD_Info.Thbp - 1) << 16;        //这些位定义累加垂直后沿宽度(垂直同步行加垂直后沿行减 1)。
    3 f6 `3 D5 V! |4 ^0 y# ?# Q0 ^$ f
  227.         LTDC->BPCR=temp;        ! C1 V4 X. \" h6 |" e, J2 C
  228.         1 \& ^. Z3 [9 f. A% L. L8 r
  229.         //LTDC 有效宽度配置寄存器 (LTDC_AWCR)# o9 b# C  ^2 L. v  S9 w
  230.         temp=(DefaultLCD_Info.Tvw+DefaultLCD_Info.Tvbp+DefaultLCD_Info.Height-1)<<0;        //累加有效高度=垂直脉宽+垂直后沿+垂直分辨率-1
    * q7 [3 B' T7 R7 F. @$ z( x
  231.         temp|=(DefaultLCD_Info.Thw+DefaultLCD_Info.Thbp+DefaultLCD_Info.Width-1)<<16;        //累加有效宽度=水平脉宽+水平后沿+水平分辨率-1
    ) _! i# X, k: T: Z
  232.         LTDC->AWCR=temp;        
    ) b6 F( s5 h" u  E2 s7 H2 ^$ L# h
  233.         //LTDC 总宽度配置寄存器 (LTDC_TWCR); {' ~: n: ^- o1 q% B0 k) p
  234.          temp=(DefaultLCD_Info.Tvw+DefaultLCD_Info.Tvbp+DefaultLCD_Info.Height+DefaultLCD_Info.Tvfp-1)<<0;        //总高度=垂直脉宽+垂直后沿+垂直分辨率+垂直前廊-1/ r; ^  v9 H4 ?7 q. f4 v
  235.         temp|=(DefaultLCD_Info.Thw+DefaultLCD_Info.Thbp+DefaultLCD_Info.Width+DefaultLCD_Info.Thfp-1)<<16;        //总宽度=水平脉宽+水平后沿+水平分辨率+水平前廊-1
    # A$ X0 I" ^7 C1 c
  236.         LTDC->TWCR=temp;                                
    + n$ f/ |$ R2 w

  237. " E3 R9 e& U% y5 Z3 y
  238.         //背景设置
    # |& o0 p$ T& y5 f5 W# `
  239.         LTDC->BCCR=0xffffff;                                //设置背景层颜色寄存器(RGB888格式)
    1 [4 ]. Z4 e. l
  240.         LTDC_Enable(TRUE);                                        //开启LTDC
    7 h( S; z' F& |0 y# ^% Z) x
  241.         //初始化层1
      P5 p; |0 ]* l. f; Z
  242.         LTDC_SetLayerConfig(0, 0, 0, LTDC_WIDTH, LTDC_HEIGHT, (u32)g_LTDC_BUFF_RGB888[0], 255);
    & y5 P, e4 ~/ W# u5 |4 {
  243.         //初始化层22 F/ `& c- P; P3 j" j* L8 J; e
  244.         LTDC_SetLayerConfig(1, 0, 0, LTDC_WIDTH, LTDC_HEIGHT, (u32)g_LTDC_BUFF_RGB888[1], 255);$ X1 V3 F3 M1 }! \
  245.         LTDC_Clear(0, 0xFF000000);                        //清屏层1-不透明的黑色
    1 F. V9 I: S0 R9 Y" G- ^
  246.         LTDC_Clear(1, 0x00000000);                        //清屏层2-透明的黑色
    - v+ e3 x2 x% t" {( L
  247.         LTDC_LayerEnable(0, TRUE);                        //使能层1; y6 ]/ i# A4 a% r
  248.         LTDC_LayerRefreshConfig();                        //LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)
    - K& T1 w" \) H; D9 o
  249.         LCD_DispIoInit();                                        //初始化DISP引脚-启动显示
    6 k7 a  Y9 y  K& P) v- }( x2 E3 ^
  250. }( }# y) S* V2 v  [* g

  251. 2 H0 R6 l5 ]8 t1 M7 |
  252. /*************************************************************************************************************************
    % e" h& h6 y" Z& o9 \; \
  253. * 函数                        :        void LTDC_LayerRefreshConfig(void)
    5 e4 W- h" ?& C/ T% |7 p
  254. * 功能                        :        LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)/ Z4 K' ^0 {2 o. k2 X
  255. * 参数                        :        无
    8 ?9 W% w$ B+ M7 u2 X9 T
  256. * 返回                        :        无, V# h* n% |, A6 J: ]& s
  257. * 依赖                        :        底层宏定义, d) E) A/ v2 i9 M" d6 Z
  258. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    & x& ^, P7 N/ q, ?0 H; [  W
  259. * 时间                        :        2019-10-29
    0 B! ^/ x2 }9 Y. w5 G5 U
  260. * 最后修改时间         :         2019-10-29
    , r9 ?) \& Y; A0 v
  261. * 说明                        :        修改层配置后必须重新加载,否则不会生效' y6 j+ T4 P1 m: \: P
  262. *************************************************************************************************************************/
    ) X5 L. o; Q. w$ g" @0 W" p
  263. void LTDC_LayerRefreshConfig(void)
    9 z0 B6 {$ L* F0 \
  264. {  b8 t! @: _3 J) R
  265.         LTDC->SRCR|=1<<0;                                                        //重新加载配置-必须重新加载,否则上面的层不会更新,折腾好久才发现,叫啥影子寄存器重载,也不说清楚
    0 y" E6 G: d+ M9 g4 l$ y9 o( T
  266. }% A& Y( ^' d4 y, d; g

  267. 4 [1 {2 W  B6 B( J9 \3 Y9 ?
  268. /*************************************************************************************************************************0 ~( L8 x- d  U& U7 u2 h, w, ?7 I
  269. * 函数                        :        void LTDC_Enable(bool Enable)( e5 R* k$ T$ e
  270. * 功能                        :        LTDC使能设置! q: I! O5 Z+ x4 s/ E$ V
  271. * 参数                        :        Enable:TRUE:使能;FALSE:失能
    + m, E% y- u( s# G( h1 x, I* h
  272. * 返回                        :        无' x. n# C; K/ ]) Q3 g9 d6 [; Q7 n3 }5 f4 h
  273. * 依赖                        :        底层宏定义
    2 {+ p  v) a& \! B6 O* N3 }
  274. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>+ y6 @. @6 v# p. [
  275. * 时间                        :        2019-10-29( k1 O' t  t7 m
  276. * 最后修改时间         :         2019-10-299 q+ b. h1 P! A, q! M
  277. * 说明                        :        - z+ @% L, ~$ P4 H  l& L9 X
  278. *************************************************************************************************************************/( `! R3 _# Y9 h. V1 F2 y
  279. void LTDC_Enable(bool Enable)
    * O1 G0 a* v' Z5 x  x  ~8 i2 i# x
  280. {
    . H* k- H  g% V$ e
  281.         if(Enable)+ N) q) S; t8 ^% ]
  282.         {
    6 m! F' C0 ~2 j+ `
  283.                 LTDC->GCR |= BIT0;                                        //打开LTDC' G' H2 h8 \, H$ T/ w- K# c: T
  284.         }8 D% S& C$ f. h6 A- y: D
  285.         else
    ( X7 Y( P! C* _7 ~3 D
  286.         {
    8 c  S+ [3 x5 d: m7 b
  287.                 LTDC->GCR &= ~BIT0;                                        //关闭LTDC
    2 U+ R& a* v  m7 ~3 [
  288.         }# a0 W8 `5 q) g
  289. }4 T, x: I; @+ P5 ]: @+ r

  290. ; I* Z7 }( q  ^1 \* k
  291. /*************************************************************************************************************************
    % J# h0 m, x8 C8 u3 G
  292. * 函数                        :        void LTDC_LayerEnable(u8 LayerIndex, bool Enable), b  U& M7 T, f2 F
  293. * 功能                        :        LTDC 层使能设置* ?" \5 U  @5 }% l& @1 Q7 D
  294. * 参数                        :        LayerIndex:层选择0-1;Enable:TRUE:使能;FALSE:失能
      b  T# b# ^2 `- ]/ R
  295. * 返回                        :        无
    ' n: \. y$ Q/ ]3 n
  296. * 依赖                        :        底层宏定义. h. u2 [# u3 W8 x
  297. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>' h, b$ p/ r5 V; R( X$ G
  298. * 时间                        :        2019-10-29
    , X7 s1 G% R& H+ E6 P
  299. * 最后修改时间         :         2019-10-29
    ' e$ i/ @) ^# y( v0 M+ O/ d) b
  300. * 说明                        :        2 I# d# ~! n3 e% g4 D6 |! e
  301. *************************************************************************************************************************/
    $ D. w1 j! i3 Y& s4 a* C
  302. void LTDC_LayerEnable(u8 LayerIndex, bool Enable)5 b8 O& C0 l& w/ E! U* Z. t- r
  303. {
    9 f) _2 f2 T9 A7 o- o6 j
  304.         if(Enable)
    0 A- |( T! w: @( w/ z' C
  305.         {1 _* u8 i6 Z9 y2 P  [8 X
  306.                 if(LayerIndex == 0)                                        //层16 L/ {6 }) r0 m9 [. D7 e# {# J
  307.                 {
    ) D8 ~; y2 L1 R: z3 _' X
  308.                         LTDC_Layer1->CR |= BIT0;                //使能层1
    . U* l' `3 w1 G. U3 o
  309.                 }/ F6 k* P6 |7 `% _
  310.                 else" D' E. i2 P. _/ i3 A# G
  311.                 {8 g7 }! [) I/ i& u7 L
  312.                         LTDC_Layer2->CR |= BIT0;                //使能层2
    $ A1 _/ a# v# w, R. G$ p: h
  313.                 }
    4 k1 m% C% C1 v7 {
  314.         }9 ?% s* {) C% L  K9 d
  315.         else: M1 a7 r0 h3 Z
  316.         {
    " |% \4 \* Q# W! W  z; B% v
  317.                 if(LayerIndex == 0)                                        //层1
    7 S0 k: _  {- U5 u% ]
  318.                 {
    . @( Z& O% i+ ^+ \3 `! t
  319.                         LTDC_Layer1->CR &= ~BIT0;                //失能层1
    % U& N+ k4 ?* X0 n3 {) z
  320.                 }
    # Z( p( |, d6 M- b
  321.                 else
    $ J1 ]: v! W- |, m: X+ R
  322.                 {
    8 a( Y9 E5 }% o3 v: Q3 A
  323.                         LTDC_Layer2->CR &= ~BIT0;                //失能层20 Q. M- ~" B) f
  324.                 }
    / ^  h) T: e; L8 F. p
  325.         }6 B$ t" c& P7 ^/ D: e6 p4 _' f
  326. }
    ' Y* `% ~) r2 A+ N& N

  327. 3 V2 a8 n$ U" J0 ]& p
  328. 9 l8 P# U, E* k

  329. $ i& q4 N& v( u* z% S

  330. 5 o! B& l5 V& J
  331. /*************************************************************************************************************************. Y% ~3 O$ c$ l' O
  332. * 函数                        :        bool LTDC_ClockInit(u16 ClockFreq)                        
    4 e/ O2 j5 E4 w7 p
  333. * 功能                        :        STM32F7 LTDC时钟初始化* k- ]7 g4 G9 S  _& c# ^" P
  334. * 参数                        :        ClockFreq:时钟频率,2-168MHZ
      Z- g3 q. e% n
  335. * 返回                        :        是否设置成功+ o( q# {' o) F$ K
  336. * 依赖                        :        底层宏定义5 S  f$ E# D) Q$ J5 T
  337. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    " j% f9 o" z: ?0 C8 T" J' G
  338. * 时间                        :        2019-10-28
    3 Z+ I& [" Z( O& I/ ~2 F! R# A8 t) t
  339. * 最后修改时间         :         2019-10-28# S6 Y# R2 w6 h  J* J
  340. * 说明                        :        输入时钟频率在系统主时钟初始化之后就会设置为1MHz,通过设置SAI PLL实现LTDC所需频率,VCO频率范围:49~432
    ) o9 Z+ b! U/ j$ i/ {+ f0 l- |8 J
  341. *************************************************************************************************************************/
      L# O% y, A5 Y3 @, R
  342. bool LTDC_ClockInit(u16 ClockFreq)& u* Z' k- ~' x: b  }
  343. {7 Q+ d+ P& P: @* [& d, |
  344.         u32 TimeOut = 0;
    0 o8 l: Q) l% Z( e! c+ D" w' T
  345.         u32 VCO;6 k9 Y' T& T& A1 r8 I
  346.         u32 PLLSAIR;                //PLLSAICFGR[30:28]
    2 q( f5 }3 W# [
  347.         u32 PLLSAIDIVR;                //DCKCFGR1[17:16]
    8 G- k5 h( V4 k  R
  348.         u32 temp;
    + Q! r' }( O; r* l7 {, ~' P
  349.         % E/ ?9 ^0 v0 M3 {
  350.         if(ClockFreq < 1)ClockFreq = 1;; d# N/ x6 g9 S3 t
  351.         if(ClockFreq > 100) ClockFreq = 100;
    6 P. f8 N$ F  m
  352.         
    ' X2 ~- S& g8 i1 K+ R
  353.         RCC->CR &= ~(1<<28);                                                //关闭SAI时钟 $ ~, W: m1 h& a# F
  354.         TimeOut = 0;
    + g8 C1 i# p6 i  Y1 k# C
  355.         while(RCC->CR&(1<<29))                                                //等待关闭成功" h* \* h' J9 ?' f0 @
  356.         {, k* L! j3 p8 n8 z8 D" d- r
  357.                 nop;3 ]" T" ~! y7 ]5 f- D
  358.                 TimeOut ++;
    4 X# a' |/ h3 s$ a2 ?6 `1 A/ c* p. p' ^
  359.                 if(TimeOut > 0xFFFF) return FALSE;                //关闭超时$ _  _" B; x( C# C- u" L$ q
  360.         }
    5 b/ [  r+ X& E2 }8 l; x/ C
  361.         //计算分频与VCO频率,通过PLLSAICFGR[30:28]可以设置2-7分频! j+ F1 U; q! ?% B
  362.         //通过PLLSAICFGR[17:16]可以设置00:2 01:4 10:8 11:16分频) C6 c" x. |- `0 Q$ |8 h# e
  363.         //通过PLLSAICFGR[14:6]可以设置为49-432MHz的VCO频率
    + ]: s% I7 f8 ^$ p6 S, V6 R; p; T6 x" Z" j
  364.         if(ClockFreq <= 6)
    / ]+ ^; F4 P1 R' o2 V6 ]
  365.         {! P1 l9 u: {9 l9 @; g. r' l
  366.                 PLLSAIR = 4;        //4分频& L4 I+ w) X- E5 S4 n# W: m. U
  367.                 PLLSAIDIVR = 3;        //16分频
    2 D6 @& ^4 n5 Q$ Z* H- u
  368.                 VCO = ClockFreq * PLLSAIR * 16;                        //VCO范围:64-384;
    & z  {4 _8 P5 O* n9 a( v; H
  369.         }0 b0 O. ]4 _; U4 P& `  V3 C
  370.         else if(ClockFreq <= 13)
    # Y. m' f2 }9 E4 X
  371.         {
    . n9 `6 `$ w% y, M3 g3 t
  372.                 PLLSAIR = 4;        //4分频
    6 v4 X- i% n" e. H: n, L( p3 i; @/ p
  373.                 PLLSAIDIVR = 2;        //8分频
    - j; @6 p! K) q8 d6 b& j2 o
  374.                 VCO = ClockFreq * PLLSAIR * 8;                        //VCO范围:224-416;
    ( h3 a2 u8 X, c' o/ u- n- _
  375.         }5 b7 z1 u9 j, H5 }; o* j
  376.         else if(ClockFreq <= 26)
    ; y, ]. V% @* i8 B+ X" i
  377.         {/ N* k/ j; a  o# A2 k
  378.                 PLLSAIR = 2;        //2分频
    + T/ L4 i) `& O/ z# m
  379.                 PLLSAIDIVR = 2;        //8分频
    # I9 Z& {: m4 k! s6 M
  380.                 VCO = ClockFreq * PLLSAIR * 8;                        //VCO范围:224-416;
    1 V+ A; x, b, [( p5 L
  381.         }
    . l. P# N( L! o  _; o
  382.         else if(ClockFreq <= 52)
    3 B( y0 ~- L( r6 t
  383.         {
    . z3 M; h* c- T% R8 G
  384.                 PLLSAIR = 2;        //2分频8 c+ P  D8 |% i- L, A$ U$ f, c* Q
  385.                 PLLSAIDIVR = 1;        //4分频
    ) {4 k* A. y5 l- f2 ^  J
  386.                 VCO = ClockFreq * PLLSAIR * 4;                        //VCO范围:216-416;
    ) c, `- p; L: ~7 O
  387.         }: L  `6 I0 g5 L3 i$ @& {
  388.         else if(ClockFreq <= 104)
    1 S4 {# i3 E& K# X
  389.         {
    " F* Z; d! v7 F* @/ t) k
  390.                 PLLSAIR = 2;        //2分频
    ! u. N: d( [, J3 ?4 b1 A
  391.                 PLLSAIDIVR = 0;        //2分频
    : }" U7 Q4 f8 G1 g4 _
  392.                 VCO = ClockFreq * PLLSAIR * 2;                        //VCO范围:212-416;
    & R( Y) l; h( C) v0 q% b
  393.         }- W; d' Z3 M! }
  394.         //设置PLLSAICFGR3 }/ a1 A% A) Z# {& _# {
  395.         temp = RCC->PLLSAICFGR;
    9 k4 t6 f$ I1 k/ c& d
  396.         temp &= ~((3<<28) | (0x1FF<<6));                        //清除之前的设置3 M8 F, [5 L9 [, |5 }7 B
  397.         temp |= PLLSAIR << 28;                                                //设置分频PLLSAICFGR[30:28]
    ) Y  p  b' S; \7 w% O7 Q
  398.         temp |= VCO << 6;                                                        //设置VCO
    ; _6 G" m$ n) G7 _+ G; C
  399.         RCC->PLLSAICFGR = temp;* B1 Y. C2 F. g  w# \
  400.         //设置DCKCFGR1
    0 l, K* p8 A3 Z0 z* H" I" g
  401.         temp = RCC->DCKCFGR1;
    3 O+ k! H4 e0 L2 J) x
  402.         temp &= ~(3<<16);                                                        //清除之前的设置
    ' o/ Q$ B6 Z. I' y: y  [  x7 q
  403.         temp |= PLLSAIDIVR << 16;                                        //设置分频DCKCFGR1[17:16]) f0 h* o, f' g8 j& `* q4 y6 r
  404.         RCC->DCKCFGR1 = temp;0 L& Z9 c* z" M/ @
  405.         //启动时钟6 b, W* Q$ K' }6 x' z
  406.         RCC->CR |= 1<<28;                                                        //启动SAI时钟  Z7 |6 l3 k& f) N& V. x( H1 u
  407.         TimeOut = 0;% A  X+ `7 Y  [5 Z+ u; j3 S8 F
  408.         while((RCC->CR&(1<<29)) == 0)                                //等待开启成功4 J* v3 d$ R* d# U( ]% O, [
  409.         {
    : Q2 b  f0 f6 ~. C
  410.                 nop;( b# o4 k( X' E2 j- O9 B, H& x
  411.                 TimeOut ++;
    + I  J- i' [4 `/ W2 L- W, b7 y
  412.                 if(TimeOut > 0xFFFF) return FALSE;                //开启超时
    " b& _/ B0 ^1 J  H3 f5 }% Y+ J1 R# Q+ m
  413.         }
    / B: e! b! v+ C6 _
  414.         % h/ w% R' L$ j- r
  415.         return TRUE;
    ; w. \9 T' x6 A* |
  416. }6 X4 x8 K! @$ @$ Z, p+ v

  417. 3 t" G9 m/ j0 {0 I

  418. 4 o" z! \. y  D& N. w
  419. /*************************************************************************************************************************4 w% F0 i3 T/ x5 o" u! X' u
  420. * 函数                        :        void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color)        
    4 v' k- w. w6 d- E) Z8 v
  421. * 功能                        :        矩形填充(使用DMA2D): P  Q, N, D4 i7 J( G, x
  422. * 参数                        :        LayerIndex:层选择0-1;sx,sy:开始坐标;ex,ey:结束坐标,color:需要填充的颜色
    2 i8 [) I( @% i# E" \
  423. * 返回                        :        无
    ( k4 Q8 \2 e! |6 x9 ]
  424. * 依赖                        :        底层宏定义+ v, ?, R6 n1 u: E# ~- N  v" P9 ^
  425. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    % Y8 \6 L9 P# e$ `9 a$ c/ ]* ]
  426. * 时间                        :        2019-10-30
    - f+ X+ u$ b% y7 v4 X& V. R
  427. * 最后修改时间         :         2019-10-30
    , |0 i9 R! f3 R8 u1 O( X' b* E
  428. * 说明                        :        采用DMA2D实现
    9 R7 a6 r' \8 B
  429. *************************************************************************************************************************/
    ; v- }3 M7 W0 |; ]
  430. void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color)8 ^% c) q* \* @' A& _: c9 d/ O. G4 }
  431. {! n9 n: D5 l$ ~' ~1 _( M4 ]: n
  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进行单色填充; M% m+ N% C  q: F& C
  433.         DMA2D_WaitTransferComplete(500);                                                                                                                                                                                                                                //等待DMA2D传输完成( r+ G4 D' W7 Y
  434. }1 c3 f; W8 ], p6 X1 _3 R

  435. 6 H& ?, t9 C: M. @

  436. ' P2 j) Y: d1 x% v
  437. /*************************************************************************************************************************
    4 l" n, C. v' L; I2 s
  438. * 函数                        :        void LTDC_Clear(u8 LayerIndex,u32 color)8 l) T) @6 O3 N( y8 N3 n; D& t
  439. * 功能                        :        清屏(使用DMA2D)
    . j' Y; f; U5 ^0 N8 z/ t6 l9 C
  440. * 参数                        :        LayerIndex:层选择0-1;color:需要填充的颜色& I  ?7 K5 m4 U( r. t
  441. * 返回                        :        无
    2 p: P. e* v1 `4 P" \  l
  442. * 依赖                        :        底层宏定义$ g% Z, W( a, y! O% L' [3 [. @! @
  443. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    ( ~: r9 i& ^/ s
  444. * 时间                        :        2019-10-30
    8 e5 f+ p& Q2 D4 I( |  C9 s, A
  445. * 最后修改时间         :         2019-10-30
    7 R) g$ o7 o9 D: w9 a6 [% _
  446. * 说明                        :        采用DMA2D实现
    6 W1 {  V: Y$ O( Y4 v( u. ]
  447. *************************************************************************************************************************/! c& \# c: {. R5 i- }
  448. void LTDC_Clear(u8 LayerIndex,u32 color). G9 N6 q4 `9 p$ o) W/ {
  449. {
    ) y4 j" e. n. I) n" k- v; \
  450.         DMA2D_FillColorToFGRAM((u32)&g_LTDC_BUFF_RGB888[LayerIndex][0][0], LTDC_WIDTH, LTDC_HEIGHT, 0,  DMA2D_COLOR_ARGB8888, color);                                        //DMA2D进行单色填充( {' M9 L6 ?2 z! p
  451.         SYS_DelayMS(5);
    " j5 i% {3 c' E- k5 D* J* R5 n
  452.         DMA2D_WaitTransferComplete(500);                                                                                                                                                                                                                                //等待DMA2D传输完成3 R; a% b, Q. t
  453. }
    ! X1 n" b. m; G  Z% A/ _$ T
  454. . Y) C3 V! H) s. e

  455. * r/ P5 R; k% h+ S; c6 s. p$ U. Z
  456. /*************************************************************************************************************************! Q, M$ i8 b3 V8 E; y
  457. * 函数                        :        void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr)
    6 ]5 y$ J! o5 O2 z, z7 _+ R8 U
  458. * 功能                        :        矩形图像填充(相同坐标范围传输,要求源图像与目标显示器分辨率一致,使用DMA2D)& i5 d$ n4 C8 s
  459. * 参数                        :        LayerIndex:层选择0-1;sx,sy:开始坐标;ex,ey:结束坐标,ImageAddr:需要填充的图像地址
    : X( Z0 \  b4 r: K
  460. * 返回                        :        无
    ' c; Y. X; P0 S- m. E6 a+ G
  461. * 依赖                        :        底层宏定义
    * |7 R+ P: j/ X. ~( e5 x" C" q
  462. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>9 _  ^8 r4 ?" L8 h5 D5 ~! x) e9 D
  463. * 时间                        :        2019-10-30( G) I$ H( V; g5 [7 R' a9 o
  464. * 最后修改时间         :         2019-10-30
    # J% a4 L# z; |5 d
  465. * 说明                        :        采用DMA2D实现,将源图像指定位置传输到现存,要求源图像与显存大小一致# w) U( c" X& d! c& `9 |
  466. *************************************************************************************************************************/  f3 B, N3 `" |; [7 O# |
  467. void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr)
    + Z1 l3 Q& y2 R8 l( F! y3 A
  468. {
    6 ]8 {3 S6 z" w
  469.         DMA2D_FillImageToFGRAM(ImageAddr+sy*LTDC_WIDTH+sx, (u32)&g_LTDC_BUFF_RGB888[LayerIndex][sy][sx], ex-sx+1, ey-sy+1, LTDC_WIDTH-(ex-sx+1), LTDC_WIDTH-(ex-sx+1), DMA2D_COLOR_ARGB8888);//DMA2D进行矩形图形填充
    5 h( E4 R8 s- B9 l; e# a, {3 j& B
  470.         DMA2D_WaitTransferComplete(500);
    6 a; P8 h1 r9 u8 i0 x/ ?
  471. }
复制代码
  1. /*************************************************************************************************************, |# i# B9 P8 x3 \3 U
  2. * 文件名                :        stm32f7_ltdc.h  Q9 z5 M% C( g& d' t) O: D/ x
  3. * 功能                        :        STM32F7 外部RGB LCD驱动/ B1 ?. N) _2 |* c0 Y! S
  4. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>8 P; X/ Q2 t. R- l
  5. * 创建时间                :        2019-09-12
    7 O5 V* E) s7 e  n# Z/ C; [; \
  6. * 最后修改时间        :        2019-09-12% S: T) _- l* C1 ]
  7. * 详细:        
    & T, o  Q! m" y; U3 n5 c0 Q% j
  8. *************************************************************************************************************/               
    6 y+ n) Y8 V1 g  s
  9. #ifndef __STM32F7_LTDC_H_5 f: Z3 m; d+ K; f/ i* r
  10. #define        __STM32F7_LTDC_H_           
    3 c4 d+ V) L, [: ~' }
  11. #include "system.h"
    " ^8 s' w! M5 i$ l! p7 W
  12. #include "DMA2D.h"
    % n+ q! r9 T! [# t' h3 N
  13. * ^; U5 q: W7 W, D$ U: D
  14. #define LTDC_WIDTH                480; |& Q4 ]8 Z- F( i! d$ h
  15. #define LTDC_HEIGHT                272
    5 l& |7 f7 {3 c5 ?6 i% O# Y
  16. ' q; X, E7 Z2 Z1 I7 V( @& R+ \* e
  17. 6 d% u! Z4 Z, Y% `! p: h
  18. extern u32 g_LTDC_BUFF_RGB888[2][LTDC_HEIGHT][LTDC_WIDTH];( i- i5 m/ p' e: {: K4 E

  19. / l5 \- V# B: r  h& ^& G5 S
  20. //像素格式定义8 W% i" i/ n- F- l, |% r) d: _
  21. typedef enum
    3 u/ f1 `4 }1 D: }/ l7 d
  22. {5 ^  K8 M2 H. _& J$ t3 [+ ?0 A) p
  23.         LTDC_ARGB8888         = 0,: J) P! G) K1 @% ~
  24.         LTDC_RGB888         = 1,( P4 s) n1 A+ L1 E6 _
  25.         LTDC_RGB565         = 2,) y7 Z$ q3 B2 l
  26.         /*LTDC_ARGB1555         = 3,
      @& F2 m  F3 s/ d/ [8 `
  27.         LTDC_ARGB4444         = 4,; {7 e3 S. R  |4 ~, l$ g* I. e
  28.         LTDC_L8                 = 5,        //8 位 Luminance0 O! R7 F+ o( t! |$ `
  29.         LTDC_AL44                 = 6,        //4 位 Alpha,4 位 Luminance. w) Y' O: f: r' j1 X
  30.         LTDC_AL88                 = 7,        //8 位 Alpha,8 位 Luminance*/
    2 e3 \4 _8 _4 Y" _* u4 @8 f
  31. }LTDC_PixelFormat;
    * ?# y1 q0 Q6 c4 U0 _* A/ G1 S! ^
  32. #define LTDC_PIXEL_FORMAT                LTDC_ARGB8888                //选择ARGB8888格式; T5 R/ H0 ~5 p& B2 R5 e
  33. / z7 c# e: }# D! N3 M' W4 w/ h
  34. ( x' M3 M+ `& X+ [8 R! R; s
  35. 9 n& i4 A/ a$ `" O" \; J2 Y
  36. + ^% g9 s3 |6 J# E5 l! I/ j$ b
  37. //画点函数32bit ARGB8888格式  s9 h4 `3 V, p! ^# O4 j  i7 O
  38. __inline void LTDC_DrawPoint(u8 LayerIndex, u16 Xpos,u16 Ypos,u32 ARGB8888_Color)
    & s! m2 O9 Y  w: L$ x
  39. {
    : K0 o" ]; m5 R0 b( g8 F
  40.         g_LTDC_BUFF_RGB888[LayerIndex][Ypos][Xpos] = ARGB8888_Color;
    0 o" U9 H7 ?; p) Q
  41. }
    ' a$ r6 u/ {: O7 U  {% y# u" S

  42. + f  @" p) [* O$ N+ {9 W% `
  43. //初始化DISP引脚+ C- B- i' X( O
  44. __inline void LCD_DispIoInit(void)
    # t+ ^1 t2 |  S! a. i2 l. C3 N+ k8 p
  45. {
    ( S. S' L/ T+ s
  46.         SYS_GPIOx_Init(GPIOI, BIT12, OUT_PP, SPEED_25M);                                                                                                //PI12 LCD_DISP H:正常模式;L:低功耗                                                        
    % Y* T' }0 P0 h5 x
  47.         PIout(12) = 1;                                                                                                                                                                        //DISP = H  2019-10-16:一直忽略将此引脚置为高电平,调试走了很多弯路" U4 Q4 \4 F. A: _: y
  48. }3 H& x# P4 e$ N$ _2 k
  49.   q8 M5 e; R2 Q) I6 Q# q* ^( O, ?
  50. void LTDC_Enable(bool Enable);                                                                                                                                                //LTDC使能设置5 t! ?) ~4 U4 Y, V* s3 g$ J/ W, ]
  51. void LTDC_Init(void);                                                                                                                                                                //LTDC 接口初始化
    $ C' s* X. C, o: G2 d6 v
  52. void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha);//LTDC 层窗口尺寸设置) i9 F9 B- c4 C7 u
  53. void LTDC_LayerEnable(u8 LayerIndex, bool Enable);                                                                                                        //LTDC 层使能设置
    ; R  A+ Y" e' b
  54. void LTDC_LayerRefreshConfig(void);                                                                                                                                        //LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)
    + c( X: [# T/ v4 c  G8 [
  55. - y" ~0 Q4 u! F. Z* V2 a. W5 M9 ]- C" Z
  56. //图形相关API
    ! w: g/ v' q$ ~1 X. ]8 \! l
  57. void LTDC_DrawPoint(u8 LayerIndex, u16 Xpos,u16 Ypos,u32 ARGB8888_Color);                                                        //画点函数32bit ARGB8888格式+ S% G3 V. Z$ G+ _& Y
  58. void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color);                                                                //矩形填充(使用DMA2D)
    + F% ]- [  S( ]3 X
  59. void LTDC_Clear(u8 LayerIndex,u32 color);                                                                                                                        //清屏(使用DMA2D)" Y9 Q6 w8 B/ [. l& d
  60. $ N& u1 E/ V( ?* Z$ z/ N
  61. void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr);//矩形图像填充(相同坐标范围传输,要求源图像与目标显示器分辨率一致,使用DMA2D)
复制代码
9 `3 P8 v4 Q8 A& j/ k' C
+ I1 M7 z, W& m
#endif //__STM32F7_LTDC_H_& d, w  u; \2 \4 |, v
4 W, b! o0 j7 W  Z' u$ D6 B# Q

+ q6 P7 g" r4 e# V8 I% ]9 {& K2 c# d! D
赞 收藏 评论0 发布时间:2021-12-14 10:49

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版