创建的按钮点击可以暂停图表画面刷新,但是为什么会暂停的图表越多,图表刷新的速率越慢呢。

lv_obj_t * charts[4];
lv_chart_series_t* ser[4];
static lv_timer_t * chart_update_timer[4];
static lv_timer_t * data_add_timer[4];
static lv_obj_t * btn[4];
static lv_obj_t * label[4];
static bool is_paused[4] = {false, false, false, false};

typedef struct Node {
    float data; // 假设队列存储的是整数
    struct Node* next;
} Node;

typedef struct {
    Node* front; // 队列前端
    Node* rear;  // 队列后端
} Queue;

Queue dataQueue[4];

// 初始化队列,都设为空表示队列为空
void initQueue(Queue* q) {
    q->front = q->rear = NULL;
}

// 检查队列是否为空
int isEmpty(Queue* q) {
    return q->front == NULL;
}

// 入队
void enqueue(Queue* q, int value) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    if (newNode == NULL) {
        // 处理内存分配失败的情况
        printf("Memory allocation failed\n");
        return;
    }
    newNode->data = value;
    newNode->next = NULL;
    if (q->rear == NULL) { // 队列为空
        q->front = q->rear = newNode;
    }
    else {
        q->rear->next = newNode;
        q->rear = newNode;
    }
}

// 出队
int dequeue(Queue* q) {
    if (isEmpty(q)) {
        printf("Queue is empty\n");
        return -1.0f; // 使用 float 并返回特殊值表示错误
    }
    Node* temp = q->front;
    float value = temp->data;
    q->front = q->front->next;
    if (q->front == NULL) {
        q->rear = NULL;
    }
    free(temp);
    return value;
}

// 销毁队列(释放所有内存)
void destroyQueue(Queue* q) {
    Node* current = q->front;
    Node* next;
    while (current != NULL) {
        next = current->next;
        free(current);
        current = next;
    }
    q->front = q->rear = NULL;
}

static void add_data(lv_timer_t * timer)
{
    LV_UNUSED(timer);
    int16_t fangbo, jucibo;
    for (int i = 0; i < 4; i++) {
        if (!is_paused[i]) {

            static float angle = 0; // 为每个图表使用不同的角度可能会导致混乱,这里仅为示例
            angle += 0.1;
            if (angle > 2 * M_PI) angle -= 2 * M_PI;

            if (i == 1) {
                fangbo = (int)(rand() % 100); // 假设使用随机数模拟数据
                enqueue(&dataQueue[i], fangbo);
            } else if (i == 0) {
                int value = (int)(50 + 40 * sin(angle));
                enqueue(&dataQueue[i], value);
            } else if (i == 2) {
                int value = (int)(50 + 40 * cos(angle));
                enqueue(&dataQueue[i], value);
            } else if (i == 3) {
                jucibo = (int)(rand() % 100); // 假设使用随机数模拟数据
                enqueue(&dataQueue[i], jucibo);
            }
        }
    }
}

static void update_chart(lv_timer_t * timer) {
    for (int i = 0; i < 4; i++) {
        if (!isEmpty(&dataQueue[i])) {
            float value = dequeue(&dataQueue[i]);
            lv_chart_set_next_value(charts[i], ser[i], (int16_t)value); // 注意类型转换
            lv_chart_refresh(charts[i]); // 刷新图表
        }
    }
}

static void everyBtn_event (lv_event_t * event)
{
    lv_event_code_t code = lv_event_get_code(event);
    lv_obj_t * btn_clicked = lv_event_get_target(event);

    if (code == LV_EVENT_CLICKED) {
        for (int i = 0; i < 4; i++) {
            if (btn_clicked == btn[i]) {
                if (is_paused[i]) {
                    // 如果当前是暂停状态,则启动定时器
                    if (!data_add_timer[i]) {
                        data_add_timer[i] = lv_timer_create(add_data, 50, NULL);
                    }
                    if (!chart_update_timer[i]) {
                        chart_update_timer[i] = lv_timer_create(update_chart, 50, NULL);
                    }
                    lv_label_set_text(lv_obj_get_child(btn[i], 0), "Resume");
                    is_paused[i] = false;
                } else {
                    // 如果当前是运行状态,则停止定时器
                    if (data_add_timer[i]) {
                        lv_timer_del(data_add_timer[i]);
                        data_add_timer[i] = NULL;
                    }
                    if (chart_update_timer[i]) {
                        lv_timer_del(chart_update_timer[i]);
                        chart_update_timer[i] = NULL;
                    }
                    lv_label_set_text(lv_obj_get_child(btn[i], 0), "Pause");
                    is_paused[i] = true;
                }
            }
        }
    }
}


void init_chart(void)
{
    for(int i=0;i<4;i++)
    {
        initQueue(&dataQueue[i]);

        charts[i]=lv_chart_create(lv_scr_act());
        lv_obj_set_size(charts[i],350,100);
        lv_obj_set_pos(charts[i],225,i * 100);

        lv_chart_set_point_count(charts[i],100);
        lv_chart_set_div_line_count(charts[i],0,0);
        lv_obj_set_style_size(charts[i],0,LV_PART_INDICATOR);
        lv_obj_set_style_bg_color(charts[i], lv_color_hex(0x575757), LV_STATE_DEFAULT);
        ser[i] = lv_chart_add_series(charts[i],
                                     lv_palette_main(LV_PALETTE_BLUE),
                                     LV_CHART_AXIS_PRIMARY_X);
        lv_chart_set_update_mode(charts[i], LV_CHART_UPDATE_MODE_SHIFT);
        //添加控制按钮
        btn[i] = lv_btn_create(lv_scr_act());
        lv_obj_set_size(btn[i],80,50);
        lv_obj_align_to(btn[i],charts[i],LV_ALIGN_OUT_LEFT_MID,-50,0);
        label[i] = lv_label_create(btn[i]);
        lv_label_set_text(label[i], "Pause");
        lv_obj_center(label[i]);
        //给按钮添加事件,点击暂停
        lv_obj_add_event_cb(btn[i],everyBtn_event,LV_EVENT_CLICKED,NULL);
        //添加定时器把波形数据加入队列
        data_add_timer[i]= lv_timer_create(add_data,50 , NULL);
        //此定时器是为了把队列数据输出给chart控件以生成波形
        chart_update_timer[i] = lv_timer_create(update_chart, 50 , NULL);
        lv_chart_refresh(charts[i]);
    }

}

void spinner(void)
{
    init_chart();
}

是共用定时器的问题么。

你这代码写得有点乱,不需要使用btn数组记录每个按钮的状态,回调函数也不是一次就要将所有的btn的都遍历一遍;定时器的暂停与恢复有专门的函数接口,而不是直接del然后再create了,请先看看我们的视频教程吧: