用户工具

站点工具


icore4tlvgl_33

这是本文档旧的修订版!


银杏科技有限公司旗下技术文档发布平台
技术支持电话0379-69926675-801
技术支持邮件Gingko@vip.163.com
技术论坛http://www.eeschool.org
版本 日期 作者 修改内容
V1.0 2021-01-05 yang 初次建立

实验三十三:lv_chart图表

一、图表

图表是可视化数据点的基本对象,它有折线图(线上带点或不带点)和柱状图两种类型,还支持网格线、2个y轴、轴刻度和刻度文本。

图表的主体部分叫做 LV_CHART_PART_BG ,它使用所有典型的背景属性。其中text样式属性决定轴文本的样式,line属性决定刻度的样式,填充值在侧面增加了一些空间,因此会使数据序列区域更小,填充也可用于为轴文本和刻度线留出空间。

数据序列区域的背景称为 LV_CHART_PART_SERIES_BG ,并放置在主体背景上。在此部分上绘制了网格线和数据,除典型的背景样式属性外,网格线还使用线型属性。数据序列的样式可以通过 LV_CHART_PART_SERIES 引用。

对于柱状图,使用以下属性:

  • radius 柱的半径。
  • padding_inner 相同 x 坐标的柱间距。

如果是折线图,则使用以下属性:

  • line properties 线属性来描述线。
  • size 点的大小半径。
  • bg_opa 线条下方区域的整体不透明度。
  • bg_main_stop 在顶部的渐变透明度的百分比(0:在顶部透明,255:bg_opa 在顶部不透明)。
  • bg_grad_stop 在底部的渐变透明度的百分比(0:底部透明,255:bg_opa 在底部不透明)。
  • bg_drag_dir设置为 LV_GRAD_DIR_VER 使能通过 bg_main_stopbg_grad_stop 进行透明度渐变功能。

二、图表数据

2.1、数据序列

通过 lv_chart_add_series(chart, color) 可以在图表中添加多条数据序列。如果不使用外部数组,结构体 lv_chart_series_t将包含所选颜色和数据点的数组,如果分配了外部数组,则与该序列关联的任何数据点缩占用的内存都将释放,而数据系列将指向外部数组。

2.2、数据类型

数据显示类型有以下几种:

  • LV_CHART_TYPE_NONE 不显示任何数据,可用于隐藏系列。
  • LV_CHART_TYPE_LINE 在两点之间画线。
  • LV_CHART_TYPE_COLUMN 绘制柱。

指定显示类型使用lv_chart_set_type(chart, LV_CHART_TYPE_…)

2.3、修改数据

有几种方式可以设置序列数据值:

  • 使用ser1→points[3] = 7在数组中手动设置值,并使用lv_chart_refresh(chart)刷新图表。
  • 使用lv_chart_set_point_id(chart, ser, value, id),其中 id 是要更新的点的索引。
  • 使用 lv_chart_set_next(chart, ser, value) 在数据末尾添加新值。
  • 将所有点初始化为给定值lv_chart_init_points(chart, ser, value)
  • 使用lv_chart_set_points(chart, ser, value_array)设置数组中的所有点。

注意:使用 LV_CHART_POINT_DEF 作为值时,图表将跳过此步骤,不绘制数据。

2.4、修改数列的默认起点

如果希望从默认点(序列的point[0])以外的其他点开始绘图,则可以使用函数 lv_chart_set_x_start_point(chart, ser, id) 设置新的起始索引,其中 id 是开始绘图的新索引位置。

2.5、设置外部数据源

使用lv_chart_set_ext_array(chart, ser, array, point_cnt ) 可以将外部数据源分配给图表数据系列,其中 arraylv_coord_t 的外部数组,具有 point_cnt 个元素。注意:在外部数据源更新后应该调用lv_chart_refresh(chart) 以更新图表。

三、图表设置

3.1、获取当前图表信息

有四种方式可获取有关图表的信息:

  • lv_chart_get_type(chart) 返回当前图表类型。
  • lv_chart_get_point_count(chart) 返回当前图表点数。
  • lv_chart_get_x_start_point(ser) 返回指定数据序列的当前绘图索引。
  • lv_chart_get_point_id(chart, ser, id) 返回指定数据序列的指定索引处的数据值。

3.2、更新方式

在末尾添加新值的情况下 (lv_chart_set_next),有两种更新模式:

  • LV_CHART_UPDATE_MODE_SHIFT 将旧数据整体向左移动一位,丢掉第一个,然后在右侧末尾添加新数据。
  • LV_CHART_UPDATE_MODE_CIRCULAR 循环添加新数据(类似心电图,总是从前往后逐个更新数据)。

使用 lv_chart_set_update_mode(chart, LV_CHART_UPDATE_MODE_…) 可以更改图表的更新模式。

3.3、点数

数据序列中的点数默认值为 10,可以通过 lv_chart_set_point_count(chart, point_num) 来修改。注意:将外部缓冲区分配给序列时,也会影响处理点的数量。

3.4、垂直范围

使用 lv_chart_set_range(chart, y_min, y_max) 可以指定 y 轴方向上的最小值和最大值。数据点的值将按比例缩放。默认范围是:[0,100]

3.5、网格线

水平和垂直网格线的数量可以通过lv_chart_set_div_line_count(chart, hdiv_num, vdiv_num) 来修改。默认设置为 3 条水平分割线和 5 条垂直分割线。

3.6、刻度线和标签

坐标轴可以添加刻度线和标签。

若要想在 x 轴上设置刻度线和标签文本,可以使用lv_chart_set_x_tick_text(chart, list_of_values, num_tick_marks, LV_CHART_AXIS_…) list_of_values 是一个带有 '\n' 终止文本(最后一个元素没有)且带有用于刻度的文本的字符串,例如:const char * list_of_values = “first\nsec\nthird”。如果设置了list_of_values,则num_tick_marks为两个标签之间的刻度数。list_of_values可以为NULL,如果为NULL,则它指定总的刻度数。

主刻度线绘制在放置文本的位置,次刻度线绘制在其他位置。要设置 x 轴上刻度线的长度,使用lv_chart_set_x_tick_length(chart, major_tick_len, minor_tick_len)。同样的,要设置y 轴也有相同功能的函数 lv_chart_set_y_tick_text 和 lv_chart_set_y_tick_length

下面的例子实现的功能为,从ADC读取iCore4T电源电压值并以折线图的形式绘制在图表中,上方的文本显示当前电压值,下方的滑块可以调节当前y轴的显示区间[0v,6v]。

// main.c 文件内容
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include "gui.h"
#include "power_adc.h"
 
#define LED0_PIN GET_PIN(A, 10)                /* 定义LED引脚 */
#define THREAD_PRIORITY         25             /* 线程优先级 */
#define THREAD_STACK_SIZE       1024           /* 线程堆栈大小 */
#define THREAD_TIMESLICE        5              /* 线程时间片 */
static rt_thread_t tid1 = RT_NULL;             /* 定义线程 */
 
int main(void)
{
	lv_gui_run();                                 /* 绘制图形界面 */
	                                              /* 创建线程,获取AD值更新到图表 */
	tid1 = rt_thread_create("thread1", power_adc_run, RT_NULL, THREAD_STACK_SIZE, THREAD_PRIORITY, THREAD_TIMESLICE);
	if (tid1 != RT_NULL) rt_thread_startup(tid1); /* 启动线程 */
 
	rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);       /* 设置LED引脚为输出模式 */
	while(1){
		rt_pin_write(LED0_PIN, PIN_HIGH);     /* LED闪烁 */
		rt_thread_mdelay(100);	
		rt_pin_write(LED0_PIN, PIN_LOW);
		rt_thread_mdelay(100);	
	}
	return RT_EOK;
}
// power_adc.c 文件内容
#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include "lvgl.h"
#include "gui.h"
#include "power_adc.h"
 
void power_adc_run(void *parameter) {                         /* 电源AD读取线程入口函数 */
	int value = 0;
	int voltage;
	static rt_adc_device_t adc_device = RT_NULL;
 
	adc_device = (rt_adc_device_t)rt_device_find("adc1"); /* 搜搜索ADC设备 */
	if(adc_device != RT_NULL){
		while(1){
			value = rt_adc_read(adc_device, atoi("16"));/* 读取电源电压,通道16 */ 
			voltage = (int) (value*1500/65535);	    /* 换算电压值*100 */
			lv_chart_set_next(chart, ser1, voltage);    /* 更新数据序列 */
			lv_chart_refresh(chart);                    /* 刷新图标 */
                                                                    /* 更新标签 */
			lv_label_set_text_fmt(label, "The voltage of iCore4T is: %d.%d v", voltage/100, voltage%100);
			rt_thread_mdelay(100);	                    /* 100ms采集一次 */
  		}
	}
}
// gui.c 图形界面绘制函数
void lv_gui_run(void) {
	lvgl2rtt_init("lcd");                                       /* 初始化lvgl2rtt */
 
	chart = lv_chart_create(lv_scr_act(), NULL);                /* 创建图表 */
	lv_obj_set_size(chart, 200, 150);                           /* 设置尺寸 */
	lv_obj_align(chart, NULL, LV_ALIGN_CENTER, 0, 0);           /* 设置位置 */
	lv_chart_set_type(chart, LV_CHART_TYPE_LINE);               /* 选择折线图 */
	lv_chart_set_update_mode(chart, LV_CHART_UPDATE_MODE_SHIFT);/* 更新模式为左移 */
	lv_chart_set_y_tick_texts(chart, list_of_values, NULL, LV_CHART_AXIS_PRIMARY_Y); /* 设置刻度 */
	lv_chart_set_range(chart, 440, 470);                        /* 设置y轴显示范围 */
	lv_chart_set_point_count(chart, 50);                        /* 设置图表点数 */
 
	lv_obj_set_style_local_bg_opa(chart, LV_CHART_PART_SERIES, LV_STATE_DEFAULT, LV_OPA_50); 
	lv_obj_set_style_local_bg_grad_dir(chart, LV_CHART_PART_SERIES, LV_STATE_DEFAULT , LV_GRAD_DIR_VER);
	lv_obj_set_style_local_bg_main_stop(chart, LV_CHART_PART_SERIES, LV_STATE_DEFAULT, 255); /* 顶部透明度 */
	lv_obj_set_style_local_bg_grad_stop(chart, LV_CHART_PART_SERIES, LV_STATE_DEFAULT, 200); /* 底部透明度 */
 
	ser1 = lv_chart_add_series(chart, LV_COLOR_RED);            /* 图表添加红色线 */
	lv_chart_init_points(chart, ser1, 0);                       /* 赋初值为0 */
	lv_chart_refresh(chart);                                    /* 刷新图表 */
 
	label = lv_label_create(lv_scr_act(), NULL);                /* 创建标签 */
	lv_obj_align(label, NULL, LV_ALIGN_IN_TOP_MID, -105, 20);   /* 设置位置 */
 
	lv_obj_t * slider = lv_slider_create(lv_scr_act(), NULL);   /* 创建滑块 */
	lv_slider_set_value(slider, 30, LV_ANIM_OFF);               /* 设置初始值 */
	lv_obj_set_event_cb(slider, slider_event_cb);               /* 绑定回调函数 */
	lv_slider_set_range(slider, 0, 600);                        /* 设置值范围 */
	lv_obj_set_size(slider, 200, 10);                           /* 设置滑块尺寸 */
	lv_obj_align(slider, NULL, LV_ALIGN_CENTER, 0, 100);        /* 设置滑块位置 */
	lv_slider_set_type(slider, LV_SLIDER_TYPE_RANGE);           /* 设置双点模式 */
	lv_slider_set_left_value(slider, 440, LV_ANIM_OFF);         /* 设置左值位置 */
	lv_slider_set_value(slider, 470, LV_ANIM_OFF);              /* 设置右值位置 */
}

更改样式,显示刻度坐标可以参考下例:

// power_adc.c 文件内容
	static lv_style_t style1;                                        /* 新建样式 */
	lv_style_set_bg_color(&style1, LV_CHART_PART_BG, LV_COLOR_BLUE); /* 背景色蓝色*/
	lv_style_set_pad_left(&style1, LV_STATE_DEFAULT, LV_DPX(240));   /* 左填充 */
 
	chart = lv_chart_create(lv_scr_act(), NULL);                     /* 创建图表 */
	lv_obj_set_size(chart, 300, 150);                                /* 设置尺寸 */
 
	lv_obj_add_style(chart,LV_OBJ_PART_MAIN, &style1);               /* 设置样式 */
 
	lv_chart_set_div_line_count(chart, 5, 7);                        /* 设置网格线 */
 
	lv_obj_align(chart, NULL, LV_ALIGN_CENTER, 0, 0);                /* 设置位置 */
	lv_chart_set_type(chart, LV_CHART_TYPE_LINE);                    /* 选择折线图 */
	lv_chart_set_update_mode(chart, LV_CHART_UPDATE_MODE_SHIFT);     /* 更新模式为左移 */
	lv_chart_set_y_tick_texts(chart, list_of_values, NULL, LV_CHART_AXIS_PRIMARY_Y); /* 设置刻度 */
	lv_chart_set_range(chart, 0, 600);                               /* 设置y轴显示范围 */
	lv_chart_set_point_count(chart, 50);                             /* 设置图表点数 */
icore4tlvgl_33.1610417608.txt.gz · 最后更改: 2021/01/12 10:13 由 zgf