一、展示成果

博客上传图片限制在5M内,视频转 GIF 帧率压缩太严重了,还得再次压缩才小于5M,效果完全失真了
小伙伴们有什么好的工具或方法解决吗

gif 图上应该看不出什么区别。但是ESP32 用60MHz的 spi 驱动跑 lvgl,其卡顿比 stm32 spi 驱动跑 lvgl 明显好很多,,毕竟stm32 spi 也达不到 60MHz嘛

  • 主控:ESP32
  • 开发工具:esp- idf-v4.3
  • LCD 4.3寸 ILI9488
  • 温度传感器:K型热电偶+MAX6675
  • GUI:little VGL v8.1.0
  • 简单的跑个 little VGL 例程而已,下一步再搞点好玩的

ESP32

60MHz SPI 驱动 little VGL v8.1 效果

STM32

SPI驱动 little VGL v7.8效果

二、LCD驱动调试

老样子,直接上代码
// 头文件

#ifndef __SLIM_LCD_H__
#define __SLIM_LCD_H__#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/spi_master.h"
#include "driver/gpio.h"
#include "lvgl/lvgl.h"
//*************************************************************************************************
//      引脚描述
//  CS      --> 15
//  SCK     -->  14
//  SDO     -->  12
//  SDI     -->  13
//  RESET   -->
//  DC/RS   -->
//  LED     -->
//  T_CLK   -->
//  T_CS    -->
//  T_DIN   -->
//  T_DO    -->
//  T_IRQ   -->
//*************************************************************************************************
#ifdef CONFIG_IDF_TARGET_ESP32
#define LCD_SPI     HSPI_HOST
#define GPIO_HANDSHAKE  2
#define PIN_LCD_MISO    12
#define PIN_LCD_MOSI    13
#define PIN_LCD_CLK     14
#define PIN_LCD_CS      15
#define PIN_LCD_RST     25
#define PIN_LCD_DC      26
#define PIN_LCD_LED     27
#endif//LCD parameter
typedef struct{                                         uint16_t    width;  //LCD widthuint16_t height; //LCD heightuint16_t    id;     //LCD IDuint8_t     dir;    //0:vertical / 1:Horizontaluint16_t wramcmd;//start write GRAM commanduint16_t  setxcmd;//setting x axisuint16_t    setycmd;//setting y axis
}_lcd_dev;  extern _lcd_dev lcddev;
#define USE_HORIZONTAL      1   //0:0 / 1:90 / 2:180 / 3:270
#define USER_BUFF_LEN       1440    //3*480//画笔颜色
#define WHITE       0xFFFF
#define BLACK       0x0000
#define BLUE        0x001F
#define BRED        0XF81F
#define GRED        0XFFE0
#define GBLUE       0X07FF
#define RED         0xF800
#define MAGENTA     0xF81F
#define GREEN       0x07E0
#define CYAN        0x7FFF
#define YELLOW      0xFFE0
#define BROWN       0XBC40  //棕色
#define BRRED       0XFC07  //棕红色
#define GRAY        0X8430  //灰色
//GUI颜色#define DARKBLUE 0X01CF  //深蓝色
#define LIGHTBLUE   0X7D7C  //浅蓝色
#define GRAYBLUE    0X5458  //灰蓝色
//以上三色为 PANEL颜色 #define LIGHTGREEN  0X841F  //灰绿色
#define LIGHTGRAY   0XEF5B  //浅灰色(PANNEL)
#define LGRAY       0XC618  //浅灰色(PANNEL),窗体背景色#define LGRAYBLUE    0XA651 //浅灰蓝色(中间层颜色)
#define LBBLUE      0X2B12 //浅棕蓝色(选择条目的反色)//brush color and background color
#define POINT_COLOR 0x0000
#define BACK_COLOR  0xFFFFenum{REG = 0,DATA,
};
enum{OFF = 0,ON,
};
//==================================================================================
//LCD size
#define LCD_W 320
#define LCD_H 480void LCD_Init(void);
void LCD_SetCursor(uint16_t Xpos, uint16_t Ypos);
void LCD_Refresh(uint16_t Color);
void LCD_Flush(uint16_t xStart, uint16_t yStart, uint16_t xEnd, uint16_t yEnd, uint16_t *buff);
void LCD_Disp_Flush(const lv_area_t * area, lv_color_t * color_p);#endif
/**************************************************************************************************** @file    : slim_lcd.c* @author  : slim * @version : V0.0.1* @date    : 2021.07.11* @brief   : LCD moduler for ILI9488 IC driver**************************************************************************************************/
#include "slim_lcd.h"#define RGB_R(n) (n>>8)&0xF8
#define RGB_G(n)    (n>>3)&0xFC
#define RGB_B(n)    n<<3_lcd_dev lcddev;
static spi_device_handle_t spi_handle;
uint8_t GRAM_BUFF[USER_BUFF_LEN] = {0};//===========================================================================
// 静态函数声明
static void _spi_init(void);
static void _lcd_spi_pre_transfer_callback(spi_transaction_t *trans);
static void _lcd_cmd(uint8_t reg);
static void _lcd_data(uint8_t *buff, uint16_t len);
static void _byte_read(uint8_t *buff, uint16_t len);
static uint32_t _lcd_get_id(void);
static void _lcd_init(void);
static void _lcd_led_set(uint8_t state);
static void _lcd_direction(uint8_t direction);
static void _lcd_write_data_16bit(uint16_t rgb_data);
static void _lcd_SetWindows(uint16_t xStar, uint16_t yStar,uint16_t xEnd,uint16_t yEnd);
static void _lcd_clear(uint16_t color);
//============================================================================
// spi/lcd 初始化、读、写
//============================================================================
static void _spi_init(void){esp_err_t ret;spi_bus_config_t buscfg = {.miso_io_num = PIN_LCD_MISO,.mosi_io_num = PIN_LCD_MOSI,.sclk_io_num = PIN_LCD_CLK,.quadwp_io_num = -1,.quadhd_io_num = -1,.max_transfer_sz = 4096, //非DMA:64byte,,DMA:4096Byte.flags = SPICOMMON_BUSFLAG_MASTER,  //初始化检查SPI主机模式是否成功};//Configuration for the SPI device on the other side of the busspi_device_interface_config_t devcfg = {.command_bits = 0,.address_bits = 0,.dummy_bits = 0,.clock_speed_hz = 60*1000000,.duty_cycle_pos = 0,        //50% duty cycle.mode = 0,.spics_io_num = PIN_LCD_CS,.cs_ena_posttrans = 1,      //Keep the CS low 3 cycles after transaction, to stop slave from missing the last bit when CS has less propagation delay than CLK.queue_size = 3,.pre_cb = _lcd_spi_pre_transfer_callback,   //Specify pre-transfer callback to handle D/C line};//Initialize the SPI bus and add the device we want to send stuff to.ret=spi_bus_initialize(LCD_SPI, &buscfg, SPI_DMA_CH1);    //总线初始化assert(ret==ESP_OK);ret=spi_bus_add_device(LCD_SPI, &devcfg, &spi_handle);assert(ret==ESP_OK);
}
static void _lcd_spi_pre_transfer_callback(spi_transaction_t *trans){uint32_t dc = (uint32_t)trans->user;gpio_set_level(PIN_LCD_DC, dc);
}
// LCD写寄存器
static void _lcd_cmd(uint8_t reg){esp_err_t ret;spi_transaction_t trans;memset(&trans, 0, sizeof(trans));trans.length = 8;       //Command is 8 bitstrans.tx_buffer = &reg;trans.user = (void*)0;  //regret=spi_device_polling_transmit(spi_handle, &trans);   //Transmit!assert(ret==ESP_OK);//Should have had no issues.
}
// LCD写数据
static void _lcd_data(uint8_t *buff, uint16_t len){esp_err_t ret;spi_transaction_t trans;memset(&trans, 0, sizeof(trans));trans.length = len*8;trans.tx_buffer = buff;trans.user = (void*)1;  //dataret=spi_device_polling_transmit(spi_handle, &trans);   //Transmit!assert(ret==ESP_OK);//Should have had no issues.
}
static void _byte_read(uint8_t *buff, uint16_t len){spi_transaction_t trans;memset(&trans, 0, sizeof(trans));trans.length=len*8;// trans.flags = SPI_TRANS_USE_RXDATA;trans.tx_buffer = NULL;trans.rx_buffer = buff;trans.user = (void*)1;esp_err_t ret = spi_device_polling_transmit(spi_handle, &trans);assert( ret == ESP_OK );
}
// 读取LCD id
static uint32_t _lcd_get_id(void){uint8_t tmp_id[4] = {0};_lcd_cmd(0xD3);_byte_read(tmp_id, 4);return (tmp_id[0]<<24 | tmp_id[1]<<16 | tmp_id[2]<<8 | tmp_id[3]);
}// 初始化LCD
static void _lcd_init(void){_spi_init();//Initialize non-SPI GPIOsgpio_set_direction(PIN_LCD_DC, GPIO_MODE_OUTPUT);gpio_set_direction(PIN_LCD_RST, GPIO_MODE_OUTPUT);gpio_set_direction(PIN_LCD_LED, GPIO_MODE_OUTPUT);//Reset the displaygpio_set_level(PIN_LCD_RST, 0);vTaskDelay(100 / portTICK_RATE_MS);gpio_set_level(PIN_LCD_RST, 1);vTaskDelay(100 / portTICK_RATE_MS);_lcd_cmd(0xF7);_lcd_data((uint8_t[]){0xA9, 0x51, 0x2C, 0x82}, 4);_lcd_cmd(0xC0);_lcd_data((uint8_t[]){0x11, 0x09}, 2);_lcd_cmd(0xC1);_lcd_data((uint8_t[]){0x41}, 1);_lcd_cmd(0xC1);_lcd_data((uint8_t[]){0x41}, 1);_lcd_cmd(0XC5);_lcd_data((uint8_t[]){0x00, 0x0A, 0x80}, 3);_lcd_cmd(0xB1);_lcd_data((uint8_t[]){0xB0, 0x11}, 2);_lcd_cmd(0xB4);_lcd_data((uint8_t[]){0x02}, 1);_lcd_cmd(0xB6);_lcd_data((uint8_t[]){0x02, 0x42}, 2);_lcd_cmd(0xB7);_lcd_data((uint8_t[]){0xc6}, 1);_lcd_cmd(0xBE);_lcd_data((uint8_t[]){0x00, 0x04}, 2);_lcd_cmd(0xE9);_lcd_data((uint8_t[]){0x00}, 1);_lcd_cmd(0x36);_lcd_data((uint8_t[]){(1<<3)|(0<<7)|(1<<6)|(1<<5)}, 1);_lcd_cmd(0x3A);_lcd_data((uint8_t[]){0x66}, 1);_lcd_cmd(0xE0);_lcd_data((uint8_t[]){0x00, 0x07, 0x10, 0x09, 0x17, 0x0B, 0x41, 0x89, 0x4B, 0x0A, 0x0C, 0x0E, 0x18, 0x1B, 0x0F}, 15);_lcd_cmd(0XE1);_lcd_data((uint8_t[]){0x00, 0x17, 0x1A, 0x04, 0x0E, 0x06, 0x2F, 0x45, 0x43, 0x02, 0x0A, 0x09, 0x32, 0x36, 0x0F}, 15);_lcd_cmd(0x11);vTaskDelay(120 / portTICK_RATE_MS);_lcd_cmd(0x29);printf("==== LCD ID: %X ====\n",_lcd_get_id());_lcd_direction(USE_HORIZONTAL); //setting direction_lcd_led_set(ON);_lcd_clear(GREEN);  //clear screen
}
// 背光灯设置
static void _lcd_led_set(uint8_t state){if(state){gpio_set_level(PIN_LCD_LED, 1);}else{gpio_set_level(PIN_LCD_LED, 0);}
}
// lcd显示方向设置
static void _lcd_direction(uint8_t direction){switch(direction){          case 0:                                   lcddev.width=LCD_W;lcddev.height=LCD_H;_lcd_cmd(0x36);_lcd_data((uint8_t[]){(1<<3)|(0<<6)|(0<<7)}, 1);//BGR==1,MY==0,MX==0,MV==0break;case 1:lcddev.width=LCD_H;lcddev.height=LCD_W;_lcd_cmd(0x36);_lcd_data((uint8_t[]){(1<<3)|(0<<7)|(1<<6)|(1<<5)}, 1);//BGR==1,MY==1,MX==0,MV==1break;case 2:                                 lcddev.width=LCD_W;lcddev.height=LCD_H;_lcd_cmd(0x36);_lcd_data((uint8_t[]){(1<<3)|(1<<6)|(1<<7)}, 1);//BGR==1,MY==0,MX==0,MV==0break;case 3:lcddev.width=LCD_H;lcddev.height=LCD_W;_lcd_cmd(0x36);_lcd_data((uint8_t[]){(1<<3)|(1<<7)|(1<<5)}, 1);//BGR==1,MY==1,MX==0,MV==1break; default:break;}
}
// 写一个RGB像素点
static void _lcd_write_data_16bit(uint16_t rgb_data){//18Bit    uint8_t rgb_r = (rgb_data>>8)&0xF8;  //REDuint8_t rgb_g = (rgb_data>>3)&0xFC; //GREENuint8_t rgb_b = rgb_data<<3;      //BLUE_lcd_data((uint8_t[]){rgb_r, rgb_g, rgb_b}, 3);
}
static void _lcd_SetWindows(uint16_t xStar, uint16_t yStar,uint16_t xEnd,uint16_t yEnd){lcddev.setxcmd=0x2A;lcddev.setycmd=0x2B;lcddev.wramcmd=0x2C;_lcd_cmd(lcddev.setxcmd);_lcd_data((uint8_t[]){xStar>>8, 0x00FF&xStar, xEnd>>8, 0x00FF&xEnd}, 4);_lcd_cmd(lcddev.setycmd);   _lcd_data((uint8_t[]){yStar>>8, 0x00FF&yStar, yEnd>>8, 0x00FF&yEnd}, 4);_lcd_cmd(lcddev.wramcmd);   //start writing GRAM
}
//清屏
static void _lcd_clear(uint16_t color){uint32_t i = 0;memset(GRAM_BUFF, 0, USER_BUFF_LEN);_lcd_SetWindows(0,0,lcddev.width-1,lcddev.height-1);for(i=0;i<USER_BUFF_LEN;){GRAM_BUFF[i] = RGB_R(color);GRAM_BUFF[i+1] = RGB_G(color);GRAM_BUFF[i+2] = RGB_B(color);i += 3;}for(i=0;i<(lcddev.height*lcddev.width*3)/USER_BUFF_LEN;i++){_lcd_data(GRAM_BUFF, USER_BUFF_LEN);}
}
//============================================================================
// lcd 初始化、读、写
//============================================================================
void LCD_Init(void){_lcd_init();
}
void LCD_SetCursor(uint16_t Xpos, uint16_t Ypos){                       _lcd_SetWindows(Xpos,Ypos,Xpos+1,Ypos+1);
}
void LCD_Refresh(uint16_t color){_lcd_clear(color);
}void LCD_Disp_Flush(const lv_area_t * area, lv_color_t * color_p){int32_t cnt = (area->x2 - area->x1 + 1) * (area->y2 - area->y1 + 1) * 3;uint16_t i = 0;uint16_t index = 0;uint16_t numTime = 0;   //多少组GRAM_BUFFuint16_t numSurplus = 0;//最后剩下的if(cnt < 0){printf("parameter setting error!!!\n");return;}_lcd_SetWindows(area->x1, area->y1, area->x2, area->y2);// printf("CNT  %d\n\n\n",cnt);if(cnt <= USER_BUFF_LEN){memset(GRAM_BUFF, 0, USER_BUFF_LEN);for(i=0;i<cnt;){GRAM_BUFF[i] = RGB_R(color_p->full);GRAM_BUFF[i+1] = RGB_G(color_p->full);GRAM_BUFF[i+2] = RGB_B(color_p->full);i += 3;color_p++;}_lcd_data(GRAM_BUFF, cnt);}else{numTime = cnt/USER_BUFF_LEN;numSurplus = cnt%USER_BUFF_LEN;printf("NumTime:%d  NumSurplus:%d\n\n", numTime, numSurplus);for(uint16_t j=0;j<numTime;j++){// index = j*USER_BUFF_LEN;memset(GRAM_BUFF, 0, USER_BUFF_LEN);for(i=0;i<USER_BUFF_LEN;){GRAM_BUFF[i] = RGB_R(color_p->full);GRAM_BUFF[i+1] = RGB_G(color_p->full);GRAM_BUFF[i+2] = RGB_B(color_p->full);i += 3;color_p++;}_lcd_data(GRAM_BUFF, USER_BUFF_LEN);}if(numSurplus > 0){// index = cnt-numSurplus;memset(GRAM_BUFF, 0, USER_BUFF_LEN);for(i=0;i<=numSurplus;){GRAM_BUFF[i] = RGB_R(color_p->full);GRAM_BUFF[i+1] = RGB_G(color_p->full);GRAM_BUFF[i+2] = RGB_B(color_p->full);i += 3;color_p++;}_lcd_data(GRAM_BUFF, numSurplus);}}
}

ESP32 的spi 驱动还是挺有意思的
ESP32共有 3 组SPI,这里用的是 HSPI,另一个 VSPI 用于驱动MAX6675 读取温度
ESP32 的 SPI 在传输前和传输完成时可设置回调
transaction_cb_t pre_cb; /**< Callback to be called before a transmission is started.
transaction_cb_t post_cb; /**< Callback to be called after a transmission has completed.,这里就是用的在传输前设置 LCD D/C的 IO 来设置传输的是命令还是数据。
还有个妙用:就是当 SPI 接口不够用时,可以用该回调实现多个 IO 做软CS 片选来复用出多个 SPI。

三、LVGL v8移植

little VGL下载 请点击 转到这篇博客查看

  1. 将下载的 lvgl 移动到 esp-idf-v4.3/components 下
  2. 设置 lvgl 目录下的 lvgl.h 和 lv_conf.h,按需配置即可
  3. 实现 lv_port_displv_port_indevlv_port_fs

port 为接口文件,其中lv_port_disp/lv_port_indev/lv_port_fs 分别对应 LCD 屏绘制,触摸、鼠标、编码器等输入设备,还有文件系统,这里只使能lv_port_disp

// lv_port_disp.c部分函数

void lv_port_disp_init(void){disp_init();static lv_disp_draw_buf_t draw_buf_dsc_1;static lv_color_t buf_1[LV_HOR_RES_MAX * 10];                          /*A buffer for 10 rows*/lv_disp_draw_buf_init(&draw_buf_dsc_1, buf_1, NULL, LV_HOR_RES_MAX * 10);   /*Initialize the display buffer*/static lv_disp_drv_t disp_drv;                         /*Descriptor of a display driver*/lv_disp_drv_init(&disp_drv);                    /*Basic initialization*/disp_drv.hor_res = 480;disp_drv.ver_res = 320;disp_drv.flush_cb = disp_flush;disp_drv.draw_buf = &draw_buf_dsc_1;lv_disp_drv_register(&disp_drv);
}static void disp_init(void){LCD_Init();
}static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p){LCD_Disp_Flush(area, color_p);lv_disp_flush_ready(disp_drv);
}

四、LVGL v8测试线程

// 创建 lvgl 相关的线程

......xSta = xTaskCreate(Thread_lvgl, /* 任务函数指针 */"LVGL Thread",   /* 任务名:调试使用 */15 * 1024,       /* 栈深 */NULL,       /* 任务参数 */2,          /* 优先级. */lvgl_task_handle);  /* 任务 handle */if(pdPASS == xSta){// vTaskStartScheduler();   //不需要printf("create lvgl thread successful!!!\n");}else{printf("create lvgl thread failed!!!\n");return -1;}
......

// lvgl线程

lv_tick_inc(50) 最好用定时器去实现周期调用

void Thread_lvgl(void *arg){lv_init();lv_port_disp_init();        // 显示器初始化
//    lv_port_indev_init();       // 输入设备初始化(如果没有实现就注释掉)
//    lv_port_fs_init();          // 文件系统设备初始化(如果没有实现就注释掉)slim_index();       //小控件测试while(1){lv_tick_inc(50);lv_task_handler();vTaskDelay(10 / portTICK_PERIOD_MS);}
}

//上测试控件

little VGL v8.1 跟 v7.8 的控件设置、style设置还是有很大不同的哈,从v7.8转过来的,还得先适应适应

static void slim_index(void){lv_obj_t *scr = lv_scr_act(); //获取屏幕对象//彩色标签
#if 1static lv_style_t label_styles;lv_style_init(&label_styles);lv_style_set_anim_speed(&label_styles, 50);lv_style_set_text_font(&label_styles, &lv_font_montserrat_20);lv_obj_t * label1 = lv_label_create(scr);lv_label_set_recolor(label1, true);lv_label_set_long_mode(label1, LV_LABEL_LONG_SCROLL_CIRCULAR); /*Circular scroll*/lv_obj_set_width(label1, 120);// lv_obj_add_style(label1, LV_LABEL_PART_MAIN, &label_styles);lv_label_set_text(label1, "#ff0000 Hello# #00ff00 world ! slim su.#");lv_obj_align(label1, LV_ALIGN_TOP_LEFT, 20, 5);lv_obj_add_style(label1, &label_styles, 0);// lv_label_set_anim_speed(label1, 80);
#endif//圆弧
#if 1static lv_style_t style_arc1_bg, style_arc1_indic, style_arc1_knob;lv_style_init(&style_arc1_bg);lv_style_set_arc_width(&style_arc1_bg, 10);lv_style_set_arc_color(&style_arc1_bg, lv_color_make(0, 255, 0));lv_style_init(&style_arc1_indic);lv_style_set_arc_width(&style_arc1_indic, 10);lv_style_set_arc_color(&style_arc1_indic, lv_color_make(255, 0, 0));lv_style_init(&style_arc1_knob);lv_style_set_bg_color(&style_arc1_knob, lv_color_make(255, 0, 0));lv_style_set_bg_opa(&style_arc1_knob, LV_OPA_0);lv_obj_t *arc1 = lv_arc_create(scr);lv_obj_set_size(arc1, 100, 100);lv_obj_set_pos(arc1, 5, 50);lv_arc_set_bg_angles(arc1, 0, 360);lv_arc_set_angles(arc1, 0, 90);lv_obj_add_style(arc1, &style_arc1_bg, LV_PART_MAIN);lv_obj_add_style(arc1, &style_arc1_indic, LV_PART_INDICATOR);lv_obj_add_style(arc1, &style_arc1_knob, LV_PART_KNOB);static lv_style_t style_arc2_bg, style_arc2_indic, style_arc2_knob;lv_style_init(&style_arc2_bg);lv_style_set_arc_width(&style_arc2_bg, 15);lv_style_set_arc_color(&style_arc2_bg, lv_color_make(0xC0, 0xC0, 0xC0));lv_style_init(&style_arc2_indic);lv_style_set_arc_width(&style_arc2_indic, 15);lv_style_set_arc_color(&style_arc2_indic, lv_color_make(0x80, 0x00, 0x80));lv_style_init(&style_arc2_knob);lv_style_set_bg_color(&style_arc2_knob, lv_color_make(0x80, 0x00, 0x80));lv_style_set_bg_opa(&style_arc2_knob, LV_OPA_0);lv_obj_t *arc2 = lv_arc_create(scr);lv_obj_set_size(arc2, 100, 100);lv_obj_set_pos(arc2, 120, 50);lv_arc_set_bg_angles(arc2, 0, 360);lv_arc_set_angles(arc2, 90, 270);lv_obj_add_style(arc2, &style_arc2_bg, LV_PART_MAIN);lv_obj_add_style(arc2, &style_arc2_indic, LV_PART_INDICATOR);lv_obj_add_style(arc2, &style_arc2_knob, LV_PART_KNOB);lv_obj_t *label2 = lv_label_create(arc2);     // 在Arc控件上创建一个标签lv_obj_align(label2, LV_ALIGN_CENTER, 0, 0); // 对齐到Arc控件中心lv_label_set_text(label2, "2");                 // 设置标签文本
//  lv_obj_set_event_cb(arc2, arc_event_handler);
#endif//进度条
#if 1static lv_style_t style_bar1_bg, style_bar1_indic, style_bar_label1;lv_style_init(&style_bar_label1);lv_style_set_text_font(&style_bar_label1, &lv_font_montserrat_18);lv_style_init(&style_bar1_bg);lv_style_set_bg_opa(&style_bar1_bg, LV_OPA_COVER);lv_style_set_bg_color(&style_bar1_bg, lv_color_make(0xFF, 0xFF, 0x00));lv_style_init(&style_bar1_indic);lv_style_set_bg_opa(&style_bar1_indic, LV_OPA_COVER);lv_style_set_bg_color(&style_bar1_indic, lv_palette_main(LV_PALETTE_RED));lv_style_set_bg_grad_color(&style_bar1_indic, lv_palette_main(LV_PALETTE_BLUE));lv_style_set_bg_grad_dir(&style_bar1_indic, LV_GRAD_DIR_VER);bar1 = lv_bar_create(scr);lv_obj_add_style(bar1, &style_bar1_bg, LV_PART_MAIN);lv_obj_add_style(bar1, &style_bar1_indic, LV_PART_INDICATOR);lv_obj_set_size(bar1, 20, 200);lv_obj_align(bar1, LV_ALIGN_TOP_RIGHT, -30, 50);lv_bar_set_range(bar1, 0, 100);label_bar1 = lv_label_create(scr);lv_obj_add_style(label_bar1, &style_bar_label1, LV_PART_MAIN);lv_obj_align_to(label_bar1, bar1, LV_ALIGN_OUT_BOTTOM_MID, 0, 10); lv_label_set_text(label_bar1, "80%");lv_anim_t a;lv_anim_init(&a);lv_anim_set_exec_cb(&a, set_temp);lv_anim_set_time(&a, 8000);lv_anim_set_playback_time(&a, 1000);lv_anim_set_var(&a, bar1);lv_anim_set_values(&a, 0, 100);lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);lv_anim_start(&a);
#endif//复选框
#if 1static lv_style_t style_checkbox1;lv_style_init(&style_checkbox1);lv_style_set_text_font(&style_checkbox1, &lv_font_montserrat_18);lv_style_set_bg_opa(&style_checkbox1, LV_OPA_100);lv_style_set_bg_color(&style_checkbox1, lv_color_make(0xFF, 0x00, 0x00));lv_obj_t *checkbox1 = lv_checkbox_create(scr);lv_obj_set_width(checkbox1, 130);lv_obj_set_pos(checkbox1, 250, 150);lv_obj_add_style(checkbox1, &style_checkbox1, LV_PART_MAIN);lv_checkbox_set_text(checkbox1, "CheckBox");
#endif//滑块
#if 0slider1 = lv_slider_create(scr, NULL);lv_obj_set_size(slider1, 100, 10);lv_slider_set_range(slider1, 0, 100);lv_slider_set_anim_time(slider1, 200);lv_bar_set_value(slider1, 20, LV_ANIM_ON);lv_obj_align(slider1, scr, LV_ALIGN_IN_TOP_RIGHT, -20, 20);
//  lv_obj_set_event_cb(slider1, arc_event_handler);
#endif//按钮
#if 1lv_obj_t *btn1 = lv_btn_create(scr);lv_obj_set_pos(btn1, 250, 50);lv_obj_set_size(btn1, 120, 40);lv_obj_t *label_btn1 = lv_label_create(scr);lv_obj_align_to(label_btn1, btn1, LV_ALIGN_CENTER, 0, 0); lv_label_set_text(label_btn1, "key1");
//  lv_obj_set_event_cb(btn1, arc_event_handler);btn2 = lv_btn_create(scr);lv_obj_set_pos(btn2, 250, 220);lv_obj_set_size(btn2, 80, 40);lv_obj_add_flag(btn2, LV_OBJ_FLAG_CHECKABLE);// lv_btn_set_checkable(btn2, true);// lv_btn_set_state(btn2, true);lv_obj_t *label_btn2 = lv_label_create(scr);lv_obj_align_to(label_btn2, btn2, LV_ALIGN_CENTER, 0, 0); lv_label_set_text(label_btn2, "key2");
//  lv_obj_set_event_cb(btn2, arc_event_handler);
#endif //预加载
#if 1static lv_style_t style_spinner1_bg, style_spinner1_indic;lv_style_init(&style_spinner1_bg);lv_style_set_bg_opa(&style_spinner1_bg, LV_OPA_100);lv_style_set_arc_width(&style_spinner1_bg, 15);lv_style_set_arc_color(&style_spinner1_bg, lv_color_make(0xFF, 0x00, 0xFF));lv_style_init(&style_spinner1_indic);lv_style_set_bg_opa(&style_spinner1_indic, LV_OPA_100);lv_style_set_arc_width(&style_spinner1_indic, 15);lv_style_set_arc_color(&style_spinner1_indic, lv_color_make(0x00, 0x00, 0x80));lv_obj_t * spinner1 = lv_spinner_create(scr, 2000, 60);lv_obj_set_size(spinner1, 80, 80);lv_obj_set_pos(spinner1, 10, 180);lv_obj_add_style(spinner1, &style_spinner1_bg, LV_PART_MAIN);lv_obj_add_style(spinner1, &style_spinner1_indic, LV_PART_INDICATOR);static lv_style_t style_spinner2_bg, style_spinner2_indic;lv_style_init(&style_spinner2_bg);lv_style_set_arc_width(&style_spinner2_bg, 0);lv_style_init(&style_spinner2_indic);lv_style_set_arc_width(&style_spinner2_indic, 8);lv_style_set_arc_color(&style_spinner2_indic, lv_color_make(0x80, 0x00, 0x00));lv_obj_t *spinner2 = lv_spinner_create(scr, 2000, 120);lv_obj_set_size(spinner2, 60, 60);lv_obj_set_pos(spinner2, 120, 180);lv_obj_add_style(spinner2, &style_spinner2_bg, LV_PART_MAIN);lv_obj_add_style(spinner2, &style_spinner2_indic, LV_PART_INDICATOR);
#endif  //线条
#if 1static lv_style_t style_line1;lv_style_init(&style_line1);lv_style_set_line_width(&style_line1, 10);lv_style_set_line_color(&style_line1, lv_color_make(255, 100, 100));lv_style_set_line_rounded(&style_line1, true); //圆角static lv_point_t line_points[] = {{180, 8},{460,40}};lv_obj_t *line1 = lv_line_create(scr);lv_obj_add_style(line1, &style_line1, LV_PART_MAIN);lv_line_set_points(line1, line_points, 2);lv_obj_set_pos(line1, 0, 0);    //点的坐标以此为原点
#endif//led
#if 1static lv_style_t style_led1;lv_style_init(&style_led1);lv_style_set_bg_color(&style_led1, lv_color_make(0xff, 0xff, 0x00));led1 = lv_led_create(scr);lv_obj_set_pos(led1, 350, 215);lv_obj_set_size(led1, 50, 50);lv_led_off(led1);lv_led_set_color(led1, lv_palette_main(LV_PALETTE_YELLOW));
#endif//文本域
#if 1txt1 = lv_textarea_create(scr);lv_obj_set_size(txt1, 380, 30);lv_obj_set_pos(txt1, 50, 280);// lv_textarea_set_one_line(txt1, true);lv_textarea_set_text(txt1, "MAX6675 detect Tempuration: --.-C");
#endif
}//这里就是测试用的,实际项目不能这么写咯
static void set_temp(void * bar, int32_t temp){char str[10] = {0};float temp_val = 0;lv_bar_set_value(bar, temp, LV_ANIM_ON);if(0 == temp%10){sprintf(str, "%d%%", temp);lv_label_set_text(label_bar1, str);}if((led1 != NULL) && (0 == temp%50) && (txt1 != NULL)){lv_led_toggle(led1);max6675_get_temp(&temp_val);sprintf(str, "%2.1fC", temp_val);lv_textarea_del_char(txt1);lv_textarea_del_char(txt1);lv_textarea_del_char(txt1);lv_textarea_del_char(txt1);lv_textarea_del_char(txt1);lv_textarea_add_text(txt1, str);}
}

差不多就是这样咯

想玩下语音控制,小伙伴们有木有好的 ESP 离线语音开发方案 或 开发板推荐吖

[GUI] ESP32(idf)驱动3.5寸SPI-TFT屏移植LittleVGL相关推荐

  1. STM32L010驱动2.7寸电子水墨屏心得亲测可用

    #STM32L010驱动2.7寸电子水墨屏心得 经过几天的折腾调试2.7寸电子水墨屏的驱动,驱动芯片使用GDEW027W3芯片,厂家给了调试驱动,但是一开始使用原厂给的Demon移植过来无法实现局部刷 ...

  2. STM32F103C8T6+2.4寸SPI TFT触摸屏代码+标准库 项目开发

    目录 模块清单: 模块介绍: 1:STM32F103C8T6 2:2.4寸SPI TFT触摸屏 项目结果展示 2.4寸 TFT SPI显示触摸屏 2.4寸 SPI TFT 显示触摸屏代码下载链接: ( ...

  3. ESP32 IDF LVGL 1.47寸圆角屏幕测试

    前言 基于ESP32 IDF框架移植的LVGL,IDF版本为4.3.1,LVGL版本为8.1.1.屏幕为中景园的1.47寸172x320分辨率的圆角IPS,驱动芯片为st7789v3. B站视频效果: ...

  4. [GUI] ESP32(idf)触摸屏(XPT2046)驱动及驱动校准

    1. XPT2046简介 XPT2046是一款4线电阻式触摸屏控制器,包含12位125 kHz采样SAR型a /D转换器. XPT2046可以通过执行两个A/D转换来检测按下的屏幕位置. - 下面简单 ...

  5. 树莓派4B驱动1.8寸ST7735S TFT屏幕

    用到的第三方库的官方文档:Introduction - Luma.LCD: Display drivers for PCD8544, ST7735, ST7789, HT1621, UC1701X, ...

  6. STM32驱动0.96寸OLED液晶屏

    一.OLED简述 1.OLED模块简介 2.SSD1306控制芯片驱动 3.如何显示字符 4.字幕显示原理 二. 上下或左右的滑动显示长字符 三. 显示AHT20的温度和湿度 四.总结 一.OLED简 ...

  7. ESP32驱动3.2寸ILI9341显示屏+XPT2046触摸,GUIslice用户图形库

    ESP32的主板ESPDUINO-32如下: 屏用如下的: 显示驱动用TFT_eSPI,这个显示的速度比adafruit ILI9341快10倍. 一.配置TFT_eSPI: arduino IDE ...

  8. STM32F103ZET6通过SPI驱动2.4寸TFT彩屏

    2.4寸TFT情况如下(此屏幕不带触摸,也无触摸驱动程序,但是有底层) 接线情况如下 主要程序如下: main.c #include "delay.h" #include &quo ...

  9. 1.8寸TFT LCD128X160 ST7735S SPI串口屏驱动示例

    1.8寸TFT LCD128X160 ST7735S SPI串口屏驱动示例 1.8寸TFT LCD128X160 ST7735S SPI串口屏 驱动资料 由中景园提供的,里面包含了: 链接:https ...

最新文章

  1. IOS类似9.png
  2. 论文浅尝 | WWW2020 - 知识图谱中的实体摘要:算法、评价和应用 (PPT)
  3. memcpy和strcpy函数
  4. java明星游戏_#IT明星不是梦#Java14不得不知的5个新功能
  5. EverWeb for Mac(网页设计软件)v3.5.1中文版
  6. 刷机出现未将对象引用设置到对象的实例是什么意思_Java 虚拟机 2:Java 内存区域及对象简单理解...
  7. python下dicom格式图像转化为jpg格式图像
  8. dm9000a驱动源码分析
  9. 申请Freenom免费顶级域名的正确做法
  10. 计算机软件又必须包括什么,计算机系统应包括硬件和软件两个子系统,硬件和软件又必须依次分别包括______?...
  11. java将元素添加进数组_如何在Java中将元素添加到数组的中点?
  12. v4l2_async_subdev_notifier_register 分析
  13. 字体 跨域访问_21个访问量最大的免费字体网站
  14. win2d 渐变颜色
  15. VMware ESXI上开虚机玩KVM
  16. 2021年安全员-C证(上海市)考试APP及安全员-C证(上海市)新版试题
  17. 天融信上网行为管理如何做短信验证?
  18. arp broadcast enable命令
  19. python3 列表生成式,字典生成式,generator列表生成器的应用
  20. 数据结构与算法37-堆石子

热门文章

  1. 中国AIGC产业全景图报告
  2. mov和lea指令的区别
  3. 全卷积(fully convolution)
  4. Android图片加载神器之Fresco-加载图片基础[详细图解Fresco的使用]
  5. 无心剑英译北岛诗9首
  6. 华为在印度市场再受挫折,跌出智能手机市场份额前五
  7. 盘点国内外8个好用的二维码平台
  8. itunes connect开发者账号的区别,企业账号,个人账号,公司团队账号,教育账号
  9. Zookeeper分布式应用协调软件的核心概念以及部署
  10. 09Python爬虫---爬虫实战之京东图片