Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
LittlevGL_LVGL
基于RT1060EVKB+LVGL的便携移动示波器
发布于 2022-08-09 23:38:42 浏览:2083
订阅该版
[tocm] # 代码 https://gitee.com/qinyunti/rt1060-evkb-dso.git # 演示视频 文章中插入视频文件失败,见评论 # 开发环境准备 ## 安装RT-Rhread Studio 从以下地址https://www.rt-thread.org/page/download.html下载 安装RT-Thread Studio,安装过程一路NEXT即可,无需特别注意的地方,不再赘述。 打开RT-Thread Studio 工具栏点击SDK Manager 安装板级支持包:没有MIMXRT1060-EVKB,则选择相近的IMXRT1064-NXP-EVK 图中是显示的已经安装后的结果: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20220809/43533477906429e22c64b84d0bde2dfa.png.webp) 相应的源码,编译工具,调试工具会自动安装,没有安装的话可以手动再安装: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20220809/151a8a0a8fc781c33500f69a1c74d3e5.png.webp) ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20220809/5601f24e25b5681f77afe05fd0420b1b.png.webp) ## 下载源码 git clone https://github.com/RT-Thread/rt-thread.git ## 导入BSP 【文件】->【导入】 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20220809/28e86fff69bd858d11e0d570bf4c7648.png.webp) ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20220809/da6325d94cdf1675b306a127cb8e1e21.png.webp) 【项目】->【全部构建】 编译结果如下: ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20220809/12a1ac9592f52832ca644bb9091520fd.png.webp) # 配置LVGL ## 添加软件包 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20220809/a0ede223a9afd180eb6090e77707a10a.png.webp) ctrl+S自动更新或者关闭标签页说动更新 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20220809/40e91c1b2a4934eeb9eae7aeb2577895.png.webp) 更新后文件如下 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20220809/6ad6fd1d7a96640574b3155e8aa184cb.png.webp) ## `rtconfig.h`中定义 ``` #define BSP_USING_LVGL #define LCD_WIDTH 480 #define LCD_HEIGHT 272 #define LCD_HFP 4 #define LCD_VFP 4 #define LCD_HBP 8 #define LCD_VBP 2 #define LCD_HSW 40 #define LCD_VSW 10 #define LCD_BL_PIN 63 #define LCD_RST_PIN 2 #define BSP_USING_LVGL_DEMO ``` ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20220809/6a522d925425928df60197a9857ab882.png.webp) 更新后增加如下文件 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20220809/25eea1eb3ba659a86a71fb3b7e477be7.png.webp) 因为目录下的SConscript依赖 depend = ['BSP_USING_LVGL', 'BSP_USING_LVGL_DEMO'] 所以前面需要修改rtconfig.h,然后更新scons配置, 当然也可以使用menuconfig配置,我们这里直接修改。 ## 工程设置宏LV_LVGL_H_INCLUDE_SIMPLE ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20220809/18223be6623010dfee8bbd75d0e280f3.png.webp) 【项目】-【清理】 【项目】-【构建项目】 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20220809/0aa68203abbd73535f4335c65fa9ad4a.png.webp) 有错误是有些代码没有编译进来,按下面的说明添加 ## 添加代码编译 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20220809/819fc844168e21c7caac28d50d91dc43.png.webp) 找到lv_demo_music在demos代码里将demos文件夹添加到编译 再编译提示lv_demo_music未定义, 在lv_conf.h ``` #define PKG_USING_LV_MUSIC_DEMO 1 #define LV_USE_DEMO_MUSIC 1 ``` 同样搜索FT5406_RT_Init 找到fsl_ft5406_rt.c添加编译 同样搜索ELCDIF_RgbModeInit找到代码在 fsl_elcdif.c添加到编译 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20220809/1b8d7d5c6f53b268e7d51f44e7b507c4.png.webp) https://mcuxpresso.nxp.com/api_doc/comp/242/ https://mcuxpresso.nxp.com/api_doc/dev/3151/ ## 配置LCD类型 从LCD背面可以看到型号为RK043FN66HS rtconfig.h中 ``` #define BSP_USING_TOUCHPAD 1 #define DEMO_PANEL_RK043FN66HS 1 ``` 右键点击左侧目录树项目->同步scons配置至项目 项目->全部构建 board.h中 ``` #include "touchpad.h" ``` 此时如果提示ELCDIF_RgbModeInit未定义需要rtconfig中 ``` #define BSP_USING_LCD 1 ``` 右键点击左侧目录树项目->同步scons配置至项目 项目->全部构建 如果lv_demo_music未定义 需要将demos文件加添加到编译 ## 配置仿真器 并不支持MIMXRT1062DVL6B所以 芯片需要按照如下选择接近的设置为MIMXRT1062xxx5A ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20220809/1224d323219f1f643329c11171ce770e.png.webp) ## Demo演示 下载运行,可以看到Demo程序运行,可以触摸操作 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20220809/2c473b5ece177723f39691cb5bfb9fa9.png.webp) ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20220809/6b9727f7b5550458236030d2bee45f5c.png.webp) # LVGL接口 见https://docs.lvgl.io/master/porting/project.html ## 时钟滴答 方式1 不定义LV_TICK_CUSTOM 每隔x毫秒,调用一次lv_tick_inc(x),lvgl自己计数。 方式2 定义LV_TICK_CUSTOM为1 提供接口LV_TICK_CUSTOM_SYS_TIME_EXPR用于获取毫秒滴答。 这里使用的是方式2 见lv_rt_thread_conf.h ``` #define LV_TICK_CUSTOM 1 #define LV_TICK_CUSTOM_SYS_TIME_EXPR (rt_tick_get_millisecond()) /*Expression evaluating to current system time in ms*/ ``` ## 显示设备 见lv_port_disp.c的lv_port_disp_init static lv_disp_drv_t disp_drv; 定义显示设备 必须全局的 static lv_disp_draw_buf_t disp_buf; 定义绘图缓冲区 lv_disp_draw_buf_init(&disp_buf, s_frameBuffer[0], s_frameBuffer[1], LCD_WIDTH * LCD_HEIGHT); 初始化绘图缓冲区 lv_disp_drv_init(&disp_drv); 初始化显示设备 设置显示设备属性,绑定到绘图缓冲区 ``` disp_drv.hor_res = LCD_WIDTH; disp_drv.ver_res = LCD_HEIGHT; disp_drv.flush_cb = lcd_fb_flush; disp_drv.draw_buf = &disp_buf; disp_drv.full_refresh = 1; lv_disp_drv_register(&disp_drv); 注册设备 ``` 其中lcd_fb_flush由lvgl自动回调,用于将绘图缓冲区的数据写入LCD 这里使用LCDIF配置需要显示color_p,操作前先获取信号量, ``` static void lcd_fb_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p) { rt_sem_take(s_frameSema, RT_WAITING_FOREVER); DCACHE_CleanInvalidateByRange((uint32_t)color_p, DISP_BUF_SIZE); ELCDIF_SetNextBufferAddr(LCDIF, (uint32_t)color_p); s_framePending = true; } ``` LCDIF刷新完后释放信号量,并且 lv_disp_flush_ready(&disp_drv);告诉lvgl已经刷新显示。 ``` void LCDIF_IRQHandler(void) { rt_interrupt_enter(); uint32_t intStatus = ELCDIF_GetInterruptStatus(LCDIF); ELCDIF_ClearInterruptStatus(LCDIF, intStatus); if (s_framePending) { if (intStatus & kELCDIF_CurFrameDone) { /* IMPORTANT!!! * Inform the graphics library that you are ready with the flushing*/ lv_disp_flush_ready(&disp_drv); s_framePending = false; rt_sem_release(s_frameSema); } } rt_interrupt_leave(); SDK_ISR_EXIT_BARRIER; } ``` ### 单缓冲区 必须disp_drv.flush_cb调用lv_disp_flush_ready(&disp_drv);之后,lvgl才会更新。所以更新->刷新显示串行 lv_disp_flush_ready实际就是设置了标志,lvgl根据该标志判断。 ``` LV_ATTRIBUTE_FLUSH_READY void lv_disp_flush_ready(lv_disp_drv_t * disp_drv) { disp_drv->draw_buf->flushing = 0; disp_drv->draw_buf->flushing_last = 0; } ``` ### 双缓冲区 disp_drv.flush_cb在刷新显示时,lvgl可以更新另外一个缓冲区,不需要等待刷新显示完,可以并行。 ### 全部刷新 disp_drv.full_refresh = 1;时 disp_drv.flush_cb的const lv_area_t *area参数不需要,直接刷新整个缓冲区,会降低效率。适合MCU有内部LCD控制器的场景,如果是使用外部LCD控制器则可能会变得慢。 ## 输入设备 必须在初始化显示设备之后 见lv_port_indev.c的lv_port_indev_init static lv_indev_drv_t indev_drv; 定义设备 必须全局的 ``` lv_indev_drv_init(&indev_drv); 初始化 indev_drv.type = LV_INDEV_TYPE_POINTER; 设备设备类型 indev_drv.read_cb = DEMO_ReadTouch; 设置读回调函数 lv_indev_drv_register(&indev_drv); 注册设备 ``` lvgl会周期回调 indev_drv.read_cb获取输入状态 ## 周期调度 按照LV_DISP_DEF_REFR_PERIOD周期调用lv_timer_handler,优先级要比lv_tick_inc低 这里是在任务中周期调用 ``` 见lv_rt_thread_port.c while(1) { lv_task_handler(); rt_thread_mdelay(LV_DISP_DEF_REFR_PERIOD); } ``` lv_task_handler实际就是调用lv_task_handler,5毫秒周期。 ``` #define LV_DISP_DEF_REFR_PERIOD PKG_LVGL_DISP_REFR_PERIOD #define PKG_LVGL_DISP_REFR_PERIOD 5 ``` ## 初始化过程 先调用lv_init()初始化lvgl 再lv_port_disp_init初始化显示设备 再lv_port_indev_init初始化输入设备 再lv_user_gui_init初始化应用 最后周期调用lv_task_handler ``` static void lvgl_thread_entry(void *parameter) { #if LV_USE_LOG lv_log_register_print_cb(lv_rt_log); #endif /* LV_USE_LOG */ lv_init(); lv_port_disp_init(); lv_port_indev_init(); lv_user_gui_init(); /* handle the tasks of LVGL */ while(1) { lv_task_handler(); rt_thread_mdelay(LV_DISP_DEF_REFR_PERIOD); } } ``` # ADC采集 rtconfig.h中添加 ``` #define RT_USING_ADC #define BSP_USING_ADC #define BSP_USING_ADC1 ``` 同步scons配置至项目 重新编译 原理图中 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20220809/31f63da4780289de61e50d3c1506bdad.png.webp) 参考手册中 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20220809/c29c4400497305ca9aa0ef24fb52a698.png.webp) ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20220809/d6695b2af96a6e5e22c7e96a21e732e0.png.webp) 可以看到J33引脚1,A0/ADC0,GPIO_AD_B1_10对应ADC1的通道ADC1_IN15 main.c中main函数中 ``` rt_adc_device_t adc_dev; /* ADC 设备句柄 */ rt_uint32_t value,vol; /* 查找设备 */ adc_dev = (rt_adc_device_t)rt_device_find("adc1"); /* 使能设备 */ if(adc_dev != RT_NULL) { rt_adc_enable(adc_dev, 0); } while (1) { if(adc_dev != RT_NULL) { /* 读取采样值 */ value = rt_adc_read(adc_dev, 15); /* 转换为对应电压值 */ vol = value * 330 / (1<<12); rt_kprintf("the voltage is :%d.%02d \n", vol / 100, vol % 100); } rt_thread_mdelay(500); } ``` 将J33引脚分别短接到J22的2和6引脚,分别打印3.22V和0V。 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20220809/3cb847487e489a6c051f6eefa56d5e2a.png.webp) ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20220809/b169a722f269753072ec23aa1cb94718.png.webp) # CHART显示ADC曲线 https://docs.lvgl.io/master/widgets/chart.html lv_conf.h中 ``` #define LV_USE_CHART 1 Main.c中 lv_obj_t * chart; lv_chart_series_t * ser1; lv_chart_series_t * ser2; int adc_chart_init(void) { lv_obj_set_style_bg_color(lv_scr_act(), lv_color_hex(0x343247), 0); /*Create a chart*/ chart = lv_chart_create(lv_scr_act()); lv_chart_set_type(chart, LV_CHART_TYPE_LINE); lv_chart_set_point_count(chart, 100); lv_chart_set_range(chart,LV_CHART_AXIS_PRIMARY_Y, 0, 330); lv_chart_set_range(chart,LV_CHART_AXIS_SECONDARY_Y, 0, 330); lv_chart_set_update_mode(chart, LV_CHART_UPDATE_MODE_SHIFT); lv_chart_set_div_line_count(chart, 4, 8); //lv_chart_set_zoom_x(lv_obj_t * obj, uint16_t zoom_x); //lv_chart_set_zoom_y(lv_obj_t * obj, uint16_t zoom_y); lv_chart_set_axis_tick(chart, LV_CHART_AXIS_PRIMARY_Y, 0, 0, 5, 1, true, 80); lv_chart_set_axis_tick(chart, LV_CHART_AXIS_PRIMARY_X, 0, 0, 12, 1, true, 50); lv_obj_set_size(chart, LCD_WIDTH, LCD_HEIGHT); lv_obj_align(chart, LV_ALIGN_CENTER, 0, 0); /*Add two data series*/ ser1 = lv_chart_add_series(chart,lv_color_hex(0xe9dbfc),LV_CHART_AXIS_PRIMARY_Y); ser2 = lv_chart_add_series(chart,lv_color_hex(0x6f8af6),LV_CHART_AXIS_PRIMARY_Y); return 0; } int adc_chart_newdata(int index,uint32_t newdata,int refresh) { if(index == 0) { lv_chart_set_next_value(chart, ser1, newdata); } else { lv_chart_set_next_value(chart, ser2, newdata); } if(refresh) { lv_chart_refresh(chart); /*Required after direct set*/ } return 0; } int main(void) { rt_adc_device_t adc_dev; /* ADC 设备句柄 */ rt_uint32_t value,vol; /* 查找设备 */ adc_dev = (rt_adc_device_t)rt_device_find("adc1"); /* 使能设备 */ if(adc_dev != RT_NULL) { rt_adc_enable(adc_dev, 15); rt_adc_enable(adc_dev, 0); } #ifndef PHY_USING_KSZ8081 /* set LED0 pin mode to output */ rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT); while(lv_is_initialized() != true) { rt_thread_mdelay(500); } adc_chart_init(); while (1) { ///rt_pin_write(LED0_PIN, PIN_HIGH); ///rt_thread_mdelay(500); ///rt_pin_write(LED0_PIN, PIN_LOW); ///rt_thread_mdelay(500); if(adc_dev != RT_NULL) { static int num = 0; num++; /* 读取采样值 */ value = rt_adc_read(adc_dev, 15); vol = value * 330 / (1u<<12); adc_chart_newdata(0,vol,0); value = rt_adc_read(adc_dev, 0); vol = value * 330 / (1u<<12); if(num>=10) { num = 0; adc_chart_newdata(1,vol,1); } else { adc_chart_newdata(1,vol,0); } } rt_thread_mdelay(50); } #endif } ``` 将J33引脚分别短接到J22的2和6引脚,模拟电压变化 ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20220809/e463da661b6094b905a02c0814cc3af3.png.webp) ![screenshot_image.png](https://oss-club.rt-thread.org/uploads/20220809/51b5800f245cd83ca461484d31f246ee.png.webp) # @todo 1.添加按钮控件控制x,y轴缩放 2.移植CMSIS-DSP,实现FFT,各类滤波等。
6
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
qinyunti
这家伙很懒,什么也没写!
文章
30
回答
1
被采纳
0
关注TA
发私信
相关文章
1
LittlevGL + DMA2D 显示图案扭曲
2
LittleVGL2RTT软件包还有在维护吗,测试遇到一些问题求解
3
使用littlevgl2rtt软件包实例运行不成功,emwin正常
4
关于littlevgl2rtt软件包刷频慢的解决方案?
5
移植了littlevGUI之后,用动态 线程去跑例程会卡死
6
lvgl的字体、图片文件如何升级?
7
qemu-vexpress-a9bsp下的littvgl工程可以实现触屏操作吗?
8
LVGL控件刷新死机问题
9
在lvgl上设置一个时间显示的label,一段时间后所有控件消失。
10
littlevgl2rtt和littlevgl的pc模拟器源码不兼容吗?
推荐文章
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组件
热门标签
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
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
编译报错
Debug
SFUD
msh
rt_mq_消息队列_msg_queue
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
出出啊
1517
个答案
342
次被采纳
小小李sunny
1443
个答案
289
次被采纳
张世争
807
个答案
174
次被采纳
crystal266
547
个答案
161
次被采纳
whj467467222
1222
个答案
148
次被采纳
本月文章贡献
出出啊
1
篇文章
4
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
1
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
1
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部