Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
GUI
art-pi多媒体扩展屏使用littlevgl
发布于 2021-08-02 11:30:40 浏览:1056
订阅该版
参考了大佬的相关文章(https://club.rt-thread.org/ask/article/2434.html)修改了ilittlevgl2rtt的软件包,在art-pi的多媒体扩展屏上成功应用,但是遇到了一些问题: 1 跑官方例程的时候出现了按键显示不全的现象,一个btn只能显示上半部分,且有时候更新显示的某个变量时会出现卡顿,撕裂的现象。 2 在用了自己写的代码后按键能够显示完全,但是在按下按钮后按钮区域会消失按键区域会出现花屏现象。 @adaphoto
查看更多
1
个回答
默认排序
按发布时间排序
adaphoto
2021-08-03
这家伙很懒,什么也没写!
感觉你这个问题很像是使用了双缓冲没配置好,下面是我的littlevgl2rtt.c的代码,你对比一下看看和你的有什么不同。特别是刷屏函数lcd_fb_flush() ``` #include "littlevgl2rtt.h" #include "lvgl.h" static rt_device_t device; static struct rt_device_graphic_info info; static struct rt_messagequeue *input_mq; static int _lv_init = 0; static lv_disp_drv_t disp_drv; static lv_disp_buf_t disp_buf; static void color_to16_maybe(lv_color16_t *dst, lv_color_t *src) { #if (LV_COLOR_DEPTH == 16) dst->full = src->full; #else dst->ch.blue = src->ch.blue; dst->ch.green = src->ch.green; dst->ch.red = src->ch.red; #endif } /* Todo: add gpu */ static void lcd_fb_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p) { int x1, x2, y1, y2; x1 = area->x1; x2 = area->x2; y1 = area->y1; y2 = area->y2; /*Return if the area is out the screen*/ if (x2 < 0) return; if (y2 < 0) return; if (x1 > info.width - 1) return; if (y1 > info.height - 1) return; /*Truncate the area to the screen*/ int32_t act_x1 = x1 < 0 ? 0 : x1; int32_t act_y1 = y1 < 0 ? 0 : y1; int32_t act_x2 = x2 > info.width - 1 ? info.width - 1 : x2; int32_t act_y2 = y2 > info.height - 1 ? info.height - 1 : y2; uint32_t x; uint32_t y; long int location = 0; /* 8 bit per pixel */ if (info.bits_per_pixel == 8) { uint8_t *fbp8 = (uint8_t *)info.framebuffer; //TODO color convert maybe for (y = act_y1; y <= act_y2; y++) { for (x = act_x1; x <= act_x2; x++) { location = (x) + (y)*info.width; fbp8[location] = color_p->full; color_p++; } color_p += x2 - act_x2; } } /* 16 bit per pixel */ else if (info.bits_per_pixel == 16) { lv_color16_t *fbp16 = (lv_color16_t *)info.framebuffer; for (y = act_y1; y <= act_y2; y++) { for (x = act_x1; x <= act_x2; x++) { location = (x) + (y)*info.width; color_to16_maybe(&fbp16[location], color_p); color_p++; } color_p += x2 - act_x2; } } #ifndef BSP_USING_SPI_LCD_ILI9488 /* 24 or 32 bit per pixel */ else if (info.bits_per_pixel == 24 || info.bits_per_pixel == 32) { uint32_t *fbp32 = (uint32_t *)info.framebuffer; //TODO for (y = act_y1; y <= act_y2; y++) { for (x = act_x1; x <= act_x2; x++) { location = (x) + (y)*info.width; fbp32[location] = color_p->full; color_p++; } color_p += x2 - act_x2; } } //#elif defined(BSP_USING_DMA2D) // else if (info.bits_per_pixel == 24 || info.bits_per_pixel == 32) // { // uint8_t * lcd_buf = (uint8_t *)info.framebuffer; // for (y = act_y1; y <= act_y2; y++) // { // extern void dma2d_send(uint32_t pdata, uint32_t DstAddress, uint32_t Width, uint32_t Height); // dma2d_send((uint32_t)color_p, (uint32_t)(&lcd_buf[3*(act_x1 + y * info.width)]), act_x2 - act_x1 + 1, 1); // color_p += x2 - act_x1 + 1; // } // } #else else if (info.bits_per_pixel == 24 || info.bits_per_pixel == 32) { uint8_t * lcd_buf = (uint8_t *)info.framebuffer; for (y = act_y1; y <= act_y2; y++) { for (x = act_x1; x <= act_x2; x++) { location = (x) + (y)*info.width; lcd_buf[3 * location] = color_p->ch.red; lcd_buf[3 * location + 1] = color_p->ch.green; lcd_buf[3 * location + 2] = color_p->ch.blue; color_p++; } color_p += x2 - act_x2; } } #endif struct rt_device_rect_info rect_info; rect_info.x = x1; rect_info.y = y1; rect_info.width = x2 - x1 + 1; rect_info.height = y2 - y1 + 1; rt_device_control(device, RTGRAPHIC_CTRL_RECT_UPDATE, &rect_info); lv_disp_flush_ready(disp_drv); } static void lcd_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p) { int x1, x2, y1, y2; x1 = area->x1; x2 = area->x2; y1 = area->y1; y2 = area->y2; /*Return if the area is out the screen*/ if (x2 < 0) return; if (y2 < 0) return; if (x1 > info.width - 1) return; if (y1 > info.height - 1) return; /*Truncate the area to the screen*/ int32_t act_x1 = x1 < 0 ? 0 : x1; int32_t act_y1 = y1 < 0 ? 0 : y1; int32_t act_x2 = x2 > info.width - 1 ? info.width - 1 : x2; int32_t act_y2 = y2 > info.height - 1 ? info.height - 1 : y2; uint32_t x; uint32_t y; //TODO color convert for (y = act_y1; y <= act_y2; y++) { rt_graphix_ops(device)->blit_line((const char *)color_p, act_x1, y, act_x2 - act_x1 + 1); color_p += (x2 - x1 + 1); } } static rt_bool_t touch_down = RT_FALSE; static rt_int16_t last_x = 0; static rt_int16_t last_y = 0; static bool input_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data) { data->point.x = last_x; data->point.y = last_y; data->state = (touch_down == RT_TRUE) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; return false; } static void lvgl_tick_run(void *p) { while (_lv_init) { lv_tick_inc(1); rt_thread_delay(1); } } static int lvgl_tick_handler_init(void) { rt_thread_t thread = RT_NULL; int ret; thread = rt_thread_create("lv_tick", lvgl_tick_run, RT_NULL, 512, 6, 10); if (thread == RT_NULL) { return RT_ERROR; } ret = rt_thread_startup(thread); return ret; } static void lvgl_task_run(void *p) { void *buf1 = disp_buf.buf1; while (_lv_init) { rt_thread_mdelay(10); // rt_enter_critical(); lv_task_handler(); // rt_exit_critical(); } #if (LV_ENABLE_GC == 1) lv_deinit(); #endif rt_free(buf1); } static int lvgl_task_handler_init(void) { rt_err_t ret = RT_EOK; rt_thread_t thread = RT_NULL; /* littleGL demo gui thread */ thread = rt_thread_create("lv-task", lvgl_task_run, RT_NULL, 10 * 1024, 5, 10); if (thread == RT_NULL) { return RT_ERROR; } ret = rt_thread_startup(thread); return ret; } void littlevgl2rtt_send_input_event(rt_int16_t x, rt_int16_t y, rt_uint8_t state) { switch (state) { case LITTLEVGL2RTT_INPUT_UP: touch_down = RT_FALSE; break; case LITTLEVGL2RTT_INPUT_DOWN: last_x = x; last_y = y; touch_down = RT_TRUE; break; case LITTLEVGL2RTT_INPUT_MOVE: last_x = x; last_y = y; break; } } #if USE_LV_LOG void littlevgl2rtt_log_register(lv_log_level_t level, const char *file, uint32_t line, const char *dsc) { if (level >= LV_LOG_LEVEL) { //Show the log level if you want if (level == LV_LOG_LEVEL_TRACE) { rt_kprintf("Trace:"); } rt_kprintf("%s\n", dsc); //You can write 'file' and 'line' too similary if required. } } #endif rt_err_t littlevgl2rtt_init(const char *name) { lv_color_t *fbuf; RT_ASSERT(name != RT_NULL); if (_lv_init == 1) return 0; /* LCD Device Init */ device = rt_device_find(name); RT_ASSERT(device != RT_NULL); if (rt_device_open(device, RT_DEVICE_OFLAG_RDWR) == RT_EOK) { rt_device_control(device, RTGRAPHIC_CTRL_GET_INFO, &info); } RT_ASSERT(info.bits_per_pixel == 8 || info.bits_per_pixel == 16 || info.bits_per_pixel == 24 || info.bits_per_pixel == 32); #if 0 if ((info.bits_per_pixel != LV_COLOR_DEPTH) && (info.bits_per_pixel != 32 && LV_COLOR_DEPTH != 24)) { rt_kprintf("Error: framebuffer color depth mismatch! (Should be %d to match with LV_COLOR_DEPTH)", info.bits_per_pixel); return RT_ERROR; } #endif fbuf = rt_malloc(info.width * info.height * sizeof(*fbuf)); if (!fbuf) { rt_kprintf("Error: alloc disp buf fail\n"); return -1; } /* littlevgl Init */ lv_init(); #if USE_LV_LOG /* littlevgl Log Init */ lv_log_register_print(littlevgl2rtt_log_register); #endif /* littlevGL Display device interface */ lv_disp_drv_init(&disp_drv); disp_drv.hor_res = info.width; disp_drv.ver_res = info.height; if (info.framebuffer == RT_NULL) { disp_drv.flush_cb = lcd_flush; } else { disp_drv.flush_cb = lcd_fb_flush; } lv_disp_buf_init(&disp_buf, fbuf, NULL, info.width * info.height); disp_drv.buffer = &disp_buf; lv_disp_drv_register(&disp_drv); static lv_indev_drv_t indev_drv; lv_indev_drv_init(&indev_drv); indev_drv.type = LV_INDEV_TYPE_POINTER; indev_drv.read_cb = input_read; lv_indev_drv_register(&indev_drv); _lv_init = 1; /* littlevGL Tick thread */ lvgl_tick_handler_init(); lvgl_task_handler_init(); /* Info Print */ rt_kprintf("[littlevgl2rtt] Welcome to the littlevgl2rtt.\n"); rt_kprintf("[littlevgl2rtt] You can find latest ver from https://github.com/liu2guang/LittlevGL2RTT.\n"); return RT_EOK; } void littlevgl2rtt_deinit(void) { _lv_init = 0; } ```
撰写答案
登录
注册新账号
关注者
0
被浏览
1.1k
关于作者
tasd
这家伙很懒,什么也没写!
提问
6
回答
1
被采纳
0
关注TA
发私信
相关问题
1
[已解决]创建GUI显示线程,出现bus fault错误应该怎么解?
2
移植RTGUI后,使用RealBoard4088的按键驱动切换画面,出现一次按键,触发两次事件的异常
3
【已解决】keil中添加rtgui的demo程序的问题
4
RT-GUI触摸BUG?
5
【已解决】请问:如何把example目录下rtgui的例子添加到工程中
6
RT-GUI不需要开辟一块和屏尺寸相同的存储空间记录屏幕上的数据吗?
7
RT-GUI开发疑问?
8
RTGUI 发送消息队列失败
9
gui的汉字字库能只挑出自己使用的汉字编译吗?
10
建议RTGUI的汉字和BMP等方框绘图增加窗口支持
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
rt-thread 小内存算法源码分析
2
env中添加lvgl软件包后,keil编译包--c99错误
3
【NXP-MCXA153】 定时器驱动移植
4
GD32F450 看门狗驱动适配
5
【NXP-MCXA153】看门狗驱动移植
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
PWM
freemodbus
flash
cubemx
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
编译报错
Debug
rt_mq_消息队列_msg_queue
SFUD
keil_MDK
msh
ulog
C++_cpp
MicroPython
本月问答贡献
踩姑娘的小蘑菇
7
个答案
2
次被采纳
a1012112796
18
个答案
1
次被采纳
红枫
5
个答案
1
次被采纳
Ryan_CW
5
个答案
1
次被采纳
张世争
4
个答案
1
次被采纳
本月文章贡献
YZRD
3
篇文章
6
次点赞
catcatbing
3
篇文章
6
次点赞
lizimu
2
篇文章
11
次点赞
qq1078249029
2
篇文章
2
次点赞
xnosky
2
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部