最新的评测中有一个需求,需要用一块性价比高,RAM够大,支持快速刷屏的单片机开发板做图形显示,因此我这边选用手头现成的惠勤致远STM32H743VI开发板,并搭载一个并口的ST7796彩屏:$ e- T0 f+ w3 ~. h+ O0 V
6 S7 N$ {( y& J6 a7 L' R STM32H743VI使用FMC16位8080并口给ST7796彩屏发送数据和指令,并使用FMC自带的时钟线提供时钟信号,效率相比SPI_DMA是快很多的,整套设备的成本是120出头。5 C: u4 P- r' o7 X 要使用开发板移植LVGL,需要用官方例程里面的触摸屏实验例程:
其实就是要调通LCD刷入缓存和触摸坐标读取的功能: void FMCTFTLCD_ST7796_Fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t *color) { uint16_t height, width; 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; , `2 \6 V$ E" x4 ?* z$ F% A for (i = 0; i < height; i++) {- ^0 @: N* \' I* i- Y lcd_set_cursor(sx, sy + i); lcd_write_ram_prepare();- T) z7 w6 i3 l for (j = 0; j < width; j++) { LCD->LCD_RAM = color[i * width + j]; }$ p3 ^; K$ N! k& G- w# |2 b }5 O6 Q7 H) ~; k3 Q }" g) [* T) G7 [) o3 Z0 X7 z % L0 Y6 v& |2 S/ v: b + Z3 N) Z% o7 r: x- T uint8_t tp_scan(uint8_t mode) {- A+ a$ ?, W. p" B: B+ I# B if (T_PEN == 0) /* 有按键按下 */ { 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 } else if (tp_read_xy2(&tp_dev.x[0], &tp_dev.y[0])) /* 读取屏幕坐标, 需要转换 */ { /* 将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 /* 将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 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]; } }% P" w( i4 F, j D2 S0 } else { if (tp_dev.sta & TP_PRES_DOWN) /* 之前是被按下的 */ { tp_dev.sta &= ~TP_PRES_DOWN; /* 标记按键松开 */1 _3 {% |* u& l$ [9 v+ k } else /* 之前就没有被按下 */ {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 a4 g& z7 y9 o4 k) h return tp_dev.sta & TP_PRES_DOWN; /* 返回当前的触屏状态 */ }/ ?9 i1 r/ a& L: n1 w7 x% ~ 然后是从Github官网下载LVGL9.5:
) ]( k0 y, q1 z* V+ U8 ] 可以看出来,LVGL9.5相比起LVGL9.3,更新了很多内容,主目录有疑似Zephyr的更新,libs目录也加入了3dmaths和webp的支持,也就是后续可能支持3D图形算法和网页端应用,很让人期待!将LVGL9.5代码放进单片机工程,并依次添加支持文件即可:/ y$ z- ?- w8 x: J3 k, n- A
3 j& r" u5 j( E# A( I2 k 然后在port_disp文件中添加局部刷新机制,经常移植LVGL的对此应该会很熟练了:
extern void FMCTFTLCD_ST7796_Fill(uint16_t sx, uint16_t sy, uint16_t ex, uint16_t ey, uint16_t *color); static void disp_flush(lv_display_t * disp_drv, const lv_area_t * area, uint8_t * px_map) { if(disp_flush_enabled) {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 // { // 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 } /*IMPORTANT!!!7 a/ B/ M1 i. |$ g, O b& F; y *Inform the graphics library that you are ready with the flushing*/ lv_display_flush_ready(disp_drv); }7 e& ?( q8 h, r # ^: q0 ~1 O/ @ % C/ l8 V- |$ v0 L- \ 在indev_disp文件中添加触摸的支持:
* \ s6 A) t7 c: ^/ _ static bool touchpad_is_pressed(void) { tp_dev.scan(0); 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*/ static void touchpad_get_xy(int32_t * x, int32_t * y) {) @' 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]; }8 u9 x% r5 S8 M3 h+ _ , ^# d6 ~# `. d2 x y4 T 搞定,然后看看刷屏效果:, S$ Z0 T/ g" z* ~+ C1 X( I$ c7 P 可以看出来,使用FMC并口来刷屏,效果还是很丝滑顺畅的,可以满足图形化界面显示要求。 ( 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
野火H743挑战者例程DMA MEM2MEM例程里面,对aDST_Buffer是限定了0x30000000即SRAM1区域的地址进行分配,但实际上,使用%p打印出来,地址并不在这个范围里,还是在0x2000000的DTCM和0x24000000的用户RAM区域中。 0 _- i2 Y" g! A3 v( w5 Q ' b" t$ m1 l! o7 H0 Q, A5 N 使用这个例程移植到我自己的LVGL例程中,DMA MEM2MEM也不能正常工作,原因未知,还在探索中。 ! R5 V9 e, T& y! H2 P5 x |
STM32C542RC开发板PWM呼吸灯及多功能按键实验
NUCLEO-H5E5ZJ 移植 LVGL
NUCLEO-H5E5ZJ 移植 ST7735 SPI LCD 驱动
NUCLEO-H5E5ZJ 以太网(Ethernet)移植记录
【STM32H5 评测】1、移植记录(LED / Shell)
架构革新篇:单芯片 GUI 方案原理与核心优化技术
STM32C542RC开发板实现长短按键识别功能
STM32C542RC开发板PWM呼吸灯实验
STM32C542RC开发板的串口不定长数据接收实验
《STM32CubeMX2 实战课程》学习笔记——STM32C562RE开发测试
微信公众号
手机版