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

【经验分享】STM32f746gdiscovery LTDC 驱动

[复制链接]
STMCU小助手 发布时间:2021-12-14 10:49
需要提前准备好SDRAM驱动,如果没有SDRAM可以进行纯色彩测试,底层时钟,IO操作相关看注释,我使用的是寄存器封装的。: u6 y- {# z+ ^$ A! N/ e

$ N6 a4 Q% l$ |
  1. /************************************************************************************************************** p: Y! \; x, Y/ f9 C
  2. * 文件名                :        stm32f7_ltdc.c
    9 r1 Z+ e: V$ P
  3. * 功能                        :        STM32F7 外部RGB LCD驱动
    1 K: u6 B* a4 B3 C8 Q2 I3 z
  4. * 创建时间                :        2019-09-127 B* f  J/ Y, Z
  5. * 最后修改时间        :        2019-09-12/ e. y& L, M4 s) z! K$ _# m& {/ J
  6. * 详细:        
    9 P/ i( p% q2 m& c/ b0 s0 f
  7. *************************************************************************************************************/        % E: k! S; L* {" t3 ^% h% [
  8. #include "stm32f7_ltdc.h"
    # g- f7 q3 W  I9 D% F6 ]$ b9 X1 u6 ~' z
  9. #include "SYSTEM.H"
    0 R0 L9 t: X2 x# Q6 E
  10. #include "stm32f7_sdram.h"
    3 O' O4 l2 q2 ^4 _2 x# y. J3 c
  11. #include "DMA2D.h"
    & n; s9 U' P" I+ h) u

  12. " `- }1 Q" ~2 a1 K0 C- w, Y, D
  13. % h. E4 u, o) `8 H6 o) \" H
  14. u32 g_LTDC_BUFF_RGB888[2][LTDC_HEIGHT][LTDC_WIDTH]  __attribute__ ((at(Bank5_SDRAM_ADDR)));                //需要SDRAM支持,LCD帧缓冲区,RGB888格式/ b& B# v+ C' R; T8 i. Z* C3 U

  15. ; T  h5 g, |' W) H9 ^! L
  16. + n, T+ @' Y$ M2 N  `; F  H* j1 i
  17. //记录全局层配置信息
    / `* o; M- j0 g1 E. v  o
  18. typedef struct
    + r0 T$ _7 r0 X# e+ F$ x3 x
  19. {
    ) g) `. L9 X$ Q) B2 r- E0 W  R
  20.         u16 sx;                                        //层开始X坐标,从0开始
    2 w$ u) J* y0 ]! c+ F
  21.         u16 sy;                                        //层开始Y坐标,从0开始
    , ?0 x! c; Y, R" A6 r% w! w$ T2 s
  22.         u16 width;                                //层宽度( e3 `7 r$ k+ u, `4 B
  23.         u16 height;                                //层高度
    # P% k( F/ p8 k
  24.         u32 *pFrameBuff;                //帧缓冲区指针,需要进行初始化9 ]9 c! c3 M5 K. K: r- B
  25. }LTDC_LayerConfig;
    8 y. y8 o1 D2 [- x
  26. ; e( f% S: a1 p/ X* d9 H! Q
  27. . l' N4 l# B4 Z5 g
  28. 7 |; s+ h0 D6 N, e
  29. //全局的LTDC配置信息
    ) v" c  `3 d4 T, j, w) N; J
  30. typedef struct0 n1 }# ?% h; ~6 ?9 d
  31. {
      q8 p. I! P; L& ]1 @% P1 q# h, l! G
  32.         u16 lcd_width;                                                //显示器宽度0 e7 O, e: G0 _$ e: m
  33.         u16 lcd_height;                                                //显示器高度% {7 b3 v. c6 Q. o0 z
  34.         LTDC_LayerConfig LayerConfig[2];        //层信息
    9 e( S1 `- i: p5 p8 `+ m1 y9 G
  35. }LTDC_ConfigData;
    : {! F# {8 a7 v) Y4 v1 ?0 Z
  36. . ?# y# J$ q9 u% R0 p% A
  37. 7 ?# I$ V% s; |" ~, e* {: v
  38. static LTDC_ConfigData sg_LTDC_ConfigData;        //记录全局的LCD配置
    5 M2 Z$ l; a. K/ f. w3 P' T, \8 {
  39. % r4 E" A$ _9 q7 o

  40. - D' A' S  s: `
  41. //显示屏信息
    . f& X  p+ p9 t7 j
  42. typedef struct
      u# U" X3 W% i9 s5 s7 O
  43. {: n" l" q" p; A1 V
  44.         u16         Width;                //面板宽度,单位:像素
    0 ~7 N* J$ W! w9 L' ~& X
  45.         u16         Height;                //面板高度,单位:像素: ~; R$ c0 U* n; U0 j6 w
  46.         u8          Thbp;                //水平后廊
    ) }4 t+ d, g4 J$ S2 ^
  47.         u8          Thfp;                //水平前廊
    / x0 B# z( T; N, |. q5 b
  48.         u8          Thw;                //水平同步宽度
    / e8 [; f# V7 u3 z! P% a
  49.         u8          Tvbp;                //垂直后廊
    2 `' @! }" M- ~2 E4 M6 A7 d
  50.         u8          Tvfp;                //垂直前廊
    5 \7 c( Q0 v. ]  E
  51.         u8          Tvw;                //垂直同步宽度& Q! \$ E  n* ^6 m
  52.         u8          DCLK;                //时钟速度,MHz
    6 }% T/ \2 L9 z" G; ]( u
  53.         
    / N2 y) Z; \3 k, z6 P
  54.         u8                HSPOL;                //水平同步极性,0:低电平有效;1:高电平有效1 B6 _5 d) ~! m6 J. ~& O5 U
  55.         u8                VSPOL;                //垂直同步极性,0:低电平有效;1:高电平有效; d1 f# P3 t) j- `* a
  56.         u8                DEPOL;                //数据使能极性,0:低电平有效;1:高电平有效9 i' w4 O9 r6 w2 D. ?6 t! ]
  57.         bool        PCPOL;                //像素时钟反向
    0 A8 L) e1 O$ A, z! @; G8 m
  58. }LTDC_INFO_TYPE;
    ; V" y) l! P" V) e- n# u2 @8 [# i
  59. * k8 ?6 S" j3 ]9 {7 J3 C: }
  60. 0 \# j5 E2 ]6 k% C! f* Q! Z' I
  61. LTDC_INFO_TYPE DefaultLCD_Info =
    $ q1 L& I0 W5 X6 }9 a+ h" k
  62. {2 I4 W7 u/ J! E8 q- X/ M
  63.         480,        //面板宽度,单位:像素
    * L, e# g& n- y# S- P
  64.         272,        //面板高度,单位:像素
    1 q' N& E& a" Z; b/ v
  65.         41,                //水平后廊- W, q4 [2 B7 g  f+ C  ?
  66.         8,                //水平前廊
    * k, }1 e4 B- u
  67.         2,                //水平同步宽度" c3 n& r- {; \6 }- A3 e3 p
  68.         2,                //垂直后廊$ z( J! ~# _! I: K( S# Y! i
  69.         4,                //垂直前廊
    $ l9 M) X# h  C( |" q
  70.         10,                //垂直同步宽度
    * K% t; d- U: I2 F7 r) _+ g6 o
  71.         9,                //时钟速度,MHz! f+ |# g" n. \, A* j( C% v, y1 u" i
  72.         0,                //水平同步极性,0:低电平有效;1:高电平有效
    4 l% J: I* y3 G* J' ~
  73.         0,                //垂直同步极性,0:低电平有效;1:高电平有效
    & u, k1 D. ^$ ^- `! S; ]5 Y, E
  74.         1,                //数据使能极性,0:低电平有效;1:高电平有效
    2 C# ^0 g" Y8 [! P/ o% J
  75.         FALSE,        //像素时钟反向
    4 R& B* W  G& u6 ]( h9 O
  76. };
    ( C/ g9 d: y* C! G5 G# C
  77. / [+ u! |  U+ B
  78. bool LTDC_ClockInit(u16 ClockFreq);                                                        //STM32F4 LTDC时钟初始化
    4 L% k# J4 Y6 N1 w& L
  79. ; n) Q+ T2 o; I7 P

  80. ! N) i! a; ~4 ?
  81. /*************************************************************************************************************************
    + O. h; `1 N9 L
  82. * 函数        :                        void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha)6 Q4 A: {5 t" u# P
  83. * 功能        :                        LTDC 层窗口尺寸设置(会自动根据窗口尺寸以及像素格式设置帧缓冲区大小)$ D) O' @4 L& A' B
  84. * 参数        :                        LayerIndex:层选择(0-1);sx,sy:起始坐标;width,height:宽度和高度  U. K* n$ V1 q: V2 _; H5 e' S
  85. * 返回        :                        无6 ?8 f1 s' x. V- Q& h
  86. * 依赖        :                        底层宏定义
      i! N' o8 k+ e7 y/ N
  87. * 作者        :                        <a href="mailto:cp1300@139.com">cp1300@139.com</a>3 n1 h! ~( |3 B1 d: u0 }% d
  88. * 时间        :                        2019-10-28- t: c9 Y4 K8 `" k% K) a- M- y
  89. * 最后修改时间 :         2019-10-28* H& x, a, u/ e5 O- {
  90. * 说明        :                         不会使能层,不会更新层,只设置配置,需要刷新层配置后更新
    2 K; A8 t. \6 n* ~) w' M
  91. *************************************************************************************************************************/
    & y* N1 y& r" r
  92. void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha)6 N% M7 H: S. j! ~
  93. {
    * A  D- @$ @3 ?9 R. l+ R
  94.         u32 temp;7 X% ~1 h4 {0 Z, P3 Z/ [- b+ _+ b
  95.         u8 pixformat=0;
    * A# J( i+ x* k% [, c3 R8 t
  96.         
    & W- k( ^4 u$ D' o/ a! M
  97.         if(LayerIndex==0)/ Z' S9 g! s. {2 z: L5 w% @
  98.         {; p2 {8 G* a8 c
  99.                 //基本配置/ K/ f" T& f4 o8 i' y' K0 O
  100.                 LTDC_Layer1->CFBAR = FrameBuff;                                                                        //设置层颜色帧缓存起始地址
    $ B- w1 v! g. Z3 L% W9 r
  101.                 LTDC_Layer1->PFCR = LTDC_PIXEL_FORMAT;                                                        //设置层颜色格式! R" D5 y( ]2 l  }1 v
  102.                 LTDC_Layer1->CACR = Alpha;                                                                                //常数 Alpha,255分频;设置255,则不透明! n9 z. q5 e) ~2 N9 B8 {# g
  103.                 LTDC_Layer1->DCCR = 0x00;                                                                                //设置默认颜色:透明的黑色- J/ Q( g1 ?( @6 H% u$ o' w. T  g
  104.                 LTDC_Layer1->BFCR = ((u32)6<<8)|7;                                                                //设置层混合系数
    . J  ?8 q9 |1 S8 v
  105.                 //配置窗口
    1 T. ~0 X9 `. v2 ]7 }
  106.                 temp = (sx+width+((LTDC->BPCR&0X0FFF0000)>>16))<<16; : @8 m, B( x' ?5 C! Y/ [
  107.                 LTDC_Layer1->WHPCR = (sx+((LTDC->BPCR&0X0FFF0000)>>16)+1)|temp;//设置行起始和结束位置
    " {$ C6 O6 {3 q; U- m
  108.                 temp = (sy+height+(LTDC->BPCR&0X7FF))<<16; 5 \6 }: l9 U* b/ f) w0 Q
  109.                 LTDC_Layer1->WVPCR = (sy+(LTDC->BPCR&0X7FF)+1)|temp;                        //设置列起始和结束位置
    7 d, ]" d& ]8 ^0 B9 a; }
  110.                 pixformat = LTDC_Layer1->PFCR&0X07;                                                                //得到颜色格式
    " L0 L7 D9 P: L9 [" ?* E
  111.                 if(pixformat == 0)temp=4;                                                                                //ARGB8888,一个点4个字节
    & x+ X. `4 \7 c- w2 }
  112.                 else if(pixformat == 1)temp=3;                                                                        //RGB888,一个点3个字节9 R8 k9 X7 s1 s3 K; N3 K! X
  113.                 else if(pixformat==5||pixformat==6)temp=1;                                                //L8/AL44,一个点1个字节! p  @+ X0 f$ W# g# n! C
  114.                 else temp=2;                                                                                                        //其他格式,一个点2个字节
    ! Z: M& L+ I5 N
  115.                 LTDC_Layer1->CFBLR = (width*temp<<16)|(width*temp+3);                        //帧缓冲区长度设置(字节为单位)
    , z' R% o- j  p' l6 e
  116.                 LTDC_Layer1->CFBLNR = height;                                                                        //帧缓冲区行数设置        
    8 F* l) H2 n- h0 I. l# a9 g2 L5 W+ L
  117.                 0 Z8 ^8 h; z  e0 A* O1 D
  118.                 //记录层窗口大小位置信息
    * i6 g0 N9 o/ K+ w$ S$ q, x+ C6 E
  119.                 sg_LTDC_ConfigData.LayerConfig[0].sx = sx;               
    & |( r2 R  p' R$ u2 P# n; o! X/ Y5 I
  120.                 sg_LTDC_ConfigData.LayerConfig[0].sy = sy;        , Z! J1 o; _$ T% v7 A$ n: d+ B9 y
  121.                 sg_LTDC_ConfigData.LayerConfig[0].width = width;        0 l7 n* @# W- F  r( s) l
  122.                 sg_LTDC_ConfigData.LayerConfig[0].height = height;        
    . R3 W3 P7 p" ?7 H8 V+ x7 U
  123.         }else9 |* X4 w% d; R8 P7 R" C2 J
  124.         {
    # e4 d7 O, @1 k. j5 {+ c/ Y( P
  125.                 //基本配置" u, y% J' ~3 g
  126.                 LTDC_Layer2->CFBAR = FrameBuff;                                                                        //设置层颜色帧缓存起始地址, S, e* X; k. C: ^* J( j
  127.                 LTDC_Layer2->PFCR = LTDC_PIXEL_FORMAT;                                                        //设置层颜色格式6 _$ t8 V( O( i6 V
  128.                 LTDC_Layer2->CACR = Alpha;                                                                                //常数 Alpha,255分频;设置255,则不透明  ^: X3 h: N+ t- @9 y2 E
  129.                 LTDC_Layer2->DCCR = 0x00;                                                                                //设置默认颜色:透明的黑色
    $ T2 F7 d( n8 C" V# A9 y1 r/ Z$ t, [
  130.                 LTDC_Layer2->BFCR = ((u32)6<<8)|7;                                                                //设置层混合系数) _" N7 l0 v3 G( G' W& {1 R: ?8 A
  131.                 //配置窗口7 b. c& B1 s% t/ {2 t, `: M
  132.                 temp = (sx+width+((LTDC->BPCR&0X0FFF0000)>>16))<<16;
    5 U, x9 y4 c. C3 p2 O2 z
  133.                 LTDC_Layer2->WHPCR = (sx+((LTDC->BPCR&0X0FFF0000)>>16)+1)|temp;        //设置行起始和结束位置
    9 c$ \& s3 p/ O, V- B- h
  134.                 temp = (sy+height+(LTDC->BPCR&0X7FF))<<16; 5 ]# v0 P& Q; c5 V% S) F! R& j! f
  135.                 LTDC_Layer2->WVPCR = (sy+(LTDC->BPCR&0X7FF)+1)|temp;                        //设置列起始和结束位置. ?! p; D8 I# r/ {/ v, X
  136.                 pixformat = LTDC_Layer2->PFCR&0X07;                                                                //得到颜色格式
    0 ^1 j2 O. }/ @$ e% `
  137.                 if(pixformat == 0)temp=4;                                                                                //ARGB8888,一个点4个字节
    & ]; }& o" J9 G! O
  138.                 else if(pixformat == 1)temp=3;                                                                        //RGB888,一个点3个字节5 z9 H. c4 p7 d4 O1 O! q
  139.                 else if(pixformat == 5||pixformat==6)temp=1;                                        //L8/AL44,一个点1个字节
    ) y0 V0 [2 q" c7 O% F: f5 z. p. x
  140.                 else temp = 2;                                                                                                        //其他格式,一个点2个字节
    9 Z- n0 a! f7 i0 _7 _5 {
  141.                 LTDC_Layer2->CFBLR = (width*temp<<16)|(width*temp+3);                        //帧缓冲区长度设置(字节为单位), v3 o2 r5 ?7 X# }# x. [0 {
  142.                 LTDC_Layer2->CFBLNR = height;                                                                        //帧缓冲区行数设置        4 B$ n( `7 F8 W7 K0 [6 c/ M& i# @8 [) W
  143.                
    9 u! G# H. w/ \3 b" \
  144.                 //记录层窗口大小位置信息; s8 d6 E+ y- B/ e
  145.                 sg_LTDC_ConfigData.LayerConfig[1].sx = sx;               
    : G* T* |3 G- ?& c$ C/ @
  146.                 sg_LTDC_ConfigData.LayerConfig[1].sy = sy;        
    1 M! ]: U" f( D$ U  h5 d
  147.                 sg_LTDC_ConfigData.LayerConfig[1].width = width;        & I* j+ f. n% q' |1 u* ~
  148.                 sg_LTDC_ConfigData.LayerConfig[1].height = height;                ' F' ]& i' V8 T1 ]* W
  149.         }
    $ H! r6 P5 Z5 ~7 ]. Z
  150. }  {6 d8 y* |& G3 Y# L$ S

  151. $ N$ G7 X0 Y, r' J, H
  152. 3 u1 X# |1 T, Q- ]0 ]: e/ K
  153. % Z1 Z# ~. [2 v5 k( d
  154. /*************************************************************************************************************************, x5 z2 {  ~9 @6 W
  155. * 函数        :                        void LTDC_Init(void)
    7 ]% t7 ^9 ?' R. x
  156. * 功能        :                        LTDC 接口初始化
    0 h4 v( d0 Z+ k- `* b/ R& U6 U
  157. * 参数        :                        无
    0 w; B( p: h4 }2 E& F6 w# ]/ z
  158. * 返回        :                        无
    ! @* l* F: |7 J$ y6 w, v5 Y+ T0 R+ ^' `4 K
  159. * 依赖        :                        底层宏定义4 L6 J" F2 S' T1 \, X
  160. * 作者        :                        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    ! m6 G, a' K5 Z
  161. * 时间        :                        2019-09-08
    5 t* o3 @- t5 v' r( @
  162. * 最后修改时间 :         2019-09-082 g, i$ r1 [( D$ O: b2 L
  163. * 说明        :                         用于初始化STM32F7 LTDC 接口
    0 M% m% r' n/ ^- d
  164. *************************************************************************************************************************/  
    5 U$ ^/ S9 J# z1 S" `/ m8 f
  165. void LTDC_Init(void)+ B( b% ~7 H1 _: u6 y
  166. {6 ]- t4 s1 i4 H- X+ N, v* s) s( y. I( h
  167.         u32 temp;* N) E' c+ s# x, v% N2 o5 J  t
  168.         6 t2 Z6 n% Z. |- w% z
  169.         SYS_DeviceClockEnable(DEV_LTDC, TRUE);        //LTDC时钟使能
    , V+ P& H7 I- g6 }0 H' _" q9 O
  170.         SYS_DeviceReset(DEV_LTDC);                                //STM32F7外设复位* `5 L9 H5 G; A5 s( n
  171.         SYS_DeviceClockEnable(DEV_GPIOE, TRUE);        //使能GPIOE时钟
    & |( Y6 ]& [6 R; C  o0 h# X
  172.         SYS_DeviceClockEnable(DEV_GPIOG, TRUE);        //使能GPIOG时钟7 b. s# p' [2 v, K; N
  173.         SYS_DeviceClockEnable(DEV_GPIOJ, TRUE);        //使能GPIOJ时钟
    ) t. e8 v  {0 N  X2 }
  174.         SYS_DeviceClockEnable(DEV_GPIOK, TRUE);        //使能GPIOK时钟
    ) v4 J& a' h9 D5 j4 F! q
  175.         SYS_DeviceClockEnable(DEV_GPIOI, TRUE);        //使能GPIOI时钟' ~& F6 s) }8 {2 O- A1 J- I

  176. 1 o5 o7 e% o3 P$ \  U
  177.         
    3 l. ~- Y8 M5 a( o( e$ q
  178.         //初始化IO
    8 w" z+ Z2 ], o: B
  179.         SYS_GPIOx_Init(GPIOE, BIT4, AF_PP_OPU, SPEED_100M);                                                                                //PE49 L: c; r% f" l% d
  180.         SYS_GPIOx_Init(GPIOG, BIT12, AF_PP_OPU, SPEED_100M);                                                                        //PG128 Z' f) J* f9 n
  181.         SYS_GPIOx_Init(GPIOJ, 0Xffff&(~BIT12), AF_PP_OPU, SPEED_100M);                                                        //PJ0~11/13/14/15
    - n1 e) H8 h6 H
  182.         SYS_GPIOx_Init(GPIOK, BIT0|BIT1|BIT2|BIT4|BIT5|BIT6|BIT7, AF_PP_OPU, SPEED_100M);                //PK0/1/2/4/5/6/7; N5 [0 T( M' M" T
  183.         SYS_GPIOx_Init(GPIOI, BIT9|BIT10|BIT14|BIT15, AF_PP_OPU, SPEED_100M);                                        //PI9/10/14/15
    / s& i; }" w" r+ z- ^  W
  184.         
    ( R% z$ ~) s( W
  185.         SYS_GPIOx_SetAF(GPIOE, 4, AF14_LTDC);                //PE4,AF14        
    . Z8 v5 {# n+ r! |8 d/ v! R3 @
  186.          SYS_GPIOx_SetAF(GPIOG, 12, AF14_LTDC);                //PG12,AF14        
    ! f+ Q3 K" r4 X
  187.         SYS_GPIOx_SetAF(GPIOJ, 0, AF14_LTDC);                //PJ0,AF142 b9 \( m) a7 o
  188.         SYS_GPIOx_SetAF(GPIOJ, 1, AF14_LTDC);                //PJ1,AF14
    ! e4 |7 p6 r5 Q/ o0 q: U! w& m0 u$ B; Z
  189.         SYS_GPIOx_SetAF(GPIOJ, 2, AF14_LTDC);                //PJ2,AF14
    - |. T8 [4 f- F0 g, U
  190.         SYS_GPIOx_SetAF(GPIOJ, 3, AF14_LTDC);                //PJ3,AF14
    / Y9 h( W, E) a. o# I" O
  191.         SYS_GPIOx_SetAF(GPIOJ, 4, AF14_LTDC);                //PJ4,AF14' p) }' j) }$ t) |6 M
  192.         SYS_GPIOx_SetAF(GPIOJ, 5, AF14_LTDC);                //PJ5,AF14. V' o1 O6 n! h- I! ^3 p/ W
  193.         SYS_GPIOx_SetAF(GPIOJ, 6, AF14_LTDC);                //PJ6,AF14
    # a" A. M6 D) A( R* X5 \' w
  194.         SYS_GPIOx_SetAF(GPIOJ, 7, AF14_LTDC);                //PJ7,AF14
    5 x, A. `, f/ T
  195.         SYS_GPIOx_SetAF(GPIOJ, 8, AF14_LTDC);                //PJ8,AF14
    / U# G: \6 x) ^$ ^. B1 r7 H
  196.         SYS_GPIOx_SetAF(GPIOJ, 9, AF14_LTDC);                //PJ9,AF14# U$ n2 s1 B# j1 X6 }6 d% ?+ W
  197.         SYS_GPIOx_SetAF(GPIOJ, 10, AF14_LTDC);                //PJ10,AF14$ k- k$ g. Z+ m; e2 \- V
  198.         SYS_GPIOx_SetAF(GPIOJ, 11, AF14_LTDC);                //PJ11,AF14
    * X7 j& F3 V' B4 i+ e  n/ Q/ ^
  199.         SYS_GPIOx_SetAF(GPIOJ, 13, AF14_LTDC);                //PJ13,AF14
    % ~( F2 y3 p) w/ a( f% t
  200.         SYS_GPIOx_SetAF(GPIOJ, 14, AF14_LTDC);                //PJ14,AF14
    / C( K. D1 l+ f. i; Y, v
  201.         SYS_GPIOx_SetAF(GPIOJ, 15, AF14_LTDC);                //PJ15,AF14
    2 U1 c) r* F0 c% K# e  v9 m2 l6 K
  202.         
    ! d& q% V. W2 E
  203.         SYS_GPIOx_SetAF(GPIOK, 0, AF14_LTDC);                //PK0,AF14
      n1 _9 }9 x0 C8 Z
  204.         SYS_GPIOx_SetAF(GPIOK, 1, AF14_LTDC);                //PK1,AF14! w4 W, N# W9 _- ~; |. _" ?
  205.         SYS_GPIOx_SetAF(GPIOK, 2, AF14_LTDC);                //PK2,AF14
    5 p, P& G7 v; `' A
  206.         SYS_GPIOx_SetAF(GPIOK, 4, AF14_LTDC);                //PK4,AF14$ b: n7 W" Z5 N" n1 h9 @5 s1 X, ?
  207.         SYS_GPIOx_SetAF(GPIOK, 5, AF14_LTDC);                //PK5,AF14: ~: y& B# R6 ^$ X& T
  208.         SYS_GPIOx_SetAF(GPIOK, 6, AF14_LTDC);                //PK6,AF14
    # g, X; s& z- g4 p, f. p0 _
  209.         SYS_GPIOx_SetAF(GPIOK, 7, AF14_LTDC);                //PK7,AF14, {4 U0 j; a2 a- Z" }
  210.           x# ~1 B6 K# S
  211.          SYS_GPIOx_SetAF(GPIOI, 9, AF14_LTDC);                //PI9,AF14
    5 Y9 l. b: R6 l6 o# W* P9 X
  212.          SYS_GPIOx_SetAF(GPIOI, 10, AF14_LTDC);                //PI10,AF14 1 h7 s. A1 S: h) {
  213.         SYS_GPIOx_SetAF(GPIOI, 14, AF14_LTDC);                //PI14,AF14
    ' D7 S4 A. j$ U* Q2 y# P
  214.          SYS_GPIOx_SetAF(GPIOI, 15, AF14_LTDC);                //PI15,AF14 ) G/ b* Q, n& c
  215.         + Z' ?6 A8 o" B1 V
  216.         LTDC_ClockInit(DefaultLCD_Info.DCLK);                 //设置像素时钟  9Mhz
    - k2 z( q9 X4 r; `( Z
  217.         //设置LTDC 全局控制寄存器 (LTDC_GCR)3 O) Q, d- A; |
  218.         temp = 0;: Z* h+ L! x. q& w6 q- o/ J5 q
  219.         temp |= (DefaultLCD_Info.HSPOL&0x01) << 31;        //水平同步极性
    % e8 S4 d4 i7 Z$ C! w2 {% i' D
  220.         temp |= (DefaultLCD_Info.VSPOL&0x01) << 30;        //垂直同步极性
    5 h  q* \. s' U1 x& Y. k& }
  221.         temp |= (DefaultLCD_Info.DEPOL&0x01) << 29;        //数据使能极性! ?1 C9 ], C' X+ V" K
  222.         temp |= (DefaultLCD_Info.PCPOL&0x01) << 28;        //像素时钟极性
    ! }3 }: e7 K) e/ z1 z9 B1 H/ Q
  223.         LTDC->GCR = temp;
    . J3 H+ b- b+ g) y
  224.         //LTDC 后沿配置寄存器 (LTDC_BPCR)
    ! c) S; J  K1 V' s- W! Y. }0 Q4 R0 P
  225.         temp = (DefaultLCD_Info.Tvw + DefaultLCD_Info.Tvbp - 1) << 0;        //这些位定义累加水平后沿宽度(水平同步像素加水平后沿像素减 1)。
    , _1 g  F% ?! K% j- K. i& B4 K
  226.         temp |= (DefaultLCD_Info.Thw + DefaultLCD_Info.Thbp - 1) << 16;        //这些位定义累加垂直后沿宽度(垂直同步行加垂直后沿行减 1)。4 Y3 o& r6 ?; \
  227.         LTDC->BPCR=temp;        % g$ [$ ]6 X1 u7 Q
  228.         
    3 V; j% }/ l5 b- A. ]
  229.         //LTDC 有效宽度配置寄存器 (LTDC_AWCR)  n% k8 h4 _. g& C( J- i4 m" v
  230.         temp=(DefaultLCD_Info.Tvw+DefaultLCD_Info.Tvbp+DefaultLCD_Info.Height-1)<<0;        //累加有效高度=垂直脉宽+垂直后沿+垂直分辨率-1
    5 q6 ]& U/ ~$ E9 L, t# a& r* C
  231.         temp|=(DefaultLCD_Info.Thw+DefaultLCD_Info.Thbp+DefaultLCD_Info.Width-1)<<16;        //累加有效宽度=水平脉宽+水平后沿+水平分辨率-1
    9 b! g. C4 f) z" P- C
  232.         LTDC->AWCR=temp;        # k/ J/ g) C' V9 e7 ?& t% ]
  233.         //LTDC 总宽度配置寄存器 (LTDC_TWCR)
    ! J3 [2 M, {, A& A& r0 p
  234.          temp=(DefaultLCD_Info.Tvw+DefaultLCD_Info.Tvbp+DefaultLCD_Info.Height+DefaultLCD_Info.Tvfp-1)<<0;        //总高度=垂直脉宽+垂直后沿+垂直分辨率+垂直前廊-1
    % g- ]: E/ y1 ~  z
  235.         temp|=(DefaultLCD_Info.Thw+DefaultLCD_Info.Thbp+DefaultLCD_Info.Width+DefaultLCD_Info.Thfp-1)<<16;        //总宽度=水平脉宽+水平后沿+水平分辨率+水平前廊-1
    ( X; S- ]1 L! F: v8 Q) e
  236.         LTDC->TWCR=temp;                                
    - b! b  {, A3 T
  237. ! c$ [* ]( Y, X) G) U) J
  238.         //背景设置8 j3 q6 N: I# G% f4 q
  239.         LTDC->BCCR=0xffffff;                                //设置背景层颜色寄存器(RGB888格式)
    . F7 {& j( q5 F8 k: u7 W
  240.         LTDC_Enable(TRUE);                                        //开启LTDC
    , _' \: L* |4 p. d- x
  241.         //初始化层1& c- W+ Q9 ~* P9 M! W* u: m  M8 K
  242.         LTDC_SetLayerConfig(0, 0, 0, LTDC_WIDTH, LTDC_HEIGHT, (u32)g_LTDC_BUFF_RGB888[0], 255);' o+ u  y% l2 `9 D. [+ o
  243.         //初始化层2
    # a* `0 N* i1 C3 `& k+ q8 ^
  244.         LTDC_SetLayerConfig(1, 0, 0, LTDC_WIDTH, LTDC_HEIGHT, (u32)g_LTDC_BUFF_RGB888[1], 255);
    5 }5 e; t& O& `; l
  245.         LTDC_Clear(0, 0xFF000000);                        //清屏层1-不透明的黑色
    . @% S6 b2 A+ O8 g
  246.         LTDC_Clear(1, 0x00000000);                        //清屏层2-透明的黑色7 e+ \) [! l$ a2 x- o
  247.         LTDC_LayerEnable(0, TRUE);                        //使能层1
    2 r4 p$ m5 N0 n( H# Z
  248.         LTDC_LayerRefreshConfig();                        //LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)
    - ^6 T& j9 j3 u% s( z
  249.         LCD_DispIoInit();                                        //初始化DISP引脚-启动显示$ l1 n0 W( ]1 K* Y8 h$ A; D- |
  250. }; [6 y4 R9 a- c9 J7 r
  251. + ]1 c$ g' \; A, D# K8 l+ G
  252. /*************************************************************************************************************************
    0 V( H, g- Z0 G0 F6 Q
  253. * 函数                        :        void LTDC_LayerRefreshConfig(void)
    : V6 e% `; S5 S! E+ Q1 T
  254. * 功能                        :        LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)
    % g8 V/ U; @8 @0 K- P
  255. * 参数                        :        无
      o' ~1 D7 K' q+ f2 k% [- J$ M% c' g
  256. * 返回                        :        无. m% M1 P- ~  @  T/ E
  257. * 依赖                        :        底层宏定义
    " K7 V! N: f7 Z0 y5 l) v" E$ `3 k: V
  258. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>6 D# }6 e5 d; q! O$ E
  259. * 时间                        :        2019-10-294 p( h; L, \* ?' n, P! J2 \" v
  260. * 最后修改时间         :         2019-10-295 Q' ]/ C0 y9 L- I; d9 s: E
  261. * 说明                        :        修改层配置后必须重新加载,否则不会生效
    : _! h1 _# q6 ]! H$ R: @3 H, I
  262. *************************************************************************************************************************/
    9 Y- X9 y; W" q8 e/ B# p, |& V
  263. void LTDC_LayerRefreshConfig(void)* [! X0 c5 G2 e5 T) H1 f+ Z6 y
  264. {
    ! U6 Q( ]5 ^/ X* K
  265.         LTDC->SRCR|=1<<0;                                                        //重新加载配置-必须重新加载,否则上面的层不会更新,折腾好久才发现,叫啥影子寄存器重载,也不说清楚4 d% n; F1 r2 ~* |
  266. }
    6 L: n: H$ B  k' m1 L( V/ W5 F

  267. ; c8 a8 N0 @" z7 z
  268. /*************************************************************************************************************************9 ~2 r* E6 ~8 A
  269. * 函数                        :        void LTDC_Enable(bool Enable)
    , ^9 H- z4 L8 x% k+ P9 q# {
  270. * 功能                        :        LTDC使能设置
    ' @* o" S! E2 F
  271. * 参数                        :        Enable:TRUE:使能;FALSE:失能
    0 p. l9 w- L( a, X, Z9 |. C
  272. * 返回                        :        无
    9 a+ c! N2 S8 T3 n- ^$ Q- a5 R
  273. * 依赖                        :        底层宏定义$ B. S3 e9 f6 C$ N9 L: C2 b/ V4 K
  274. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    , U# j" N1 U. l  ]3 u8 n$ C+ Y
  275. * 时间                        :        2019-10-29
    / ?9 j) i' A. ?1 X5 K. k. p: ]
  276. * 最后修改时间         :         2019-10-29
    * O+ ^  \8 C9 \/ j: Y' U
  277. * 说明                        :        
    , u" G% ^) O% w* J( Y$ ]4 n
  278. *************************************************************************************************************************/
    2 c; N) i$ `! j$ G& c
  279. void LTDC_Enable(bool Enable)
    . F8 K0 y3 a- a
  280. {* ~! B( T, H) Q" v* H8 L6 J
  281.         if(Enable)
    6 u/ O% n* ]+ Z8 P
  282.         {
    & j# X7 e' f  ?. x
  283.                 LTDC->GCR |= BIT0;                                        //打开LTDC
    / Y- L7 d7 A' ]' I5 f1 p# Y9 {
  284.         }
    1 U1 p4 ~; i+ u5 @* j, k& H2 |
  285.         else
    . c; }0 k) X6 \8 d' v
  286.         {1 J# r+ t8 K+ ?6 @
  287.                 LTDC->GCR &= ~BIT0;                                        //关闭LTDC
    8 S; s0 n: I) P# g& _
  288.         }  W& B: s8 e' }6 z1 a3 A! b
  289. }
    ( ?- a+ z9 F4 t6 d0 p3 Z
  290. " Q$ O2 u8 W+ r! y) T1 X
  291. /*************************************************************************************************************************
    $ Y: d9 W# s! I3 y4 N
  292. * 函数                        :        void LTDC_LayerEnable(u8 LayerIndex, bool Enable)! d, N; N( m+ ]5 a7 i' m2 N( H
  293. * 功能                        :        LTDC 层使能设置. N4 v0 y6 L' k
  294. * 参数                        :        LayerIndex:层选择0-1;Enable:TRUE:使能;FALSE:失能
    $ [9 z7 E2 b$ q0 G) @& m6 c) v
  295. * 返回                        :        无- p5 g; q" E! z: X: a
  296. * 依赖                        :        底层宏定义
    # }! ~( P  a/ K7 D+ Z( v
  297. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>. X2 u4 w' l7 V- E# l
  298. * 时间                        :        2019-10-295 |) W: R7 v$ T$ d! R
  299. * 最后修改时间         :         2019-10-29
    , v7 e9 G0 s# Z$ n4 e
  300. * 说明                        :        6 K  b: G" Y! x
  301. *************************************************************************************************************************/4 M2 o$ j6 Z' W$ B5 N$ O
  302. void LTDC_LayerEnable(u8 LayerIndex, bool Enable)& n0 Y) ?% T/ x; I0 K0 l$ I
  303. {
    / h4 w0 G% L0 t% d
  304.         if(Enable)
    * k( J- O: r9 e; t- K
  305.         {
    & l) J/ H% A" M2 J9 B
  306.                 if(LayerIndex == 0)                                        //层1
    ! T3 T* D% h4 ~; N
  307.                 {
    # G" X' b6 Z: E  K
  308.                         LTDC_Layer1->CR |= BIT0;                //使能层1
    : N7 x" ^  S6 E
  309.                 }/ C$ g- z/ H) A: O+ K
  310.                 else
    - T1 O) ]- ^3 C6 Z% |3 C. H
  311.                 {
    ' p) u) Y/ x5 K: y6 Y0 d; e0 O
  312.                         LTDC_Layer2->CR |= BIT0;                //使能层2
    6 E7 Y4 q+ b$ e3 r. U9 A
  313.                 }  Q  b9 N8 m# N' V
  314.         }3 V6 V% t% [1 @/ {
  315.         else
    ) D. l! w& M: d
  316.         {
    8 \  z- R( F: r" t+ U7 z, f
  317.                 if(LayerIndex == 0)                                        //层1
    ! r7 X  F  M! O% |: }1 Z1 l" s6 j
  318.                 {8 w6 W+ b" M, N, q
  319.                         LTDC_Layer1->CR &= ~BIT0;                //失能层18 [0 B, E0 p7 n  m9 s9 g4 g4 X$ \5 `
  320.                 }: N; r7 g: |8 Z3 t, @& M1 C
  321.                 else
    8 `6 E' X; E. X/ n
  322.                 {
    / X& W1 G5 _( n: [# n& G
  323.                         LTDC_Layer2->CR &= ~BIT0;                //失能层2
    & N0 w# a# q- C" Z, ]( E. K" o
  324.                 }
    + m2 e* M: j- _$ a* x/ f7 y
  325.         }/ F- v# }7 Z. N3 L( Z
  326. }
    & e! s) ~# f& ?4 ^" g6 v( @
  327. # l% ~6 C7 R: F7 _1 k% B: g4 X

  328. 4 Z6 p! `) \2 I+ Y1 b

  329. . l& t4 Q8 f1 i! h. E6 m& i
  330. ) H7 u( ^& E/ z
  331. /*************************************************************************************************************************3 Y3 L7 F7 g. Q, o! z  T3 P
  332. * 函数                        :        bool LTDC_ClockInit(u16 ClockFreq)                        
    * O5 [2 J7 D9 j8 b% F/ N
  333. * 功能                        :        STM32F7 LTDC时钟初始化
    % c) V  g- G! P( {$ Z' q
  334. * 参数                        :        ClockFreq:时钟频率,2-168MHZ7 l6 e: W1 G; k. N+ G2 G2 q% f8 I
  335. * 返回                        :        是否设置成功
    7 F( k' a' \: |6 u
  336. * 依赖                        :        底层宏定义
    , y, c' U( D. `% {1 H2 |) Y
  337. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    + F! U- }9 E" D! j! x8 f
  338. * 时间                        :        2019-10-28- @$ D; a6 {, d) z: [' l3 V
  339. * 最后修改时间         :         2019-10-28
    8 D) b$ T9 O9 B2 L  J
  340. * 说明                        :        输入时钟频率在系统主时钟初始化之后就会设置为1MHz,通过设置SAI PLL实现LTDC所需频率,VCO频率范围:49~432( W# N- \6 r- X! D
  341. *************************************************************************************************************************/
    8 x6 a0 x3 D+ n
  342. bool LTDC_ClockInit(u16 ClockFreq)  M( G5 h% u1 }. x) m# \+ C% @- Q
  343. {0 F% J% M+ [" S( A: @
  344.         u32 TimeOut = 0;$ k# W# Q$ v  b
  345.         u32 VCO;% K, ?% }% o5 z& ?! V) R) a# e
  346.         u32 PLLSAIR;                //PLLSAICFGR[30:28]
    % S2 |* G& [# ?5 L
  347.         u32 PLLSAIDIVR;                //DCKCFGR1[17:16]
    1 e, j( R3 c3 k, t) Y
  348.         u32 temp;) Y) h* O0 o$ L' X9 z  y% f) C( R
  349.         
    7 f' j5 ^9 n$ i' b* ~, e6 K6 G; ~5 a3 k
  350.         if(ClockFreq < 1)ClockFreq = 1;
    7 c# g/ a% H& g/ p6 G
  351.         if(ClockFreq > 100) ClockFreq = 100;& n; p& a& p4 x
  352.         
    - U- P. ?1 G/ x: m. N5 W
  353.         RCC->CR &= ~(1<<28);                                                //关闭SAI时钟
    : L+ o/ ^% ]8 W% S
  354.         TimeOut = 0;
    9 C  v& Q: @9 k+ D
  355.         while(RCC->CR&(1<<29))                                                //等待关闭成功  U, a+ |$ R: }6 k  U* R
  356.         {
    4 s; Q7 V. z3 W: o
  357.                 nop;5 K- _0 [1 p) f6 J
  358.                 TimeOut ++;4 e! J' C9 j2 t
  359.                 if(TimeOut > 0xFFFF) return FALSE;                //关闭超时
    # Z0 U, X( m/ S! V2 U% z% Y- j( b
  360.         }7 Z: {$ q: k; z4 e5 M
  361.         //计算分频与VCO频率,通过PLLSAICFGR[30:28]可以设置2-7分频- B! E6 b& J8 X* m8 z- l
  362.         //通过PLLSAICFGR[17:16]可以设置00:2 01:4 10:8 11:16分频
    % `+ c: p' [8 D. r& ?
  363.         //通过PLLSAICFGR[14:6]可以设置为49-432MHz的VCO频率6 |+ T# W0 E! H
  364.         if(ClockFreq <= 6)( m2 a, D4 `5 |2 G# I
  365.         {2 y9 d+ b5 }6 c/ O
  366.                 PLLSAIR = 4;        //4分频$ X& X/ b* ?& S; c2 L. ], O" {
  367.                 PLLSAIDIVR = 3;        //16分频
    . W5 H3 H6 E5 {6 O3 u" A
  368.                 VCO = ClockFreq * PLLSAIR * 16;                        //VCO范围:64-384;& D5 L7 _" z6 a' T- `
  369.         }$ w1 \; V) y! e" l, e" t% F6 S
  370.         else if(ClockFreq <= 13)
    ! d$ C2 s; ]% h6 Y5 v+ v  Y, \
  371.         {* C0 _! o9 ~5 M8 I7 c- q4 m" w
  372.                 PLLSAIR = 4;        //4分频. c: F( k3 e- U
  373.                 PLLSAIDIVR = 2;        //8分频
    * h* j) l6 _, ~- u6 e+ b
  374.                 VCO = ClockFreq * PLLSAIR * 8;                        //VCO范围:224-416;
    ) M- [' r) `7 @. b) d
  375.         }9 [1 r# B+ z8 s/ I6 @
  376.         else if(ClockFreq <= 26)' t  k; m3 R6 L1 Z
  377.         {! y2 m4 o1 e" A& `3 `9 {) `* z
  378.                 PLLSAIR = 2;        //2分频* M& C& v' J3 X1 G
  379.                 PLLSAIDIVR = 2;        //8分频
    7 k8 |3 f3 j* L8 x; i3 U
  380.                 VCO = ClockFreq * PLLSAIR * 8;                        //VCO范围:224-416;+ u' o4 J' _) a  X; H5 T
  381.         }+ n+ @4 C( J! O$ r2 S7 }" h
  382.         else if(ClockFreq <= 52)
    3 Y, x+ _) c6 |& T( ]
  383.         {
    " M5 Z5 W: x" t7 ]' d
  384.                 PLLSAIR = 2;        //2分频9 H$ a, |  N# ?) k- `: W) i# h
  385.                 PLLSAIDIVR = 1;        //4分频/ j7 d) |1 x0 E. W! ?- J
  386.                 VCO = ClockFreq * PLLSAIR * 4;                        //VCO范围:216-416;
    6 h* I8 `" H2 [1 q0 B
  387.         }
    ! W/ k( q0 E  [7 T0 `) p
  388.         else if(ClockFreq <= 104)$ P2 x5 k% L* H8 R% N" i
  389.         {
    $ c9 I2 _6 Q" W6 p! ^. [: t
  390.                 PLLSAIR = 2;        //2分频' o$ r, V4 {, W
  391.                 PLLSAIDIVR = 0;        //2分频8 \7 ?/ V, r1 ?5 Q; S
  392.                 VCO = ClockFreq * PLLSAIR * 2;                        //VCO范围:212-416;
    ; d; |+ _8 R* m0 g
  393.         }& Y+ X5 V8 y7 L( z8 k
  394.         //设置PLLSAICFGR
    2 W" r3 {$ q* S. E. I
  395.         temp = RCC->PLLSAICFGR;
    ! g9 b' i3 z& Q3 g  c
  396.         temp &= ~((3<<28) | (0x1FF<<6));                        //清除之前的设置5 r8 A: U" L9 M
  397.         temp |= PLLSAIR << 28;                                                //设置分频PLLSAICFGR[30:28]( q& v! `* x0 M& x
  398.         temp |= VCO << 6;                                                        //设置VCO& b) T6 p( E) `/ F$ X
  399.         RCC->PLLSAICFGR = temp;
    2 Z2 `7 L& e" _. W9 A6 u2 K& n# O$ p
  400.         //设置DCKCFGR1
    - ~1 ]9 f4 _3 P+ Q% @) C
  401.         temp = RCC->DCKCFGR1;. l+ W, N6 x5 ]6 w1 e  H) N
  402.         temp &= ~(3<<16);                                                        //清除之前的设置! Z, {9 k+ |9 ~2 U
  403.         temp |= PLLSAIDIVR << 16;                                        //设置分频DCKCFGR1[17:16]  S# l7 w7 t3 E  N, W0 l
  404.         RCC->DCKCFGR1 = temp;
    ' p; X9 ?- @; N0 @
  405.         //启动时钟
    ! H' i0 W& B! W' }  N. N
  406.         RCC->CR |= 1<<28;                                                        //启动SAI时钟6 M( z4 c, c4 A+ ~5 h
  407.         TimeOut = 0;
    9 {' Y. w  P  L6 V
  408.         while((RCC->CR&(1<<29)) == 0)                                //等待开启成功
    5 h# s7 r: H7 b) o
  409.         {
    " w7 y3 t# _, n: I8 C
  410.                 nop;2 @4 P3 ~% K2 _8 ?
  411.                 TimeOut ++;, F) b" D  k3 W5 t6 ~
  412.                 if(TimeOut > 0xFFFF) return FALSE;                //开启超时9 R2 D+ O/ }. ]- V
  413.         }- v  ^8 b0 ~# G3 j
  414.         
    " c" l, D+ N9 P* D( l: F- G: S
  415.         return TRUE;
    - |4 R. d: B3 v
  416. }6 k  {0 B7 [5 Z( {0 |, `

  417. & W* u0 _- p- I8 v3 F
  418. " _& q6 A+ ?  |
  419. /*************************************************************************************************************************1 W) L# t! h* r2 x
  420. * 函数                        :        void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color)        9 E" E5 z' g( ^  F- ~* S3 V. X
  421. * 功能                        :        矩形填充(使用DMA2D)2 l! C2 V* X! y9 Q  A6 }. p# E
  422. * 参数                        :        LayerIndex:层选择0-1;sx,sy:开始坐标;ex,ey:结束坐标,color:需要填充的颜色+ E. k* i# |# S4 s8 c% T
  423. * 返回                        :        无
    # W/ X4 e9 v0 q4 ]  D
  424. * 依赖                        :        底层宏定义
    . ~  |& p+ @% u& x6 b* w
  425. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>6 H( w$ W; T+ P) _! C2 _
  426. * 时间                        :        2019-10-301 ?: G' Q* i9 m4 |/ y6 O9 d% r
  427. * 最后修改时间         :         2019-10-30
    ) ^1 W) L: |- t6 \/ b
  428. * 说明                        :        采用DMA2D实现* U. E4 J8 w! _" t
  429. *************************************************************************************************************************/
    : K6 u  H* R. @9 ]) F
  430. void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color)
    ; t. }! e$ N" A2 q9 u5 ]+ [5 m
  431. {* v8 @/ m5 K; j: [6 ~- [
  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进行单色填充
    & ]4 d' ^( V9 T! y% S( h1 [' V( \" T, v: k
  433.         DMA2D_WaitTransferComplete(500);                                                                                                                                                                                                                                //等待DMA2D传输完成5 ]3 ~. w: T( }6 f1 n6 t  i$ v
  434. }# u& C0 b  Q0 x! n
  435. / g( W. i( A- p( x; f* S
  436. " B( B; r7 n# S2 V
  437. /*************************************************************************************************************************; N# B8 D0 A! L" e+ M* u. E
  438. * 函数                        :        void LTDC_Clear(u8 LayerIndex,u32 color)& B3 d, v5 I' @1 G
  439. * 功能                        :        清屏(使用DMA2D)
    ) f  q. K( h0 M$ W' t$ S
  440. * 参数                        :        LayerIndex:层选择0-1;color:需要填充的颜色
    3 ^9 r0 h/ H2 ~9 x% j
  441. * 返回                        :        无: g9 q& {4 c# l  k* q, ]
  442. * 依赖                        :        底层宏定义  b+ }4 z; ^! h" A! A% E
  443. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>( Q0 L/ M' i7 o* F3 G
  444. * 时间                        :        2019-10-300 ^+ b1 d4 g$ j0 j. V& p, E
  445. * 最后修改时间         :         2019-10-30, Y+ }1 A/ x' A2 |' B
  446. * 说明                        :        采用DMA2D实现
    1 y  P  u) o8 d/ y$ x! D' k
  447. *************************************************************************************************************************/! y( o2 q% w9 |$ S2 A8 @$ ?& @
  448. void LTDC_Clear(u8 LayerIndex,u32 color)# C; m# [- d% ]6 V$ R
  449. {
    6 s0 y9 ]8 m) }; \: V- ]" N2 Y
  450.         DMA2D_FillColorToFGRAM((u32)&g_LTDC_BUFF_RGB888[LayerIndex][0][0], LTDC_WIDTH, LTDC_HEIGHT, 0,  DMA2D_COLOR_ARGB8888, color);                                        //DMA2D进行单色填充3 l- B8 F9 i. G% [
  451.         SYS_DelayMS(5);8 W( g0 V- h  A$ ?5 [. a7 Q
  452.         DMA2D_WaitTransferComplete(500);                                                                                                                                                                                                                                //等待DMA2D传输完成! _8 _4 M& M  n7 u
  453. }
    : Y; d9 b; a' i9 v! v* ~5 G
  454. ! V( V. u7 Y& C4 r

  455.   l- M4 K# W3 y* o7 w0 D
  456. /*************************************************************************************************************************
    : h* I) y( e* t1 e7 v
  457. * 函数                        :        void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr)
    # p9 t, H4 [0 |/ _
  458. * 功能                        :        矩形图像填充(相同坐标范围传输,要求源图像与目标显示器分辨率一致,使用DMA2D)
    5 e+ I7 Y+ p  ~' @6 @
  459. * 参数                        :        LayerIndex:层选择0-1;sx,sy:开始坐标;ex,ey:结束坐标,ImageAddr:需要填充的图像地址
    ) g" t5 \6 i1 ~- o! E- x) n" F5 @1 u
  460. * 返回                        :        无
    * k7 m, y; b$ [- K  }+ T. V
  461. * 依赖                        :        底层宏定义8 u2 n( N$ p  \" H% |+ f
  462. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    4 o) H% X4 l. r7 o9 o. X9 J# v2 t4 F% R
  463. * 时间                        :        2019-10-30) c- Z+ v3 _+ y% d2 Z9 O# D
  464. * 最后修改时间         :         2019-10-30: v9 t# m6 {& k- h
  465. * 说明                        :        采用DMA2D实现,将源图像指定位置传输到现存,要求源图像与显存大小一致  Z! D; D( P9 p/ A9 q6 c
  466. *************************************************************************************************************************/3 V6 M  J. H/ ]$ T# [
  467. void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr)
    ! b+ S; q1 u% v: e  @: ^$ n
  468. {
    9 k! x1 q" S" p3 V6 i) c5 F
  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! ]3 C" L) Z! g8 L
  470.         DMA2D_WaitTransferComplete(500);
    4 H, c/ _0 V# d% [7 J7 O  Y
  471. }
复制代码
  1. /*************************************************************************************************************8 y' U) i& ~2 X3 R! _9 k
  2. * 文件名                :        stm32f7_ltdc.h4 u5 l/ z! U) s" i7 f
  3. * 功能                        :        STM32F7 外部RGB LCD驱动2 c: w9 R2 F% s6 p; L' Y- e$ s, \3 @
  4. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>  E& o( J- B$ z3 `  _
  5. * 创建时间                :        2019-09-12
    2 L: W0 X) z* ?/ f9 G* ^0 ?+ X
  6. * 最后修改时间        :        2019-09-123 c3 X$ o; v3 [( b5 \9 F. S
  7. * 详细:        , [5 C# D+ n6 Q7 b: K
  8. *************************************************************************************************************/                - S* y  M% \' H+ a, r
  9. #ifndef __STM32F7_LTDC_H_
    1 A; w6 P: g  w7 {
  10. #define        __STM32F7_LTDC_H_           
    9 j  T+ W- f" A/ k4 t
  11. #include "system.h"
    2 r3 V1 ]' ^; U: x% t
  12. #include "DMA2D.h"
    ; O! s8 U1 c7 J, o3 |
  13. ) [$ \- A* h/ Z0 N: m9 ?; F' D$ x% P
  14. #define LTDC_WIDTH                480% S- ^& l* F6 J+ B* B
  15. #define LTDC_HEIGHT                272
    $ v$ O2 C* _/ T- I, r

  16. ! l* k3 ?5 G- i: i" M

  17. ) _2 B" m* _, d
  18. extern u32 g_LTDC_BUFF_RGB888[2][LTDC_HEIGHT][LTDC_WIDTH];7 }# ?3 I* s# Z$ e

  19. + `7 m2 [/ w, x
  20. //像素格式定义
    % J7 ^7 J% q$ F: T% z) c: F
  21. typedef enum
    4 T4 h5 j0 D2 h. A( t
  22. {
    . |# A* }& T( u( h, s! d
  23.         LTDC_ARGB8888         = 0,. h+ [: u$ ?" K
  24.         LTDC_RGB888         = 1,. m, f7 Z( w) o7 @
  25.         LTDC_RGB565         = 2,
    # f9 _' \3 M7 o+ r% e
  26.         /*LTDC_ARGB1555         = 3,
    ) F  R0 {" g* L7 K; F
  27.         LTDC_ARGB4444         = 4,
    / a$ N/ D- c( k
  28.         LTDC_L8                 = 5,        //8 位 Luminance3 L7 k, {: I8 `7 M
  29.         LTDC_AL44                 = 6,        //4 位 Alpha,4 位 Luminance
    : ~+ `7 k* \  g
  30.         LTDC_AL88                 = 7,        //8 位 Alpha,8 位 Luminance*/2 N% h+ U. E$ r: V" W# B3 }
  31. }LTDC_PixelFormat;( T2 C1 Y* B5 O9 q9 h: |' i
  32. #define LTDC_PIXEL_FORMAT                LTDC_ARGB8888                //选择ARGB8888格式2 Y" \% h3 j& l

  33. . N. ~  \0 T# I! k$ Y

  34. 8 v" m% O9 \0 C; {  ]/ y3 p0 @

  35. - o9 M. d' J; J: Y; A4 K
  36. + y: P& s$ a3 ~. Z
  37. //画点函数32bit ARGB8888格式0 \2 i$ D! k* q
  38. __inline void LTDC_DrawPoint(u8 LayerIndex, u16 Xpos,u16 Ypos,u32 ARGB8888_Color)
    % J4 ~) Q. ?, j0 y) m2 E. G
  39. {
    + n* A$ |9 q" {! f, E
  40.         g_LTDC_BUFF_RGB888[LayerIndex][Ypos][Xpos] = ARGB8888_Color;+ i; u9 W. K, \
  41. }
    . d7 t& F) _9 z" W0 u8 ~/ ?/ j

  42. : L' o9 ~) @/ e# H* X" Q
  43. //初始化DISP引脚
    * U3 |7 T! X6 o. C; I+ l0 H! a
  44. __inline void LCD_DispIoInit(void)- r& G/ k# g2 T# ^+ r/ c  F* [
  45. {/ }1 e$ |( v! u+ t2 i
  46.         SYS_GPIOx_Init(GPIOI, BIT12, OUT_PP, SPEED_25M);                                                                                                //PI12 LCD_DISP H:正常模式;L:低功耗                                                        
      T  v4 C: m4 g( H
  47.         PIout(12) = 1;                                                                                                                                                                        //DISP = H  2019-10-16:一直忽略将此引脚置为高电平,调试走了很多弯路
    , |2 e( Y4 L9 |0 f
  48. }
    # U2 o, w0 [# ~8 z' g9 _' e: H$ U
  49. ! Y& J, L. x7 b) j. x, ]
  50. void LTDC_Enable(bool Enable);                                                                                                                                                //LTDC使能设置* V% C% f( t* j# B+ \; c+ N& \& Z: }
  51. void LTDC_Init(void);                                                                                                                                                                //LTDC 接口初始化: a8 E4 m; A+ w
  52. void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha);//LTDC 层窗口尺寸设置
      m8 {1 J" P6 G  D$ E. A
  53. void LTDC_LayerEnable(u8 LayerIndex, bool Enable);                                                                                                        //LTDC 层使能设置% a  F; p5 s/ W4 t5 I  |
  54. void LTDC_LayerRefreshConfig(void);                                                                                                                                        //LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)' v: K! q+ z* X: o1 j" u5 Q1 M
  55. ( G) ]$ J) o+ j8 r2 ?
  56. //图形相关API
    2 y- g) A. D9 E4 A1 y( M  a
  57. void LTDC_DrawPoint(u8 LayerIndex, u16 Xpos,u16 Ypos,u32 ARGB8888_Color);                                                        //画点函数32bit ARGB8888格式
    7 w# Z# Z" u- I, y- F. w
  58. void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color);                                                                //矩形填充(使用DMA2D)
    1 O# R/ k: c  ]- ~* n8 n7 ~
  59. void LTDC_Clear(u8 LayerIndex,u32 color);                                                                                                                        //清屏(使用DMA2D)
    2 [6 E2 r2 f- C4 W5 ?
  60. 4 U8 Z( v' b: x' V, L
  61. void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr);//矩形图像填充(相同坐标范围传输,要求源图像与目标显示器分辨率一致,使用DMA2D)
复制代码
8 h, }# z! z4 Z- r
2 |. {9 j8 z/ Z5 I5 d$ p! l0 G& x: A( i/ V
#endif //__STM32F7_LTDC_H_
" ]5 F5 `6 V3 h2 S. ~" W' e9 w. p
# g3 q/ Q" o; g# V. A. H- Z" o% n. r8 M9 N

' P" l% K7 S* {1 C
收藏 评论0 发布时间:2021-12-14 10:49

举报

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