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

【经验分享】STM32f746gdiscovery LTDC 驱动

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

$ T0 W! {2 s. w+ o4 v7 d! w! K
  1. /*************************************************************************************************************% ?  R) T8 @9 j& p: }9 W5 _
  2. * 文件名                :        stm32f7_ltdc.c
      ]2 i* v  r$ x% T7 s
  3. * 功能                        :        STM32F7 外部RGB LCD驱动
    3 ^* G* _: m: P) W$ D
  4. * 创建时间                :        2019-09-12! ]& g  p9 y% S
  5. * 最后修改时间        :        2019-09-12
    1 D/ f! I3 s2 v  X" L
  6. * 详细:        
    1 X: c3 n! o1 d; |: \
  7. *************************************************************************************************************/        
    ! q5 f5 n( J! D: ]6 C- w
  8. #include "stm32f7_ltdc.h"
    , F9 ?3 ]# M7 O( w1 t( Q
  9. #include "SYSTEM.H" 1 B6 [( L9 A& o9 n; ~5 p
  10. #include "stm32f7_sdram.h"( Y4 }: ]( h! v
  11. #include "DMA2D.h"
    6 s6 E3 U: V! x; V! c

  12. # m& ?- [: A+ T# S/ a
  13. : `& ^4 l0 J+ q; o
  14. u32 g_LTDC_BUFF_RGB888[2][LTDC_HEIGHT][LTDC_WIDTH]  __attribute__ ((at(Bank5_SDRAM_ADDR)));                //需要SDRAM支持,LCD帧缓冲区,RGB888格式; c) E. o3 v8 n! j
  15. , ?$ _# ]. r5 T0 A/ P9 N. X
  16. $ V% u3 j. @) a" v: \
  17. //记录全局层配置信息  V8 z1 F# Z3 N) Y/ M( l- G
  18. typedef struct
    - x( u) S9 f4 j4 ]9 X3 y2 O
  19. {
    9 j& {7 f3 k3 D; n1 @6 z0 `
  20.         u16 sx;                                        //层开始X坐标,从0开始" N# C& y2 d4 `* U0 {- ~; r5 t2 y
  21.         u16 sy;                                        //层开始Y坐标,从0开始4 \$ `8 i, ^# X2 P  J2 F
  22.         u16 width;                                //层宽度
    4 Q5 R. e6 M: _- Y' E- `( h
  23.         u16 height;                                //层高度+ l2 G- _0 c: s" H% o# M. d" h
  24.         u32 *pFrameBuff;                //帧缓冲区指针,需要进行初始化$ Q* j% w! p1 `$ j* c4 V/ {
  25. }LTDC_LayerConfig;
    0 O* S; [- A3 B, N" p, Y
  26. 0 s6 S) L  P" b, V! B, w

  27. - {4 Z8 S' \$ X7 N: p

  28. # b6 g& V0 p6 \1 S. P5 e# |
  29. //全局的LTDC配置信息
    # H8 ~& y4 y* H% y; e% Z
  30. typedef struct- G; d# |9 Z! G5 q5 i' [) a2 V
  31. {1 [2 ~$ Z5 f' r5 K# P* ]
  32.         u16 lcd_width;                                                //显示器宽度9 N/ C5 }# f# [
  33.         u16 lcd_height;                                                //显示器高度
    / |/ @2 f* u4 E6 N, W4 f
  34.         LTDC_LayerConfig LayerConfig[2];        //层信息" b2 s( W4 X' I  x! v
  35. }LTDC_ConfigData;
    2 A  k# a* T( u2 l4 x+ t

  36. ' H$ E' k" z2 p: {, O; q

  37. ) q3 H, j$ t' K4 b( O
  38. static LTDC_ConfigData sg_LTDC_ConfigData;        //记录全局的LCD配置; h1 t4 R; l3 P; U; Q3 g. \: U- ]
  39.   f. ?2 D6 r. r7 B
  40. 4 ]! ?* R) ]1 Y4 G% r) i0 t2 s
  41. //显示屏信息
    3 o  A* |- L3 @1 d7 {
  42. typedef struct
      M6 n, D& r- t
  43. {# T3 z  v! A7 I# @" L
  44.         u16         Width;                //面板宽度,单位:像素
    7 ^' m) ^, B3 K, b* U, A" g' R
  45.         u16         Height;                //面板高度,单位:像素. `8 N! j7 m4 S* O9 A4 H7 [
  46.         u8          Thbp;                //水平后廊5 U2 f: V6 E  o2 M& z5 W
  47.         u8          Thfp;                //水平前廊0 C& d' k. }- x7 s4 [9 C. Z7 a
  48.         u8          Thw;                //水平同步宽度1 Q; [$ [4 R. L6 \6 i
  49.         u8          Tvbp;                //垂直后廊" H% M% [% c  r
  50.         u8          Tvfp;                //垂直前廊
    * P; r5 X' e/ t& U6 q* J
  51.         u8          Tvw;                //垂直同步宽度2 @6 Q, O& H6 v- _
  52.         u8          DCLK;                //时钟速度,MHz) C2 V/ W+ i" b3 p" v
  53.         6 O1 R% |! u5 Z4 p* [
  54.         u8                HSPOL;                //水平同步极性,0:低电平有效;1:高电平有效4 j8 I- C$ e) G' V. F* x! K
  55.         u8                VSPOL;                //垂直同步极性,0:低电平有效;1:高电平有效
    . g" V; C! z( K4 C* f& U# h# _
  56.         u8                DEPOL;                //数据使能极性,0:低电平有效;1:高电平有效+ \+ n" P2 V0 j/ P5 T
  57.         bool        PCPOL;                //像素时钟反向  h( M) n; y$ i
  58. }LTDC_INFO_TYPE;
    / v8 B& d& b5 b9 `+ _* x3 ^0 b

  59. . u: c' ^8 J, n9 v# J
  60. ) y* E4 X0 @) u2 |
  61. LTDC_INFO_TYPE DefaultLCD_Info =
    ) `( W1 ^. b& B1 W( P, ~
  62. {
    + A3 y) o2 Y/ H- {3 R9 I+ X
  63.         480,        //面板宽度,单位:像素3 p" [. |4 ]. A% A4 |
  64.         272,        //面板高度,单位:像素/ T+ O/ x4 q7 V# l
  65.         41,                //水平后廊
    6 M- ^1 P" ]6 L3 D) u
  66.         8,                //水平前廊
    % I) d6 Q) @/ N/ _* N
  67.         2,                //水平同步宽度: j: J: L6 Q0 ], y* m9 W
  68.         2,                //垂直后廊
    4 G' O. O5 l' C/ u! b
  69.         4,                //垂直前廊5 E0 N, U" N7 V$ S. x
  70.         10,                //垂直同步宽度8 o: u* m2 r1 @* B' m6 K
  71.         9,                //时钟速度,MHz: f( \1 t+ g& g2 E# J
  72.         0,                //水平同步极性,0:低电平有效;1:高电平有效
    ! F* U4 _" Q( o( N! G
  73.         0,                //垂直同步极性,0:低电平有效;1:高电平有效
    * j  K# B, P! J$ R; [
  74.         1,                //数据使能极性,0:低电平有效;1:高电平有效
    . B. X" i7 `' i- m
  75.         FALSE,        //像素时钟反向
    ) ^/ T: B# q+ I' |6 w. k! V
  76. };
    : z7 z. G. M( J, h) j7 [

  77. ! Z/ ^$ Y, T* `# _
  78. bool LTDC_ClockInit(u16 ClockFreq);                                                        //STM32F4 LTDC时钟初始化
    $ M6 c  F/ C7 b

  79. 1 e1 C7 k2 w) A% e# ]" w& f
  80. ) [' T0 p7 Q" i
  81. /*************************************************************************************************************************0 d6 x2 N  v4 I1 s
  82. * 函数        :                        void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha)
    ; x5 p. [! f% M2 r6 z
  83. * 功能        :                        LTDC 层窗口尺寸设置(会自动根据窗口尺寸以及像素格式设置帧缓冲区大小)9 h% F7 T0 `0 G1 O; ~5 x2 `
  84. * 参数        :                        LayerIndex:层选择(0-1);sx,sy:起始坐标;width,height:宽度和高度
    - [' y) U3 C4 k" a
  85. * 返回        :                        无3 V# ^9 P% _' q% `
  86. * 依赖        :                        底层宏定义
    1 x- s; h. x' X) j0 @% d* e
  87. * 作者        :                        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    - Z: Q- E  W8 T+ X2 f4 ?: v+ }0 t
  88. * 时间        :                        2019-10-28
    2 v9 m; X- t3 T& R% b! ^
  89. * 最后修改时间 :         2019-10-280 Z4 M7 ]- A+ O* K: R
  90. * 说明        :                         不会使能层,不会更新层,只设置配置,需要刷新层配置后更新
    . X) [; }9 D' |0 d) t
  91. *************************************************************************************************************************/ $ R6 q( N, R+ F; n3 s; |7 q' u" u
  92. void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha)3 |+ r2 E5 I4 }
  93. {
    : A. I3 L# I& A9 e/ i# z9 o
  94.         u32 temp;$ ^( [+ i) [8 F
  95.         u8 pixformat=0; ; `# {" h- d3 M' B: R$ N" R
  96.         
    ! X3 c3 R7 F3 Q& X) Z3 ]
  97.         if(LayerIndex==0)
    . I: U# l+ S* e. G3 _
  98.         {2 h3 |+ ?& t( t, m' l5 I0 L
  99.                 //基本配置) a+ R0 Y/ `) ~- j0 }- p
  100.                 LTDC_Layer1->CFBAR = FrameBuff;                                                                        //设置层颜色帧缓存起始地址
    $ x3 q- o2 f6 G( s5 ?- M7 d
  101.                 LTDC_Layer1->PFCR = LTDC_PIXEL_FORMAT;                                                        //设置层颜色格式
    $ `  \3 P8 H6 t; z6 g
  102.                 LTDC_Layer1->CACR = Alpha;                                                                                //常数 Alpha,255分频;设置255,则不透明
    4 @8 Z: l! ^- E  p# r
  103.                 LTDC_Layer1->DCCR = 0x00;                                                                                //设置默认颜色:透明的黑色
    # B. a& Z3 R5 J! l
  104.                 LTDC_Layer1->BFCR = ((u32)6<<8)|7;                                                                //设置层混合系数
    ' g2 `! S& B% i0 v' }" A5 {
  105.                 //配置窗口
    : j- F. }! M4 ~
  106.                 temp = (sx+width+((LTDC->BPCR&0X0FFF0000)>>16))<<16;
    & s8 Z4 j4 a4 t& o! l# ]$ t+ U
  107.                 LTDC_Layer1->WHPCR = (sx+((LTDC->BPCR&0X0FFF0000)>>16)+1)|temp;//设置行起始和结束位置 : O0 e  `, Q2 S3 a$ u% U( Y! ]
  108.                 temp = (sy+height+(LTDC->BPCR&0X7FF))<<16;
    3 o0 T9 b- y) `
  109.                 LTDC_Layer1->WVPCR = (sy+(LTDC->BPCR&0X7FF)+1)|temp;                        //设置列起始和结束位置: G5 @6 s" a  J
  110.                 pixformat = LTDC_Layer1->PFCR&0X07;                                                                //得到颜色格式  |) q  u- N* D6 q
  111.                 if(pixformat == 0)temp=4;                                                                                //ARGB8888,一个点4个字节: A# o5 v( i$ `# p6 z+ p
  112.                 else if(pixformat == 1)temp=3;                                                                        //RGB888,一个点3个字节# v1 j3 g8 d- {% a
  113.                 else if(pixformat==5||pixformat==6)temp=1;                                                //L8/AL44,一个点1个字节
    " ^- ^8 C& n! m4 z% K' A+ x
  114.                 else temp=2;                                                                                                        //其他格式,一个点2个字节
    3 v5 a/ \5 U3 w9 W+ [6 ]
  115.                 LTDC_Layer1->CFBLR = (width*temp<<16)|(width*temp+3);                        //帧缓冲区长度设置(字节为单位)
    1 l: c4 ^, C7 r0 W
  116.                 LTDC_Layer1->CFBLNR = height;                                                                        //帧缓冲区行数设置        5 i8 q- I2 H& W, D3 H3 T  u
  117.                
    # L& J! X# U6 |
  118.                 //记录层窗口大小位置信息
    & V0 |. q% ]5 H* c2 Y# K: Z+ `
  119.                 sg_LTDC_ConfigData.LayerConfig[0].sx = sx;               
    ' q, R  s+ K5 _
  120.                 sg_LTDC_ConfigData.LayerConfig[0].sy = sy;        
    5 W4 r- F- {3 G
  121.                 sg_LTDC_ConfigData.LayerConfig[0].width = width;        & Q2 T) i5 A* d" |& o7 K
  122.                 sg_LTDC_ConfigData.LayerConfig[0].height = height;        
    # X( j4 C' j* Q5 _4 f' |
  123.         }else0 D0 z" i. j; F6 K% J8 S
  124.         {
    1 d5 W% j- p8 h( g# e
  125.                 //基本配置
    ; Q7 U$ [- Z; _) p6 a9 Q# C2 z1 u
  126.                 LTDC_Layer2->CFBAR = FrameBuff;                                                                        //设置层颜色帧缓存起始地址
    . n9 F( `9 s7 n" q5 Z; \
  127.                 LTDC_Layer2->PFCR = LTDC_PIXEL_FORMAT;                                                        //设置层颜色格式) V- h; x6 `) W. u
  128.                 LTDC_Layer2->CACR = Alpha;                                                                                //常数 Alpha,255分频;设置255,则不透明3 Z+ s- R  F; R9 J4 w+ A/ s
  129.                 LTDC_Layer2->DCCR = 0x00;                                                                                //设置默认颜色:透明的黑色
    " H  s6 A9 A0 N2 w5 j  A
  130.                 LTDC_Layer2->BFCR = ((u32)6<<8)|7;                                                                //设置层混合系数
    6 z6 p, A/ Y- G7 Y
  131.                 //配置窗口
    1 p; |; d, d! A$ r* ?: Y4 q" l
  132.                 temp = (sx+width+((LTDC->BPCR&0X0FFF0000)>>16))<<16; # C4 @2 x' f9 t! I
  133.                 LTDC_Layer2->WHPCR = (sx+((LTDC->BPCR&0X0FFF0000)>>16)+1)|temp;        //设置行起始和结束位置
    " Z, ]7 m5 `7 Y  I* e
  134.                 temp = (sy+height+(LTDC->BPCR&0X7FF))<<16;
    6 F, E) h3 |& ~! x$ @
  135.                 LTDC_Layer2->WVPCR = (sy+(LTDC->BPCR&0X7FF)+1)|temp;                        //设置列起始和结束位置
    " P8 ^$ o! Q4 P8 d' E( H& S0 Q
  136.                 pixformat = LTDC_Layer2->PFCR&0X07;                                                                //得到颜色格式
    6 }5 w% W2 J4 f9 l0 _* w. R
  137.                 if(pixformat == 0)temp=4;                                                                                //ARGB8888,一个点4个字节
    " ?5 `  Q! @7 L' W7 k: E7 d' L: X
  138.                 else if(pixformat == 1)temp=3;                                                                        //RGB888,一个点3个字节
    / N# c8 T$ v5 q* @& K
  139.                 else if(pixformat == 5||pixformat==6)temp=1;                                        //L8/AL44,一个点1个字节
    , ^, l6 r& N6 E# [( h; ]$ x- s
  140.                 else temp = 2;                                                                                                        //其他格式,一个点2个字节
    2 I& X+ Y2 A) N1 I+ `
  141.                 LTDC_Layer2->CFBLR = (width*temp<<16)|(width*temp+3);                        //帧缓冲区长度设置(字节为单位)
    5 {: z2 W9 a- S6 |3 L. \5 D
  142.                 LTDC_Layer2->CFBLNR = height;                                                                        //帧缓冲区行数设置        
    7 U9 ]: W5 F( T$ Q) y$ M
  143.                
    : {8 G+ b9 U& v
  144.                 //记录层窗口大小位置信息) _& O3 m. O. m: K, e  Z
  145.                 sg_LTDC_ConfigData.LayerConfig[1].sx = sx;               
    ! }9 C* U! A! P$ l/ ^6 ~
  146.                 sg_LTDC_ConfigData.LayerConfig[1].sy = sy;        
    " j4 w! \6 S. M0 C, Q  y
  147.                 sg_LTDC_ConfigData.LayerConfig[1].width = width;        8 g5 ~) B! f2 X$ n" L
  148.                 sg_LTDC_ConfigData.LayerConfig[1].height = height;               
    4 ^: s8 q, I/ p9 j) I9 ]
  149.         }
    " d3 z( S. O- u! b! }. f2 W8 Q
  150. }& h' C; Q: r: e' U* Q
  151. * E  R3 R  C" q" w% P  W

  152. ' e" g% X# x7 r1 g; R; U. R# D! a: X
  153. 4 _4 a) Y7 J5 [
  154. /*************************************************************************************************************************
    8 y# R5 c* B6 x' z# h0 h
  155. * 函数        :                        void LTDC_Init(void)- g* P: j8 T8 T: S$ I' l" }
  156. * 功能        :                        LTDC 接口初始化' V# ^: e3 Z( O0 V$ ?5 y3 V
  157. * 参数        :                        无3 x7 u. v; X; p( ]8 T: M& x
  158. * 返回        :                        无2 S; ?7 V9 g* H7 N+ @/ e
  159. * 依赖        :                        底层宏定义
    . v7 Q, S" c; }' J( p1 U6 A
  160. * 作者        :                        <a href="mailto:cp1300@139.com">cp1300@139.com</a>& l4 v3 j( d9 E: M! T
  161. * 时间        :                        2019-09-08
    % `% V3 G' h( i7 P) R) r
  162. * 最后修改时间 :         2019-09-08" r6 a: q( F, u
  163. * 说明        :                         用于初始化STM32F7 LTDC 接口1 {8 k' C8 n  y: G
  164. *************************************************************************************************************************/  , `) v* J5 y* T# l3 [8 K
  165. void LTDC_Init(void)
    9 d1 X" `8 Q0 Z$ m% H) }, i! G
  166. {  G# T; H9 M) R  v- _1 {% }
  167.         u32 temp;
    + U  U, Q% ]5 s+ m$ z5 B( y( c
  168.         ; f; g) t4 r% R8 a
  169.         SYS_DeviceClockEnable(DEV_LTDC, TRUE);        //LTDC时钟使能- x/ v4 [7 S5 s8 ?2 I: Q8 L
  170.         SYS_DeviceReset(DEV_LTDC);                                //STM32F7外设复位) Q9 z& }: A$ j
  171.         SYS_DeviceClockEnable(DEV_GPIOE, TRUE);        //使能GPIOE时钟) j) R) ]1 J; D7 J2 j8 ~
  172.         SYS_DeviceClockEnable(DEV_GPIOG, TRUE);        //使能GPIOG时钟4 @* ?7 N1 n1 K/ z) C$ k
  173.         SYS_DeviceClockEnable(DEV_GPIOJ, TRUE);        //使能GPIOJ时钟: ?! Y" W! R4 x: I2 r, H; a7 p0 A
  174.         SYS_DeviceClockEnable(DEV_GPIOK, TRUE);        //使能GPIOK时钟
    - ^" |1 p2 ~% c( ]1 z
  175.         SYS_DeviceClockEnable(DEV_GPIOI, TRUE);        //使能GPIOI时钟
    & Q8 S3 |! n, Z8 C9 k/ d( p) _

  176. , [0 {7 l6 o" v" W: A
  177.           Y% V% M" {" @0 H1 |: N+ ?
  178.         //初始化IO8 N; I: W8 n/ ]
  179.         SYS_GPIOx_Init(GPIOE, BIT4, AF_PP_OPU, SPEED_100M);                                                                                //PE4
    : O0 j* z. k  Z6 \  _4 d' G
  180.         SYS_GPIOx_Init(GPIOG, BIT12, AF_PP_OPU, SPEED_100M);                                                                        //PG12& Y4 R" @9 {8 ]" T; u. [. F* M
  181.         SYS_GPIOx_Init(GPIOJ, 0Xffff&(~BIT12), AF_PP_OPU, SPEED_100M);                                                        //PJ0~11/13/14/15( ^, q1 Z( I; N, }2 n( z
  182.         SYS_GPIOx_Init(GPIOK, BIT0|BIT1|BIT2|BIT4|BIT5|BIT6|BIT7, AF_PP_OPU, SPEED_100M);                //PK0/1/2/4/5/6/7
    , Y. t& E. {7 M2 o8 p; I. r" {  ^
  183.         SYS_GPIOx_Init(GPIOI, BIT9|BIT10|BIT14|BIT15, AF_PP_OPU, SPEED_100M);                                        //PI9/10/14/15
    6 h2 D4 \- m  N! Z' O, C; o
  184.         ! k3 L8 a. i, j- U  a/ q0 p6 h! Q
  185.         SYS_GPIOx_SetAF(GPIOE, 4, AF14_LTDC);                //PE4,AF14        
    ! r  L9 S4 \: L
  186.          SYS_GPIOx_SetAF(GPIOG, 12, AF14_LTDC);                //PG12,AF14        ' G# c7 l# c8 _0 s5 f6 p
  187.         SYS_GPIOx_SetAF(GPIOJ, 0, AF14_LTDC);                //PJ0,AF14
    ; P% v5 t) Z/ I- y
  188.         SYS_GPIOx_SetAF(GPIOJ, 1, AF14_LTDC);                //PJ1,AF14; W+ @* B0 {$ k8 U$ B
  189.         SYS_GPIOx_SetAF(GPIOJ, 2, AF14_LTDC);                //PJ2,AF14, H6 q9 p: N) }! I' H: z- y
  190.         SYS_GPIOx_SetAF(GPIOJ, 3, AF14_LTDC);                //PJ3,AF14
    ) N! S: n. e: ^0 O0 {: j0 `; K0 _
  191.         SYS_GPIOx_SetAF(GPIOJ, 4, AF14_LTDC);                //PJ4,AF14
    1 x3 x! P8 H9 J3 c; u+ |0 R; R
  192.         SYS_GPIOx_SetAF(GPIOJ, 5, AF14_LTDC);                //PJ5,AF14
      L; U9 [# U. p8 s$ [0 G
  193.         SYS_GPIOx_SetAF(GPIOJ, 6, AF14_LTDC);                //PJ6,AF147 v+ N- O5 u* t6 b  P
  194.         SYS_GPIOx_SetAF(GPIOJ, 7, AF14_LTDC);                //PJ7,AF14; ], O3 J6 w% ]" x  T
  195.         SYS_GPIOx_SetAF(GPIOJ, 8, AF14_LTDC);                //PJ8,AF14. R4 @" Y! W' W) i3 w  e9 [
  196.         SYS_GPIOx_SetAF(GPIOJ, 9, AF14_LTDC);                //PJ9,AF14
    / x/ N  O# W! E- b% k
  197.         SYS_GPIOx_SetAF(GPIOJ, 10, AF14_LTDC);                //PJ10,AF141 I$ T" D. U- H3 j$ J* F7 \
  198.         SYS_GPIOx_SetAF(GPIOJ, 11, AF14_LTDC);                //PJ11,AF14
    4 m/ t2 v9 M2 h( O" Q: g: [' L
  199.         SYS_GPIOx_SetAF(GPIOJ, 13, AF14_LTDC);                //PJ13,AF14, O& H) S9 N. x. `+ b( h
  200.         SYS_GPIOx_SetAF(GPIOJ, 14, AF14_LTDC);                //PJ14,AF14
    ( \4 P9 O) X# Z. G0 ?% p
  201.         SYS_GPIOx_SetAF(GPIOJ, 15, AF14_LTDC);                //PJ15,AF14
    3 N! A, O; ~) x* w) _$ V
  202.         
    " k  x4 Y8 v; y( v9 J# |
  203.         SYS_GPIOx_SetAF(GPIOK, 0, AF14_LTDC);                //PK0,AF149 o9 W* Z8 T: Y$ N% X# b5 W
  204.         SYS_GPIOx_SetAF(GPIOK, 1, AF14_LTDC);                //PK1,AF14; D4 e+ Q1 {3 I7 @- K# F1 J
  205.         SYS_GPIOx_SetAF(GPIOK, 2, AF14_LTDC);                //PK2,AF14
    ) ~) i6 W1 {! A
  206.         SYS_GPIOx_SetAF(GPIOK, 4, AF14_LTDC);                //PK4,AF14
    2 U6 h# E. c/ H' g% B. h* m
  207.         SYS_GPIOx_SetAF(GPIOK, 5, AF14_LTDC);                //PK5,AF14
    / k, G5 D1 G/ \  i% m" e
  208.         SYS_GPIOx_SetAF(GPIOK, 6, AF14_LTDC);                //PK6,AF14; i4 [" t2 T( F& t5 n7 ]% H/ ?' \
  209.         SYS_GPIOx_SetAF(GPIOK, 7, AF14_LTDC);                //PK7,AF14
    " B0 K* i3 B- t% k
  210.         
    4 [8 ?' S- x7 X0 I
  211.          SYS_GPIOx_SetAF(GPIOI, 9, AF14_LTDC);                //PI9,AF147 Q, t/ l: v0 W. B
  212.          SYS_GPIOx_SetAF(GPIOI, 10, AF14_LTDC);                //PI10,AF14
    5 f4 o) i0 ^! v! C
  213.         SYS_GPIOx_SetAF(GPIOI, 14, AF14_LTDC);                //PI14,AF14
    , A6 m9 m. ]* [( i
  214.          SYS_GPIOx_SetAF(GPIOI, 15, AF14_LTDC);                //PI15,AF14 . r4 [  g2 w# H) |0 v. N
  215.         8 j( P& x! l4 ]3 A8 ]; u7 B! t- o
  216.         LTDC_ClockInit(DefaultLCD_Info.DCLK);                 //设置像素时钟  9Mhz % w- L" {. m& @
  217.         //设置LTDC 全局控制寄存器 (LTDC_GCR)
    % J$ ~+ l, J- }( J* R) }) ^9 |/ w
  218.         temp = 0;& B/ L7 S. ^% j8 R4 q2 q1 v+ f% N
  219.         temp |= (DefaultLCD_Info.HSPOL&0x01) << 31;        //水平同步极性6 o4 o5 m$ Q5 S( p
  220.         temp |= (DefaultLCD_Info.VSPOL&0x01) << 30;        //垂直同步极性" @1 R1 J: ]( V7 f! E: ^
  221.         temp |= (DefaultLCD_Info.DEPOL&0x01) << 29;        //数据使能极性
    3 o9 @1 Z  O( Z6 n
  222.         temp |= (DefaultLCD_Info.PCPOL&0x01) << 28;        //像素时钟极性3 ]8 ~' P, G4 c. r
  223.         LTDC->GCR = temp;9 T0 ?4 p  ?8 V# ?: T8 ]/ N% _2 P
  224.         //LTDC 后沿配置寄存器 (LTDC_BPCR)
    6 |3 j9 {! P5 O" \- S- D# z
  225.         temp = (DefaultLCD_Info.Tvw + DefaultLCD_Info.Tvbp - 1) << 0;        //这些位定义累加水平后沿宽度(水平同步像素加水平后沿像素减 1)。
      s9 a6 ^' H/ i9 b: j
  226.         temp |= (DefaultLCD_Info.Thw + DefaultLCD_Info.Thbp - 1) << 16;        //这些位定义累加垂直后沿宽度(垂直同步行加垂直后沿行减 1)。- W' x& ~2 f, T) F% h. a- D+ |9 M) s' K
  227.         LTDC->BPCR=temp;        
    ) {+ X! R) }, P2 M" r8 |
  228.         9 D7 R4 z: X9 O" E
  229.         //LTDC 有效宽度配置寄存器 (LTDC_AWCR)
    - ^  f  L8 h; {" B5 ~9 m, H" h5 l- \
  230.         temp=(DefaultLCD_Info.Tvw+DefaultLCD_Info.Tvbp+DefaultLCD_Info.Height-1)<<0;        //累加有效高度=垂直脉宽+垂直后沿+垂直分辨率-1
    2 m2 p: @, u' Q; q7 _% a* b  O
  231.         temp|=(DefaultLCD_Info.Thw+DefaultLCD_Info.Thbp+DefaultLCD_Info.Width-1)<<16;        //累加有效宽度=水平脉宽+水平后沿+水平分辨率-1
    # g+ I# f) _' x+ z7 Z8 ^
  232.         LTDC->AWCR=temp;        . a7 c9 F: K" D' S/ S% e& V
  233.         //LTDC 总宽度配置寄存器 (LTDC_TWCR); Z# ^+ ~$ L# h
  234.          temp=(DefaultLCD_Info.Tvw+DefaultLCD_Info.Tvbp+DefaultLCD_Info.Height+DefaultLCD_Info.Tvfp-1)<<0;        //总高度=垂直脉宽+垂直后沿+垂直分辨率+垂直前廊-1
    8 |' x% Y+ Q- s6 Q2 k
  235.         temp|=(DefaultLCD_Info.Thw+DefaultLCD_Info.Thbp+DefaultLCD_Info.Width+DefaultLCD_Info.Thfp-1)<<16;        //总宽度=水平脉宽+水平后沿+水平分辨率+水平前廊-1
    5 R+ a& g' o) @
  236.         LTDC->TWCR=temp;                                
    7 H) A% B, C& X2 b2 P1 m; W
  237. ; B; P8 S! N0 z( ^% U' N
  238.         //背景设置
    ; m+ z- q' `3 I4 |3 @
  239.         LTDC->BCCR=0xffffff;                                //设置背景层颜色寄存器(RGB888格式)
    : f# H% B: v! S+ c( i0 _
  240.         LTDC_Enable(TRUE);                                        //开启LTDC
    6 C% K3 y: Z! }
  241.         //初始化层17 r/ U& s# x& c; |8 P8 L6 @# v
  242.         LTDC_SetLayerConfig(0, 0, 0, LTDC_WIDTH, LTDC_HEIGHT, (u32)g_LTDC_BUFF_RGB888[0], 255);
    : s  l) }# a7 S7 W4 ?2 Y# t; |
  243.         //初始化层2
    8 i" a( C5 `0 U8 f8 B* a
  244.         LTDC_SetLayerConfig(1, 0, 0, LTDC_WIDTH, LTDC_HEIGHT, (u32)g_LTDC_BUFF_RGB888[1], 255);
    2 S8 u: N* B. v( ]( O2 L1 l
  245.         LTDC_Clear(0, 0xFF000000);                        //清屏层1-不透明的黑色0 a, |$ J. b8 r$ x1 E) _; i
  246.         LTDC_Clear(1, 0x00000000);                        //清屏层2-透明的黑色
    ; g1 L# }' n8 L! l+ h
  247.         LTDC_LayerEnable(0, TRUE);                        //使能层19 K5 J8 ?* g( F& n  q/ d- K
  248.         LTDC_LayerRefreshConfig();                        //LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)
    1 o( D# C1 v. Z$ `- e% p; Z8 S
  249.         LCD_DispIoInit();                                        //初始化DISP引脚-启动显示$ X0 A: ?& Q2 x  F
  250. }
    6 ~1 s! C4 U# p/ i/ W" d# o1 Y
  251. ) r# k6 s5 E7 e8 l1 a
  252. /*************************************************************************************************************************
    8 ^, W7 F) F" M3 B  X0 @5 x
  253. * 函数                        :        void LTDC_LayerRefreshConfig(void)8 I8 h" }, j% \- y
  254. * 功能                        :        LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)
    0 M) z/ D# `3 O+ }
  255. * 参数                        :        无
    . V* H3 ~8 ~6 O- T
  256. * 返回                        :        无
    5 x5 K# W( `3 ^- i' d
  257. * 依赖                        :        底层宏定义6 {$ x; k, l! R& q1 W( z; g# H
  258. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>. F$ r1 j& a$ r; o0 B. {
  259. * 时间                        :        2019-10-29
    ; I3 X1 g0 O7 B- m( Z$ m
  260. * 最后修改时间         :         2019-10-29
    ! Y( e% x; x! c; Z4 f% `
  261. * 说明                        :        修改层配置后必须重新加载,否则不会生效) R7 l3 Y( `+ h+ s
  262. *************************************************************************************************************************/7 {' ]5 T3 @/ v
  263. void LTDC_LayerRefreshConfig(void)  B) V( ?% r8 s6 h
  264. {
    7 a7 ^: ?- G9 y( q( y% U0 P
  265.         LTDC->SRCR|=1<<0;                                                        //重新加载配置-必须重新加载,否则上面的层不会更新,折腾好久才发现,叫啥影子寄存器重载,也不说清楚
    * Z3 W( A5 A$ Y. a" O* d$ g' i/ v
  266. }5 Y) X! u/ l  F" `7 x& Q% C. {1 D/ ]" S

  267. " z2 l: n3 s$ x+ p4 ~5 y) H
  268. /*************************************************************************************************************************
      z& j/ c: A% c: E8 U6 V" E" t5 |
  269. * 函数                        :        void LTDC_Enable(bool Enable)
    6 k. T! ?3 y; W" ^1 Z0 }) z
  270. * 功能                        :        LTDC使能设置, _$ D0 L& F9 E0 W, F. M
  271. * 参数                        :        Enable:TRUE:使能;FALSE:失能
    9 x1 l  n+ N4 o- X
  272. * 返回                        :        无
    1 W% k- J* K+ I+ L
  273. * 依赖                        :        底层宏定义/ i# I5 c4 p) T( L* [* ?
  274. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    . h; U) ]) A5 W& C/ j. o2 X) `% i
  275. * 时间                        :        2019-10-29
    9 F9 U+ p: x- ~  W6 U
  276. * 最后修改时间         :         2019-10-29
    1 [  _+ H- ~$ y7 A* i; {, \
  277. * 说明                        :        
    ! {" A; U9 O, Y  l, [
  278. *************************************************************************************************************************/" l! V* u% _, T4 }9 |
  279. void LTDC_Enable(bool Enable)* _2 I' @0 C$ |: \
  280. {/ \9 x. a/ S' i% q3 V
  281.         if(Enable)
    / Q9 `" n1 M, q
  282.         {! S1 ?, y* U8 y' t* k; C
  283.                 LTDC->GCR |= BIT0;                                        //打开LTDC
    ) Q) i+ F6 Z% ~6 B/ x8 a
  284.         }% M- ?2 u9 W% G6 t+ I
  285.         else6 K9 Z, U% Y& W$ k  t. i& _
  286.         {' L, X% t: G0 I
  287.                 LTDC->GCR &= ~BIT0;                                        //关闭LTDC8 \9 A- w1 X& x/ O2 g- a/ c. q
  288.         }
    2 Z5 z; W9 p- N/ L
  289. }
    1 z1 I3 q# x/ b: P

  290. 7 ]& k( D5 E( x1 T. G* l
  291. /************************************************************************************************************************** j: f" c& S' W0 Z; Q4 \' R
  292. * 函数                        :        void LTDC_LayerEnable(u8 LayerIndex, bool Enable)
    ; i, L' c. C! A1 v5 ~8 E- N
  293. * 功能                        :        LTDC 层使能设置7 G/ a* `+ c% N* k- g6 T# Z
  294. * 参数                        :        LayerIndex:层选择0-1;Enable:TRUE:使能;FALSE:失能
    5 h' x$ K' b" e0 _! C3 f6 l2 L
  295. * 返回                        :        无; \4 B1 h6 O- @6 l' ?  z
  296. * 依赖                        :        底层宏定义
    9 Q6 m$ V; f7 G& L# u
  297. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>1 D- h! r4 m! B5 t. ?
  298. * 时间                        :        2019-10-290 o! e3 O; g9 d) ]
  299. * 最后修改时间         :         2019-10-29' X- Y$ {( i$ O) w: O  K) h
  300. * 说明                        :        3 P% m' I1 g2 ]- G" s' m
  301. *************************************************************************************************************************/5 p, w& t7 m/ q# r+ W
  302. void LTDC_LayerEnable(u8 LayerIndex, bool Enable)
    8 Y8 f9 ?8 e/ I- Q
  303. {- O9 F9 j- \- B2 v8 M( F  l
  304.         if(Enable)
    6 V6 \7 R/ ~+ Y4 d; T8 V
  305.         {
    ' Z# s; }% O# f$ z: V! [
  306.                 if(LayerIndex == 0)                                        //层1- b  {% R! i1 U3 S
  307.                 {
    / g2 F. l- Q9 X# l
  308.                         LTDC_Layer1->CR |= BIT0;                //使能层12 U( Q9 [( f% s7 u7 B& x8 @; u4 z; F, |
  309.                 }
    " b7 s% c1 g) h( X2 @8 `9 q0 z! H
  310.                 else5 r3 Z; S" e' Y( j5 S) p
  311.                 {
    0 S. v5 i/ \3 I. }. Q) l
  312.                         LTDC_Layer2->CR |= BIT0;                //使能层2" i% M1 U2 P* p! H; z
  313.                 }0 x! v" ]6 w+ B* {: M+ t
  314.         }
    * T+ l' ~, ]  _, |
  315.         else) L- W% _, u1 C8 i9 v. Z
  316.         {5 \! n/ t; |# ?" ~& _8 S  ^
  317.                 if(LayerIndex == 0)                                        //层14 f, L0 r$ e# d- c
  318.                 {
    ) H/ E2 L* S& }0 s$ X/ ^
  319.                         LTDC_Layer1->CR &= ~BIT0;                //失能层1
    3 y0 v3 [, D3 S
  320.                 }  x" W) r0 a0 d5 U# F0 D
  321.                 else4 K# U3 K- O- ?3 j  q
  322.                 {
    4 @3 L5 k: p2 a6 ^* b
  323.                         LTDC_Layer2->CR &= ~BIT0;                //失能层2% R- D+ h4 Q+ ~; ?% A+ l# w
  324.                 }% }' A' P3 `7 ?( C$ e
  325.         }6 h' A& `8 _8 Q  M" ], v
  326. }
    " m# b& S4 m7 ]+ M4 \

  327. 3 h5 p7 X% w0 r' N

  328. 0 X9 b# P# R8 f4 |+ O

  329.   O3 C! C1 ?' |; k, Q( C( D& g; r
  330. - x1 o) g7 e( v7 J
  331. /*************************************************************************************************************************
    $ x$ b7 O: v3 j0 U# g3 B
  332. * 函数                        :        bool LTDC_ClockInit(u16 ClockFreq)                        
    : V- V4 Z& I/ H- L9 v
  333. * 功能                        :        STM32F7 LTDC时钟初始化
    - u+ S" p5 D0 c  Q& }4 m! T
  334. * 参数                        :        ClockFreq:时钟频率,2-168MHZ
    $ z3 U, G" z2 {3 X. y. _+ y& V% b3 X
  335. * 返回                        :        是否设置成功- w7 e( M9 |) A9 n- }7 q- `7 V* A
  336. * 依赖                        :        底层宏定义
    / X7 q. J# v- g
  337. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    ) [9 B5 _, c8 ^
  338. * 时间                        :        2019-10-28# ?6 @% e9 W3 F# q3 b8 D) e( X
  339. * 最后修改时间         :         2019-10-284 J' ~  X+ d" G, C! a
  340. * 说明                        :        输入时钟频率在系统主时钟初始化之后就会设置为1MHz,通过设置SAI PLL实现LTDC所需频率,VCO频率范围:49~4326 C" ^7 u5 X& |+ [
  341. *************************************************************************************************************************/
    $ J/ M6 p" W" J, w" A( n
  342. bool LTDC_ClockInit(u16 ClockFreq)
    9 Z+ O9 D. U, j% E/ P4 g& ?
  343. {- X) h$ ?+ q0 E8 n
  344.         u32 TimeOut = 0;
    # J2 I& Y. L; E% A/ J; m. @, P6 G
  345.         u32 VCO;
    , p, l2 }' b! s% }
  346.         u32 PLLSAIR;                //PLLSAICFGR[30:28]. a# M2 r( A( S" R
  347.         u32 PLLSAIDIVR;                //DCKCFGR1[17:16]
    / u& `1 t1 Y1 r6 m/ Q+ Q% U
  348.         u32 temp;
    ( `/ M4 A4 @, m
  349.         
    ( I2 X  F! k% H) e
  350.         if(ClockFreq < 1)ClockFreq = 1;
    " i; S4 G6 V+ @6 h  ^: l. n4 x0 ^
  351.         if(ClockFreq > 100) ClockFreq = 100;
    6 ^4 Z+ @( s! R/ G
  352.         
    ) I5 l5 p5 Y8 `& f
  353.         RCC->CR &= ~(1<<28);                                                //关闭SAI时钟 , N) `/ ^, _& o! p
  354.         TimeOut = 0;* B: W, w* C) P$ v% E6 I
  355.         while(RCC->CR&(1<<29))                                                //等待关闭成功" |1 @  }- v. s) C  C( L
  356.         {5 w# M' o; M5 t8 h
  357.                 nop;
    , I  t+ Q1 m! G" x7 W
  358.                 TimeOut ++;
    , ^! P+ l+ h5 p. ]+ m4 ^; y
  359.                 if(TimeOut > 0xFFFF) return FALSE;                //关闭超时
    ( m# F( W$ l2 n7 [3 D  V# T
  360.         }" Z* U7 `9 S. }0 Q9 N
  361.         //计算分频与VCO频率,通过PLLSAICFGR[30:28]可以设置2-7分频4 G7 o! |8 b5 V3 {, G; P
  362.         //通过PLLSAICFGR[17:16]可以设置00:2 01:4 10:8 11:16分频8 P8 M4 {3 f" J0 m/ R: J
  363.         //通过PLLSAICFGR[14:6]可以设置为49-432MHz的VCO频率
    1 F, J3 c' e7 q& q  @* M
  364.         if(ClockFreq <= 6)
    # @* I0 r# i4 l2 D* F
  365.         {
    , ?# |: H2 i1 O! \- _5 d" E& O
  366.                 PLLSAIR = 4;        //4分频
    * o/ @# o  ~+ H' `4 @
  367.                 PLLSAIDIVR = 3;        //16分频
      Z+ B2 l' I8 Q+ ]4 c
  368.                 VCO = ClockFreq * PLLSAIR * 16;                        //VCO范围:64-384;) y" w/ R. C+ L! V+ X) m) f0 s# ]
  369.         }# t* o0 G# |6 v" g1 Y
  370.         else if(ClockFreq <= 13)" b. D. d  h6 A: s, L, v4 g
  371.         {
    ( `) \8 n  v% U, k. F
  372.                 PLLSAIR = 4;        //4分频
    0 u" Y5 Q3 K' b7 G
  373.                 PLLSAIDIVR = 2;        //8分频' }- h4 l' M; {& K+ v+ U
  374.                 VCO = ClockFreq * PLLSAIR * 8;                        //VCO范围:224-416;! M3 ~$ a" H7 J- r
  375.         }9 y' e+ |' |, B
  376.         else if(ClockFreq <= 26)4 m- s: A* J9 _- s- t& c
  377.         {
    " U  N2 G* c7 ?' I8 t
  378.                 PLLSAIR = 2;        //2分频
      d# P; z- p- T5 r- `* G& g# e
  379.                 PLLSAIDIVR = 2;        //8分频/ n& f5 x4 m2 h6 s9 I0 ?
  380.                 VCO = ClockFreq * PLLSAIR * 8;                        //VCO范围:224-416;, B. U. G* {; P8 g1 U9 x, ~
  381.         }9 A, p6 x, R7 ^. q8 V
  382.         else if(ClockFreq <= 52)
    % _% c' f; [9 ]% U2 `) K
  383.         {9 p3 j: _$ e0 ?  W: Y; c: R+ X
  384.                 PLLSAIR = 2;        //2分频  c9 K, E  i+ n5 {8 L
  385.                 PLLSAIDIVR = 1;        //4分频
    , _/ B- N/ z. D# w2 q4 {" F
  386.                 VCO = ClockFreq * PLLSAIR * 4;                        //VCO范围:216-416;
    ) }* m9 `6 l$ q) H: g2 n4 @
  387.         }
    7 R* w7 M, g# s) c0 z3 V: h1 j
  388.         else if(ClockFreq <= 104)
    4 a) Z& z/ N, T1 U6 w; V2 t1 T% m
  389.         {
    : H/ a. l8 t$ b
  390.                 PLLSAIR = 2;        //2分频; _" S2 L" u# B% H' K/ h3 {5 {0 |
  391.                 PLLSAIDIVR = 0;        //2分频
    : \: g+ r* W" u1 P9 O& g* Z. V; x
  392.                 VCO = ClockFreq * PLLSAIR * 2;                        //VCO范围:212-416;( g2 N: d2 n: j$ l5 |
  393.         }
    7 u2 E0 r- Q  j7 M/ k2 E9 S" ?0 L6 ~
  394.         //设置PLLSAICFGR
    : G; _' u+ D' f# Y; {; W# |
  395.         temp = RCC->PLLSAICFGR;& w8 w" \' X2 L# {9 P/ l* \
  396.         temp &= ~((3<<28) | (0x1FF<<6));                        //清除之前的设置: _: [7 Q: Q: w' E7 D2 T
  397.         temp |= PLLSAIR << 28;                                                //设置分频PLLSAICFGR[30:28]
    : {8 n; C, {9 d3 c8 c
  398.         temp |= VCO << 6;                                                        //设置VCO% I+ ^  s& s8 b; h" f4 v( I
  399.         RCC->PLLSAICFGR = temp;5 l% j" U$ Z" y; Q9 z
  400.         //设置DCKCFGR1; T+ D' O) N8 W9 t1 `+ ~0 r
  401.         temp = RCC->DCKCFGR1;2 S$ F. L2 N) Z
  402.         temp &= ~(3<<16);                                                        //清除之前的设置
    " q, C/ o: q5 _+ e
  403.         temp |= PLLSAIDIVR << 16;                                        //设置分频DCKCFGR1[17:16]+ m- Y1 M# a7 \2 T
  404.         RCC->DCKCFGR1 = temp;) w6 ^! }* [6 t) F0 ]. s
  405.         //启动时钟
    $ G/ C' T! H; G; o- R" g( K
  406.         RCC->CR |= 1<<28;                                                        //启动SAI时钟
    4 S  K% U6 l/ @) a( q4 Y  [
  407.         TimeOut = 0;
    0 M, h( H% J2 F$ |
  408.         while((RCC->CR&(1<<29)) == 0)                                //等待开启成功
    # J+ E: N& N- ~, R1 P
  409.         {( r) C; r. ]& Y; C" l+ @/ _
  410.                 nop;6 i/ j: M& g5 A( v2 s
  411.                 TimeOut ++;
    % I5 c/ T% }, @/ D
  412.                 if(TimeOut > 0xFFFF) return FALSE;                //开启超时6 |0 A  B2 B: F/ W# k! G
  413.         }
    " A; K' W2 `6 D( g6 A
  414.         
    * y: [" M5 I% @  }
  415.         return TRUE;/ ?! ~; m  r+ j8 p& g
  416. }
    ; Y+ V) H, K( d8 z' ~

  417. ' C6 l5 A$ p+ m
  418. * ~9 `5 v6 k% ^5 ~$ T9 I
  419. /*************************************************************************************************************************
    # V* q( z$ A- E# j5 D  ~* L' M
  420. * 函数                        :        void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color)        7 Q0 _; A0 `) I3 j# q" A
  421. * 功能                        :        矩形填充(使用DMA2D)4 M  M$ A' p/ _9 N* ]
  422. * 参数                        :        LayerIndex:层选择0-1;sx,sy:开始坐标;ex,ey:结束坐标,color:需要填充的颜色- ?2 w* v3 i" D% M- H' m
  423. * 返回                        :        无
    9 _8 {- q) |& I$ z
  424. * 依赖                        :        底层宏定义
    2 f* Q  Q1 @, ^
  425. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    . p+ k/ h) q. w
  426. * 时间                        :        2019-10-30
    9 Z, T* g$ b! y4 I/ s& v
  427. * 最后修改时间         :         2019-10-30
    & z7 ]" `+ G$ a. ^
  428. * 说明                        :        采用DMA2D实现9 g5 Z. e7 r, }4 p) D
  429. *************************************************************************************************************************/" \8 {# S2 T9 J; D: g$ s
  430. void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color)
    3 R$ i) T, Z" i/ m
  431. {4 |0 F1 @9 c. y2 E+ b# y
  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进行单色填充
      K0 q; S& h' ^$ O4 h! o) O2 L
  433.         DMA2D_WaitTransferComplete(500);                                                                                                                                                                                                                                //等待DMA2D传输完成
    6 a' L& r0 A+ D. C5 ?2 z
  434. }8 q$ ?( X: ~4 ]) ?4 W  s
  435. 6 N* h7 H8 z" v2 R

  436.   H7 \6 u8 @/ O' S# j3 `& {9 Z
  437. /*************************************************************************************************************************
    : A; x2 ]8 O  L" J
  438. * 函数                        :        void LTDC_Clear(u8 LayerIndex,u32 color)6 ~* Z9 n0 K1 o7 r6 i
  439. * 功能                        :        清屏(使用DMA2D)
    - e% J; [; c; p# Q. {3 K
  440. * 参数                        :        LayerIndex:层选择0-1;color:需要填充的颜色; }6 ]( a3 C( ?( d, _* X
  441. * 返回                        :        无
    $ E  _( j2 X# J2 f0 ^
  442. * 依赖                        :        底层宏定义
    / Z6 C1 ?- |0 y0 l7 f
  443. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    0 |6 l6 g. U) O3 C
  444. * 时间                        :        2019-10-30
    + k4 v& N9 Y5 |, ^
  445. * 最后修改时间         :         2019-10-30
    : S: C) Y' i' J% ~
  446. * 说明                        :        采用DMA2D实现3 [5 H  f3 {$ E9 A* B
  447. *************************************************************************************************************************/
    7 F* }) ]) I( i- z7 A3 l
  448. void LTDC_Clear(u8 LayerIndex,u32 color)6 _5 i  t! V! q' n; S0 B
  449. {% w* k; s% G) k+ Q7 i: E& U
  450.         DMA2D_FillColorToFGRAM((u32)&g_LTDC_BUFF_RGB888[LayerIndex][0][0], LTDC_WIDTH, LTDC_HEIGHT, 0,  DMA2D_COLOR_ARGB8888, color);                                        //DMA2D进行单色填充
    ; D# U6 {; w  i8 [/ c
  451.         SYS_DelayMS(5);4 g) u! Q* `; d- V
  452.         DMA2D_WaitTransferComplete(500);                                                                                                                                                                                                                                //等待DMA2D传输完成
    / Z! |! z  H5 O
  453. }7 ~3 j% ~& R$ ^! j5 ^4 m0 @) }
  454. + C' G& x8 k& r  T  n$ ]2 S
  455. ( ^- B4 X" i7 |* v  ]+ [/ m) y# ]
  456. /*************************************************************************************************************************
    1 T  i' V# l7 H* T
  457. * 函数                        :        void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr)/ v8 o. p8 [5 V: ]  M
  458. * 功能                        :        矩形图像填充(相同坐标范围传输,要求源图像与目标显示器分辨率一致,使用DMA2D)3 S5 J$ \( @. v/ g1 ^1 e
  459. * 参数                        :        LayerIndex:层选择0-1;sx,sy:开始坐标;ex,ey:结束坐标,ImageAddr:需要填充的图像地址/ b9 ?; _! W0 y1 q
  460. * 返回                        :        无3 ~, K( z' I# K
  461. * 依赖                        :        底层宏定义; D' U4 e: O# h' _! W& {/ I
  462. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>1 f% Q) ?3 g6 _- o3 M( y( c: K
  463. * 时间                        :        2019-10-30
    3 S+ x* W( N# `5 v2 I( z
  464. * 最后修改时间         :         2019-10-30
    # ~4 \& Q0 z% B; T% n) u
  465. * 说明                        :        采用DMA2D实现,将源图像指定位置传输到现存,要求源图像与显存大小一致, q6 |; Q* S7 M$ V/ j
  466. *************************************************************************************************************************/4 |* M8 x- p. |8 n+ o# f
  467. void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr)9 J  O, P5 K4 |5 I3 e
  468. {( g, N0 N3 `" ]
  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进行矩形图形填充
    * u# _4 _" _! }) A# a
  470.         DMA2D_WaitTransferComplete(500);
    ! S3 B6 F% D, e4 c+ |' x* _
  471. }
复制代码
  1. /*************************************************************************************************************
    1 ?; G, v( J& j% e
  2. * 文件名                :        stm32f7_ltdc.h' `, d1 j) @" E) \+ J
  3. * 功能                        :        STM32F7 外部RGB LCD驱动
    , s1 M; I7 M8 k, [$ m
  4. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a># P3 ^6 X+ i3 ]6 r4 R
  5. * 创建时间                :        2019-09-12
    0 c; M3 b" r/ ^, I3 E. o
  6. * 最后修改时间        :        2019-09-12" b+ B3 D$ ^! y+ i6 @; z
  7. * 详细:        2 A2 Y8 {* Z  b
  8. *************************************************************************************************************/               
    ! _+ n. m) X: |* l5 S
  9. #ifndef __STM32F7_LTDC_H_
    1 L/ }" g" d) w, @% X
  10. #define        __STM32F7_LTDC_H_           
      M+ \) ?5 d1 Z0 ~2 a" c- v/ K. t
  11. #include "system.h"+ J! t  ~  K4 P7 N! }& P, |
  12. #include "DMA2D.h"
      A: h5 X/ Z1 E8 }# W% d  J( t5 q- v
  13. - J4 ^( u; E$ i$ h
  14. #define LTDC_WIDTH                480
    % o3 v" d- n# x6 Q2 }+ f
  15. #define LTDC_HEIGHT                272
    & b+ u* a* H' X* V3 I8 I8 h

  16. - J0 I0 O+ Z  k# W/ c2 y

  17. * }9 H6 B- `: M# O: [( Y6 f* A* i3 k+ `
  18. extern u32 g_LTDC_BUFF_RGB888[2][LTDC_HEIGHT][LTDC_WIDTH];
    " y0 g& _' h' m6 @: @1 n
  19. ; k/ a* [0 e2 v* I+ {
  20. //像素格式定义
    $ @# Z- r2 A, {$ g" g! B6 i
  21. typedef enum
    : g" |, i+ j7 T' _  e% o
  22. {) d# F' k* V  E& r* x2 z: A
  23.         LTDC_ARGB8888         = 0,7 C9 w* y# e* f! y
  24.         LTDC_RGB888         = 1,
    ; T" Y/ }, |+ E) P2 r9 W# X0 }
  25.         LTDC_RGB565         = 2,
    % \2 z: Y: p2 k9 @; x6 `
  26.         /*LTDC_ARGB1555         = 3,
    . k4 a3 w' Z. E: b# D
  27.         LTDC_ARGB4444         = 4,$ d# b. y3 O( Z# L. e4 O7 _2 h  f
  28.         LTDC_L8                 = 5,        //8 位 Luminance
    % J) R3 k) ]6 I" \
  29.         LTDC_AL44                 = 6,        //4 位 Alpha,4 位 Luminance3 p  {: I( x) T. W5 M7 ^
  30.         LTDC_AL88                 = 7,        //8 位 Alpha,8 位 Luminance*/8 e  c0 i* C5 U6 C; a9 ]! K6 {
  31. }LTDC_PixelFormat;; V" C: F; N+ O$ g2 x
  32. #define LTDC_PIXEL_FORMAT                LTDC_ARGB8888                //选择ARGB8888格式
    1 n* @! ^3 ^8 q) Y7 _

  33. 4 _  s& v: H0 {+ I/ A6 q. i! K: j

  34. ( I! S, t5 f7 c* o

  35. ; r; [( Y$ ]$ @3 [  i
  36. 9 ?8 p+ U  E* H% K" p' L& z9 V
  37. //画点函数32bit ARGB8888格式
    ( K& K7 w+ t( j: v
  38. __inline void LTDC_DrawPoint(u8 LayerIndex, u16 Xpos,u16 Ypos,u32 ARGB8888_Color)# N: g4 k: Q1 s+ O; z, ?
  39. {
    8 Q: e% S) c! s2 W
  40.         g_LTDC_BUFF_RGB888[LayerIndex][Ypos][Xpos] = ARGB8888_Color;7 C) Q; d  D2 y. K$ F  B
  41. }' q7 b% f) ^% N5 j) H+ O) }6 y/ B2 Q

  42. 9 J7 r* Z3 D3 e3 ^5 u) s
  43. //初始化DISP引脚2 O$ J- J2 p3 k  r8 ^
  44. __inline void LCD_DispIoInit(void)& m; v3 d- o7 d. [* B2 s
  45. {8 F- _( c" a- _5 c6 B2 J
  46.         SYS_GPIOx_Init(GPIOI, BIT12, OUT_PP, SPEED_25M);                                                                                                //PI12 LCD_DISP H:正常模式;L:低功耗                                                        
    ( l2 Z$ P) D- K0 O' L4 z
  47.         PIout(12) = 1;                                                                                                                                                                        //DISP = H  2019-10-16:一直忽略将此引脚置为高电平,调试走了很多弯路
    , J. Z5 ]& H8 n! G2 ^- y
  48. }7 n& k/ M" t" C3 Q+ B- N

  49. 3 t% ]& L2 x9 Q) x  f. ]% c" v
  50. void LTDC_Enable(bool Enable);                                                                                                                                                //LTDC使能设置
    & J7 G/ @% ~, V, N8 d8 Z' Q2 E
  51. void LTDC_Init(void);                                                                                                                                                                //LTDC 接口初始化
    " L( |0 w7 C* X) f. m! E
  52. void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha);//LTDC 层窗口尺寸设置
    & c9 ~" }! m( Y* S9 `
  53. void LTDC_LayerEnable(u8 LayerIndex, bool Enable);                                                                                                        //LTDC 层使能设置
    3 C" Z! w% V0 h, ]
  54. void LTDC_LayerRefreshConfig(void);                                                                                                                                        //LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)" J1 Z8 Z( k% b$ i' Q7 E$ |7 R
  55. 5 E. S( ~# ]# E* L7 `, |, Q9 x9 Y
  56. //图形相关API
    ! M3 T/ E2 n: R* U6 p
  57. void LTDC_DrawPoint(u8 LayerIndex, u16 Xpos,u16 Ypos,u32 ARGB8888_Color);                                                        //画点函数32bit ARGB8888格式4 a8 \! v. F( d" ?
  58. void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color);                                                                //矩形填充(使用DMA2D)9 {$ s" U. h+ }+ ^" F
  59. void LTDC_Clear(u8 LayerIndex,u32 color);                                                                                                                        //清屏(使用DMA2D)5 [: \# k! R# H4 `. Q& b

  60. # w6 D8 j4 Z! K, }0 Z5 ]
  61. void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr);//矩形图像填充(相同坐标范围传输,要求源图像与目标显示器分辨率一致,使用DMA2D)
复制代码
5 M6 T7 U; _9 W: w
+ V# l2 ]+ r8 J3 }/ R0 U7 ?3 _
#endif //__STM32F7_LTDC_H_! g% _9 G0 P0 p1 P6 N8 Y
# p4 D8 h2 _* @

6 P' |- ^, O. o* v2 g' J- R( C8 E9 r1 }& ^3 O( t
收藏 评论0 发布时间:2021-12-14 10:49

举报

0个回答

所属标签

相似技术帖

官网相关资源

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