建立esp-idf工程
1. 添加自己的component时一直报错 “undefined reference to”
使用了很多方法都不行,起初以为是CMakeLists没有写对,按着乐鑫的官方文档一步一步重写还是报错。偶然看到说要去掉函数的static前缀,去掉之后编译通过。
2. “fatal error: esp_vfs_fat.h: No such file or directory”
在/component下使用命令创建新组件
idf.py create-component
自己的component当中使用了已经包装好的系统组件,我这里就是使用了fatfs组件,需要去到component的CMakeLists添加REQUIRES:
//CMakeList.txt
idf_component_register(SRCS "sd.c"
INCLUDE_DIRS "include"
REQUIRES fatfs)
3. 注意!!! 添加新的component后,使用“idf.py fullclean”清除build重新编译
否则可能会出现“undefine reference to”错误
SD驱动
1. 换引脚
使用esp-idf当中的sd_card_example_main.c的简单驱动作为组件,esp-idf当中使用了GPIO2作为MISO,芯片重启时受到影响,根据稚晖君的提示MISO改到GPIO26,简单define一下就好:
#define PIN_NUM_MISO 26
2. SPI分配
参考
由于屏幕和SD卡都使用SPI通信,而esp-idf当中默认的的SPI都是HSPI,不更改的话在同时使用屏幕和SD时会产生冲突并报错:
设置SD驱动使用HSPI:
//注意DMA的使用可能会冲突,需要更改DMA通道
#define SPI_DMA_CHAN 2
spi_bus_initialize(HSPI_HOST/*host.slot*/, &bus_cfg, SPI_DMA_CHAN);
LVGL
1. ST7789
(1)移植LVGL库时报错 implicit declaration of function ‘gpio_pad_select_gpio’
st7789.c当中的函数gpio_pad_select_gpio要替换成函数gpio_reset_pin
(2)ST7789颜色显示调整
参考链接这个文章帮助很大,不过好像不是原出处,害怕以后找不到了,截图了几个配置图,侵删。
这里面选择驱动屏幕的是HSPI还是VSPI,按照我的这个设置屏幕这里使用VSPI。
(3)ST7789镜像
参考
在lvgl_tft文件夹当中找到st7789.c,在st7789_set_orientation() 函数当中更改写入MADCTL(0x36)当中的值,根据自己的情况调整:
//static void st7789_set_orientation(uint8_t orientation)函数中添加
uint8_t mirror;
mirror = 0x20;
st7789_send_cmd(ST7789_MADCTL);
st7789_send_data((void *) &mirror, 1);
2. 文件系统移植
使用~/esp32/项目名称/components/lvgl/examples/porting当中的移植模板,将它作为组件添加到项目当中。
文件系统的移植主要照搬的稚晖君的函数定义,复刻小电视时间比较赶,具体还不太理解。
拿到模板后主要有这几个地方需要更改:
#define SD_LETTER 'P' //SD卡挂载字母
typedef FIL file_t; // 把FIL类型定义成file_t
typedef FF_DIR dir_t; // 把DIR类型定义成dir_t
//具体函数的内容照抄,注意形参名可能不一样需要更改
移植好之后可以从SD卡读一张图片到屏幕上来测试是否成功。
3. 输入设备移植
(1)报错“Guru Meditation Error: Core 0 panic’ed (LoadProhibited). Exception was unhandled.”
输入系统的移植有一个大坑,一定要把显示驱动初始化的语句放在输入设备之前不然会报错Guru Meditation Error: Core 0 panic’ed (LoadProhibited). Exception was unhandled.
这里的错误提示引用到了非法地址,在网上查询后,这个错误通常在使用空指针寻址时发生。一番查找后发现
//lv_port_indev.c当中indev_encoder一直是空指针导致后来group设置时一直引用空指针触发错误
indev_encoder = lv_indev_drv_register(&indev_drv);
//lv_indev_t * lv_indev_drv_register(lv_indev_drv_t * driver)
if(driver->disp == NULL) driver->disp = lv_disp_get_default();
if(driver->disp == NULL) {
LV_LOG_WARN("lv_indev_drv_register: no display registered hence can't attach the indev to "
"a display");
return NULL;
}
而lv_indev_drv_register()中会先检查显示驱动是否装载好,而我的输入设备初始化刚好在显示设备初始话之前,我推测可能会有影响,调整顺序后不再报错。不过我的串口控制台上并没有显示LV_LOG_WARN()当中的提示信息。这里还不太清楚怎么回事。
桌面框架
待续