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

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

[复制链接]
donatello1996 发布时间:2026-7-15 20:02
       最新的评测中有一个需求,需要用一块性价比高,RAM够大,支持快速刷屏的单片机开发板做图形显示,因此我这边选用手头现成的惠勤致远STM32H743VI开发板,并搭载一个并口的ST7796彩屏:
, y! K1 E* m& k2 Q3 ^, n 1.jpg 2.jpg 3.jpg 4.jpg 2 ], f, R3 D4 M! d* I8 B
0 q/ L: P/ p  J/ M
* Y' m6 {' ]& E
STM32H743VI使用FMC16位8080并口给ST7796彩屏发送数据和指令,并使用FMC自带的时钟线提供时钟信号,效率相比SPI_DMA是快很多的,整套设备的成本是120出头。
9 |, \$ {( o" X# u' @5 @7 |. r要使用开发板移植LVGL,需要用官方例程里面的触摸屏实验例程:9 }- v- ~. ^! w) T3 G0 q: G! k
5.JPG
# f5 s$ Y# ]5 @7 C1 M$ r! M  O7 L6 d: w6 I% ^

) a# A" m4 [  O( r其实就是要调通LCD刷入缓存和触摸坐标读取的功能:
' M9 T' b: P* I  D1 M
+ n5 l. ^6 p3 ~2 Z& a- ?void FMCTFTLCD_ST7796_Fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t *color)
" |) `8 w' r% c{
0 H' q0 B. a2 Z  J# U5 ?- B    uint16_t height, width;
: {0 G! H  b* S5 S/ c    uint16_t i, j;    ; ~5 J7 k% h; t/ M
   
5 @* A( p: _9 G6 x$ k7 s    width = ex - sx + 1;9 d3 y7 u+ w9 i0 x0 P' W$ `# ~
    height = ey - sy + 1;
# `: j+ \, u& k! j0 z9 q( b4 _5 l4 l' e' p8 U
    for (i = 0; i < height; i++)
# b5 u5 t6 b9 e+ f. Z4 U" n6 X% i    {, R. e8 a+ }2 E: F9 @5 |
        lcd_set_cursor(sx, sy + i);. p, ^  c; G3 z3 N0 J6 u! o
        lcd_write_ram_prepare();2 S/ N4 W$ }" M$ x* V
, @, I0 s+ W! a/ }: @
        for (j = 0; j < width; j++)
4 O8 i- L; z3 r* _        {
+ |; p& Q/ r+ O8 U% y) t            LCD->LCD_RAM = color[i * width + j];0 [& g& q' y# L. b! }7 M* {- s
        }
/ `  I( d3 J) u! o* b/ V( j8 P" A. \; l+ `    }
! U. {: U6 n$ l$ n- F7 E$ q}& b) ~/ b4 Z: Y8 E6 x$ `
/ }7 I: t+ R; J% b# L3 J; ]
' H: {9 n0 J' T
8 U. _7 D; |: s" V$ K
8 j. }3 J# n( N$ M8 N) z& t

) H: x; K  l$ `1 n4 I
* {" c. O% t- i/ S% n$ yuint8_t tp_scan(uint8_t mode)
6 p; U( r$ v+ @$ O{
8 a0 ~2 J) k1 l% d5 `5 U; X    if (T_PEN == 0)     /* 有按键按下 */
7 X: a7 A; G2 n' ~4 H! T( H    {
3 a) S7 d8 B% Z# @) y. h( x        if (mode)       /* 读取物理坐标, 无需转换 */8 k% p5 L1 y) P4 R# b
        {  `  f' ?: h: m- C4 l
            tp_read_xy2(&tp_dev.x[0], &tp_dev.y[0]);( g6 x; L3 y) k2 L" S( t
        }  o& r& F6 H' `
        else if (tp_read_xy2(&tp_dev.x[0], &tp_dev.y[0]))     /* 读取屏幕坐标, 需要转换 */$ R6 d) c4 L! |  y+ ~" ?4 W1 p* R
        {# }. r* E; Q' g- U$ ~5 ?
            /* 将X轴 物理坐标转换成逻辑坐标(即对应LCD屏幕上面的X坐标值) */
, j8 W0 @. q- p- f) U            tp_dev.x[0] = (signed short)(tp_dev.x[0] - tp_dev.xc) / tp_dev.xfac + lcddev.width / 2;$ H2 F* K; ~: v  b! Y

1 p% o; p5 S* r% x  p            /* 将Y轴 物理坐标转换成逻辑坐标(即对应LCD屏幕上面的Y坐标值) */8 ?( s9 R( G2 s/ |9 K( [
            tp_dev.y[0] = (signed short)(tp_dev.y[0] - tp_dev.yc) / tp_dev.yfac + lcddev.height / 2;" j' v& i  B2 E1 O. `9 N
        }, A/ \& e! q" G& M
0 I5 ~: Z5 i; j5 [
        if ((tp_dev.sta & TP_PRES_DOWN) == 0)   /* 之前没有被按下 */
5 ~, I5 j8 g6 E/ R/ M5 l$ r        {
: {; U& }& p* i/ |  p8 G            tp_dev.sta = TP_PRES_DOWN | TP_CATH_PRES;   /* 按键按下 */
/ f4 ?. x: C7 p1 P5 A5 p            tp_dev.x[CT_MAX_TOUCH - 1] = tp_dev.x[0];   /* 记录第一次按下时的坐标 */6 p% s% a  S' Z1 i( p, \
            tp_dev.y[CT_MAX_TOUCH - 1] = tp_dev.y[0];
3 m3 E( x) ?9 X9 j; _; e8 X        }
/ f) g! ~  m4 ?" z& b    }* d: N0 a% q% E2 i* N! l: d5 n4 {
    else
8 g2 Y* K' U( N: X    {5 a8 W6 @- Q2 [! X$ `
        if (tp_dev.sta & TP_PRES_DOWN)      /* 之前是被按下的 */
$ ]" D: C" A4 X5 Q0 c4 w2 P/ d        {
4 [1 t$ x4 U1 g( W) x! M3 o            tp_dev.sta &= ~TP_PRES_DOWN;    /* 标记按键松开 */  w  M! D  S. g& [2 t7 s
        }
7 g: P' u  [  u0 e/ ?5 e        else     /* 之前就没有被按下 */) R8 G* [/ q- a& p9 u! a. R! D
        {
0 o, _3 s- M  x& N8 B            tp_dev.x[CT_MAX_TOUCH - 1] = 0;1 i# G* k9 {- T% p1 V/ b' ~
            tp_dev.y[CT_MAX_TOUCH - 1] = 0;/ A' b# N5 i" ]& y
            tp_dev.x[0] = 0xffff;6 H, A0 d9 U) w6 R; L+ O1 f
            tp_dev.y[0] = 0xffff;
" y" Q  ~7 y7 E" e6 ?- r4 i0 S) `- R        }
8 _7 Y& e8 E7 U% Y, @; h  g, ^    }% Z; I4 H0 l6 `7 N6 Z- }, |! W

) E4 h3 Q5 I$ A    return tp_dev.sta & TP_PRES_DOWN; /* 返回当前的触屏状态 */
" R* W/ s& |3 T+ k+ R}3 T8 |  @  {. O8 ~# I- V

  s7 o0 Q' ^) f5 z% I- l然后是从Github官网下载LVGL9.5:% y. w8 o: f$ |* @' s4 `" R
6.JPG 7.JPG 8.JPG 9.JPG & q4 K" g" f' d# s
3 K2 B$ j  O, X$ w5 }9 U+ ^

5 m- P0 i0 }; Y% Y: H( k0 f可以看出来,LVGL9.5相比起LVGL9.3,更新了很多内容,主目录有疑似Zephyr的更新,libs目录也加入了3dmaths和webp的支持,也就是后续可能支持3D图形算法和网页端应用,很让人期待!将LVGL9.5代码放进单片机工程,并依次添加支持文件即可:3 X; d6 p  H* x5 _" D/ \; H- e
10.JPG
  @( [) V* M% c$ X4 D! M5 Z5 f% `' g5 N  o- V

1 }1 K4 A2 I! e" `* T然后在port_disp文件中添加局部刷新机制,经常移植LVGL的对此应该会很熟练了:
, J. x# H4 ^* w4 \ 11.JPG 9 r. k: d$ ?' }+ c

) {4 D  D9 ^5 e! X- nextern void FMCTFTLCD_ST7796_Fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t *color);
/ S+ y6 ]- }- Q/ ~1 e. u1 W
" F. ^. z$ e) k! m4 K& Z3 V+ e+ Zstatic void disp_flush(lv_display_t * disp_drv, const lv_area_t * area, uint8_t * px_map). Y8 k! r- L0 b
{
* `% X9 b( N% D% f7 A4 F    if(disp_flush_enabled)
/ a+ }3 k( F/ w, L3 E  l- u                {
$ b0 d2 {% N) y7 `& U  p( d9 }      int32_t x;
2 ^- S# \- y+ q" G# K      int32_t y;' A% T: p( d- O
                        FMCTFTLCD_ST7796_Fill(area->x1 , area->y1 , area->x2 , area->y2 , px_map);
: C5 }" X& g. \( V( N5 B  ^//        for(y = area->y1; y <= area->y2; y++) & l+ O7 \7 [, u2 e; v  N9 a
//                                {# O: {+ f" s* \7 v, Q" F0 e
//            for(x = area->x1; x <= area->x2; x++) 9 M/ u! q7 ?; J9 G& T$ u
//                                                {0 x" G; `$ M4 P+ `  X% S" e0 k9 }
//                px_map++;
$ T6 L& j9 U) ]" Q# C//            }1 ?/ p8 B8 R  v2 X2 K
//        }
2 o7 `* K- Q6 f% b    }
, }* Z* I, \. T) v3 H4 @
" ^# |) {) M4 V    /*IMPORTANT!!!/ B3 @) u8 R6 p; Y' N
     *Inform the graphics library that you are ready with the flushing*/
( r: A% e! }; Z2 Z5 _    lv_display_flush_ready(disp_drv);
. O  V- W# {: H+ @' m5 H}2 y$ o; I4 x6 {6 a

- o& y7 \4 E) v1 Z2 `# j7 }

2 t. P% }# @; I0 e2 F! S0 X& z在indev_disp文件中添加触摸的支持:
1 [) Z' a, i. I  o7 G 12.JPG
9 w6 F7 p  j; H( ^/ K9 h6 m+ c. j- ^3 ?2 Q( q; \: o1 z& ?
static bool touchpad_is_pressed(void)
$ \" x! f- x: B( s4 e. V{8 v7 G' A  w7 j9 z* e# d7 r
                tp_dev.scan(0);
9 U1 k' P, m* ~                if (tp_dev.sta && tp_dev.x[0] < 320 && tp_dev.y[0] < 480)8 X1 {0 H0 s. m- Z) \, D2 H
                {% G" s7 k  s: G
                        //printf("%d %d.\n" , tp_dev.x[0] , tp_dev.y[0]);
3 v& S* b) ]) T5 Y- w! E1 @                        return true;7 q  [: N! G4 s( v, }
                }
, ^9 v3 T. D7 W. n6 D( z$ f! ~    return false;. t% Y  |. N1 n1 _/ M3 q
}- O2 T, ~0 Y/ O) a2 k
, B. _' j' |$ E' D
/*Get the x and y coordinates if the touchpad is pressed*/
$ L, {0 @8 U* ?" w' [0 Xstatic void touchpad_get_xy(int32_t * x, int32_t * y)/ U5 P( h9 w9 q# D
{" y! K- {) q" R, ]" s/ d
    /*Your code comes here*/; k* g$ Q3 L; M+ |- x/ M
% t' V  i+ S/ X" M7 ]7 {: y
    (*x) = tp_dev.x[0];
8 W) T1 ^4 R; |+ K    (*y) = tp_dev.y[0];- S  L4 l2 E% I1 q9 Q! Y
}
  \5 i7 N! D- S* m

) ^2 x" \5 {3 V( ~# u5 b+ p搞定,然后看看刷屏效果:8 q+ Q2 B9 {0 f' S
+ t# O; v: S+ @: @* l
可以看出来,使用FMC并口来刷屏,效果还是很丝滑顺畅的,可以满足图形化界面显示要求。
; I/ l' i( e# N- n0 g6 A: w! r% v6 V

# z6 H  _) R* w$ i+ _4 ?9 [, q0 N然后是一些额外的内容,对DMA MEM2MEM机制的尝试,我们知道FMC刷屏其实也是对RAM(GRAM显存)进行操作,因此理论上可以用DMA MEM2MEM机制来实现对刷屏的加速(并非DMA2D,DMA2D是针对LTDC接口的屏幕),参考野火H743挑战者例程:+ V  @8 A4 _. X5 s, U
13.JPG 14.JPG 15.JPG ( K/ E/ |% [0 L  i  u
野火H743挑战者例程DMA MEM2MEM例程里面,对aDST_Buffer是限定了0x30000000即SRAM1区域的地址进行分配,但实际上,使用%p打印出来,地址并不在这个范围里,还是在0x2000000的DTCM和0x24000000的用户RAM区域中。
+ m( ^" T4 \- F9 p4 k3 K/ k. F
/ G1 x- U' O/ F. y: V$ B: K
$ a1 o- V; t6 ~" B! C  b
使用这个例程移植到我自己的LVGL例程中,DMA MEM2MEM也不能正常工作,原因未知,还在探索中。  b, K4 o$ ]' J; ?/ n
0 }0 x( f7 z4 K# j  B! i

7 J" ?4 H/ {3 l( }
收藏 评论0 发布时间:2026-7-15 20:02

举报

0个回答

所属标签

相似技术帖

官网相关资源

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