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

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

[复制链接]
donatello1996 发布时间:2026-7-15 20:02
       最新的评测中有一个需求,需要用一块性价比高,RAM够大,支持快速刷屏的单片机开发板做图形显示,因此我这边选用手头现成的惠勤致远STM32H743VI开发板,并搭载一个并口的ST7796彩屏:
. ~7 A" [0 v& v6 ~ 1.jpg 2.jpg 3.jpg 4.jpg ) |8 M/ u$ g0 `3 J8 m/ N
4 ^4 m% Z+ F6 y7 _

2 R  y! f7 |% k3 ]4 _7 V- eSTM32H743VI使用FMC16位8080并口给ST7796彩屏发送数据和指令,并使用FMC自带的时钟线提供时钟信号,效率相比SPI_DMA是快很多的,整套设备的成本是120出头。$ I3 d  K: E' \( w, ?
要使用开发板移植LVGL,需要用官方例程里面的触摸屏实验例程:! {5 c  t( `, b" X0 J5 J
5.JPG ' z9 |* U8 `! q1 t; I8 O
: D& u- m& e* G

; D5 g3 C- J3 J, v5 f0 X其实就是要调通LCD刷入缓存和触摸坐标读取的功能:2 ?" t/ D+ S$ V  ?. o

  d* S6 ^. D$ {! M5 z7 mvoid FMCTFTLCD_ST7796_Fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t *color)
9 }9 o) U* t* V7 t- H: C{
  H( ]6 V+ |$ x  y    uint16_t height, width;* [. x' U6 h2 U$ E, u6 ?
    uint16_t i, j;    / @8 Y$ G9 {( B
   
7 q2 l4 N" o( i; p    width = ex - sx + 1;' g! q- Q, J4 @; b1 u$ Q/ C
    height = ey - sy + 1;
1 N3 k" a9 d) S! K$ @) ^% s1 O+ g; Z& d& @
    for (i = 0; i < height; i++)
: I) W" h" g/ |- S9 X; K+ b    {
; e* U0 Y( v# K7 H5 x$ O        lcd_set_cursor(sx, sy + i);
( X" g, b* p+ y" r, V2 X        lcd_write_ram_prepare();
1 Z: v" A& z' H1 h# H0 @6 N: i- ~6 |$ o% K
        for (j = 0; j < width; j++)' P# N4 f4 s6 b; a! a" o/ g
        {
" u5 Q7 a% }: E; X            LCD->LCD_RAM = color[i * width + j];: p  {0 L0 S+ F$ I  W1 S1 x
        }, X+ a. S, ], _9 f" s2 g
    }9 w$ R, w9 ~+ \& h" C( O  L  p
}
  x$ T2 n( Z0 h4 A
  n$ Z8 Q# |* @2 J8 @8 i2 j6 q

5 H  f' J9 ~* q) X+ ^
" h1 I+ Y- R. D* l3 b+ j

0 O7 g+ e5 U9 s

. ^. J3 {, E6 P4 m$ U8 E  u
9 s, d3 r9 J& L; R6 G8 wuint8_t tp_scan(uint8_t mode)
0 x5 x# v1 D0 q6 F- F7 U9 H7 R{* k4 G0 t/ s+ g' m2 C
    if (T_PEN == 0)     /* 有按键按下 */
$ z- V& d/ |3 [% I3 K4 M. U    {2 ~) u% E) Q2 k" s
        if (mode)       /* 读取物理坐标, 无需转换 */& l$ \& n( {# B* Z0 o
        {0 ?$ s" `, Z$ Z0 Z! }
            tp_read_xy2(&tp_dev.x[0], &tp_dev.y[0]);
! c" c; }0 s5 V- L: ~8 c$ ]        }
. I/ \1 S  [" i5 i4 E- y        else if (tp_read_xy2(&tp_dev.x[0], &tp_dev.y[0]))     /* 读取屏幕坐标, 需要转换 */% y9 H5 F8 l1 d9 V
        {
' e2 ?  g- ^2 Q  N$ S            /* 将X轴 物理坐标转换成逻辑坐标(即对应LCD屏幕上面的X坐标值) */" G1 C) C- n, _
            tp_dev.x[0] = (signed short)(tp_dev.x[0] - tp_dev.xc) / tp_dev.xfac + lcddev.width / 2;: D% B$ w% ]: B; d
& O, \7 v" C- [! a, A, q7 ]7 ^
            /* 将Y轴 物理坐标转换成逻辑坐标(即对应LCD屏幕上面的Y坐标值) */
3 n9 V( I3 k2 p( O' |            tp_dev.y[0] = (signed short)(tp_dev.y[0] - tp_dev.yc) / tp_dev.yfac + lcddev.height / 2;
$ k* e* @2 e5 L  g( g        }
' x6 y0 \) r+ G% N3 E2 {' [% u6 p- N: e6 A9 D: b( j* v
        if ((tp_dev.sta & TP_PRES_DOWN) == 0)   /* 之前没有被按下 */
& S% E' _3 d- d- f; A9 G        {
) r: o- Q4 B2 {& ~            tp_dev.sta = TP_PRES_DOWN | TP_CATH_PRES;   /* 按键按下 */
) t# h4 w5 v- w% f/ X5 h+ G  E9 j; V            tp_dev.x[CT_MAX_TOUCH - 1] = tp_dev.x[0];   /* 记录第一次按下时的坐标 */
# v$ s7 |/ g7 E& d# n9 j            tp_dev.y[CT_MAX_TOUCH - 1] = tp_dev.y[0];
& k# C# }% V! q7 ^6 _( U% h        }& |; ?( h- E9 }! V/ K# c  {
    }
: i( H0 J8 S, e$ ]! L3 K    else
! y7 B0 G, o2 O8 P    {& P& L* S+ a  \+ y5 R
        if (tp_dev.sta & TP_PRES_DOWN)      /* 之前是被按下的 */% e6 B- O5 V5 M
        {
/ r' u9 z& I- {            tp_dev.sta &= ~TP_PRES_DOWN;    /* 标记按键松开 */, h/ v6 c8 P) W; K. q6 B0 L
        }- C5 X+ f8 P5 g- F  J5 F
        else     /* 之前就没有被按下 */+ r7 a3 p. c/ y1 I7 o. h- G
        {+ Q0 @6 m, j+ e2 z  g
            tp_dev.x[CT_MAX_TOUCH - 1] = 0;
* V. `4 H  U4 R/ I            tp_dev.y[CT_MAX_TOUCH - 1] = 0;
5 s5 B' G6 n; L- |( w% u            tp_dev.x[0] = 0xffff;
. J% }9 }4 }* E( V3 q            tp_dev.y[0] = 0xffff;- L) P  x4 s7 ^- z) ?# j
        }, S9 M. A" m/ ?1 k- G+ E
    }
0 b  `$ a% y0 \: P3 [7 @  e9 {; M. d7 L. {! R8 m
    return tp_dev.sta & TP_PRES_DOWN; /* 返回当前的触屏状态 */1 `; d  s% |- z1 v4 u6 ~# Y( z
}
& Q/ t# t. t$ H2 s6 \( J. w/ W. f
- i9 K: h5 b9 v' c2 n
然后是从Github官网下载LVGL9.5:; j9 G/ `( m  K0 l; c/ Y
6.JPG 7.JPG 8.JPG 9.JPG 9 D5 [7 i7 r+ C; i/ l

0 z5 Y9 L/ o* r) h7 r( I6 H
/ ]" T1 j9 M) Q2 M' ]! x5 w: M
可以看出来,LVGL9.5相比起LVGL9.3,更新了很多内容,主目录有疑似Zephyr的更新,libs目录也加入了3dmaths和webp的支持,也就是后续可能支持3D图形算法和网页端应用,很让人期待!将LVGL9.5代码放进单片机工程,并依次添加支持文件即可:
" R0 x; R  j* l. w 10.JPG 7 l( z7 {$ W- T9 W8 A3 h- ~5 n, W

4 h  O$ `. v# r8 s6 F4 D' {

9 h+ X3 ]$ k+ u% g% L& o" }然后在port_disp文件中添加局部刷新机制,经常移植LVGL的对此应该会很熟练了:
' X6 d, U. |6 h. j" ^1 b( E, r. z 11.JPG # l# v7 z8 S& n

7 ?1 W& F0 J3 g# \7 pextern void FMCTFTLCD_ST7796_Fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t *color);) j% `5 M. ?$ Q0 w8 N! T3 ?$ a
9 w; H7 P8 b( L, ?. e
static void disp_flush(lv_display_t * disp_drv, const lv_area_t * area, uint8_t * px_map)/ r* U+ R; ^9 p# ], R0 W- Y
{
5 r3 k8 x0 T8 _+ @3 I( H3 ]/ e( ]    if(disp_flush_enabled)
9 t) r8 J! i& \% y3 m                {3 c1 Y2 h" l8 H$ t0 f
      int32_t x;7 D" C) W1 W& K& s' P; Q3 q; t
      int32_t y;; t" m& Q' \0 Z7 B2 \+ f
                        FMCTFTLCD_ST7796_Fill(area->x1 , area->y1 , area->x2 , area->y2 , px_map);" `6 y' ]8 N" N" \0 g# Y
//        for(y = area->y1; y <= area->y2; y++)
: k7 V7 M2 s9 H& Z9 f6 H//                                {
  z! D, `2 c: E/ A. F) y4 _# y//            for(x = area->x1; x <= area->x2; x++)
$ ?) g2 S1 {6 N1 c; P//                                                {
& @5 R* }- `8 R& b//                px_map++;' U6 F! v  c$ f! N8 }* b7 v
//            }8 C9 r  H. D! C% O
//        }
% u0 o: n3 Y" ?! J    }
! z3 `7 N, @# i+ O4 T- J6 R+ S" G  T
    /*IMPORTANT!!!/ j9 s( T) S+ j  V
     *Inform the graphics library that you are ready with the flushing*/" [% o4 H4 k/ @% M7 C
    lv_display_flush_ready(disp_drv);3 {  t! B% ]: ~. E2 e& K  R9 U
}
" w/ w6 A2 [! k! k, s% N. B
/ I0 ]$ g7 j  }5 Q' `# @& l$ d

- x# P+ {- O1 b# s在indev_disp文件中添加触摸的支持:- @3 e/ K. x; Y3 k
12.JPG
% |0 u3 B: b/ }8 ^; m6 I8 m6 U0 _
0 q8 E1 i1 n! ?9 Sstatic bool touchpad_is_pressed(void)
$ @( J7 X9 p4 A8 J{
: v. n# V. h5 J* h, |/ R                tp_dev.scan(0);) P0 P! n# r! W! ^$ L# R" f
                if (tp_dev.sta && tp_dev.x[0] < 320 && tp_dev.y[0] < 480)7 {7 p# l. k3 P
                {
( c1 B' [; J) i" x9 f# u  m  d                        //printf("%d %d.\n" , tp_dev.x[0] , tp_dev.y[0]);& I" k+ V. h' x/ W2 Q
                        return true;
2 x0 J' X& ?* O8 d/ T; t% }                }$ ~7 u* }) p; ^8 U" [( _3 [; I4 m
    return false;7 f- @' J8 J8 c- k+ q/ w
}! s* ^3 F. ?$ h
- c+ i6 ~" X4 D$ @
/*Get the x and y coordinates if the touchpad is pressed*/
7 w. b, p7 ^/ b" _2 H" t1 Z+ Dstatic void touchpad_get_xy(int32_t * x, int32_t * y)
. K- c1 `& S5 i% n, d& R' U{
$ n9 A' Q6 N/ ]- |2 f5 p    /*Your code comes here*/
0 u# }; _' Z$ ^
6 ]6 l) u1 ^  O1 \& x( _    (*x) = tp_dev.x[0];
* `) r, I0 w0 a* `& i# b    (*y) = tp_dev.y[0];: f. [/ Q6 m" ^8 b4 X' f5 b
}9 |( u* A% p+ i; c* r. D

5 v9 c# Z4 Y1 M搞定,然后看看刷屏效果:
# g6 m, ~) e  q' {# g" o2 T3 G
& [; ~) j8 Y3 S* l可以看出来,使用FMC并口来刷屏,效果还是很丝滑顺畅的,可以满足图形化界面显示要求。0 Q0 G2 M9 W. K( y! f. {

( s8 v( j  q! o/ |$ K! g( Z

1 V1 H7 ]$ V- s" @* E/ L' y然后是一些额外的内容,对DMA MEM2MEM机制的尝试,我们知道FMC刷屏其实也是对RAM(GRAM显存)进行操作,因此理论上可以用DMA MEM2MEM机制来实现对刷屏的加速(并非DMA2D,DMA2D是针对LTDC接口的屏幕),参考野火H743挑战者例程:
6 |& C* l/ u7 n$ a, I. f 13.JPG 14.JPG 15.JPG
) k$ ?: n7 m$ p' r6 B$ D野火H743挑战者例程DMA MEM2MEM例程里面,对aDST_Buffer是限定了0x30000000即SRAM1区域的地址进行分配,但实际上,使用%p打印出来,地址并不在这个范围里,还是在0x2000000的DTCM和0x24000000的用户RAM区域中。/ ~8 }4 t  X( i9 B2 |8 h9 g6 T4 ?$ ?

/ f" g5 A" \. S0 x, [

% V' c; o: V! P8 Q. i* S使用这个例程移植到我自己的LVGL例程中,DMA MEM2MEM也不能正常工作,原因未知,还在探索中。. K  V+ I9 M" h1 L9 r* z( q& m

0 E9 ?; _! E: s8 i( s" Q. \5 H, M
% ^2 w/ ~, a& z7 P) X
赞 收藏 评论0 发布时间:2026-7-15 20:02

举报

0个回答

所属标签

相似技术帖

官网相关资源

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