【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】
前面为了开发lvgl,我们做了一些准备。这里面包括了屏幕的驱动,触摸屏的驱动,屏幕和lvgl的适配,触摸和lvgl的适配,以及触摸的简单修改和标定。做好了这几部分之后,基本上就可以做lvgl的开发了。
1、lvgl开发基本就是纯软开发
这里的lvgl,其实不光用在mcu上,还比较多的用在了linux上。比如很多的linux界面,早期的时候可能用qt还是比较多的,现在越来越多的开发者转到了lvgl上面。如果底层驱动都ok了,相关的适配也就没有问题了,那么l此时vgl之上的开发基本就是纯软开发了。
2、lvgl可以用windows仿真
对于lvgl开发的同学,如果对底层参与不多,完全可以先用windows vs开发后,再移植到嵌入式设备上面,这样效率反而是最高的。反之,如果每一步都是用硬件去开发,反而效率是最低的。
3、纯软+ai开发
软件开发中,ai适配最好的其实就是纯软开发。比如一般的网页前端开发、java后端开发,这部分用ai的其实已经很多了。那现在有了ai之后,用ai做lvgl开发也是非常方便的。对于简单的、不复杂的、页面不多的应用,ai开发的效率远远高于个人本身。所以大家在开发的过程当中,对于纯软这部分呢,也要尽可能用ai去做。这部分既然效率高,是趋势,我们不妨好好研究、好好去利用起来就好了。
4、以抽奖程序作为demo进行ai开发
前面我们用ai写了一个进度条程序。其实自己稍微改一下,或者让ai改一下界面和逻辑,就可以变成一个抽奖程序。当然,下面代码里面因为还涉及到了驱动和适配的内容,稍显复杂。而真正和业务相关的部分,代码不算多的。
#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 "esp_log.h" #include "esp_timer.h" #include "lvgl.h" static void lvgl_task(void *arg); // ================= CONFIG ================= #define LCD_W 480 #define LCD_H 320 #define PIN_MOSI 13 #define PIN_CLK 14 #define PIN_CS 15 #define PIN_DC 2 #define PIN_RST 4 #define PIN_BL 12 #define TP_MOSI 23 #define TP_MISO 19 #define TP_CLK 18 #define TP_CS 5 #define TP_IRQ 27 static spi_device_handle_t spi_lcd; static spi_device_handle_t spi_tp; static const char *TAG = "ILI9488_LVGL"; // ====================================================== // GPIO control // ====================================================== static inline void dc_cmd(void) { gpio_set_level(PIN_DC, 0); } static inline void dc_data(void) { gpio_set_level(PIN_DC, 1); } static void lcd_reset(void) { gpio_set_level(PIN_RST, 0); vTaskDelay(pdMS_TO_TICKS(100)); gpio_set_level(PIN_RST, 1); vTaskDelay(pdMS_TO_TICKS(150)); } // ====================================================== // SPI CMD / DATA // ====================================================== static void lcd_cmd(uint8_t cmd) { spi_transaction_t t = { .length = 8, .tx_buffer = &cmd, }; dc_cmd(); spi_device_polling_transmit(spi_lcd, &t); } static void lcd_data(const void *data, int len) { spi_transaction_t t = { .length = len * 8, .tx_buffer = data, }; dc_data(); spi_device_polling_transmit(spi_lcd, &t); } // ====================================================== // ILI9488 INIT (stable version) // ====================================================== static void ili9488_init(void) { lcd_reset(); lcd_cmd(0x01); // Software reset vTaskDelay(pdMS_TO_TICKS(120)); lcd_cmd(0x11); // Sleep out vTaskDelay(pdMS_TO_TICKS(120)); // RGB565 mode (important for stability) lcd_cmd(0x3A); uint8_t pix = 0x66; lcd_data(&pix, 1); // MADCTL (display orientation) lcd_cmd(0x36); uint8_t mad = 0x28; // change to 0x28 if upside-down lcd_data(&mad, 1); lcd_cmd(0x29); // Display ON vTaskDelay(pdMS_TO_TICKS(50)); ESP_LOGI(TAG, "LCD init OK"); } // ====================================================== // Set drawing window // ====================================================== static void set_window(int x1,int y1,int x2,int y2) { uint8_t d[4]; lcd_cmd(0x2A); d[0]=x1>>8; d[1]=x1; d[2]=x2>>8; d[3]=x2; lcd_data(d,4); lcd_cmd(0x2B); d[0]=y1>>8; d[1]=y1; d[2]=y2>>8; d[3]=y2; lcd_data(d,4); lcd_cmd(0x2C); } // ====================================================== // Touch read (XPT2046 style) // ====================================================== static uint16_t tp_read(uint8_t cmd) { uint8_t tx[3] = {cmd,0,0}; uint8_t rx[3] = {0}; spi_transaction_t t = { .length = 24, .tx_buffer = tx, .rx_buffer = rx, }; spi_device_polling_transmit(spi_tp, &t); return ((rx[1] << 8) | rx[2]) >> 3; } static void touch_read(lv_indev_drv_t *drv, lv_indev_data_t *data) { static bool touched = false; if (gpio_get_level(TP_IRQ) == 0) { >5、后续验证和测试如之前所说,如果是纯lvgl的开发,可以先用windows vs2019 + lvgl8.3仿真好,再port到设备上面进行测试。哪怕是串口、232、485、can这些,其实也是可以通过serial做一个接口,先在windows开发好之后,再移植到设备,这样效率才是最高的。
软硬分离的好处,就是各司其职。如果软件规模不大,软硬件都是一个人来做,这种情况还可以接受。一旦软件规模超过一个人能力的范围,就必须要软硬分家了。