美文网首页
STM32 移植 littlevGL GUI

STM32 移植 littlevGL GUI

作者: 招风小妖怪 | 来源:发表于2020-01-07 18:38 被阅读0次

    以正点原子探索者开发为例,其他板子和屏幕也是可以的,因为只需要读点和写点

    哔哩哔哩视频 https://b23.tv/av82484462/p1
    这是我已经移植成功的例子基于STM32F407,修改读点函数和写点函数其他不用变就变成你的
    https://github.com/TuShen121/littlevGL-STM32F407

    组件介绍和使用
    https://docs.littlevgl.com/en/html/index.html

    第一步,准备工作

    • 先准备一个工程
    • 自己要先实现屏幕的写点,如果要触摸功能还要实现读点。

    第二步,下载和移植

    1. 官方的github项目地址https://github.com/littlevgl/lvgl
    2. 下载的解压后名称为lvgl-master,重命名为lvgl(下面也用lvgl也是这个文件夹)
    3. 将lvgl文件夹放到你的项目中
    4. 将lvgl文件夹中的lv_conf_template.h复制到与lvgl同级目录,并重命名为lv_conf
    5. 打开lv_conf,将#if 0改为 # if 1,设置你的命名的宽高像素,以及颜色模式,如下代码所示
    6. 在你需要用到的littlevGL的文件添加#include "lvgl.h"
    /**
     * @file lv_conf.h
     *
     */
    
    /*
     * COPY THIS FILE AS `lv_conf.h` NEXT TO the `lvgl` FOLDER
     */
    
    #if 1 /*Set it to "1" to enable content*///改为1
    
    #ifndef LV_CONF_H
    #define LV_CONF_H
    /* clang-format off */
    
    #include <stdint.h>
    
    /*====================
       Graphical settings
     *====================*/
    
    /* Maximal horizontal and vertical resolution to support by the library.*/
    #define LV_HOR_RES_MAX          (480)//屏幕宽
    #define LV_VER_RES_MAX          (800)//屏幕高
    
    /* Color depth:
     * - 1:  1 byte per pixel//如果是黑白屏就设置这个
     * - 8:  RGB233
     * - 16: RGB565
     * - 32: ARGB8888
     */
    #define LV_COLOR_DEPTH     16//这里选择 RGB565模式
    
    /* Swap the 2 bytes of RGB565 color.
    
    ......
    
    1. 调用lv_init();函数
    2. 设置显示缓冲区
    //显示缓冲区,如下代码
        static lv_disp_buf_t disp_buf;
        static lv_color_t buf[LV_HOR_RES_MAX * 10];                     /*Declare a buffer for 10 lines*/
        lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);    /*Initialize the display buffer*/
    
    1. 注册屏幕写点函数
    //像素打点,函数注册
        lv_disp_drv_t disp_drv;               /*Descriptor of a display driver*/
        lv_disp_drv_init(&disp_drv);          /*Basic initialization*/
        disp_drv.flush_cb = my_disp_flush;    /*Set your driver function*/
        disp_drv.buffer = &disp_buf;          /*Assign the buffer to the display*/
        lv_disp_drv_register(&disp_drv);      /*Finally register the driver*/   
    
    //打点函数实现
    void my_disp_flush(lv_disp_drv_t * disp, const lv_area_t * area, lv_color_t * color_p)
    {
        int32_t x, y;
        for(y = area->y1; y <= area->y2; y++) {
            for(x = area->x1; x <= area->x2; x++) {
                //set_pixel(x, y, *color_p);  /* Put a pixel to the display.*/
                LCD_Fast_DrawPoint( x, y,color_p->full );//自己的打点函数
                color_p++;
            }
        }
        lv_disp_flush_ready(disp);         /* Indicate you are ready with the flushing*/
    }
    

    9.如果需要触摸输入就进行输入函数注册和实现,不需要就算了

    //触摸输入注册
        lv_indev_drv_t indev_drv;
        lv_indev_drv_init(&indev_drv);             /*Descriptor of a input device driver*/
        indev_drv.type = LV_INDEV_TYPE_POINTER;    /*Touch pad is a pointer-like device*/
        indev_drv.read_cb = my_touchpad_read;      /*Set your driver function*/
        lv_indev_drv_register(&indev_drv);         /*Finally register the driver*/
    
    //读点函数实现
    bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data)
    {
       static lv_coord_t last_x = 0;
       static lv_coord_t last_y = 0;
    
       /*Save the state and save the pressed coordinate*/
       data->state = tp_dev.sta&TP_PRES_DOWN ?  LV_INDEV_STATE_PR : LV_INDEV_STATE_REL; 
       //    if(data->state == LV_INDEV_STATE_PR) touchpad_get_xy(&last_x, &last_y);
      if(LV_INDEV_STATE_PR)            //触摸屏被按下
           {   
               if(tp_dev.x[0]<lcddev.width&&tp_dev.y[0]<lcddev.height)
               {   
                   //TP_Draw_Big_Point(tp_dev.x[0],tp_dev.y[0],RED);       //画图
                   last_x=tp_dev.x[0];//将触摸的点的位置高速littlevGL
                   last_y=tp_dev.y[0];
               }
           }
       /*Set the coordinates (if released use the last pressed coordinates)*/
       data->point.x = last_x;
       data->point.y = last_y;
    
       return false; /*Return `false` because we are not buffering and no more data to read*/
    }
    
    1. 在while(1)里调用lv_task_handler();
    while(1)
        {
            lv_task_handler();
            tp_dev.scan(0); //这是我自己的屏幕触摸扫描, 
        }
    
    1. 配置一个1~10ms的定时器调用lv_tick_inc(x);x是定时器周期
    //我这里是一个5ms的定时器
    //定时器3中断服务函数
    void TIM3_IRQHandler(void)
    {
        if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
        {
            lv_tick_inc(5);
        }
        TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //清除中断标志位
    }
    

    通过上述步骤就移植完成了,

    编译可能会有很多警告,如果警告是在littlevGL的文件里可以不用管,因为官方总不可能出错的,应该是编译器的问题,

    例子测试 ---你可以在while(1) 之前 尝试如下添加如下代码,会创建1个按钮 ,按钮可以有回调函数,回调函数要写在main函数外面,这里的回调函数是弹出一个消息框,消息框按钮点击会自动关闭,不用设置

        
    //建立一按钮
        lv_obj_t * label;
    
        lv_obj_t * btn1 = lv_btn_create(lv_scr_act(), NULL);
        lv_obj_set_event_cb(btn1, event_handler);//按钮按下回调函数,可以不用设置,可以多按钮同一个回调函数
        lv_obj_align(btn1, NULL, LV_ALIGN_CENTER, 0, -40);
    
        label = lv_label_create(btn1, NULL);
        lv_label_set_text(label, "Button");
    
    
    //按钮回调函数
    static void event_handler(lv_obj_t * obj, lv_event_t event)
    {
        
        if(event == LV_EVENT_CLICKED) {//如果按钮按下
            
            //建立一个消息框
             lv_obj_t * mbox = lv_mbox_create(lv_scr_act(), NULL);//创建消息框
            lv_obj_set_width(mbox, 200);//设置宽度
            static const char * mbox_btns[] = {"ok","cancel", ""};//设置按钮名字
            lv_mbox_add_btns(mbox, mbox_btns);    /*The default action is close*///给消息框添加一个按钮,默然按钮事件会关闭消息框
            lv_obj_align(mbox, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 0, LV_DPI / 2);//按钮居中
        }
    
    }
    

    效果如如下

    1578392140568.gif

    相关文章

      网友评论

          本文标题:STM32 移植 littlevGL GUI

          本文链接:https://www.haomeiwen.com/subject/lvqdactx.html