需要提前准备好SDRAM驱动,如果没有SDRAM可以进行纯色彩测试,底层时钟,IO操作相关看注释,我使用的是寄存器封装的。
4 F0 C0 a2 W& Z! j/ z5 t1 W9 j
5 q0 v8 ?5 L" Z- /*************************************************************************************************************
. q8 a# A: x5 b% H- u! v1 ]! W - * 文件名 : stm32f7_ltdc.c
6 e, m( @/ [3 l+ ?( c1 f* y F, t - * 功能 : STM32F7 外部RGB LCD驱动
, N% g2 n, O2 j H' z8 z5 O; t - * 创建时间 : 2019-09-124 }( `" w* K, q4 Z D5 i$ y
- * 最后修改时间 : 2019-09-12
/ E( k' K& u6 e" Z, z, K9 ]. X - * 详细:
' J+ i9 O+ j6 T: `! {% d - *************************************************************************************************************/ - Z5 d3 c6 M s5 y2 ?: _) X
- #include "stm32f7_ltdc.h"0 ]2 ~* A* F* V" \- J; Z. i
- #include "SYSTEM.H" / L# M2 p( H8 ?2 [7 \; o
- #include "stm32f7_sdram.h"* ~; a. \" u/ K: a! }
- #include "DMA2D.h"5 \- L! H) H& C9 m8 e, N
- 8 _& s3 P. e" O+ I5 X* h
L: U/ M1 }" [) e+ i. L _2 J- u32 g_LTDC_BUFF_RGB888[2][LTDC_HEIGHT][LTDC_WIDTH] __attribute__ ((at(Bank5_SDRAM_ADDR))); //需要SDRAM支持,LCD帧缓冲区,RGB888格式1 H: Z, ]$ ^/ K: F) A# H, V9 t# c
- , J; O) e2 F! k
; ~+ F! y' O+ @" _( C- //记录全局层配置信息
, l2 |7 s7 g+ H) ~( g! z! ` - typedef struct
& |) ^6 v6 f4 H. A' j0 { d. R C - {0 K. h+ z+ j% \$ S
- u16 sx; //层开始X坐标,从0开始9 V! B5 u4 G2 Y8 I! R. I
- u16 sy; //层开始Y坐标,从0开始
: A- p# k+ }( {5 @3 J - u16 width; //层宽度, v! K! S2 M* m* K6 I. D$ A
- u16 height; //层高度
- _5 k3 H4 e6 s. m; v. T - u32 *pFrameBuff; //帧缓冲区指针,需要进行初始化# t1 C% { S9 ?3 Z: W$ H
- }LTDC_LayerConfig;3 w* ~1 b |" r
9 ]: Q" w- m! G( z3 N; w
. r3 m+ I- b5 J' x/ C" h2 W$ M
& y6 K0 P/ F0 Q' M- d- Y- //全局的LTDC配置信息
: G+ d* b( X* m$ p. ]5 r" l - typedef struct
* K5 s d4 ~/ \ - {3 a* Z4 C9 G1 g- f! d
- u16 lcd_width; //显示器宽度
1 H: b& R7 Z( F, _0 B* U - u16 lcd_height; //显示器高度
6 h+ M6 T$ w6 Q( F - LTDC_LayerConfig LayerConfig[2]; //层信息- y4 ]( s; s/ q y# A7 `* w2 y
- }LTDC_ConfigData;
! G; ^, Q$ p' h8 E ?& k - ) M+ w0 a ^; e
! H0 I0 f+ }/ T- static LTDC_ConfigData sg_LTDC_ConfigData; //记录全局的LCD配置4 j, d$ ~$ k3 C0 `3 {
: o6 u8 s4 v8 G' `* T- + P8 Q9 O. }& t* k
- //显示屏信息
4 |$ x9 R4 ~, a4 r, T - typedef struct6 F6 y7 j+ @" ^+ U. E
- {
4 l, Y+ N. q' T5 @" Q/ [ - u16 Width; //面板宽度,单位:像素( Y& J+ x1 K8 `. Z+ v+ t% B
- u16 Height; //面板高度,单位:像素
: ~5 E; y& i" h6 h - u8 Thbp; //水平后廊
5 A: j$ ~0 v' r! c( B% T R5 o - u8 Thfp; //水平前廊
. T6 p* j- T- e G7 s' Z+ Q - u8 Thw; //水平同步宽度
" Q" ^4 I* p, }( a5 M - u8 Tvbp; //垂直后廊6 Y( i% l1 Z3 o8 G
- u8 Tvfp; //垂直前廊
, k O9 P v" C - u8 Tvw; //垂直同步宽度' S% T/ k( w! q s
- u8 DCLK; //时钟速度,MHz
4 [. }' M+ l% x& S$ d - 8 u( H' i4 |+ ]% K9 Y# Y
- u8 HSPOL; //水平同步极性,0:低电平有效;1:高电平有效; X% A6 ~4 X6 a; @/ T& _- w( {
- u8 VSPOL; //垂直同步极性,0:低电平有效;1:高电平有效9 C$ G, v* |# u3 f! ?! s, @
- u8 DEPOL; //数据使能极性,0:低电平有效;1:高电平有效: F; B7 Z3 c/ P$ `+ D3 K
- bool PCPOL; //像素时钟反向- o6 Q+ T$ F) o" p! @
- }LTDC_INFO_TYPE;) p8 o2 U3 P. v( c7 B) U
4 v$ m3 S7 G6 ]( g$ w- / N( ?5 B4 [8 p& i# S1 O+ @, @" B7 U
- LTDC_INFO_TYPE DefaultLCD_Info =
2 Z$ W$ F4 \1 l B - {) F, u3 n! h- k8 F
- 480, //面板宽度,单位:像素3 `4 `( `3 C. _, v6 Q$ E* s
- 272, //面板高度,单位:像素
3 D% n# J) ?* |# }& Y% Y - 41, //水平后廊. w( S' b8 w, P( s; Y
- 8, //水平前廊8 W( M" Z" O0 u. J0 h+ A3 A
- 2, //水平同步宽度
. O# Z! k- Z# i4 H6 N0 j. ?7 m - 2, //垂直后廊' ?' o J, B) B6 |) V3 @7 L2 A
- 4, //垂直前廊
5 f7 \1 d: n& s: _ W$ j - 10, //垂直同步宽度) a/ @5 e" m3 z4 q; h8 h
- 9, //时钟速度,MHz
8 E, D8 D& p( P) _* b - 0, //水平同步极性,0:低电平有效;1:高电平有效
, w8 ?5 c6 s( }( J( `+ ^ - 0, //垂直同步极性,0:低电平有效;1:高电平有效
. d, f# R$ R0 L% a1 y# Q - 1, //数据使能极性,0:低电平有效;1:高电平有效; S" M. _$ j! E7 _1 N% ?4 s3 t; s7 s
- FALSE, //像素时钟反向
7 c" z. m# i0 ~9 `" p: V* O* L - };
9 P# T2 L0 n5 x - , [0 @! z) p. G9 L0 o) A! ]
- bool LTDC_ClockInit(u16 ClockFreq); //STM32F4 LTDC时钟初始化
6 [/ p1 l& T: Z: z3 b9 i
: d) {& i, e! E% ?; [7 v% S
7 k: ?; Q+ j, k j6 W: w( ^- /*************************************************************************************************************************
: L6 A. w7 y4 k1 u% C4 h - * 函数 : void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha)
* N8 ?# B8 h$ i$ @* h2 U3 R - * 功能 : LTDC 层窗口尺寸设置(会自动根据窗口尺寸以及像素格式设置帧缓冲区大小)7 u% W; q9 c: y# M2 |. n& O& F
- * 参数 : LayerIndex:层选择(0-1);sx,sy:起始坐标;width,height:宽度和高度* l( w' V! [: [( d6 a
- * 返回 : 无# j0 u* I6 ]6 z* X. z
- * 依赖 : 底层宏定义$ K0 b9 `5 I' I2 _6 H1 Z
- * 作者 : <a href="mailto:cp1300@139.com">cp1300@139.com</a>
/ r. B% v ~" C# ^* Z- M6 L- o" t - * 时间 : 2019-10-28( }5 q7 K: r4 \" Z8 N- c
- * 最后修改时间 : 2019-10-285 s1 l7 O' E, O3 {
- * 说明 : 不会使能层,不会更新层,只设置配置,需要刷新层配置后更新( m+ j; O. x K" P0 a
- *************************************************************************************************************************/
; U* a; s6 F2 b0 Q - void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha)
/ a: p1 F1 e* D% C/ ^3 f% J - {
$ H5 M- S2 y* z' F: b; `$ B8 }# I - u32 temp;) D* A: J4 N$ P0 o' F4 r, i( X
- u8 pixformat=0; " o7 [, d' Y# T7 Y! J0 \
-
2 h" _( D& O! K4 { - if(LayerIndex==0)
9 c4 y K2 _- V7 y - {, L+ _. l8 S3 Z" f
- //基本配置/ U6 u( G% s2 {/ |/ T D' H4 k
- LTDC_Layer1->CFBAR = FrameBuff; //设置层颜色帧缓存起始地址& Q4 v, {" H/ _2 [ s
- LTDC_Layer1->PFCR = LTDC_PIXEL_FORMAT; //设置层颜色格式0 k* Q" i6 U8 e, _* }
- LTDC_Layer1->CACR = Alpha; //常数 Alpha,255分频;设置255,则不透明
7 p: C, I0 J8 }/ i/ \, ~ - LTDC_Layer1->DCCR = 0x00; //设置默认颜色:透明的黑色0 _7 F8 P8 [* [1 K" U8 E) q
- LTDC_Layer1->BFCR = ((u32)6<<8)|7; //设置层混合系数
- z5 X" X. C' n7 F8 P5 B - //配置窗口
2 \5 p/ w2 ]$ t: B - temp = (sx+width+((LTDC->BPCR&0X0FFF0000)>>16))<<16;
* M! ]2 B9 N" L0 D( K, c - LTDC_Layer1->WHPCR = (sx+((LTDC->BPCR&0X0FFF0000)>>16)+1)|temp;//设置行起始和结束位置
8 Z% v! Z5 G( p0 m9 d4 g - temp = (sy+height+(LTDC->BPCR&0X7FF))<<16; + _4 [5 @2 z: \/ W, t
- LTDC_Layer1->WVPCR = (sy+(LTDC->BPCR&0X7FF)+1)|temp; //设置列起始和结束位置
1 e! H, d& |& `" C; x - pixformat = LTDC_Layer1->PFCR&0X07; //得到颜色格式+ r! x: r% n/ Z) e2 F6 _3 T% U
- if(pixformat == 0)temp=4; //ARGB8888,一个点4个字节) T8 ]! A3 _( r0 r
- else if(pixformat == 1)temp=3; //RGB888,一个点3个字节
* v# Z; a3 |- j; u5 Y, a - else if(pixformat==5||pixformat==6)temp=1; //L8/AL44,一个点1个字节
% [+ Z3 @3 O J: K; _$ f( V* v X- P - else temp=2; //其他格式,一个点2个字节
* a' j8 b& }" U& u% D- c - LTDC_Layer1->CFBLR = (width*temp<<16)|(width*temp+3); //帧缓冲区长度设置(字节为单位)1 h* V( X( ^2 {+ X" E4 M4 c
- LTDC_Layer1->CFBLNR = height; //帧缓冲区行数设置
4 h ]8 n* i7 N$ `# l9 |+ j - . U+ m: ~$ I y2 o9 g* E
- //记录层窗口大小位置信息
/ M- \6 e/ ?7 a6 a# {+ |* j - sg_LTDC_ConfigData.LayerConfig[0].sx = sx; 4 t4 E$ H. d; ?6 [ y, p* g% b
- sg_LTDC_ConfigData.LayerConfig[0].sy = sy;
& R u5 `: _. @/ e. N- w% @* z& X - sg_LTDC_ConfigData.LayerConfig[0].width = width;
+ x1 a$ r) s# E& J+ R - sg_LTDC_ConfigData.LayerConfig[0].height = height; - o5 i# Q% a5 F
- }else
7 F8 U/ `9 o& {3 H - {
. L) z' q/ q9 s; y, M! i; o - //基本配置
5 I# R4 U. |0 V5 n1 t) w - LTDC_Layer2->CFBAR = FrameBuff; //设置层颜色帧缓存起始地址
" }# L+ w& T) y) y7 H - LTDC_Layer2->PFCR = LTDC_PIXEL_FORMAT; //设置层颜色格式% o: h; i3 C5 f1 T* r
- LTDC_Layer2->CACR = Alpha; //常数 Alpha,255分频;设置255,则不透明' R* X3 m* v: Y( C
- LTDC_Layer2->DCCR = 0x00; //设置默认颜色:透明的黑色* O4 p' ]7 j* f7 l$ V
- LTDC_Layer2->BFCR = ((u32)6<<8)|7; //设置层混合系数
5 y: h: I& ?" l \ - //配置窗口& s- r l2 k1 V9 A
- temp = (sx+width+((LTDC->BPCR&0X0FFF0000)>>16))<<16;
C5 I, `3 X b6 W1 b. @" G+ _ - LTDC_Layer2->WHPCR = (sx+((LTDC->BPCR&0X0FFF0000)>>16)+1)|temp; //设置行起始和结束位置
, L: d7 l Q) f/ i% a - temp = (sy+height+(LTDC->BPCR&0X7FF))<<16;
5 H4 r: \! |- p; u' F* ]7 I a - LTDC_Layer2->WVPCR = (sy+(LTDC->BPCR&0X7FF)+1)|temp; //设置列起始和结束位置
) t% y# T5 c. T7 a2 a - pixformat = LTDC_Layer2->PFCR&0X07; //得到颜色格式# {% K. @4 ?6 k: S! i4 {) a
- if(pixformat == 0)temp=4; //ARGB8888,一个点4个字节1 K7 Y! h5 i* c8 \
- else if(pixformat == 1)temp=3; //RGB888,一个点3个字节9 C: Y0 L% s& h1 `$ l
- else if(pixformat == 5||pixformat==6)temp=1; //L8/AL44,一个点1个字节
8 a# o3 |: }+ ?6 p8 h1 g - else temp = 2; //其他格式,一个点2个字节$ H8 Z! j" P3 v
- LTDC_Layer2->CFBLR = (width*temp<<16)|(width*temp+3); //帧缓冲区长度设置(字节为单位)/ n+ y& \3 a6 o/ T) O" L. _
- LTDC_Layer2->CFBLNR = height; //帧缓冲区行数设置 . Y- ~; I2 A9 M7 u+ z
-
4 h4 i% G* C' G1 {; S0 } - //记录层窗口大小位置信息6 u. u) }3 ?: U' |
- sg_LTDC_ConfigData.LayerConfig[1].sx = sx;
3 \2 ^3 @: q9 u5 x$ f - sg_LTDC_ConfigData.LayerConfig[1].sy = sy;
- U% c5 V* S( m - sg_LTDC_ConfigData.LayerConfig[1].width = width; / n% m- X {# P: |7 t
- sg_LTDC_ConfigData.LayerConfig[1].height = height;
3 @6 F3 I3 g7 G1 H" R# q - }' X5 ]& D4 S6 i) \* T
- } V, x5 i1 E! F+ c
- % _% ]: O7 m( A) T. a. d+ x
- ! ~) N5 X1 R6 B
- [# m6 N% b2 p. y( I6 D9 N
- /*************************************************************************************************************************: k! r7 j- H, }% L- W: Q* E6 k
- * 函数 : void LTDC_Init(void)
( y' K9 c6 A0 r' v" B( y6 y - * 功能 : LTDC 接口初始化( l/ V1 v' l# m( d" Q$ C1 S8 [% z d ^; O
- * 参数 : 无
0 F+ f8 a* _6 p8 t6 M - * 返回 : 无
5 V, b/ U. H& J; g8 n - * 依赖 : 底层宏定义
( r2 W6 \- c) W - * 作者 : <a href="mailto:cp1300@139.com">cp1300@139.com</a>
0 ]) D- [4 F! t! g - * 时间 : 2019-09-08! i* m" \2 |6 r( L/ O
- * 最后修改时间 : 2019-09-08
- Y! R8 y7 P t8 D7 A9 T+ c - * 说明 : 用于初始化STM32F7 LTDC 接口
& A$ W) @$ J- u* C, k( i - *************************************************************************************************************************/
. T! D$ Z6 s c5 j. q - void LTDC_Init(void)# {: s" Z4 v, y" g& O
- {
* p/ C. u* H( H. o- a, Q - u32 temp;
4 z# q+ y) q& S6 d' b; {" e -
_3 }4 E' }, R. { - SYS_DeviceClockEnable(DEV_LTDC, TRUE); //LTDC时钟使能) j6 E6 A" E) a% N
- SYS_DeviceReset(DEV_LTDC); //STM32F7外设复位
( G. x. |6 F+ L+ b7 C* V7 z$ ^3 ? - SYS_DeviceClockEnable(DEV_GPIOE, TRUE); //使能GPIOE时钟6 `% @+ I4 i# A/ m$ s+ ]
- SYS_DeviceClockEnable(DEV_GPIOG, TRUE); //使能GPIOG时钟' @. G0 |- f0 p. V0 j
- SYS_DeviceClockEnable(DEV_GPIOJ, TRUE); //使能GPIOJ时钟
' p; p! d$ R& W5 G% ` - SYS_DeviceClockEnable(DEV_GPIOK, TRUE); //使能GPIOK时钟
: j6 I6 o" Z3 ]* B+ ~$ k - SYS_DeviceClockEnable(DEV_GPIOI, TRUE); //使能GPIOI时钟' C: a5 V0 f! b
- / m7 d& E- E; }
-
- r- s& u1 x% Y9 c# k - //初始化IO; w) p$ w% s" O6 H
- SYS_GPIOx_Init(GPIOE, BIT4, AF_PP_OPU, SPEED_100M); //PE4" U. C2 o6 O5 B% p+ w
- SYS_GPIOx_Init(GPIOG, BIT12, AF_PP_OPU, SPEED_100M); //PG12
; {2 q/ x7 h8 p5 } - SYS_GPIOx_Init(GPIOJ, 0Xffff&(~BIT12), AF_PP_OPU, SPEED_100M); //PJ0~11/13/14/15! J2 ^( p8 g4 `* H% w4 A4 i
- SYS_GPIOx_Init(GPIOK, BIT0|BIT1|BIT2|BIT4|BIT5|BIT6|BIT7, AF_PP_OPU, SPEED_100M); //PK0/1/2/4/5/6/7
' l9 w0 b% j" X* V5 X/ s/ C - SYS_GPIOx_Init(GPIOI, BIT9|BIT10|BIT14|BIT15, AF_PP_OPU, SPEED_100M); //PI9/10/14/15% a0 e) y3 W$ o) g8 b0 B* d
- / u0 Q' J& @4 G/ V
- SYS_GPIOx_SetAF(GPIOE, 4, AF14_LTDC); //PE4,AF14 * c* `' \' z- I8 D$ `
- SYS_GPIOx_SetAF(GPIOG, 12, AF14_LTDC); //PG12,AF14
8 C7 R. {; }' p - SYS_GPIOx_SetAF(GPIOJ, 0, AF14_LTDC); //PJ0,AF14
# d( }/ z2 W- [" Y* c% {& B3 Z - SYS_GPIOx_SetAF(GPIOJ, 1, AF14_LTDC); //PJ1,AF14
$ u' A. d) z2 J' G' m5 c7 G - SYS_GPIOx_SetAF(GPIOJ, 2, AF14_LTDC); //PJ2,AF149 D5 @' F+ P' o: ~# j9 z1 ^% a
- SYS_GPIOx_SetAF(GPIOJ, 3, AF14_LTDC); //PJ3,AF147 b" Q6 F6 U0 m! X, I/ k7 q
- SYS_GPIOx_SetAF(GPIOJ, 4, AF14_LTDC); //PJ4,AF148 U2 Z; s3 R# `; w
- SYS_GPIOx_SetAF(GPIOJ, 5, AF14_LTDC); //PJ5,AF14
: `. N6 s1 M% N; M; O' `+ d - SYS_GPIOx_SetAF(GPIOJ, 6, AF14_LTDC); //PJ6,AF14$ J, N( m% }( v% ` z
- SYS_GPIOx_SetAF(GPIOJ, 7, AF14_LTDC); //PJ7,AF14
0 G# s- a% N6 |( i* ~- t - SYS_GPIOx_SetAF(GPIOJ, 8, AF14_LTDC); //PJ8,AF14
+ _) Y3 T5 p# M- a0 I8 K- w2 ] - SYS_GPIOx_SetAF(GPIOJ, 9, AF14_LTDC); //PJ9,AF14
/ C8 G4 D% t, [ - SYS_GPIOx_SetAF(GPIOJ, 10, AF14_LTDC); //PJ10,AF14
2 C( Y$ q/ o% E* F" F: r - SYS_GPIOx_SetAF(GPIOJ, 11, AF14_LTDC); //PJ11,AF14+ j) r4 o& ? `9 f
- SYS_GPIOx_SetAF(GPIOJ, 13, AF14_LTDC); //PJ13,AF14
' I) \5 {" O7 R7 b' p G - SYS_GPIOx_SetAF(GPIOJ, 14, AF14_LTDC); //PJ14,AF14
- c2 Q' W/ x. e9 T4 v - SYS_GPIOx_SetAF(GPIOJ, 15, AF14_LTDC); //PJ15,AF14
; `/ g1 P1 W/ @; o2 x - ) [7 a: c; ^/ o$ a! D6 o
- SYS_GPIOx_SetAF(GPIOK, 0, AF14_LTDC); //PK0,AF14; ]9 ?0 |2 \4 u& F+ t" u$ y
- SYS_GPIOx_SetAF(GPIOK, 1, AF14_LTDC); //PK1,AF144 g" \: b* U8 H. d3 A. l$ N/ M
- SYS_GPIOx_SetAF(GPIOK, 2, AF14_LTDC); //PK2,AF14
7 S. F% x* j& C0 `' `2 @& I) R9 r) s - SYS_GPIOx_SetAF(GPIOK, 4, AF14_LTDC); //PK4,AF14
1 A' ^4 b8 W+ \+ C - SYS_GPIOx_SetAF(GPIOK, 5, AF14_LTDC); //PK5,AF14
' K# A- o# O2 K; c1 R% } f$ h - SYS_GPIOx_SetAF(GPIOK, 6, AF14_LTDC); //PK6,AF145 S8 a' }2 K9 p0 b( d1 v0 f8 L9 x+ u
- SYS_GPIOx_SetAF(GPIOK, 7, AF14_LTDC); //PK7,AF148 R* h4 j. ]- I7 }
- - X0 _: {9 S$ K
- SYS_GPIOx_SetAF(GPIOI, 9, AF14_LTDC); //PI9,AF14: N- e. {- |0 k# i) e6 `' ]
- SYS_GPIOx_SetAF(GPIOI, 10, AF14_LTDC); //PI10,AF14
8 i6 a/ x: r5 v4 x - SYS_GPIOx_SetAF(GPIOI, 14, AF14_LTDC); //PI14,AF14 t7 z9 Q& h' g0 d
- SYS_GPIOx_SetAF(GPIOI, 15, AF14_LTDC); //PI15,AF14
9 n3 z2 c: |6 N% a6 q -
2 _8 z7 G! j1 z4 ` - LTDC_ClockInit(DefaultLCD_Info.DCLK); //设置像素时钟 9Mhz ! A' h9 ^6 t9 M i! U
- //设置LTDC 全局控制寄存器 (LTDC_GCR). U9 s/ y8 r9 R& R8 ]
- temp = 0;
8 s. M: W. l' N2 E - temp |= (DefaultLCD_Info.HSPOL&0x01) << 31; //水平同步极性$ Q# g/ c/ @, t$ O& a c$ L K5 f' W
- temp |= (DefaultLCD_Info.VSPOL&0x01) << 30; //垂直同步极性
6 e4 r7 _' L# |4 i - temp |= (DefaultLCD_Info.DEPOL&0x01) << 29; //数据使能极性
7 H7 P j3 Y/ n) J& `/ h/ _ - temp |= (DefaultLCD_Info.PCPOL&0x01) << 28; //像素时钟极性
/ ~/ W$ K# p' ^ - LTDC->GCR = temp;. `' p# v' b3 }. P
- //LTDC 后沿配置寄存器 (LTDC_BPCR)
+ }7 ]8 Y' ?4 N; ?3 | - temp = (DefaultLCD_Info.Tvw + DefaultLCD_Info.Tvbp - 1) << 0; //这些位定义累加水平后沿宽度(水平同步像素加水平后沿像素减 1)。' A4 y5 D c* g# u) C
- temp |= (DefaultLCD_Info.Thw + DefaultLCD_Info.Thbp - 1) << 16; //这些位定义累加垂直后沿宽度(垂直同步行加垂直后沿行减 1)。4 s/ c9 B/ r; l" @
- LTDC->BPCR=temp; 4 _0 T7 \3 Y$ t" N# Y8 i9 c
- # C. N6 r2 H: p0 K
- //LTDC 有效宽度配置寄存器 (LTDC_AWCR)7 O5 {2 t+ [! I: J' Z" k& b; X$ F
- temp=(DefaultLCD_Info.Tvw+DefaultLCD_Info.Tvbp+DefaultLCD_Info.Height-1)<<0; //累加有效高度=垂直脉宽+垂直后沿+垂直分辨率-1/ r: n Z J7 {3 l2 M* r
- temp|=(DefaultLCD_Info.Thw+DefaultLCD_Info.Thbp+DefaultLCD_Info.Width-1)<<16; //累加有效宽度=水平脉宽+水平后沿+水平分辨率-1
7 z1 u1 @& `- g6 _2 g4 h( Q+ H' i - LTDC->AWCR=temp; }3 ?0 Y7 X m5 L8 a; [# H
- //LTDC 总宽度配置寄存器 (LTDC_TWCR)
5 Q! o6 H5 l. L3 D7 _2 a - temp=(DefaultLCD_Info.Tvw+DefaultLCD_Info.Tvbp+DefaultLCD_Info.Height+DefaultLCD_Info.Tvfp-1)<<0; //总高度=垂直脉宽+垂直后沿+垂直分辨率+垂直前廊-1& R- p! n9 D4 Q" P) p
- temp|=(DefaultLCD_Info.Thw+DefaultLCD_Info.Thbp+DefaultLCD_Info.Width+DefaultLCD_Info.Thfp-1)<<16; //总宽度=水平脉宽+水平后沿+水平分辨率+水平前廊-19 v" k& [7 ~$ ~/ o1 B6 M
- LTDC->TWCR=temp;
; v9 a: c$ g9 v" L/ w- ^5 O
% v7 U9 G) M& G2 c. ?6 O( R- //背景设置
5 E2 T/ c; a9 K, ^: @- G: ?# j - LTDC->BCCR=0xffffff; //设置背景层颜色寄存器(RGB888格式)
" {2 v) i( K1 o# o0 K# z! q* x9 R - LTDC_Enable(TRUE); //开启LTDC$ a) Q: T0 X9 m1 s
- //初始化层1: q v! L/ j( i$ u0 U2 A
- LTDC_SetLayerConfig(0, 0, 0, LTDC_WIDTH, LTDC_HEIGHT, (u32)g_LTDC_BUFF_RGB888[0], 255);& |1 R- N: w8 U/ W) B* C/ }
- //初始化层2& u/ x" N% X2 C5 d
- LTDC_SetLayerConfig(1, 0, 0, LTDC_WIDTH, LTDC_HEIGHT, (u32)g_LTDC_BUFF_RGB888[1], 255);
+ H1 T5 B2 }$ H - LTDC_Clear(0, 0xFF000000); //清屏层1-不透明的黑色, B6 Z- O7 j- f% S
- LTDC_Clear(1, 0x00000000); //清屏层2-透明的黑色
8 e/ C1 w4 P9 r& @* S! w - LTDC_LayerEnable(0, TRUE); //使能层12 Q- N1 [& j( A" H# |
- LTDC_LayerRefreshConfig(); //LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)
" c2 p* Q0 F( v+ `! b$ @ - LCD_DispIoInit(); //初始化DISP引脚-启动显示
8 H! x9 q" L1 ?* O9 b5 ^+ f - }
! Z4 @' u. }( a0 d; |6 O+ X) f
0 c5 e( K% H( b' o* t( k9 o3 _- /*************************************************************************************************************************3 d: }0 K5 c$ ]
- * 函数 : void LTDC_LayerRefreshConfig(void)
a' S; q; t6 n8 Q6 y - * 功能 : LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)
S5 N- Q, T4 |3 Q! @! n' q - * 参数 : 无. A# q& h1 ~2 x9 {
- * 返回 : 无
1 g* s8 |4 q0 w/ v( G* L' e g- c - * 依赖 : 底层宏定义
! \% w1 t; B$ W9 q( u - * 作者 : <a href="mailto:cp1300@139.com">cp1300@139.com</a>
5 [: u$ F, p: w2 L( k. f8 y' M - * 时间 : 2019-10-29
: K2 M, W- x; W3 y - * 最后修改时间 : 2019-10-29
6 ~1 c- Q+ Q6 Z0 u - * 说明 : 修改层配置后必须重新加载,否则不会生效) u' q$ d5 z& q
- *************************************************************************************************************************/* E7 H; P8 Q R y/ W
- void LTDC_LayerRefreshConfig(void)
6 b- ]0 q6 ~) { n - { {8 y: B. l9 i9 X3 y" I
- LTDC->SRCR|=1<<0; //重新加载配置-必须重新加载,否则上面的层不会更新,折腾好久才发现,叫啥影子寄存器重载,也不说清楚 ~8 n( d! Q3 ]( o2 S3 c
- }% C* j0 J1 L8 {; R6 O" g, \) ]
- ' k$ k' j+ G x+ A4 F& G5 x
- /*************************************************************************************************************************8 }, G+ ^ }9 j m- J4 v
- * 函数 : void LTDC_Enable(bool Enable)
, E# S8 A- z/ i2 T3 @ - * 功能 : LTDC使能设置
* ?: D+ X5 Z, j% ~- u6 Z - * 参数 : Enable:TRUE:使能;FALSE:失能
5 c! x/ j" ]1 u% y - * 返回 : 无
2 C" u1 ~6 W0 y4 W - * 依赖 : 底层宏定义, C2 t: r4 F1 V
- * 作者 : <a href="mailto:cp1300@139.com">cp1300@139.com</a>; e* M$ x! }% w# `6 i; `
- * 时间 : 2019-10-29 U& D; w1 b1 j" _
- * 最后修改时间 : 2019-10-29
6 }3 M# X3 O9 n5 S- Z - * 说明 : 8 n4 J. j. \& s4 y- ]3 _
- *************************************************************************************************************************/3 u2 u! b6 |* l, Q3 L* s
- void LTDC_Enable(bool Enable) [+ I1 J4 A2 B3 a
- {
: U- l0 ~! W& S$ E - if(Enable)
7 ?9 U {0 a/ p0 Q+ ~$ q* {, {- J - {
9 W1 U5 E3 x. b8 \: F3 f2 V9 P- | - LTDC->GCR |= BIT0; //打开LTDC) c8 j. D6 X7 n
- }: y; _; y% `# c2 k' B
- else, Z& z1 y3 v n( ]7 r2 ^9 w
- {! I+ Y3 T/ H4 u: |8 }
- LTDC->GCR &= ~BIT0; //关闭LTDC
4 E; o' q! w9 \$ k; @ - }) r/ p* o @' `( Y: n/ Y6 }
- }
' o. a, w$ C" Q& J! M
6 ?$ }$ j% a: A; Q8 v ?- /*************************************************************************************************************************
8 _# H: {% ~, N% c& c0 C: t - * 函数 : void LTDC_LayerEnable(u8 LayerIndex, bool Enable): M; t: I3 P. `: F" t# \
- * 功能 : LTDC 层使能设置: w! i. L: i7 }
- * 参数 : LayerIndex:层选择0-1;Enable:TRUE:使能;FALSE:失能$ p j6 z% u# `
- * 返回 : 无
, N. y, T/ Z% Z( x! v5 P* X' @' C0 _$ m - * 依赖 : 底层宏定义
1 Q2 h! p. V2 I) w9 }1 L4 R- a7 N - * 作者 : <a href="mailto:cp1300@139.com">cp1300@139.com</a>
9 u$ b! }7 {4 N3 h l) K& F2 a - * 时间 : 2019-10-29
% s; J! d1 }8 @3 r - * 最后修改时间 : 2019-10-291 Y3 A* ^7 Z' e% ]0 A2 T
- * 说明 :
7 t* s/ e* ~; ?/ @! t0 D7 ~# F - *************************************************************************************************************************/
$ J" ?+ x$ O7 ?. @/ m& t - void LTDC_LayerEnable(u8 LayerIndex, bool Enable)9 l2 G8 M0 [5 O+ S4 i% D+ j% v1 ?
- {$ M, W* h! l5 W+ \$ j$ A% C
- if(Enable)4 P! e& w# T& Z: h* u( [! g
- {, C) _* l7 r6 f8 g7 w
- if(LayerIndex == 0) //层1& r) y! i8 ~2 t8 y- X/ {! p
- {" N+ y* Z+ e) a, _* r
- LTDC_Layer1->CR |= BIT0; //使能层13 W* K2 K" Z0 m# j
- }3 S E+ w" p) b& Q
- else" G) k; O7 k# m# S Y W# I
- {
& m7 [* B$ L8 T' V4 K% I - LTDC_Layer2->CR |= BIT0; //使能层2
# p: b/ K0 p v2 B - }
7 L* H5 d2 @' j1 P - }
" y7 Y3 G. f- d - else1 x) V% m0 Z8 o( ~; i
- {: W8 \9 r7 w- @6 D
- if(LayerIndex == 0) //层1 E$ H" E, j# |6 P# Y* v. V3 `
- {
- U ^6 H; @' w9 j - LTDC_Layer1->CR &= ~BIT0; //失能层1! N) {9 ^- Q" z3 V y2 ?
- }
9 I3 U* t. Y! K% T# b4 }* C3 y( t - else
6 K5 C( O. p! b- t& z - {, J+ `! g0 U. R; b# e
- LTDC_Layer2->CR &= ~BIT0; //失能层2
. x" _; O! r9 ]* z3 @$ f4 } - }7 {; ^1 A5 | `- ~; U) W0 _
- }* W6 {! a3 x/ q0 g
- }) i0 H C' F" P5 A& l
- ( D. R" H: W. S+ D+ O( b; J
- ! L8 D4 y( j3 B! S9 {+ G7 O
/ J0 H' L8 Q- T2 d9 o- g- 2 d, K, |$ i/ C
- /*************************************************************************************************************************$ v: B# S; ?$ s3 @' h9 P
- * 函数 : bool LTDC_ClockInit(u16 ClockFreq)
6 [3 |1 W9 D8 _9 V' B# ]) E" Z! W - * 功能 : STM32F7 LTDC时钟初始化. d0 _7 |( D) K; Q& V4 v& L
- * 参数 : ClockFreq:时钟频率,2-168MHZ) C) [, W! w W* m/ t$ A2 v9 {
- * 返回 : 是否设置成功
1 c) L9 m/ ^, W& r - * 依赖 : 底层宏定义
! Q* c' j8 }; P4 w+ |6 y7 f7 B - * 作者 : <a href="mailto:cp1300@139.com">cp1300@139.com</a>
; |$ _9 g: R# `( P - * 时间 : 2019-10-28$ j$ s3 A% r5 I7 v9 c0 E2 R- l
- * 最后修改时间 : 2019-10-28* i* H4 x5 f a" o
- * 说明 : 输入时钟频率在系统主时钟初始化之后就会设置为1MHz,通过设置SAI PLL实现LTDC所需频率,VCO频率范围:49~432$ E0 j1 c# \ a+ E/ i; G4 }9 f1 B
- *************************************************************************************************************************/
3 g! g U4 @% b9 o - bool LTDC_ClockInit(u16 ClockFreq) b' B2 i4 G9 G) o* o
- {
5 b9 J5 S- \5 W, { - u32 TimeOut = 0;2 Z% Y0 ]/ I7 m- `5 K6 O- l
- u32 VCO;
3 Q5 f; t. m) _/ v; B! b - u32 PLLSAIR; //PLLSAICFGR[30:28]
2 i. n! b2 Y7 v8 w - u32 PLLSAIDIVR; //DCKCFGR1[17:16]1 q8 m& n" R0 {2 ]7 j4 r5 Z, o
- u32 temp;5 C/ O- w" s2 b& j* y
- 0 ]' v# _, m4 {( P
- if(ClockFreq < 1)ClockFreq = 1;6 ?! O$ ?4 g$ J/ ?1 V7 f# C, T
- if(ClockFreq > 100) ClockFreq = 100;/ d4 B1 b7 o8 |2 p, v( _
-
8 @2 m: A U: D( e: f - RCC->CR &= ~(1<<28); //关闭SAI时钟 @$ ] V) s7 d4 C2 s9 o' G
- TimeOut = 0;
& ]; B# b: U; F( @. n; J - while(RCC->CR&(1<<29)) //等待关闭成功1 k& K5 v+ I$ ^8 f$ F$ Y# x0 Q
- {
m3 i) v/ Y9 L, G& i - nop;
/ d% h2 W( x+ h1 M1 p - TimeOut ++;8 A8 h* N% v6 l7 V
- if(TimeOut > 0xFFFF) return FALSE; //关闭超时
- V4 J5 q9 y% i, d. T2 v - }( [% ^2 M9 w0 i: Q
- //计算分频与VCO频率,通过PLLSAICFGR[30:28]可以设置2-7分频4 {" i, x4 c' \% I
- //通过PLLSAICFGR[17:16]可以设置00:2 01:4 10:8 11:16分频
& o! R0 w J# M6 A0 o9 f/ I - //通过PLLSAICFGR[14:6]可以设置为49-432MHz的VCO频率
- S5 i, _; G& }3 { - if(ClockFreq <= 6)
, ~$ Z9 v: E$ d7 ] - {
' z' e8 u& C3 C - PLLSAIR = 4; //4分频
$ ?4 B8 J9 [/ \- O3 z- K& a5 G - PLLSAIDIVR = 3; //16分频
' F ^' T0 `* O U3 Z - VCO = ClockFreq * PLLSAIR * 16; //VCO范围:64-384;8 K9 l( I/ b3 V; D5 r2 L
- }' z4 P: d4 a2 f- z7 h2 q; R2 j/ r
- else if(ClockFreq <= 13)* ^1 @; G9 Z* z0 ?
- {% E" R% _5 b0 B) W4 {
- PLLSAIR = 4; //4分频
1 g9 k: W: W/ B5 W3 v5 N7 ?3 e - PLLSAIDIVR = 2; //8分频! Y0 @4 l3 |$ L1 h u Z8 ~8 Q% @
- VCO = ClockFreq * PLLSAIR * 8; //VCO范围:224-416;: T: i% c* n- c$ Q ]9 D$ U9 ^6 H) K
- }( s! R0 M3 E2 T: }- S1 a$ I
- else if(ClockFreq <= 26) j. Z1 Y/ y ^. B2 J$ r. @
- {9 h) e. v' b. X0 G6 s) j
- PLLSAIR = 2; //2分频
! B( V( N: u3 f# {- J8 p - PLLSAIDIVR = 2; //8分频
/ I1 }% O& f8 C: a& P - VCO = ClockFreq * PLLSAIR * 8; //VCO范围:224-416;7 {3 c7 M- h! f% B
- }
9 }* M/ u: e) G; s9 J - else if(ClockFreq <= 52)
& @5 D% o+ s; \0 H' J - {2 g% Z9 y* Q) O6 ^
- PLLSAIR = 2; //2分频' x j! S' L) [5 K/ W* w- \1 D
- PLLSAIDIVR = 1; //4分频- Q( s# K7 L6 F$ c8 U7 r
- VCO = ClockFreq * PLLSAIR * 4; //VCO范围:216-416;
+ t- j7 w& I) P ` - }/ d. O) r1 D' b( r5 K* @. [
- else if(ClockFreq <= 104)6 R# x% y. _* }4 ?: R5 o" j
- {5 L5 p5 m {/ h- P2 u! }
- PLLSAIR = 2; //2分频" F3 ?6 _1 i5 C4 t
- PLLSAIDIVR = 0; //2分频
0 h* _. I' C/ A- i" {/ ^4 u - VCO = ClockFreq * PLLSAIR * 2; //VCO范围:212-416;
4 y! X$ f+ x/ V" { - }( g( @8 v/ {2 [
- //设置PLLSAICFGR
; c& w: x8 s) Y9 p - temp = RCC->PLLSAICFGR;; V# k! T1 n' z/ C0 d1 D
- temp &= ~((3<<28) | (0x1FF<<6)); //清除之前的设置
5 p0 F* l& p: z: T- t2 H - temp |= PLLSAIR << 28; //设置分频PLLSAICFGR[30:28]0 S' E0 ]/ o# d2 P) C# ^
- temp |= VCO << 6; //设置VCO/ p. A& }7 E; N: q) Y
- RCC->PLLSAICFGR = temp;/ E9 @( a5 w" {
- //设置DCKCFGR16 q7 M: g1 j* l2 Q$ H3 w9 U' c
- temp = RCC->DCKCFGR1;7 c, F4 S; |$ E2 P: f' Y
- temp &= ~(3<<16); //清除之前的设置& P4 c U+ ~% [. I
- temp |= PLLSAIDIVR << 16; //设置分频DCKCFGR1[17:16]
- N) U/ R, `5 U - RCC->DCKCFGR1 = temp;* g& `+ h& R3 L4 [! U/ J
- //启动时钟
! F! j2 Z- p8 G% F! m* W - RCC->CR |= 1<<28; //启动SAI时钟/ ~( K4 _0 D, R+ P* W) p
- TimeOut = 0;# ^1 J* b3 q1 k( E1 J
- while((RCC->CR&(1<<29)) == 0) //等待开启成功7 @5 J0 T0 H- ~' _0 V
- {7 H9 j n: N9 y0 m! N- ?- ^
- nop;3 ~1 s; o5 I' F% u2 p
- TimeOut ++;
7 d: M8 [: L3 j1 `, `& ~ - if(TimeOut > 0xFFFF) return FALSE; //开启超时
) r1 o3 K, f. O! ` - }1 }% Q) \2 v" K8 {
-
, x3 ]2 [, g, R. A% B: b' r - return TRUE;8 }: [, S: C& d: E
- }
! u; k8 U% W B* i
) m8 E8 B3 \- n! B
* }6 C3 d. d' v* r- /*************************************************************************************************************************0 V4 \# b! c, L. r" ~8 u! D
- * 函数 : void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color) " p, E, G5 e7 e6 m4 e& B) `
- * 功能 : 矩形填充(使用DMA2D)
) Q/ v) J$ ~5 W* q2 H' I, l2 {' O F - * 参数 : LayerIndex:层选择0-1;sx,sy:开始坐标;ex,ey:结束坐标,color:需要填充的颜色
& q) W/ A6 i% g9 t1 x) m3 N' _ - * 返回 : 无
$ b2 b P0 ~: N$ K! c - * 依赖 : 底层宏定义
! H" @- e2 d: }+ }( y - * 作者 : <a href="mailto:cp1300@139.com">cp1300@139.com</a>
- K8 J% Q. k* |: ? - * 时间 : 2019-10-307 h0 x7 ^1 f, |0 {; S$ y9 ^/ k
- * 最后修改时间 : 2019-10-30
% b+ u; p6 y; H( C, p9 T- v4 W( k - * 说明 : 采用DMA2D实现2 Q1 ?, {7 b# g' a1 |6 e
- *************************************************************************************************************************/: b. V m! v8 f: j! m/ h7 A: k! ]1 ^
- void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color)
) l, v. V% [# X7 ^/ k2 E; r5 V4 A - {
6 i T. e/ ^: J# U9 Q) q - DMA2D_FillColorToFGRAM((u32)&g_LTDC_BUFF_RGB888[LayerIndex][sy][sx], ex-sx+1, ey-sy+1, LTDC_WIDTH-(ex-sx+1), DMA2D_COLOR_ARGB8888, color); //DMA2D进行单色填充
4 T m4 y, T7 r - DMA2D_WaitTransferComplete(500); //等待DMA2D传输完成5 _( ^+ T5 v$ S; j$ E1 Q+ r
- }4 n; g7 i. M7 ]) J
- b% j R% V0 M9 b z! G- C
- ' r. }( ?. P* x) B1 H! h
- /*************************************************************************************************************************
! l7 W- G* g. W - * 函数 : void LTDC_Clear(u8 LayerIndex,u32 color)) I0 @8 ?( \# v
- * 功能 : 清屏(使用DMA2D)" W+ ~6 j. j# }$ s2 V) W
- * 参数 : LayerIndex:层选择0-1;color:需要填充的颜色
! ^" ^, R( n) F+ Z P) l# R2 Z - * 返回 : 无
6 o& ]) E3 w" w9 J' \ - * 依赖 : 底层宏定义
5 R1 \7 e7 M6 X; R7 G/ \) ]; e/ K) } - * 作者 : <a href="mailto:cp1300@139.com">cp1300@139.com</a>
' t2 ]' i3 S6 R# o - * 时间 : 2019-10-30
! g+ F* d- J2 c - * 最后修改时间 : 2019-10-306 I6 l, Y, g8 ?# |; c
- * 说明 : 采用DMA2D实现4 \5 N; S% P2 w; G- n5 Y; `
- *************************************************************************************************************************/
$ ?0 f6 C4 d p4 d+ u0 G' x# M! C - void LTDC_Clear(u8 LayerIndex,u32 color)
0 h& }" N# C1 P' i8 K/ w/ [# J - {
% q, R" }* w O! H - DMA2D_FillColorToFGRAM((u32)&g_LTDC_BUFF_RGB888[LayerIndex][0][0], LTDC_WIDTH, LTDC_HEIGHT, 0, DMA2D_COLOR_ARGB8888, color); //DMA2D进行单色填充
) A+ r, ?) D, }2 ~% v - SYS_DelayMS(5);3 E7 p \* q: P. l' d
- DMA2D_WaitTransferComplete(500); //等待DMA2D传输完成! S$ f9 S( f9 k* V
- }+ I, `9 C5 u/ Z/ F$ f
_* R. h5 R( G% A5 _, z7 a2 F( F
6 Q3 O% j4 q$ ~ y- /*************************************************************************************************************************, t( e' a. F% y
- * 函数 : void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr)1 {( |0 Z' N8 [5 w3 q- Y9 T O
- * 功能 : 矩形图像填充(相同坐标范围传输,要求源图像与目标显示器分辨率一致,使用DMA2D)
' C" d# a: x5 P; e: z) @4 m8 x - * 参数 : LayerIndex:层选择0-1;sx,sy:开始坐标;ex,ey:结束坐标,ImageAddr:需要填充的图像地址
: m9 o/ S u% \+ k5 n - * 返回 : 无
2 M/ L% h; |+ k h* n3 f. a - * 依赖 : 底层宏定义
( `' _5 `$ `) j, ?2 Q& Q/ F k - * 作者 : <a href="mailto:cp1300@139.com">cp1300@139.com</a>
6 G/ M2 o* a# O+ b% i6 { - * 时间 : 2019-10-309 W% u5 R+ F: h- h- |
- * 最后修改时间 : 2019-10-308 w) k$ W" G- G' W( ^, m. U0 r
- * 说明 : 采用DMA2D实现,将源图像指定位置传输到现存,要求源图像与显存大小一致
* Q' l3 I' e5 g - *************************************************************************************************************************/* M8 Y% s3 s+ q; Z$ |+ D. z7 k# l" Z
- void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr)/ |. S; ~: I% M$ \: |* V
- {% X1 b3 O4 @) o' C' ^ A3 m' H/ [
- 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进行矩形图形填充% c s, u8 p4 ]9 ?7 \5 n
- DMA2D_WaitTransferComplete(500);+ [4 D: i" i' U+ p" b! s
- }
复制代码- /*************************************************************************************************************
3 L* D* Q6 ^- \ e4 h - * 文件名 : stm32f7_ltdc.h
' w" ?& `4 \; ?9 `, t. f - * 功能 : STM32F7 外部RGB LCD驱动$ U- z# e/ e9 p' A: D ]! n( ^
- * 作者 : <a href="mailto:cp1300@139.com">cp1300@139.com</a>6 O. U9 z8 k% A/ T( O) \
- * 创建时间 : 2019-09-12
; D6 |+ _+ @3 ~2 r. s - * 最后修改时间 : 2019-09-12
% G. L0 b% ~ \1 U5 P8 R - * 详细:
$ h0 o7 ?1 S, P, I2 x0 V; `+ S - *************************************************************************************************************/
: D1 n" ]; Q8 |+ U1 H - #ifndef __STM32F7_LTDC_H_
% I6 D3 |: J$ g6 f8 w& R1 o% w$ ~ - #define __STM32F7_LTDC_H_ 2 B! \8 V! a" T I% t$ N; O, c; P" [
- #include "system.h"( H0 E! h( L& n, O6 ^! h: \9 Q
- #include "DMA2D.h"8 V0 ~7 h' f/ M* t8 U
- ( `! u2 v. S4 [. _; O
- #define LTDC_WIDTH 4808 m6 N: ~' F$ K8 ?& X! C7 ?9 |
- #define LTDC_HEIGHT 272: q) Y4 m' t& A& r2 @
! s* T8 `' w+ D( u1 q
4 S, p* S/ m# e& i; y- extern u32 g_LTDC_BUFF_RGB888[2][LTDC_HEIGHT][LTDC_WIDTH];
( Z7 A" ^/ k' L
{8 U( P& }7 n8 X- //像素格式定义) m% H% g$ R6 ~. w* m: D
- typedef enum
$ ^. X# d# p# s! u, } Q1 p& v% S; s; W - {
$ g: B' v1 S! B" f$ X/ u( I7 d - LTDC_ARGB8888 = 0,; q. \1 ?" `7 v' B+ q
- LTDC_RGB888 = 1,5 x: z: T5 s. [& ]; K* v- }1 X: Y
- LTDC_RGB565 = 2,5 }& V) E0 c) Q, f u8 ^
- /*LTDC_ARGB1555 = 3,
# P4 W& Z- k% i+ f- L - LTDC_ARGB4444 = 4,
; K! j8 m3 {, s - LTDC_L8 = 5, //8 位 Luminance
3 ~/ D" ~7 D; x1 B - LTDC_AL44 = 6, //4 位 Alpha,4 位 Luminance
; R% D+ F1 W" P% H* m - LTDC_AL88 = 7, //8 位 Alpha,8 位 Luminance*/. h; p4 A9 }& X% o: k3 S
- }LTDC_PixelFormat;4 m5 n: y; d. {4 h: e1 h# n
- #define LTDC_PIXEL_FORMAT LTDC_ARGB8888 //选择ARGB8888格式
. _9 h, t. J# A! @0 }
$ D. j8 {, s8 ~2 B- / |! Y6 R% k- }
- 5 F9 N5 x' X& V; F
- : c1 |; O; N0 S0 r
- //画点函数32bit ARGB8888格式" A3 G( a" p- a$ g7 a
- __inline void LTDC_DrawPoint(u8 LayerIndex, u16 Xpos,u16 Ypos,u32 ARGB8888_Color) f& F s- d8 {
- {. U/ J) ]4 A! \ M6 @5 ^
- g_LTDC_BUFF_RGB888[LayerIndex][Ypos][Xpos] = ARGB8888_Color; A+ A5 E/ H" V
- }
6 |/ w6 p5 z4 v& O, [" B4 ?8 c - 2 k, ~6 r& q) @3 Y1 y
- //初始化DISP引脚( m1 U: }: o7 M" o
- __inline void LCD_DispIoInit(void)
9 |2 |, k J! o) a0 B6 x' U - {
' y" v5 t1 l1 ~, L4 |% o$ } - SYS_GPIOx_Init(GPIOI, BIT12, OUT_PP, SPEED_25M); //PI12 LCD_DISP H:正常模式;L:低功耗
: i, H2 U& R2 r4 w" ^& o - PIout(12) = 1; //DISP = H 2019-10-16:一直忽略将此引脚置为高电平,调试走了很多弯路
9 q H' m& ^ S8 X1 T, ~2 [ - }, o$ I, Y i2 y. @
2 _/ ?: K( U/ y6 y- void LTDC_Enable(bool Enable); //LTDC使能设置
+ K( S) q9 Y1 e/ ^6 m7 X- d$ k - void LTDC_Init(void); //LTDC 接口初始化8 v8 t9 R, e/ M% n. u: p
- void LTDC_SetLayerConfig(u8 LayerIndex,u16 sx,u16 sy,u16 width,u16 height, u32 FrameBuff, u8 Alpha);//LTDC 层窗口尺寸设置
3 y6 ~+ X1 f* {# a+ D9 m( Z - void LTDC_LayerEnable(u8 LayerIndex, bool Enable); //LTDC 层使能设置5 c( P7 G- Q( p5 |
- void LTDC_LayerRefreshConfig(void); //LTDC 刷新层配置(修改层配置后必须重新加载,否则不会生效)9 x: Y+ {+ _/ j3 n% _+ Z9 y
- : z- s# ]$ Y1 Y
- //图形相关API0 G& g+ j8 c& w+ h! l
- void LTDC_DrawPoint(u8 LayerIndex, u16 Xpos,u16 Ypos,u32 ARGB8888_Color); //画点函数32bit ARGB8888格式
# D( s! v+ u& y - void LTDC_Fill(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 color); //矩形填充(使用DMA2D)8 y( H: S9 N2 ]+ j( @! v! k7 N0 l
- void LTDC_Clear(u8 LayerIndex,u32 color); //清屏(使用DMA2D)
: N, C' c. i! ]6 e0 r! D1 @ - 2 E2 Y4 X, U- ]3 I6 b1 Q0 ^
- void LTDC_FillImageSamePosi(u8 LayerIndex,u16 sx, u16 sy,u16 ex,u16 ey,u32 ImageAddr);//矩形图像填充(相同坐标范围传输,要求源图像与目标显示器分辨率一致,使用DMA2D)
复制代码
. e4 T' ~" }+ @8 M
( `. i; w$ F& F& m#endif //__STM32F7_LTDC_H_
( v+ }6 m- G/ g( \6 ]/ b4 \
( i6 z( I/ |! {% T# v* v a6 T7 o
) ^- p# u. S! E0 k, O' ^6 S& _: {1 y9 @. W6 d0 I
|