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

【经验分享】STM32f746gdiscovery LTDC 驱动

[复制链接]
STMCU小助手 发布时间:2021-12-14 10:49
需要提前准备好SDRAM驱动,如果没有SDRAM可以进行纯色彩测试,底层时钟,IO操作相关看注释,我使用的是寄存器封装的。
4 u. L4 f, J7 e3 Y+ c. Z/ ~( z: B6 Y  V
  1. /*************************************************************************************************************0 N$ b8 v; H& A5 h0 C4 K6 |
  2. * 文件名                :        stm32f7_ltdc.c, q  a7 d. L6 b9 ?- A
  3. * 功能                        :        STM32F7 外部RGB LCD驱动
    , T  F# x# h. K% Q; b7 c
  4. * 创建时间                :        2019-09-12' I& O- M; k0 \$ o- O
  5. * 最后修改时间        :        2019-09-126 I! j7 Z2 w1 n0 [) H* G
  6. * 详细:        $ o! k. h3 B/ m4 P9 ]9 D
  7. *************************************************************************************************************/        
    " ^+ H' F& H1 W! X' j, a+ J1 F, _
  8. #include "stm32f7_ltdc.h"1 @& D, P8 p; U! [
  9. #include "SYSTEM.H"
    " M; O: ~3 C& S; q  M
  10. #include "stm32f7_sdram.h"$ A, \) B2 S' h6 B+ A
  11. #include "DMA2D.h"
    0 }" Y  s% z" Y+ Z; K

  12. + S: q' Z! a1 C6 h9 V
  13. " n6 p! A! Z$ h& s7 W# @3 |  r2 E1 N. t
  14. u32 g_LTDC_BUFF_RGB888[2][LTDC_HEIGHT][LTDC_WIDTH]  __attribute__ ((at(Bank5_SDRAM_ADDR)));                //需要SDRAM支持,LCD帧缓冲区,RGB888格式
    4 w* P+ L/ @/ I9 H

  15. 3 I1 t8 z  P' G4 g9 y. f
  16.   l& C* I) D+ {; v
  17. //记录全局层配置信息2 P# a4 o6 P9 u* U
  18. typedef struct
      M' A$ j9 J8 K# X" C# q" f
  19. {4 ^; N: b8 m0 ?' U5 I- M
  20.         u16 sx;                                        //层开始X坐标,从0开始( V1 z3 _7 g8 t* S: X
  21.         u16 sy;                                        //层开始Y坐标,从0开始6 G3 ~. T  C( y
  22.         u16 width;                                //层宽度8 o# b- B# S1 N, z/ _) _2 ~
  23.         u16 height;                                //层高度. X* S( H: [% m0 s" i& l
  24.         u32 *pFrameBuff;                //帧缓冲区指针,需要进行初始化
    ( \7 j6 g: A* ^( K# `. q
  25. }LTDC_LayerConfig;! [$ }6 Q% l4 b4 e: `# ^+ {  R3 q& P
  26. 7 J5 l: r8 A6 W; Q# U' e+ X

  27. 7 ^" v) ~! `: p- Y
  28. 1 e7 N: C" n; k/ c9 y; _! g
  29. //全局的LTDC配置信息' y+ z" @. ?( s' ?9 @. `
  30. typedef struct$ l: a/ t% ]" O
  31. {
    2 {( G+ m& B6 d+ m9 R7 Y/ F
  32.         u16 lcd_width;                                                //显示器宽度
    6 g2 G- b$ A  W/ d7 W2 G, v+ H
  33.         u16 lcd_height;                                                //显示器高度
    5 [: P, t5 J% Q
  34.         LTDC_LayerConfig LayerConfig[2];        //层信息3 Z/ M! ]% x( d( O! p# h& S
  35. }LTDC_ConfigData;
    " h4 Y1 I! L* A5 R% o5 F3 V8 y- K
  36. 8 C. v6 D5 a5 Y2 b1 r* D
  37. . \! m9 ~9 ]% p
  38. static LTDC_ConfigData sg_LTDC_ConfigData;        //记录全局的LCD配置
    # N& k3 `! M0 j% C
  39. : v$ e4 R' q- J  S6 e

  40. 0 b: R5 l  S: y, Z& r# j
  41. //显示屏信息
    - B! g  w" W; f* K" `" |& d( u# R
  42. typedef struct, h' T3 C% e1 F& k  R, |' z9 N
  43. {
    2 Z9 x! G" M0 Y
  44.         u16         Width;                //面板宽度,单位:像素& X) t8 H* O9 r1 s8 `
  45.         u16         Height;                //面板高度,单位:像素
    1 v  d; J1 q. {: U/ x1 S- s
  46.         u8          Thbp;                //水平后廊7 l! L3 Z( Y/ ~1 l: K
  47.         u8          Thfp;                //水平前廊
    # t, v+ q6 e9 [. [2 h
  48.         u8          Thw;                //水平同步宽度/ M$ j3 F* I! s( R, D/ q  o! E5 I9 E
  49.         u8          Tvbp;                //垂直后廊0 E7 \" u4 p9 b/ m7 `6 {; w
  50.         u8          Tvfp;                //垂直前廊% O& C# Y! g3 G& X
  51.         u8          Tvw;                //垂直同步宽度7 X6 [+ Q# U& Y" h" D- [2 J
  52.         u8          DCLK;                //时钟速度,MHz1 y; Q# K! A8 W( H4 Y
  53.         
    6 m! d. Q2 _, y: j4 j1 c  I- |
  54.         u8                HSPOL;                //水平同步极性,0:低电平有效;1:高电平有效( e2 a' k) E8 \2 A& d
  55.         u8                VSPOL;                //垂直同步极性,0:低电平有效;1:高电平有效) M( E; L- w: ]& q2 d3 }
  56.         u8                DEPOL;                //数据使能极性,0:低电平有效;1:高电平有效/ m9 W% H& Q7 \3 @
  57.         bool        PCPOL;                //像素时钟反向; [4 m. Q3 g4 ~) Z! V4 u
  58. }LTDC_INFO_TYPE;
    ! K' w7 L$ Y$ n8 j( w
  59. , m$ g( l& d7 B( u  ]1 R
  60. 0 K* d% O* H9 w7 o6 T" v
  61. LTDC_INFO_TYPE DefaultLCD_Info =
    2 l7 @' Q0 G' v/ p
  62. {
    & Q8 o6 q" s8 m' f
  63.         480,        //面板宽度,单位:像素
    ) J* R- R0 h. X1 [( h3 x# N$ f
  64.         272,        //面板高度,单位:像素
    " S$ F( x5 t& j
  65.         41,                //水平后廊
    $ n! Q" C6 {+ n
  66.         8,                //水平前廊9 D6 R2 ^/ A; a! A1 y8 d
  67.         2,                //水平同步宽度
    3 m. m% e& ]+ ]2 \; @
  68.         2,                //垂直后廊
    , `+ E0 p9 ]5 N" R: K/ O5 e2 [
  69.         4,                //垂直前廊0 _4 |3 h+ `6 r. j
  70.         10,                //垂直同步宽度
    , B& Q6 o; C& E9 E; S: _
  71.         9,                //时钟速度,MHz5 D6 u7 |$ D; m' B) t
  72.         0,                //水平同步极性,0:低电平有效;1:高电平有效
    ' ^- r1 P. y' K, I) M7 _- w. t
  73.         0,                //垂直同步极性,0:低电平有效;1:高电平有效" B1 W; t1 @0 \  R5 `3 ?
  74.         1,                //数据使能极性,0:低电平有效;1:高电平有效% f0 Q% l7 |/ Y
  75.         FALSE,        //像素时钟反向, X6 g) }) S1 l- P2 y2 K7 F( u
  76. };
    9 P% o0 @3 T% h
  77. 9 A4 \* ?- x0 M! w' P2 u
  78. bool LTDC_ClockInit(u16 ClockFreq);                                                        //STM32F4 LTDC时钟初始化
    7 ^9 a3 m. m' b1 v  g
  79. 2 o/ U( G* M- j+ x0 Y5 @, U

  80. 8 m: ?# n) q# q5 b5 @; \& ~
  81. /*************************************************************************************************************************5 d" W) E$ E0 L; Y" ?0 |0 G$ y
  82. * 函数        :                        void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha)5 O, Y4 l+ E/ m- Q8 a- a
  83. * 功能        :                        LTDC 层窗口尺寸设置(会自动根据窗口尺寸以及像素格式设置帧缓冲区大小)
    9 V2 k# n- N( m' {
  84. * 参数        :                        LayerIndex:层选择(0-1);sx,sy:起始坐标;width,height:宽度和高度% k) _+ C, O7 m9 ~% i
  85. * 返回        :                        无5 A/ k* ^% g' t0 j8 {1 ?$ E
  86. * 依赖        :                        底层宏定义
    " W4 h6 @) V0 U
  87. * 作者        :                        <a href="mailto:cp1300@139.com">cp1300@139.com</a>% ^' b/ ]( m! a+ F# p
  88. * 时间        :                        2019-10-28
    0 q7 H7 Y( @  h+ S& `/ j8 f
  89. * 最后修改时间 :         2019-10-28% k4 u# Z5 h0 h) }; q* U
  90. * 说明        :                         不会使能层,不会更新层,只设置配置,需要刷新层配置后更新
    - L+ Y3 n( F9 `+ V$ d+ v
  91. *************************************************************************************************************************/
    ! S9 }: [# i+ V7 i
  92. void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha)# y2 x* @+ s- D0 I2 H: V" N' c
  93. {
    $ d: ]* }' I; ~; |& B. V8 ^
  94.         u32 temp;
    8 c- I: Z9 |+ ^  c. X( ~( d
  95.         u8 pixformat=0; 4 ]/ u* w2 Y; M& c4 B# C( X; g
  96.         
    . Q5 N# }+ V; Z; f. F
  97.         if(LayerIndex==0)% S0 v- n  t$ {* z9 i: o# g
  98.         {
    , t, h& H: J% }7 _: g8 B
  99.                 //基本配置/ k( u9 m/ N" K
  100.                 LTDC_Layer1->CFBAR = FrameBuff;                                                                        //设置层颜色帧缓存起始地址  ]5 [9 ~% O3 _% S3 F
  101.                 LTDC_Layer1->PFCR = LTDC_PIXEL_FORMAT;                                                        //设置层颜色格式
    , Z# Z. ?3 {- n6 _
  102.                 LTDC_Layer1->CACR = Alpha;                                                                                //常数 Alpha,255分频;设置255,则不透明
    9 L) s# h5 n9 D% {6 Q4 u3 J
  103.                 LTDC_Layer1->DCCR = 0x00;                                                                                //设置默认颜色:透明的黑色: [: L5 s9 l3 H- O& Q4 }
  104.                 LTDC_Layer1->BFCR = ((u32)6<<8)|7;                                                                //设置层混合系数
    / P5 h! H5 A" k/ |+ f5 m) u2 N7 ]0 h
  105.                 //配置窗口0 T4 v! I1 z# l! p: z7 Z
  106.                 temp = (sx+width+((LTDC->BPCR&0X0FFF0000)>>16))<<16; ; V) t1 W9 x# x( M1 {5 `
  107.                 LTDC_Layer1->WHPCR = (sx+((LTDC->BPCR&0X0FFF0000)>>16)+1)|temp;//设置行起始和结束位置
    ( s+ K: Z& U3 r! v6 I
  108.                 temp = (sy+height+(LTDC->BPCR&0X7FF))<<16; 1 u; v1 F! x) |; c8 [- @
  109.                 LTDC_Layer1->WVPCR = (sy+(LTDC->BPCR&0X7FF)+1)|temp;                        //设置列起始和结束位置2 a6 s! s5 Z0 Y! ?
  110.                 pixformat = LTDC_Layer1->PFCR&0X07;                                                                //得到颜色格式
    . l4 n+ B: ^5 h. Z! ]9 j0 [3 h- z
  111.                 if(pixformat == 0)temp=4;                                                                                //ARGB8888,一个点4个字节( D, d* z, G" J3 |* U: h; C
  112.                 else if(pixformat == 1)temp=3;                                                                        //RGB888,一个点3个字节
    / m1 C. e$ `4 V8 R# N/ _
  113.                 else if(pixformat==5||pixformat==6)temp=1;                                                //L8/AL44,一个点1个字节
    3 T) l) _* l. M6 |, b) o
  114.                 else temp=2;                                                                                                        //其他格式,一个点2个字节
    3 Z* ]* Y, c8 T4 d
  115.                 LTDC_Layer1->CFBLR = (width*temp<<16)|(width*temp+3);                        //帧缓冲区长度设置(字节为单位). y1 v- U. w: b3 q5 i% v- Z7 G
  116.                 LTDC_Layer1->CFBLNR = height;                                                                        //帧缓冲区行数设置        / y, r* G1 D0 c
  117.                
    ( I- `2 m! L6 ~! l* d
  118.                 //记录层窗口大小位置信息
    5 c! O. N3 Q+ J* d
  119.                 sg_LTDC_ConfigData.LayerConfig[0].sx = sx;               
    5 I2 j3 n3 V1 w6 h7 P
  120.                 sg_LTDC_ConfigData.LayerConfig[0].sy = sy;        8 V2 P3 L( C5 s. Y6 |5 |. M8 z% P
  121.                 sg_LTDC_ConfigData.LayerConfig[0].width = width;        7 U2 E* Q( D5 R' W
  122.                 sg_LTDC_ConfigData.LayerConfig[0].height = height;        
    8 G8 m1 P. Q# c" g* F
  123.         }else
    5 k$ N; ~( W9 e6 m4 z
  124.         {" B* H& j4 C2 \& t
  125.                 //基本配置
    % L* O+ I5 ^( S6 g: Z
  126.                 LTDC_Layer2->CFBAR = FrameBuff;                                                                        //设置层颜色帧缓存起始地址( y+ s6 B+ j* e% h% Y( L. p& N
  127.                 LTDC_Layer2->PFCR = LTDC_PIXEL_FORMAT;                                                        //设置层颜色格式: H9 s) E2 u9 T6 a9 L! ^( c! M7 W/ @
  128.                 LTDC_Layer2->CACR = Alpha;                                                                                //常数 Alpha,255分频;设置255,则不透明: O, Z  V( W+ _) N" q' M) C
  129.                 LTDC_Layer2->DCCR = 0x00;                                                                                //设置默认颜色:透明的黑色4 E( u# V; L7 X8 i! J/ I5 b5 ^
  130.                 LTDC_Layer2->BFCR = ((u32)6<<8)|7;                                                                //设置层混合系数
    & y1 N+ `# q+ W9 |% b- r7 Z9 k# d
  131.                 //配置窗口
    $ M# f- I9 j2 J+ z5 h  h  s- Q$ d5 C6 o
  132.                 temp = (sx+width+((LTDC->BPCR&0X0FFF0000)>>16))<<16; 4 \5 B6 [' E& B
  133.                 LTDC_Layer2->WHPCR = (sx+((LTDC->BPCR&0X0FFF0000)>>16)+1)|temp;        //设置行起始和结束位置 - q8 v+ W' I) X+ Z6 x1 D" s
  134.                 temp = (sy+height+(LTDC->BPCR&0X7FF))<<16; & G4 [3 b1 K) a# G& u
  135.                 LTDC_Layer2->WVPCR = (sy+(LTDC->BPCR&0X7FF)+1)|temp;                        //设置列起始和结束位置
    ; Y# M  J# k% A
  136.                 pixformat = LTDC_Layer2->PFCR&0X07;                                                                //得到颜色格式5 ]" g+ v& k+ b; G, e/ B
  137.                 if(pixformat == 0)temp=4;                                                                                //ARGB8888,一个点4个字节
    : M; L" W9 A0 u" f
  138.                 else if(pixformat == 1)temp=3;                                                                        //RGB888,一个点3个字节
    ( b$ v4 [) K! G' r
  139.                 else if(pixformat == 5||pixformat==6)temp=1;                                        //L8/AL44,一个点1个字节, [! |! o  Q' v  k' _
  140.                 else temp = 2;                                                                                                        //其他格式,一个点2个字节, K& o: a% x( N& U0 Z; D7 P( V8 x" d6 u
  141.                 LTDC_Layer2->CFBLR = (width*temp<<16)|(width*temp+3);                        //帧缓冲区长度设置(字节为单位)' M3 F" b5 g+ h0 B4 g8 X4 b: W) u; E
  142.                 LTDC_Layer2->CFBLNR = height;                                                                        //帧缓冲区行数设置        ' N' B% R3 @9 u( L: ?" ?
  143.                 0 C& I+ _  f2 Y" N" T
  144.                 //记录层窗口大小位置信息
    * D; s/ V6 [4 \2 a2 N
  145.                 sg_LTDC_ConfigData.LayerConfig[1].sx = sx;               
    1 H: k- U! H9 _
  146.                 sg_LTDC_ConfigData.LayerConfig[1].sy = sy;        6 l2 c$ }: ]  j8 r) U7 E) s; a
  147.                 sg_LTDC_ConfigData.LayerConfig[1].width = width;        
    $ k' Y4 }' o, b7 o
  148.                 sg_LTDC_ConfigData.LayerConfig[1].height = height;                ' Q. {* d. A. m" W) I' T
  149.         }9 y. @; n# t/ y. b# }' V% p3 L
  150. }8 ?, R% |: M6 K8 M1 [
  151. 2 W, S( z- h: E/ s& s6 W
  152. . w' T: L7 O3 M8 _" y! s

  153. ) R; F- v% a+ r$ B; U0 G9 W
  154. /*************************************************************************************************************************( a+ [7 b  r" q' y# k
  155. * 函数        :                        void LTDC_Init(void)
    % W4 O4 t3 e) ^& Z* l
  156. * 功能        :                        LTDC 接口初始化
    ; [- b; \  X* M) l9 o/ W7 x
  157. * 参数        :                        无
    : c9 L% P* w9 {/ P  c5 t
  158. * 返回        :                        无# G0 m3 m: a. r/ o
  159. * 依赖        :                        底层宏定义0 i$ y, c& n* E% t8 `8 z9 @
  160. * 作者        :                        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    7 w# a+ @/ i9 h/ V6 c
  161. * 时间        :                        2019-09-08
    3 L7 A( D1 w  c; |  ~7 q
  162. * 最后修改时间 :         2019-09-08
    & ?; i+ x* f! p" i1 ]0 z
  163. * 说明        :                         用于初始化STM32F7 LTDC 接口
    # T$ r3 i+ l9 o# A
  164. *************************************************************************************************************************/  
    % x4 e$ E0 O; n9 m
  165. void LTDC_Init(void)
    / y) q% h% w0 z
  166. {
    " H5 M; N( O; B3 j% f4 C  C& o
  167.         u32 temp;
    # R' ^6 a# u" N
  168.         " \2 x6 j9 U# ~! R3 S2 p& V5 k7 u
  169.         SYS_DeviceClockEnable(DEV_LTDC, TRUE);        //LTDC时钟使能
    . V- b! i6 K5 K' @& u+ D6 z. g
  170.         SYS_DeviceReset(DEV_LTDC);                                //STM32F7外设复位# z; Y( _  B- s6 b" K5 H* i7 V  a
  171.         SYS_DeviceClockEnable(DEV_GPIOE, TRUE);        //使能GPIOE时钟8 c+ n; w: p( j* {' E( r# @
  172.         SYS_DeviceClockEnable(DEV_GPIOG, TRUE);        //使能GPIOG时钟
    / J" P$ t  E* U& K- y( q: u# A
  173.         SYS_DeviceClockEnable(DEV_GPIOJ, TRUE);        //使能GPIOJ时钟" I# u  H/ a& J- |. N) _/ f0 n
  174.         SYS_DeviceClockEnable(DEV_GPIOK, TRUE);        //使能GPIOK时钟
    7 l2 }4 _& a& U6 ^5 D
  175.         SYS_DeviceClockEnable(DEV_GPIOI, TRUE);        //使能GPIOI时钟
    9 g8 ?* H* [) s: y8 Q* t% c. Q3 v' H

  176. 7 K* m7 e% A9 I  S! }6 p, z" H: o- O0 r
  177.         
    6 O. m+ U% V/ @# i: E) \. F. D$ ]
  178.         //初始化IO1 P% ^$ p9 H) S) j+ F! x$ C
  179.         SYS_GPIOx_Init(GPIOE, BIT4, AF_PP_OPU, SPEED_100M);                                                                                //PE4
    4 A2 _2 y. {: U& x7 k  Y
  180.         SYS_GPIOx_Init(GPIOG, BIT12, AF_PP_OPU, SPEED_100M);                                                                        //PG12
    % k0 c. ?- C. @$ u( u
  181.         SYS_GPIOx_Init(GPIOJ, 0Xffff&(~BIT12), AF_PP_OPU, SPEED_100M);                                                        //PJ0~11/13/14/15
    ( b0 L- Z  m# p' f) B
  182.         SYS_GPIOx_Init(GPIOK, BIT0|BIT1|BIT2|BIT4|BIT5|BIT6|BIT7, AF_PP_OPU, SPEED_100M);                //PK0/1/2/4/5/6/7: e- b# @( \! a& a9 h& p, U
  183.         SYS_GPIOx_Init(GPIOI, BIT9|BIT10|BIT14|BIT15, AF_PP_OPU, SPEED_100M);                                        //PI9/10/14/15
    3 [$ P1 _" @9 z7 ?
  184.         * R+ A, @3 u( P. i0 o
  185.         SYS_GPIOx_SetAF(GPIOE, 4, AF14_LTDC);                //PE4,AF14        
    - K( K0 a9 {) q
  186.          SYS_GPIOx_SetAF(GPIOG, 12, AF14_LTDC);                //PG12,AF14        
    ) k% J8 t2 Q! ^
  187.         SYS_GPIOx_SetAF(GPIOJ, 0, AF14_LTDC);                //PJ0,AF14
    ; M  a5 [1 \8 {6 [" ?
  188.         SYS_GPIOx_SetAF(GPIOJ, 1, AF14_LTDC);                //PJ1,AF14; ]0 c$ ]3 W7 f0 [- I
  189.         SYS_GPIOx_SetAF(GPIOJ, 2, AF14_LTDC);                //PJ2,AF14
    : _- P; V9 L& e5 l3 z+ E" j
  190.         SYS_GPIOx_SetAF(GPIOJ, 3, AF14_LTDC);                //PJ3,AF14
    . b1 X- }4 z) ]% o4 {
  191.         SYS_GPIOx_SetAF(GPIOJ, 4, AF14_LTDC);                //PJ4,AF14
    0 s# Z4 j. ~" j( |0 l! ?' R
  192.         SYS_GPIOx_SetAF(GPIOJ, 5, AF14_LTDC);                //PJ5,AF14
      }/ v4 p& J3 q  D1 [* L4 v: w% g
  193.         SYS_GPIOx_SetAF(GPIOJ, 6, AF14_LTDC);                //PJ6,AF14) f0 O4 F7 l6 Y0 ^, D: w
  194.         SYS_GPIOx_SetAF(GPIOJ, 7, AF14_LTDC);                //PJ7,AF14  H1 s% R7 F0 v9 p
  195.         SYS_GPIOx_SetAF(GPIOJ, 8, AF14_LTDC);                //PJ8,AF14  E; E, r8 J+ L8 `5 G
  196.         SYS_GPIOx_SetAF(GPIOJ, 9, AF14_LTDC);                //PJ9,AF14
    6 [: m+ O# o. R7 J+ O
  197.         SYS_GPIOx_SetAF(GPIOJ, 10, AF14_LTDC);                //PJ10,AF14
    % l2 I) u1 u. U* u9 A. j. b
  198.         SYS_GPIOx_SetAF(GPIOJ, 11, AF14_LTDC);                //PJ11,AF14: u7 g% e* L4 ?6 F
  199.         SYS_GPIOx_SetAF(GPIOJ, 13, AF14_LTDC);                //PJ13,AF14  X9 {' X6 V8 G9 Y8 L; i
  200.         SYS_GPIOx_SetAF(GPIOJ, 14, AF14_LTDC);                //PJ14,AF14! p$ }3 m4 @' m
  201.         SYS_GPIOx_SetAF(GPIOJ, 15, AF14_LTDC);                //PJ15,AF14
    3 v2 d  `1 k8 r! ?. y& S
  202.         
    * R7 u2 O/ U% s* W/ l, |& D
  203.         SYS_GPIOx_SetAF(GPIOK, 0, AF14_LTDC);                //PK0,AF14
    ' k' y& L4 }1 _2 N
  204.         SYS_GPIOx_SetAF(GPIOK, 1, AF14_LTDC);                //PK1,AF14
    % V. W* L" u4 o& E$ M) q
  205.         SYS_GPIOx_SetAF(GPIOK, 2, AF14_LTDC);                //PK2,AF14
    : _: a8 m, C, u1 f
  206.         SYS_GPIOx_SetAF(GPIOK, 4, AF14_LTDC);                //PK4,AF14
    + Y. b6 Z1 Q; s( P
  207.         SYS_GPIOx_SetAF(GPIOK, 5, AF14_LTDC);                //PK5,AF14% `5 f9 N' D3 H8 q8 E
  208.         SYS_GPIOx_SetAF(GPIOK, 6, AF14_LTDC);                //PK6,AF142 F( m$ A; S& l; i  p* }8 ~0 J) P0 b
  209.         SYS_GPIOx_SetAF(GPIOK, 7, AF14_LTDC);                //PK7,AF14
    # ^, g- q$ {1 Z8 {2 K
  210.         
    8 Y* F, i% l0 x! `4 @$ O; _
  211.          SYS_GPIOx_SetAF(GPIOI, 9, AF14_LTDC);                //PI9,AF148 B, `- O* a$ i
  212.          SYS_GPIOx_SetAF(GPIOI, 10, AF14_LTDC);                //PI10,AF14
    1 a  B6 ]: u7 R3 W" k; q1 ~
  213.         SYS_GPIOx_SetAF(GPIOI, 14, AF14_LTDC);                //PI14,AF141 K4 y4 J4 a8 K0 u- r/ |3 l1 h
  214.          SYS_GPIOx_SetAF(GPIOI, 15, AF14_LTDC);                //PI15,AF14
    ! F0 e/ b# ~; L* D
  215.         7 F5 @8 G7 o9 _$ E* D" M0 T6 t
  216.         LTDC_ClockInit(DefaultLCD_Info.DCLK);                 //设置像素时钟  9Mhz # a$ j# I  Y5 |$ }
  217.         //设置LTDC 全局控制寄存器 (LTDC_GCR)2 }' v' h3 i, }! b3 x# A. Q
  218.         temp = 0;
    ! L5 B' L' A# T2 p
  219.         temp |= (DefaultLCD_Info.HSPOL&0x01) << 31;        //水平同步极性
      U% }- d: l) ~0 g! _& M+ ?+ G$ P
  220.         temp |= (DefaultLCD_Info.VSPOL&0x01) << 30;        //垂直同步极性
    $ Y$ G7 Q7 V  ~7 [) t0 i, S
  221.         temp |= (DefaultLCD_Info.DEPOL&0x01) << 29;        //数据使能极性
    7 ]5 y: f: i( _- ^6 D6 w! m
  222.         temp |= (DefaultLCD_Info.PCPOL&0x01) << 28;        //像素时钟极性
    2 ~/ L& S0 A7 D0 w8 Q
  223.         LTDC->GCR = temp;
    % A2 V# y, }) \9 \) w" J3 |7 u
  224.         //LTDC 后沿配置寄存器 (LTDC_BPCR)9 d* b: T% W' i+ B+ c
  225.         temp = (DefaultLCD_Info.Tvw + DefaultLCD_Info.Tvbp - 1) << 0;        //这些位定义累加水平后沿宽度(水平同步像素加水平后沿像素减 1)。3 C' R% K% y9 `" u- `4 J
  226.         temp |= (DefaultLCD_Info.Thw + DefaultLCD_Info.Thbp - 1) << 16;        //这些位定义累加垂直后沿宽度(垂直同步行加垂直后沿行减 1)。4 G+ Q8 Z0 w, d
  227.         LTDC->BPCR=temp;        
    & S! K; U1 v# ^- T
  228.         : Z' X: T  `/ A" V8 R7 q
  229.         //LTDC 有效宽度配置寄存器 (LTDC_AWCR)
    5 a' X3 F& K/ G
  230.         temp=(DefaultLCD_Info.Tvw+DefaultLCD_Info.Tvbp+DefaultLCD_Info.Height-1)<<0;        //累加有效高度=垂直脉宽+垂直后沿+垂直分辨率-1; O" D) D: r* I6 Q: i2 M& K" k
  231.         temp|=(DefaultLCD_Info.Thw+DefaultLCD_Info.Thbp+DefaultLCD_Info.Width-1)<<16;        //累加有效宽度=水平脉宽+水平后沿+水平分辨率-1/ A# V0 @9 G. t( c' v; c
  232.         LTDC->AWCR=temp;        
    1 N1 \- E- v/ x2 F
  233.         //LTDC 总宽度配置寄存器 (LTDC_TWCR)
    ! |- d1 p* d! ?- p9 o* y
  234.          temp=(DefaultLCD_Info.Tvw+DefaultLCD_Info.Tvbp+DefaultLCD_Info.Height+DefaultLCD_Info.Tvfp-1)<<0;        //总高度=垂直脉宽+垂直后沿+垂直分辨率+垂直前廊-1
    ' S+ {- ~5 C9 x# c) W* D8 a1 V; m1 V
  235.         temp|=(DefaultLCD_Info.Thw+DefaultLCD_Info.Thbp+DefaultLCD_Info.Width+DefaultLCD_Info.Thfp-1)<<16;        //总宽度=水平脉宽+水平后沿+水平分辨率+水平前廊-1
    ( a) r: N* x9 e! Q
  236.         LTDC->TWCR=temp;                                + n, G0 ?/ c+ R5 W: ~: \( H
  237. : E" S5 P6 G9 p5 ^
  238.         //背景设置
    . ^* T$ W7 |3 Q, ]5 T  K# G0 }! r
  239.         LTDC->BCCR=0xffffff;                                //设置背景层颜色寄存器(RGB888格式), W6 E# {- ^* k9 r" g
  240.         LTDC_Enable(TRUE);                                        //开启LTDC
    ; n5 @* z8 R' S( w% O; g
  241.         //初始化层1
    6 q) Q8 _  _# k
  242.         LTDC_SetLayerConfig(0, 0, 0, LTDC_WIDTH, LTDC_HEIGHT, (u32)g_LTDC_BUFF_RGB888[0], 255);. @9 W4 B* d7 C8 R; u' _- q
  243.         //初始化层2
    % Y5 N! `# r; g2 t  g$ a2 g0 U! x* L
  244.         LTDC_SetLayerConfig(1, 0, 0, LTDC_WIDTH, LTDC_HEIGHT, (u32)g_LTDC_BUFF_RGB888[1], 255);
    " {! F% p0 R; T3 r
  245.         LTDC_Clear(0, 0xFF000000);                        //清屏层1-不透明的黑色
      V. X2 C0 S0 n' c# A/ V8 c
  246.         LTDC_Clear(1, 0x00000000);                        //清屏层2-透明的黑色/ n1 m3 ]+ J0 ?( E3 l& @
  247.         LTDC_LayerEnable(0, TRUE);                        //使能层1
    3 Y1 L7 W' H; N+ d$ }
  248.         LTDC_LayerRefreshConfig();                        //LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)
    , {, O6 n9 |5 a- P$ @; P6 |+ c$ ]
  249.         LCD_DispIoInit();                                        //初始化DISP引脚-启动显示
    . |5 {3 R: y" e4 b8 \% t+ x7 \. u* f
  250. }
    / }: {0 R% h$ z% n2 ?1 Y
  251. + i: ^# n  z" q! j+ j6 k+ K4 O
  252. /*************************************************************************************************************************/ g2 g& |8 X" m. n
  253. * 函数                        :        void LTDC_LayerRefreshConfig(void)3 l! C+ |8 [+ ]  `3 \6 j8 L; j
  254. * 功能                        :        LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)' A. m5 D8 k0 T: I' w3 }1 H8 x
  255. * 参数                        :        无1 ~% C; L" A9 y) n* R. D  Q$ s
  256. * 返回                        :        无$ w5 S" n+ b  A+ i: n1 Z
  257. * 依赖                        :        底层宏定义% u5 q' F; V$ X' c" x
  258. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    ! l! Q  V0 r* x2 i  s
  259. * 时间                        :        2019-10-29
    - J4 i  R) k& ?8 e. @7 A9 |
  260. * 最后修改时间         :         2019-10-29
    ( `( e  U% c) X- S7 d' L" m7 ^$ T
  261. * 说明                        :        修改层配置后必须重新加载,否则不会生效
    9 l/ Z+ V7 U0 |7 {# C6 H
  262. *************************************************************************************************************************/
    8 j# U8 ?3 c: @" C% d
  263. void LTDC_LayerRefreshConfig(void)' C7 |2 }; ~! j' X( h/ a# a  z
  264. {0 V$ `( U2 [& f% I6 n
  265.         LTDC->SRCR|=1<<0;                                                        //重新加载配置-必须重新加载,否则上面的层不会更新,折腾好久才发现,叫啥影子寄存器重载,也不说清楚
    8 h4 d+ Q0 J- U5 h+ F
  266. }- I& o% @9 P) Q! e$ c' }

  267. ; H. C2 t, H  P4 @/ `8 h' M1 h& R9 K
  268. /*************************************************************************************************************************
    1 Q- `% I/ h! y
  269. * 函数                        :        void LTDC_Enable(bool Enable)
    : t* e! q0 Q- A$ }* E( Z8 C4 g" L$ v
  270. * 功能                        :        LTDC使能设置
    5 k  E& F5 ]/ r$ `8 J* p9 z
  271. * 参数                        :        Enable:TRUE:使能;FALSE:失能
    & d! j& f+ u( r+ w) ]6 e$ a
  272. * 返回                        :        无
      v9 S: `7 R' e* T
  273. * 依赖                        :        底层宏定义
    ( p7 g8 \2 d0 ^' Z% O$ @9 u! }
  274. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>3 Y3 C. |; ^" ^. a3 _/ `5 X
  275. * 时间                        :        2019-10-29( Y' n9 g/ e5 P
  276. * 最后修改时间         :         2019-10-293 [3 r- H8 z* R$ j, k
  277. * 说明                        :        * p; W0 a5 p! Z8 s8 O
  278. *************************************************************************************************************************/
    - E! n* D9 m+ {/ W
  279. void LTDC_Enable(bool Enable)
    . r. ]5 g/ I2 m6 T/ p; Q
  280. {, B1 E5 ^+ T) R' \5 `: d
  281.         if(Enable)4 H! \3 p5 G+ ^: f
  282.         {- t/ y0 C4 Q- a
  283.                 LTDC->GCR |= BIT0;                                        //打开LTDC
    ) P4 e3 _6 o* X3 f) `, ^( Q
  284.         }
    " B. j) o" _* U$ {& d' O
  285.         else
    # n$ S, m  S9 O2 }5 p
  286.         {3 @% ?$ ^  n: z/ u( A
  287.                 LTDC->GCR &= ~BIT0;                                        //关闭LTDC; d6 c0 f$ C" X% ~2 c  f
  288.         }
    0 J1 k: ^. G; W! G
  289. }
    * Z$ z3 @+ u3 z& r

  290. 8 B5 E" @$ E: P
  291. /*************************************************************************************************************************/ V$ D; P) h/ D
  292. * 函数                        :        void LTDC_LayerEnable(u8 LayerIndex, bool Enable). B( o2 l& P# n' G
  293. * 功能                        :        LTDC 层使能设置
    + e0 x. c/ z9 P- @  x
  294. * 参数                        :        LayerIndex:层选择0-1;Enable:TRUE:使能;FALSE:失能
    4 ]$ W8 i( ~# h8 r
  295. * 返回                        :        无
    " Q, y$ u: m: Q4 Z1 |7 W8 y# a
  296. * 依赖                        :        底层宏定义) q" C$ M4 d) `' N% [% m
  297. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>9 t5 ]8 p4 B2 B* a6 m1 J( b! l
  298. * 时间                        :        2019-10-297 F& _$ F1 N% ]: B
  299. * 最后修改时间         :         2019-10-29
    ( G0 l- d) Y4 f% Y$ A
  300. * 说明                        :        - B; @: p9 n# A3 v* p
  301. *************************************************************************************************************************/: D& G$ X' d* y% A; `
  302. void LTDC_LayerEnable(u8 LayerIndex, bool Enable): ~$ ~7 v* H! t' H8 h5 `- V% V% E$ l
  303. {6 j7 A' a3 l7 P2 z( w# C' f1 o
  304.         if(Enable)
    ) ]% N' B4 K. F+ [' f' z. x
  305.         {
    ( U+ [: D' [1 V$ C# Q2 V
  306.                 if(LayerIndex == 0)                                        //层1
    ( U6 v9 \0 ]/ o! f; a
  307.                 {
    % q$ S8 ?& U1 }. V, l
  308.                         LTDC_Layer1->CR |= BIT0;                //使能层1
    ; @) I% H3 d, n9 j' `
  309.                 }
    ; g0 H  Y" J% S" W8 }& Y% v" u
  310.                 else
    ) {! `, U- \( y/ T* C
  311.                 {
    2 s) I- S9 e3 g7 l8 E% {* z& e
  312.                         LTDC_Layer2->CR |= BIT0;                //使能层2
    ! {/ b4 W2 \! i2 D6 \; x. L
  313.                 }: k, Q6 g; i% ]
  314.         }! Z, \/ L3 g/ D3 o* y3 [4 O
  315.         else
    - r# w* }9 U) o
  316.         {% v! @% T. E9 k& A/ f. D9 d
  317.                 if(LayerIndex == 0)                                        //层1
    - ^; i3 R; P' b2 q
  318.                 {4 r+ ~; p; }! {
  319.                         LTDC_Layer1->CR &= ~BIT0;                //失能层1
    " ?+ S* S& u. j, ?: Q+ O" g
  320.                 }8 _$ Z! B8 `  H" ?- N4 Z- z4 N
  321.                 else
    0 a1 Q, q5 Y6 x# G( j2 p
  322.                 {: G# U$ U8 C4 U: F1 v4 @5 h* J! _
  323.                         LTDC_Layer2->CR &= ~BIT0;                //失能层2
    6 U* X3 R) E) e; F3 V" ?( x" j
  324.                 }
    % z" M" G4 P4 @6 R: T. q
  325.         }
    0 v, t7 O* m* w( ?7 T* c
  326. }
    9 S! w8 W' N# L8 y" G
  327. * q7 x0 \+ G2 D8 p2 K  _7 U
  328. ) W/ V% ?, }' ?) e

  329. : V; D9 k1 a+ X+ n& q# H4 U

  330.   h1 J. k6 y: K7 A6 c9 t. \
  331. /*************************************************************************************************************************
    ; b4 E0 z7 i+ w" r% |8 W! V, ?
  332. * 函数                        :        bool LTDC_ClockInit(u16 ClockFreq)                        * [: y  v0 }- J1 I) C0 r
  333. * 功能                        :        STM32F7 LTDC时钟初始化: k; ]* N3 _6 z& k) H" |4 R* d
  334. * 参数                        :        ClockFreq:时钟频率,2-168MHZ. H/ G/ E# C7 Z1 B+ ~  C
  335. * 返回                        :        是否设置成功# B  ]3 Y4 C4 U  {3 W2 p
  336. * 依赖                        :        底层宏定义3 _2 }! g$ X& z1 P. r
  337. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    , O  ]& c' O6 j+ _
  338. * 时间                        :        2019-10-28, {, z6 V: q% k  }* K  ?
  339. * 最后修改时间         :         2019-10-28, P3 \7 b8 G! U* p. ?$ x
  340. * 说明                        :        输入时钟频率在系统主时钟初始化之后就会设置为1MHz,通过设置SAI PLL实现LTDC所需频率,VCO频率范围:49~4326 Y2 z! N/ O+ E4 K+ f  r7 A
  341. *************************************************************************************************************************/
    ( c( w. |# M* \+ O, G( K
  342. bool LTDC_ClockInit(u16 ClockFreq), n/ Q! E, F6 c2 w+ [
  343. {5 A9 w6 d1 ~% {3 v. x
  344.         u32 TimeOut = 0;; y# r& v, P( C+ F4 n
  345.         u32 VCO;: E; c# m6 d6 o) F# ?1 S# F" x
  346.         u32 PLLSAIR;                //PLLSAICFGR[30:28]/ O2 e  c& D0 Q- M/ R+ G$ M
  347.         u32 PLLSAIDIVR;                //DCKCFGR1[17:16]5 _5 l7 r- j3 I3 {/ d; g& a
  348.         u32 temp;
    * j, {- P% I  G
  349.         - N/ Y( D' L3 G: r7 T6 r4 f/ R
  350.         if(ClockFreq < 1)ClockFreq = 1;$ c' {" }. A# x9 t+ }0 {+ ]) Q
  351.         if(ClockFreq > 100) ClockFreq = 100;, H! r- V: W( V! J; f% O
  352.         ( V2 x+ o# r+ t8 Q
  353.         RCC->CR &= ~(1<<28);                                                //关闭SAI时钟 ! J" F2 k1 o2 D* `' [
  354.         TimeOut = 0;2 o; e  h+ S& _+ F, c" n/ T
  355.         while(RCC->CR&(1<<29))                                                //等待关闭成功
    2 S5 L2 H! J% O8 z$ u5 T
  356.         {. C& i  r# b" n+ {; n
  357.                 nop;
    9 F1 \2 {9 R5 M0 r( F. R5 n( Z
  358.                 TimeOut ++;
    & _' O$ p% N7 M
  359.                 if(TimeOut > 0xFFFF) return FALSE;                //关闭超时6 j: @$ I5 [0 }0 N
  360.         }' P( G& |- J7 [
  361.         //计算分频与VCO频率,通过PLLSAICFGR[30:28]可以设置2-7分频/ L( |1 x, H: B8 ^
  362.         //通过PLLSAICFGR[17:16]可以设置00:2 01:4 10:8 11:16分频4 X+ C  Y# X7 l' Y# q. X" Q
  363.         //通过PLLSAICFGR[14:6]可以设置为49-432MHz的VCO频率
    . K! q8 I# J: ^6 a+ l
  364.         if(ClockFreq <= 6)' p8 Y: V- I9 ~( p9 n* w1 I
  365.         {
    : r" M: L# S$ I& W/ O- F( E8 u: M1 B
  366.                 PLLSAIR = 4;        //4分频
    9 h& d9 |& G. r7 W6 e+ @( Z: y
  367.                 PLLSAIDIVR = 3;        //16分频3 p1 U& D+ a, W* \: ]
  368.                 VCO = ClockFreq * PLLSAIR * 16;                        //VCO范围:64-384;6 L5 ?- c! l( e) }7 Y1 ?, N
  369.         }$ Q& W1 J. r, m# r, i6 ?
  370.         else if(ClockFreq <= 13)
    ! O8 }' o) Z# H+ G6 _% R) y
  371.         {) }  J$ i' b5 ?5 F) h
  372.                 PLLSAIR = 4;        //4分频! `6 @( V% G; D- p
  373.                 PLLSAIDIVR = 2;        //8分频. |* t) ]6 y7 L$ _
  374.                 VCO = ClockFreq * PLLSAIR * 8;                        //VCO范围:224-416;* M2 @0 S; B5 B+ {; [5 o
  375.         }$ Z$ b% p7 J  X. k, F& p, Q  Z
  376.         else if(ClockFreq <= 26)) H  {5 H# ]* V- Y% y* q5 W, O
  377.         {5 ]* E: U4 x& F' o" m
  378.                 PLLSAIR = 2;        //2分频- E1 E, a1 m. c2 t+ q3 r, }+ P
  379.                 PLLSAIDIVR = 2;        //8分频
    6 t* m- N0 \+ Y8 v* A$ _, ^4 A
  380.                 VCO = ClockFreq * PLLSAIR * 8;                        //VCO范围:224-416;
    ' ~5 k$ N1 R1 f6 D
  381.         }
    - ]" y1 G1 g; t! ]' d4 v$ a
  382.         else if(ClockFreq <= 52)+ y" i( a! U' [& z) o' B
  383.         {
    ' a# `$ Z1 b- r1 X# a( g5 k9 ~
  384.                 PLLSAIR = 2;        //2分频" y% ?5 h6 \& }" M8 _5 b  _" u
  385.                 PLLSAIDIVR = 1;        //4分频! a6 w2 E) u& y* B( u$ O7 V
  386.                 VCO = ClockFreq * PLLSAIR * 4;                        //VCO范围:216-416;& ]! C* O8 Y# W) I* N# e0 B
  387.         }3 a, c2 R6 h" c! `, ]
  388.         else if(ClockFreq <= 104)* f! ?. ^7 R. T# X
  389.         {8 ]& {/ Q! ]. M3 |1 u  {, V& N
  390.                 PLLSAIR = 2;        //2分频0 U0 U. c( T3 e' \
  391.                 PLLSAIDIVR = 0;        //2分频2 K) l4 u9 d) I; R5 V
  392.                 VCO = ClockFreq * PLLSAIR * 2;                        //VCO范围:212-416;) _0 }9 O5 J  m# H' X
  393.         }) _& T( r# m' R; e0 E
  394.         //设置PLLSAICFGR3 D* X! s* J' @- k/ i1 h$ O; i
  395.         temp = RCC->PLLSAICFGR;) q- ^# d" L8 |2 [5 @5 x
  396.         temp &= ~((3<<28) | (0x1FF<<6));                        //清除之前的设置
    6 g+ J: u0 _/ Q/ z# Z2 L2 D9 T
  397.         temp |= PLLSAIR << 28;                                                //设置分频PLLSAICFGR[30:28]
    + L' h! t! T: N7 v+ w
  398.         temp |= VCO << 6;                                                        //设置VCO( d4 D5 H8 w" b+ q5 Z  A% @
  399.         RCC->PLLSAICFGR = temp;
    % f" `- z; H2 Y* }
  400.         //设置DCKCFGR1* [! |0 n4 i/ N) e4 u3 K" F
  401.         temp = RCC->DCKCFGR1;
    4 T4 P* L( q5 H' t
  402.         temp &= ~(3<<16);                                                        //清除之前的设置( ?* i; E/ g. H, a: o
  403.         temp |= PLLSAIDIVR << 16;                                        //设置分频DCKCFGR1[17:16]
    2 e+ @; I& H; B' W
  404.         RCC->DCKCFGR1 = temp;# A3 H' ^: ]. w# m5 ]1 u. Z
  405.         //启动时钟# S$ r* ]! t- ^
  406.         RCC->CR |= 1<<28;                                                        //启动SAI时钟1 ~  K* i7 h% X
  407.         TimeOut = 0;
    4 B* B3 `( N* J% m
  408.         while((RCC->CR&(1<<29)) == 0)                                //等待开启成功( q2 y3 h* X. B; Q& K- Y
  409.         {
    2 Y7 x) _% v. x$ X  d' P9 E
  410.                 nop;$ V: ], @; ]& ^. v! ?/ B$ V
  411.                 TimeOut ++;+ ^4 q; j# t' V
  412.                 if(TimeOut > 0xFFFF) return FALSE;                //开启超时/ x1 M9 T( Z: h  I& S% b+ [
  413.         }% _1 R% k0 R9 G3 b3 e- B
  414.         
    8 q1 d% U# O: _" N# @: X
  415.         return TRUE;/ ?! w* M, ^2 B
  416. }
    & E: z' |6 |, @! F( @( _
  417. ! l5 t$ [0 r% @" u- V

  418. 4 N( A9 ^2 U6 h: Z
  419. /*************************************************************************************************************************% n0 e/ o0 ?- r* \0 D' j+ @
  420. * 函数                        :        void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color)        & ~$ J) w! V) V2 d
  421. * 功能                        :        矩形填充(使用DMA2D)
    ) g: O8 U; q; \) \& Z
  422. * 参数                        :        LayerIndex:层选择0-1;sx,sy:开始坐标;ex,ey:结束坐标,color:需要填充的颜色
    ! B/ U9 O# c2 ]" \
  423. * 返回                        :        无4 R1 Y( y, ^) \1 C$ q
  424. * 依赖                        :        底层宏定义
    9 J2 w( W% w$ G1 ?! B3 b
  425. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>; k  s5 T8 Z' f. a& a
  426. * 时间                        :        2019-10-30" [: ?" c% B! h: ~& G0 k5 P7 h9 [
  427. * 最后修改时间         :         2019-10-30
    2 ]2 {! F1 Q8 T* r& X5 s
  428. * 说明                        :        采用DMA2D实现
    $ ]' _4 n. i  l! m
  429. *************************************************************************************************************************/9 j( p, w2 ?, g% C
  430. void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color)7 Y1 A+ L  `) }4 t
  431. {
    ! W# z/ t  O' G- ]2 ?
  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进行单色填充. P1 m# f/ ]: x9 A6 C& R) ^
  433.         DMA2D_WaitTransferComplete(500);                                                                                                                                                                                                                                //等待DMA2D传输完成
    , a# U% T5 _5 O3 }( N
  434. }2 H+ b' o" c( B' v4 g* p' b2 P

  435. - R! l2 Y9 [$ @1 _* I
  436. ' C8 K& \7 A2 u8 P* B4 p1 x
  437. /*************************************************************************************************************************
    8 e9 o1 ^8 }+ I9 M) u" J' _* C: `
  438. * 函数                        :        void LTDC_Clear(u8 LayerIndex,u32 color)
    ' i" j4 r9 b% q6 n' K% ]
  439. * 功能                        :        清屏(使用DMA2D)
    $ Z; G# D: ~% i" b
  440. * 参数                        :        LayerIndex:层选择0-1;color:需要填充的颜色
    1 x0 W* y1 D% G6 P4 T  p/ v( K
  441. * 返回                        :        无% @4 x6 ]8 t8 i- E- ~& l( h
  442. * 依赖                        :        底层宏定义
    # D: r3 R# x7 B7 s0 M
  443. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    8 }# H- t) o' O: t' U8 y1 c4 s
  444. * 时间                        :        2019-10-30
    6 v: R5 z' Z& b. _; X
  445. * 最后修改时间         :         2019-10-30
    + {. r* w8 r3 V1 T* ~
  446. * 说明                        :        采用DMA2D实现/ C( S1 X" ^+ W* y2 ^- J& W2 f
  447. *************************************************************************************************************************/' ^* }0 N% x* {3 I/ {1 h
  448. void LTDC_Clear(u8 LayerIndex,u32 color)
    , r* [( a6 r" A
  449. {2 d  e+ y: ~, z6 R) D* d
  450.         DMA2D_FillColorToFGRAM((u32)&g_LTDC_BUFF_RGB888[LayerIndex][0][0], LTDC_WIDTH, LTDC_HEIGHT, 0,  DMA2D_COLOR_ARGB8888, color);                                        //DMA2D进行单色填充* o0 ]0 g! L. e" V7 F, c9 [& N- P
  451.         SYS_DelayMS(5);
    - m0 Y9 O/ x8 R0 \' T0 L$ N4 g
  452.         DMA2D_WaitTransferComplete(500);                                                                                                                                                                                                                                //等待DMA2D传输完成7 o) B+ k% R$ I. F& P" D
  453. }. d# E* v; T6 i$ B3 D& ]9 H
  454. # W: n7 q4 n3 \" q
  455. % S2 u6 f# P4 S
  456. /*************************************************************************************************************************
      R! X7 x5 y& V8 Z9 @, J
  457. * 函数                        :        void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr)
    4 a# N/ X9 R7 `( [$ x' l1 U; P
  458. * 功能                        :        矩形图像填充(相同坐标范围传输,要求源图像与目标显示器分辨率一致,使用DMA2D)5 x& q& w' W6 C
  459. * 参数                        :        LayerIndex:层选择0-1;sx,sy:开始坐标;ex,ey:结束坐标,ImageAddr:需要填充的图像地址$ o9 o7 `' P7 U3 [5 P: K* ~' Y
  460. * 返回                        :        无
    ( N2 k  `8 P! U' t5 ^
  461. * 依赖                        :        底层宏定义
    4 W4 ]& ~( I- i  t/ X
  462. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>" |1 }/ B8 R. E
  463. * 时间                        :        2019-10-304 f# \' q' J% i: N. }
  464. * 最后修改时间         :         2019-10-30
    7 g6 T; ?, y! }1 D( j  Q
  465. * 说明                        :        采用DMA2D实现,将源图像指定位置传输到现存,要求源图像与显存大小一致8 S- I4 x, B8 Z. D% e
  466. *************************************************************************************************************************/0 x$ ^% j) {4 s$ k7 ]
  467. void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr)
    : v: R; w8 t" F" Y' x
  468. {& w% p# w% \2 h- `7 \. C
  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进行矩形图形填充0 g8 f( m  j* j' w% N2 p6 y( m
  470.         DMA2D_WaitTransferComplete(500);
    4 L0 d! n$ }4 y" r' ~
  471. }
复制代码
  1. /*************************************************************************************************************
    0 F8 A/ N, p) Y$ }6 j
  2. * 文件名                :        stm32f7_ltdc.h
    0 T/ q( w' h, I2 P
  3. * 功能                        :        STM32F7 外部RGB LCD驱动& V. u% I" O& x* \) f, B# D
  4. * 作者                        :        <a href="mailto:cp1300@139.com">cp1300@139.com</a>
    8 B+ r* l' O. \0 m: Z$ H  U" v/ ]
  5. * 创建时间                :        2019-09-12: v; p- ?" [! Z5 k% P
  6. * 最后修改时间        :        2019-09-127 W2 N! `2 o4 M4 v4 u
  7. * 详细:        
    0 t0 [! u: j4 A
  8. *************************************************************************************************************/               
    $ @- l6 l' O/ _- R2 k% S, ^
  9. #ifndef __STM32F7_LTDC_H_
    & ^" B+ r, \7 x: {7 ~) B8 m1 x6 p
  10. #define        __STM32F7_LTDC_H_           5 j( K9 H3 G/ Y( |' G* T3 C) P
  11. #include "system.h"* V9 u; P+ J) R& b) f, W
  12. #include "DMA2D.h"
    1 S& @5 y9 @' W8 i+ ~/ Z  }+ [

  13. + x4 Q; ]& j- S
  14. #define LTDC_WIDTH                480
    3 ?" k6 w% E! j
  15. #define LTDC_HEIGHT                272
    % l4 N2 D2 E2 ?2 h+ |

  16. % V  L$ g6 \5 ^3 ]0 i
  17. ! E, o, P( T4 v: x% U" I  s
  18. extern u32 g_LTDC_BUFF_RGB888[2][LTDC_HEIGHT][LTDC_WIDTH];
    " O. V; X3 B/ O$ k) I5 F" ?
  19. - |3 F* M5 W3 p6 K' f" j
  20. //像素格式定义. L5 H* h: q, O
  21. typedef enum
    2 H7 X% i% R+ z0 X0 j/ ~$ [8 r( V
  22. {
      ]. e; A; f8 w  v
  23.         LTDC_ARGB8888         = 0,
      P0 i. z. p8 v& g& O
  24.         LTDC_RGB888         = 1,. E" i1 [0 o" D0 g6 [/ i
  25.         LTDC_RGB565         = 2,; m1 }6 a% A( I' W
  26.         /*LTDC_ARGB1555         = 3,8 T; {4 K5 {; M' R. a, x. }
  27.         LTDC_ARGB4444         = 4,
    9 ]- [( T6 A$ l) a  C! d6 ~
  28.         LTDC_L8                 = 5,        //8 位 Luminance6 X% V& i& p' i9 O6 @4 _3 U
  29.         LTDC_AL44                 = 6,        //4 位 Alpha,4 位 Luminance4 S$ P$ V5 Y0 q, C' _: s
  30.         LTDC_AL88                 = 7,        //8 位 Alpha,8 位 Luminance*/
    ; h* k1 q! ?: T( P# n' z
  31. }LTDC_PixelFormat;
    ! ~  p2 o4 w3 u: H; c$ |0 W
  32. #define LTDC_PIXEL_FORMAT                LTDC_ARGB8888                //选择ARGB8888格式7 m6 \' e; [% m8 j% _

  33. 2 V' }8 I* i8 g" u2 |& \2 U

  34. # ~0 Y! S* v) C. M; f. i; H
  35. " d* N6 ]+ p" O- i0 `

  36. 1 X# K0 d9 ?$ M+ [0 G; @
  37. //画点函数32bit ARGB8888格式
    0 f; i2 d  C; u
  38. __inline void LTDC_DrawPoint(u8 LayerIndex, u16 Xpos,u16 Ypos,u32 ARGB8888_Color)/ {6 u9 R! _! j8 u, S; X
  39. {0 Y# l$ q$ o" y" g: C
  40.         g_LTDC_BUFF_RGB888[LayerIndex][Ypos][Xpos] = ARGB8888_Color;& c- z$ D: l+ l) @) ^. c
  41. }
    " u# X& K' @9 X& e+ O/ i- X
  42. 1 N' J1 H9 E$ i( F6 [' [
  43. //初始化DISP引脚6 z5 ~, d2 K- q8 [8 l
  44. __inline void LCD_DispIoInit(void)
    7 Z0 }$ S. Q: h
  45. {/ m1 k2 }, [+ Z, x$ ~6 N' J0 K) K
  46.         SYS_GPIOx_Init(GPIOI, BIT12, OUT_PP, SPEED_25M);                                                                                                //PI12 LCD_DISP H:正常模式;L:低功耗                                                        # q- w) j4 V  y; ^* P
  47.         PIout(12) = 1;                                                                                                                                                                        //DISP = H  2019-10-16:一直忽略将此引脚置为高电平,调试走了很多弯路; r$ z( [- u1 e- D& D. b
  48. }! T; x4 r' @7 Z  a6 _

  49. * T  S7 ^0 F. S1 u
  50. void LTDC_Enable(bool Enable);                                                                                                                                                //LTDC使能设置9 h7 o7 r( U- u/ h0 n
  51. void LTDC_Init(void);                                                                                                                                                                //LTDC 接口初始化9 {$ m: j- [3 f$ J  r  |! H+ A
  52. void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha);//LTDC 层窗口尺寸设置2 D# M! X2 a* {. U
  53. void LTDC_LayerEnable(u8 LayerIndex, bool Enable);                                                                                                        //LTDC 层使能设置
    2 y8 |5 x3 {# m* O
  54. void LTDC_LayerRefreshConfig(void);                                                                                                                                        //LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效), u4 S0 f2 ]) ~0 p

  55. % M0 V, v  }  h  s+ k
  56. //图形相关API
    7 k: a8 ~: q" Y/ c& b3 u8 K
  57. void LTDC_DrawPoint(u8 LayerIndex, u16 Xpos,u16 Ypos,u32 ARGB8888_Color);                                                        //画点函数32bit ARGB8888格式5 t0 y" {4 y- X  W) [, Y
  58. void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color);                                                                //矩形填充(使用DMA2D)
    $ r  C' U- h7 t$ j
  59. void LTDC_Clear(u8 LayerIndex,u32 color);                                                                                                                        //清屏(使用DMA2D)
    4 n" M% O1 T/ l7 i- D/ V, q
  60. ) A- M* ]/ m2 V/ U. B* @
  61. void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr);//矩形图像填充(相同坐标范围传输,要求源图像与目标显示器分辨率一致,使用DMA2D)
复制代码

0 X4 I: a4 L8 r8 V
3 i0 d+ N0 z# A! L) `5 V4 V8 [#endif //__STM32F7_LTDC_H_
8 H/ e; a: Y8 i/ R- |
/ ^) H7 |; k. j, A" S1 T
3 @0 E3 C2 S& f# f$ B! V
7 d% o5 Q$ d7 a0 A
收藏 评论0 发布时间:2021-12-14 10:49

举报

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