最新的评测中有一个需求,需要用一块性价比高,RAM够大,支持快速刷屏的单片机开发板做图形显示,因此我这边选用手头现成的惠勤致远STM32H743VI开发板,并搭载一个并口的ST7796彩屏:: p2 Y+ ?, @ s. \
" b! B6 l S% W STM32H743VI使用FMC16位8080并口给ST7796彩屏发送数据和指令,并使用FMC自带的时钟线提供时钟信号,效率相比SPI_DMA是快很多的,整套设备的成本是120出头。1 M8 X. e' w, z$ V1 @ K 要使用开发板移植LVGL,需要用官方例程里面的触摸屏实验例程:
* Z \ M% n9 @( l . G ~: n, D7 Z' h( H 其实就是要调通LCD刷入缓存和触摸坐标读取的功能: void FMCTFTLCD_ST7796_Fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t *color)8 N& F" ` g0 q$ }6 w7 a {6 T9 u; W0 c- p& s; h uint16_t height, width;$ f/ c, G9 X, ~) {9 i' Q% l5 j8 N uint16_t i, j; + @+ s& i% ~) j. j/ \ width = ex - sx + 1; height = ey - sy + 1;" }2 ~& v1 a- r9 ~ for (i = 0; i < height; i++)' R" W3 `1 T- a0 Z" r' H4 W { lcd_set_cursor(sx, sy + i);) N: h5 q1 k0 a9 I3 a lcd_write_ram_prepare(); for (j = 0; j < width; j++) { LCD->LCD_RAM = color[i * width + j];9 T7 j# ] ~4 Z' z } } }3 j* |5 N( N% R1 j" h1 e+ t$ P : ?1 O! y, D* g( ] " K4 G( `! Q! ] : M: h4 F& ]# `% G! J . `, e, m* m$ C* c uint8_t tp_scan(uint8_t mode) { if (T_PEN == 0) /* 有按键按下 */6 N4 i" _" O; G, S' f$ Q4 S { if (mode) /* 读取物理坐标, 无需转换 */ {# f' j* [7 Z( }" N; W2 S7 K- J2 u tp_read_xy2(&tp_dev.x[0], &tp_dev.y[0]); } else if (tp_read_xy2(&tp_dev.x[0], &tp_dev.y[0])) /* 读取屏幕坐标, 需要转换 */2 }; U0 }: g2 Z/ i { /* 将X轴 物理坐标转换成逻辑坐标(即对应LCD屏幕上面的X坐标值) */$ R: k l* C7 w& V7 G tp_dev.x[0] = (signed short)(tp_dev.x[0] - tp_dev.xc) / tp_dev.xfac + lcddev.width / 2;& q( X0 }# Q& k) Z* ^( k 9 q0 F" v& q% u' W9 c /* 将Y轴 物理坐标转换成逻辑坐标(即对应LCD屏幕上面的Y坐标值) */ tp_dev.y[0] = (signed short)(tp_dev.y[0] - tp_dev.yc) / tp_dev.yfac + lcddev.height / 2;" |. ~- ]0 Q8 a' }0 A }4 p* c4 o6 t& J+ L% O2 `: ?2 B if ((tp_dev.sta & TP_PRES_DOWN) == 0) /* 之前没有被按下 */ {2 \4 I/ {+ I0 k1 l, L tp_dev.sta = TP_PRES_DOWN | TP_CATH_PRES; /* 按键按下 */ tp_dev.x[CT_MAX_TOUCH - 1] = tp_dev.x[0]; /* 记录第一次按下时的坐标 */ tp_dev.y[CT_MAX_TOUCH - 1] = tp_dev.y[0]; } } else {$ w2 L3 u" I" c7 R& h5 X if (tp_dev.sta & TP_PRES_DOWN) /* 之前是被按下的 */6 A1 c- w% P" G. s* [9 T {3 t6 x2 k3 ]/ D t+ r tp_dev.sta &= ~TP_PRES_DOWN; /* 标记按键松开 */ } else /* 之前就没有被按下 */0 L( x% E; \6 W {) S0 t% [' m1 ~9 E z8 J" j tp_dev.x[CT_MAX_TOUCH - 1] = 0;) N' x! K4 c. q, T+ J5 ` tp_dev.y[CT_MAX_TOUCH - 1] = 0;+ t. g) W8 w0 G3 n tp_dev.x[0] = 0xffff; tp_dev.y[0] = 0xffff; }1 C+ M8 X( k1 P1 l1 k& M } : R" U6 z1 H6 {, ] return tp_dev.sta & TP_PRES_DOWN; /* 返回当前的触屏状态 */ } ) u" o, T5 j2 y2 R 然后是从Github官网下载LVGL9.5:$ T8 ~' p2 J, z6 X$ I5 G
4 |* S5 ?# h1 j2 N, ~- Z- ?7 j! f 可以看出来,LVGL9.5相比起LVGL9.3,更新了很多内容,主目录有疑似Zephyr的更新,libs目录也加入了3dmaths和webp的支持,也就是后续可能支持3D图形算法和网页端应用,很让人期待!将LVGL9.5代码放进单片机工程,并依次添加支持文件即可:/ H j! x: S/ s; W* \% a
然后在port_disp文件中添加局部刷新机制,经常移植LVGL的对此应该会很熟练了:- U1 z [+ B4 O4 P7 Y5 P( D
extern void FMCTFTLCD_ST7796_Fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t *color);& A) V, w6 s7 F* u; p1 ^ " ~7 v5 D, |1 R5 f! I" t static void disp_flush(lv_display_t * disp_drv, const lv_area_t * area, uint8_t * px_map)* `$ c0 w1 Q! {1 g1 B { if(disp_flush_enabled) ! v/ `, ^# h3 a( i/ V5 N" j { int32_t x;# U" e" ] R M. I* }) ] int32_t y;. V% b( j3 }7 A+ F5 g/ E$ f FMCTFTLCD_ST7796_Fill(area->x1 , area->y1 , area->x2 , area->y2 , px_map); // for(y = area->y1; y <= area->y2; y++) // {: _* Z* C5 K* B9 | // for(x = area->x1; x <= area->x2; x++) ! Q7 ~( Q5 n3 k# m2 T // {- p3 p; w+ a: S- f- x* @/ ?% B; O9 v // px_map++;* }3 H# k. R+ ?* k1 q& [3 G // }8 @2 @3 f. j% X+ }* c // } }4 z, ^4 K0 f* }- r6 D; Q4 ~ /*IMPORTANT!!! *Inform the graphics library that you are ready with the flushing*/( a$ E$ Z' o) j" L# C lv_display_flush_ready(disp_drv);; ?1 N5 G* o4 |3 I& m3 [- I* t }8 B) l% j* h" \5 Y7 Z & j" D4 c5 z" K! R, _ T9 y) C: T1 f, ` ' f& Q$ d. ?, K% ^% W 在indev_disp文件中添加触摸的支持:! m9 y( I; Y7 o" [9 d9 t
static bool touchpad_is_pressed(void)& F7 N, J4 F' s3 F2 C# @% H. ` { tp_dev.scan(0);" u4 W5 [5 V' A if (tp_dev.sta && tp_dev.x[0] < 320 && tp_dev.y[0] < 480) {4 u4 u6 u1 j/ o+ U; K* W$ v& N% W //printf("%d %d.\n" , tp_dev.x[0] , tp_dev.y[0]);# a# \8 I# Q7 ~2 ~ return true; }7 I4 ~$ p" T0 ]3 \' N( ^ return false;. s! ^( E9 b5 y3 \" @, R }2 _% S0 I. a' S5 u9 K /*Get the x and y coordinates if the touchpad is pressed*/, A0 f6 y/ _% N9 Q( A& S static void touchpad_get_xy(int32_t * x, int32_t * y)' a$ Z- f5 j! k {; y( h7 x p8 W4 p0 s /*Your code comes here*/ (*x) = tp_dev.x[0];, B( a" k& v" @) C+ `$ V (*y) = tp_dev.y[0]; }' ~ O2 q' Y7 e' u; {; P2 B2 X1 u 2 J/ o X$ W! l# `$ B5 N/ E 搞定,然后看看刷屏效果: 可以看出来,使用FMC并口来刷屏,效果还是很丝滑顺畅的,可以满足图形化界面显示要求。& b# E5 @( I7 k1 r7 q 4 F5 T D, F- n2 B; z& r3 F 然后是一些额外的内容,对DMA MEM2MEM机制的尝试,我们知道FMC刷屏其实也是对RAM(GRAM显存)进行操作,因此理论上可以用DMA MEM2MEM机制来实现对刷屏的加速(并非DMA2D,DMA2D是针对LTDC接口的屏幕),参考野火H743挑战者例程:
野火H743挑战者例程DMA MEM2MEM例程里面,对aDST_Buffer是限定了0x30000000即SRAM1区域的地址进行分配,但实际上,使用%p打印出来,地址并不在这个范围里,还是在0x2000000的DTCM和0x24000000的用户RAM区域中。 使用这个例程移植到我自己的LVGL例程中,DMA MEM2MEM也不能正常工作,原因未知,还在探索中。& H6 d& C! \9 h, g: h 4 d$ Z4 J: d, E $ a# r; D. u3 c- r4 {+ z |
STM32C542RC开发板PWM呼吸灯及多功能按键实验
NUCLEO-H5E5ZJ 移植 LVGL
NUCLEO-H5E5ZJ 移植 ST7735 SPI LCD 驱动
NUCLEO-H5E5ZJ 以太网(Ethernet)移植记录
【STM32H5 评测】1、移植记录(LED / Shell)
架构革新篇:单芯片 GUI 方案原理与核心优化技术
STM32C542RC开发板实现长短按键识别功能
STM32C542RC开发板PWM呼吸灯实验
STM32C542RC开发板的串口不定长数据接收实验
《STM32CubeMX2 实战课程》学习笔记——STM32C562RE开发测试
微信公众号
手机版