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

【福利三:逢7发帖赢大礼】使用惠勤致远STM32H743VI开发板+ST7796并口彩屏移植LVGL9.5并分享一些额外内容

[复制链接]
donatello1996 发布时间:2026-7-15 20:02
       最新的评测中有一个需求,需要用一块性价比高,RAM够大,支持快速刷屏的单片机开发板做图形显示,因此我这边选用手头现成的惠勤致远STM32H743VI开发板,并搭载一个并口的ST7796彩屏:$ e- T0 f+ w3 ~. h+ O0 V
1.jpg 2.jpg 3.jpg 4.jpg
2 L' I* s8 g( ?/ ]$ b
9 j4 D1 {" B9 I
6 S7 N$ {( y& J6 a7 L' R
STM32H743VI使用FMC16位8080并口给ST7796彩屏发送数据和指令,并使用FMC自带的时钟线提供时钟信号,效率相比SPI_DMA是快很多的,整套设备的成本是120出头。5 C: u4 P- r' o7 X
要使用开发板移植LVGL,需要用官方例程里面的触摸屏实验例程:
- s7 D7 p8 K. ?( ?1 g 5.JPG 8 L& m5 H: t' D/ f3 ~

3 m( K- `4 @1 b6 J4 }# T

5 }0 n  p% i2 n5 Q: u. Y6 K  _6 u5 u其实就是要调通LCD刷入缓存和触摸坐标读取的功能:
9 o/ K9 F, N6 b& B$ [
# h7 d% u% ?$ k5 [( @  P+ Rvoid FMCTFTLCD_ST7796_Fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t *color)
, z9 V* i. \3 J% u  b& o{
; `) ~2 U2 M# ~' y! i    uint16_t height, width;
% t  K8 R! V9 m3 B    uint16_t i, j;    ' L9 a" {6 J* c3 b
    ) I2 X+ Q0 R1 Q- ]! k
    width = ex - sx + 1;) O+ Q+ y1 `5 U$ `5 X* B) y
    height = ey - sy + 1;
* I: n8 Z+ @4 b' u/ r, `2 \6 V$ E" x4 ?* z$ F% A
    for (i = 0; i < height; i++)
+ U) O% }1 \" H6 `  o  h6 o7 p- q    {- ^0 @: N* \' I* i- Y
        lcd_set_cursor(sx, sy + i);
% p6 i- ^( ]6 W+ L3 Q        lcd_write_ram_prepare();- T) z7 w6 i3 l

' d+ x8 N! x; V1 R$ g        for (j = 0; j < width; j++)
' i8 M4 d6 r* G/ [0 O. l2 \# O        {
3 N! a9 T  K, Q# h            LCD->LCD_RAM = color[i * width + j];
* ~2 K) E2 Y, m& ^        }$ p3 ^; K$ N! k& G- w# |2 b
    }5 O6 Q7 H) ~; k3 Q
}" g) [* T) G7 [) o3 Z0 X7 z

7 Z9 g# ?/ R$ z. U0 E6 T2 Y4 u6 u% L0 Y6 v& |2 S/ v: b
+ Z3 N) Z% o7 r: x- T

; _& r6 d' w' }. i

; j! V* d% P! E  Y( k# A& U
! v+ F1 T: p2 ?: nuint8_t tp_scan(uint8_t mode)
& B+ f* C* V9 q! C{- A+ a$ ?, W. p" B: B+ I# B
    if (T_PEN == 0)     /* 有按键按下 */
- Z- m2 P+ R1 @" A3 s    {
; w; f+ o- Z  T( z* ^. ?        if (mode)       /* 读取物理坐标, 无需转换 */* e; c) D% F9 ], I5 D( C
        {2 j- c8 D: \2 N5 [4 v7 m" a& p2 [9 }
            tp_read_xy2(&tp_dev.x[0], &tp_dev.y[0]);" N( v0 N2 u! l/ T/ N
        }
. Q7 m6 m& ]2 [, o$ [9 l: }9 s        else if (tp_read_xy2(&tp_dev.x[0], &tp_dev.y[0]))     /* 读取屏幕坐标, 需要转换 */
, h1 q0 H; a! f. C5 \        {
( q1 ?1 a4 @& h3 U$ m  N8 ]: _            /* 将X轴 物理坐标转换成逻辑坐标(即对应LCD屏幕上面的X坐标值) */  Q0 E; D, ?; R2 A7 m
            tp_dev.x[0] = (signed short)(tp_dev.x[0] - tp_dev.xc) / tp_dev.xfac + lcddev.width / 2;5 f- S) s  P* F& ^& r

4 \: N" r* \" q% y/ c! n4 R8 s7 U4 H" X            /* 将Y轴 物理坐标转换成逻辑坐标(即对应LCD屏幕上面的Y坐标值) */" ^. \) f- g, z* }3 _
            tp_dev.y[0] = (signed short)(tp_dev.y[0] - tp_dev.yc) / tp_dev.yfac + lcddev.height / 2;* ~- B; L6 _' B; N3 I" r
        }2 B- {( E% ~2 M% G, T

4 F$ e0 [' B; R8 X+ n% ?        if ((tp_dev.sta & TP_PRES_DOWN) == 0)   /* 之前没有被按下 */( z: t3 ~, i  g, J7 X; ~- Q! H7 Z
        {! j0 r& @+ C) ]0 {+ B: B3 k$ U" w1 k7 B
            tp_dev.sta = TP_PRES_DOWN | TP_CATH_PRES;   /* 按键按下 */3 H3 v2 \, Q7 \. n
            tp_dev.x[CT_MAX_TOUCH - 1] = tp_dev.x[0];   /* 记录第一次按下时的坐标 */* \1 y# o! b: W  q
            tp_dev.y[CT_MAX_TOUCH - 1] = tp_dev.y[0];
. t  n; I' @: O4 i        }
; ]1 d6 f6 @4 r6 q7 H* Z/ k& y; a    }% P" w( i4 F, j  D2 S0 }
    else
. @# T+ a4 f  X" r) O    {
+ L6 l) x& y! j. Q" G        if (tp_dev.sta & TP_PRES_DOWN)      /* 之前是被按下的 */
3 G7 @% m6 ^( y  }' _3 G        {
+ I# ]4 c1 q3 h9 [! d6 b, \6 s            tp_dev.sta &= ~TP_PRES_DOWN;    /* 标记按键松开 */1 _3 {% |* u& l$ [9 v+ k
        }
* T7 J- [  E' J( j* ~/ q$ \        else     /* 之前就没有被按下 */
& J5 Y& V5 |9 B/ q7 i        {2 E2 B( ~* V$ f
            tp_dev.x[CT_MAX_TOUCH - 1] = 0;, s3 u9 |& D( d+ X9 H4 i
            tp_dev.y[CT_MAX_TOUCH - 1] = 0;% P+ C. S7 r0 T
            tp_dev.x[0] = 0xffff;( ~4 W4 t+ `% C% q; m% i7 L
            tp_dev.y[0] = 0xffff;( q, o7 ?5 O3 z
        }0 C" t0 K0 g! e& ]+ G  i: O% ^
    }
6 ]1 Q. m- ^6 h& a; d$ b3 D6 a4 g& z7 y9 o4 k) h
    return tp_dev.sta & TP_PRES_DOWN; /* 返回当前的触屏状态 */
% z% L9 b% Y  J- `}/ ?9 i1 r/ a& L: n1 w7 x% ~

1 N' y1 R/ W( z! ]5 |2 Y6 x然后是从Github官网下载LVGL9.5:
4 J+ _: Y* q! c8 V 6.JPG 7.JPG 8.JPG 9.JPG
4 p% U) \8 W* |% ?' ~) ]( k0 y, q1 z* V+ U8 ]

! Y# @6 p8 d+ r! x可以看出来,LVGL9.5相比起LVGL9.3,更新了很多内容,主目录有疑似Zephyr的更新,libs目录也加入了3dmaths和webp的支持,也就是后续可能支持3D图形算法和网页端应用,很让人期待!将LVGL9.5代码放进单片机工程,并依次添加支持文件即可:/ y$ z- ?- w8 x: J3 k, n- A
10.JPG 1 x* U+ o# e# ]2 Q
3 j& r" u5 j( E# A( I2 k

5 U" F, B+ Q( C$ V  J" R6 z然后在port_disp文件中添加局部刷新机制,经常移植LVGL的对此应该会很熟练了:
+ I. X! i8 Q/ ?1 i# |9 b8 @ 11.JPG
9 Z. F" R  _/ H. L) c) W
9 \0 w& [5 v; bextern void FMCTFTLCD_ST7796_Fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t *color);
! c4 |6 c# Y& }# q! I4 O
( j, r/ l: Z6 z. m9 M+ Cstatic void disp_flush(lv_display_t * disp_drv, const lv_area_t * area, uint8_t * px_map)
7 @/ _9 K" L) G3 h& ~' z{
. q8 ]( I% e5 ~0 _( G    if(disp_flush_enabled)
. O" U6 Z3 x; v                {8 H7 w$ P  p- u, J) J& f  ?
      int32_t x;# a2 c" A" C, o& w
      int32_t y;# J. W( ^  S( ^. Z7 D
                        FMCTFTLCD_ST7796_Fill(area->x1 , area->y1 , area->x2 , area->y2 , px_map);7 y0 l5 f1 @# N3 G1 n+ T
//        for(y = area->y1; y <= area->y2; y++) , \5 V9 O, ]* e" k
//                                {7 z) u, @1 q! A5 Q% q% Z
//            for(x = area->x1; x <= area->x2; x++) 1 T% ]. X5 i9 r! w3 P
//                                                {
' I, b* u: d! G! `0 `6 l//                px_map++;( S: }& }5 d/ ~9 E+ ?
//            }; r% X; Z9 f, P0 \" W) C; |
//        }$ j- p. F. a; x4 d$ a4 P# L3 \: X  c
    }
. ]/ x  Q1 V6 Q) ?# |# `4 T3 I
  p6 ^/ }0 P8 G3 ~+ Q9 ?6 [    /*IMPORTANT!!!7 a/ B/ M1 i. |$ g, O  b& F; y
     *Inform the graphics library that you are ready with the flushing*/
4 N# O; K' ^. i+ a" R1 V0 o  v    lv_display_flush_ready(disp_drv);
( y* @" ~2 {6 ?}7 e& ?( q8 h, r
# ^: q0 ~1 O/ @
% C/ l8 V- |$ v0 L- \
在indev_disp文件中添加触摸的支持:
, x  @2 }! c! w" N" A5 e3 K% v" H 12.JPG ; o/ F3 C/ M9 C: w9 }& ]/ a
* \  s6 A) t7 c: ^/ _
static bool touchpad_is_pressed(void)
) {* R' z3 J% H5 a  M& A% x8 W{
3 V, e$ \4 ^+ C# Z: J/ O! @                tp_dev.scan(0);
; F: R- C0 K( b, G                if (tp_dev.sta && tp_dev.x[0] < 320 && tp_dev.y[0] < 480)# w4 @1 F, d0 L/ }/ I( D
                {/ U8 D; o6 l, F$ _$ k; l, q; D
                        //printf("%d %d.\n" , tp_dev.x[0] , tp_dev.y[0]);1 t3 l- y8 X) A* X* r! h& b
                        return true;5 w3 \3 }* B3 i9 g5 y. |, E
                }3 j& }0 p4 a, P- l
    return false;4 V) `7 i4 i0 J; F6 U$ h
}, [+ O- j: k5 D# }9 s5 m  h
) ~% t/ ]( R' M* d  V& h
/*Get the x and y coordinates if the touchpad is pressed*/
" X7 \- }4 `) ~4 Jstatic void touchpad_get_xy(int32_t * x, int32_t * y)
: S2 t/ d. o  F$ j{) @' J' Z# h' H9 g. [
    /*Your code comes here*/2 l. |. D2 L7 u% G7 p1 O
9 Y) ~0 e# m7 X8 a% K: k
    (*x) = tp_dev.x[0];8 i4 C5 a- G7 x7 |1 h
    (*y) = tp_dev.y[0];
6 f+ X1 B3 a$ J- l}8 u9 x% r5 S8 M3 h+ _
, ^# d6 ~# `. d2 x  y4 T
搞定,然后看看刷屏效果:, S$ Z0 T/ g" z* ~+ C1 X( I$ c7 P
* ^1 J2 P. D# v! ?- h  _$ n! Y! K
可以看出来,使用FMC并口来刷屏,效果还是很丝滑顺畅的,可以满足图形化界面显示要求。
2 E" P+ @+ t! M# b! C' C
% x* D1 R+ ]/ R% V' I* X6 p
( j" s9 v! L; Y+ T- Y# O8 p
然后是一些额外的内容,对DMA MEM2MEM机制的尝试,我们知道FMC刷屏其实也是对RAM(GRAM显存)进行操作,因此理论上可以用DMA MEM2MEM机制来实现对刷屏的加速(并非DMA2D,DMA2D是针对LTDC接口的屏幕),参考野火H743挑战者例程:" d3 c& T# l; ?' M& l5 T) a! |4 o
13.JPG 14.JPG 15.JPG
( @! y. W4 e6 k+ n+ }  f& [1 K野火H743挑战者例程DMA MEM2MEM例程里面,对aDST_Buffer是限定了0x30000000即SRAM1区域的地址进行分配,但实际上,使用%p打印出来,地址并不在这个范围里,还是在0x2000000的DTCM和0x24000000的用户RAM区域中。
1 b& _5 k/ Y! ?+ z5 z. s( u0 _- i2 Y" g! A3 v( w5 Q
' b" t$ m1 l! o7 H0 Q, A5 N
使用这个例程移植到我自己的LVGL例程中,DMA MEM2MEM也不能正常工作,原因未知,还在探索中。
3 j( Y" Q" t* W' A
8 \. `( {3 S1 @0 A2 [8 {! R5 V9 e, T& y! H2 P5 x
赞 收藏 评论0 发布时间:2026-7-15 20:02

举报

0个回答

所属标签

相似技术帖

官网相关资源

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