{"id":693,"date":"2025-02-28T19:35:54","date_gmt":"2025-02-28T11:35:54","guid":{"rendered":"https:\/\/www.yanwenkai.com\/?p=693"},"modified":"2025-02-28T19:39:43","modified_gmt":"2025-02-28T11:39:43","slug":"lcd%e8%a7%a6%e6%8e%a7%e5%b1%8f%e7%a7%bb%e6%a4%8d%e4%b9%8blvgl%e7%a7%bb%e6%a4%8d%e7%af%87","status":"publish","type":"post","link":"https:\/\/www.yanwenkai.com\/?p=693","title":{"rendered":"LCD\u89e6\u63a7\u5c4f\u79fb\u690d\u4e4blvgl\u79fb\u690d\u7bc7"},"content":{"rendered":"<h1>1 \u524d\u8a00<\/h1>\n<p>&emsp;&emsp;\u514b\u670d\u4e86\u8fd9\u4e48\u591a\u56f0\u96be\u7ec8\u4e8e\u4f7f\u7528lvgl\u70b9\u4eae\u5c4f\u5e55\u4e86\uff0c\u5230\u4e86\u8fd9\u6b65\u4e5f\u7b97\u662f\u62e8\u5f00\u4e91\u96fe\u89c1\u5929\u65e5\u4e86\u3002\u56e0\u4e3a\u6253\u901a\u4e86\u4ece\u8f6f\u4ef6\u5230\u786c\u4ef6\u7684\u6574\u4e2a\u6d41\u7a0b\uff0c\u6240\u4ee5\u540e\u9762\u6709\u65f6\u95f4\u4e5f\u53ef\u4ee5\u641e\u4e00\u4e9b\u82b1\u6d3b\u4e86\u3002<\/p>\n<h1>2 \u57fa\u4e8eframebuffer\u7684lvgl\u79fb\u690d<\/h1>\n<p>&emsp;&emsp;\u5c4f\u5e55\u663e\u793a\u9a71\u52a8\u91c7\u7528framebuffer\u6846\u67b6\uff0c\u79fb\u690dlvgl\u65f6\u4e5f\u8981\u57fa\u4e8e\u6b64\u6765\u914d\u7f6e\u3002\u56e0\u4e3a\u5b98\u65b9\u6559\u7a0b\u975e\u5e38\u5168\u9762\uff0c\u6211\u4e5f\u53ea\u662f\u9002\u914d\u65f6\u4fee\u6539\u4e86\u4e00\u4e9b\u4ee3\u7801\u800c\u5df2\uff1b\u6240\u4ee5\u56fe\u7701\u4e8b\uff0c\u8fd9\u91cc\u5c31\u57fa\u4e8e\u5b98\u65b9\u6559\u7a0b\u7f16\u5199\u6211\u7684\u535a\u5ba2\u4e86\u3002<\/p>\n<h2>2.1 lvgl\u7684\u79fb\u690d<\/h2>\n<h3>2.1.1 \u6240\u9700\u8d44\u6e90<\/h3>\n<table>\n<thead>\n<tr>\n<th style=\"text-align: center;\">\u8d44\u6e90\u540d\u79f0\u8d44\u6e90\u540d\u79f0<\/th>\n<th style=\"text-align: center;\">\u4ed3\u5e93\u5730\u5740<\/th>\n<th style=\"text-align: center;\">\u63cf\u8ff0<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td style=\"text-align: center;\">lvgl<\/td>\n<td style=\"text-align: center;\"><a href=\"https:\/\/github.com\/lvgl\/lvgl.git\">https:\/\/github.com\/lvgl\/lvgl.git<\/a><\/td>\n<td style=\"text-align: center;\">LVGL\u56fe\u5f62\u754c\u9762\u63a7\u4ef6\u7684\u6e90\u7801\u4ee5\u53ca\u5c11\u91cf\u4f8b\u7a0b<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\">lv_drivers<\/td>\n<td style=\"text-align: center;\"><a href=\"https:\/\/github.com\/lvgl\/lv_drivers.git\">https:\/\/github.com\/lvgl\/lv_drivers.git<\/a><\/td>\n<td style=\"text-align: center;\">\u9a71\u52a8LVGL\u56fe\u5f62\u754c\u9762\u7684\u9a71\u52a8\u63a5\u53e3\u6e90\u4ee3\u7801<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\">lv_demos<\/td>\n<td style=\"text-align: center;\"><a href=\"https:\/\/github.com\/lvgl\/lv_demos.git\">https:\/\/github.com\/lvgl\/lv_demos.git<\/a><\/td>\n<td style=\"text-align: center;\">LVGL\u7684\u4f8b\u7a0b<\/td>\n<\/tr>\n<tr>\n<td style=\"text-align: center;\">lv_port_linux_frame_buffer<\/td>\n<td style=\"text-align: center;\"><a href=\"https:\/\/github.com\/lvgl\/lv_port_linux_frame_buffer.git\">https:\/\/github.com\/lvgl\/lv_port_linux_frame_buffer.git<\/a><\/td>\n<td style=\"text-align: center;\">\u9002\u914d\u6709Framebuffer\u7684linux\u7cfb\u7edf\u7684\u63a5\u53e3<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h3>2.1.2 \u62c9\u53d6\u8d44\u6e90<\/h3>\n<p>&emsp;&emsp;\u5728\u6839\u76ee\u5f55\u4e0b\u521b\u5efa\u4e00\u4e2a\u6587\u4ef6\u5939\u5b58\u653e\u5b98\u65b9\u6e90\u7801\uff1a<\/p>\n<pre><code class=\"language-c\">luckfox@luckfox:~$ mkdir lvgl\nluckfox@luckfox:~$ cd lvgl<\/code><\/pre>\n<p>&emsp;&emsp;\u62c9\u53d6\u8d44\u6e90\uff1a<\/p>\n<pre><code class=\"language-c\">git clone -b v8.1.0 https:\/\/github.com\/lvgl\/lvgl.git\ngit clone -b v8.1.0 https:\/\/github.com\/lvgl\/lv_drivers.git\ngit clone -b v8.1.0 https:\/\/github.com\/lvgl\/lv_demos.git\ngit clone --branch release\/v8.2 --single-branch https:\/\/github.com\/lvgl\/lv_port_linux_frame_buffer.git<\/code><\/pre>\n<p>&emsp;&emsp;\u6210\u529f\u62c9\u53d6\u540e\uff0c\u5728\u6839\u76ee\u5f55\u4e0b\u521b\u5efa\u4e00\u4e2a\u5de5\u7a0b\u76ee\u5f55\uff0c\u5e76\u521b\u5efa\u4e00\u4e2a\u5de5\u7a0b\uff1a<\/p>\n<pre><code class=\"language-c\">luckfox@luckfox:~$ mkdir lvgl_project\nluckfox@luckfox:~$ cd lvgl_project\/\nluckfox@luckfox:~\/lvgl_project$ mkdir project_01\nluckfox@luckfox:~\/lvgl_project$ cd project_01\/<\/code><\/pre>\n<h3>2.1.3 \u590d\u5236\u6587\u4ef6<\/h3>\n<ul>\n<li>\u590d\u5236\u6839\u76ee\u5f55\u4e0b\u7684 lvgl \u6587\u4ef6\u5939\u4e2d\u7684 lvgl\u3001lv_drivers \u76ee\u5f55<\/li>\n<li>\u590d\u5236 lv_port_linux_frame_buffer \u4e2d\u7684 main.c \u4e0e Makefile<\/li>\n<li>\u590d\u5236 lvgl \u4e2d\u7684 lv_conf_template.h \u91cd\u547d\u540d\u4e3a lv_conf.h<\/li>\n<li>\u590d\u5236 lv_drivers \u4e2d\u7684 lv_drv_conf_template.h \u91cd\u547d\u540d\u4e3a lv_drv_conf.h<\/li>\n<\/ul>\n<pre><code class=\"language-c\">cp -r ~\/lvgl\/lvgl .\/\ncp -r ~\/lvgl\/lv_drivers .\/\ncp ~\/lvgl\/lvgl\/lv_conf_template.h .\/lv_conf.h\ncp ~\/lvgl\/lv_drivers\/lv_drv_conf_template.h  .\/lv_drv_conf.h\ncp ~\/lvgl\/lv_port_linux_frame_buffer\/main.c .\/\ncp ~\/lvgl\/lv_port_linux_frame_buffer\/Makefile .\/<\/code><\/pre>\n<p>&emsp;&emsp;\u67e5\u770b project_01 \u5de5\u7a0b\u76ee\u5f55\u4e0b\u6587\u4ef6\uff1a<\/p>\n<pre><code class=\"language-c\">luckfox@luckfox:~\/lvgl_project\/project_01$ ls -l\n\u603b\u7528\u91cf 64 \n-rw-rw-r--  1 luckfox luckfox 29023 12\u6708 27 19:14 lv_conf.h\ndrwxrwxr-x 12 luckfox luckfox  4096 12\u6708 27 19:14 lv_drivers\n-rw-rw-r--  1 luckfox luckfox 15184 12\u6708 27 19:14 lv_drv_conf.h\ndrwxrwxr-x 12 luckfox luckfox  4096 12\u6708 27 19:14 lvgl\n-rw-rw-r--  1 luckfox luckfox  2350 12\u6708 27 19:14 main.c\n-rw-rw-r--  1 luckfox luckfox  2321 12\u6708 27 19:14 Makefile<\/code><\/pre>\n<h3>2.1.4 \u4fee\u6539\u6587\u4ef6<\/h3>\n<p>lv_conf.h<br \/>\n1.\u4f7f\u80fd<br \/>\n&emsp;&emsp;\u5c06\u4e00\u5f00\u59cb\u7684 #if 0 \u6539\u6210 #if 1\u3002<\/p>\n<pre><code class=\"language-c\">\/* clang-format off *\/\n#if 1 \/*Set it to \"1\" to enable content*\/<\/code><\/pre>\n<p>2.\u5206\u914d\u663e\u5b58<br \/>\n&emsp;&emsp;\u4f7f\u80fd LV_MEM_CUSTOM \uff0c\u9009\u62e9\u81ea\u884c\u5206\u914d\u663e\u5b58\u3002<\/p>\n<pre><code class=\"language-c\">\/*1: use custom malloc\/free, 0: use the built-in <code>lv_mem_alloc()<\/code> and <code>lv_mem_free()<\/code>*\/#define LV_MEM_CUSTOM 1<\/code><\/pre>\n<p>3.\u5237\u65b0\u65f6\u95f4<br \/>\n&emsp;&emsp;\u5c06\u539f\u672c\u7684 30ms \u8c03\u6574\u6210\u4e86 10ms\u3002<\/p>\n<pre><code class=\"language-c\">\/*Default display refresh period. LVG will redraw changed areas with this period time*\/#define LV_DISP_DEF_REFR_PERIOD 10      \/*[ms]*\/\/*Input device read period in milliseconds*\/#define LV_INDEV_DEF_READ_PERIOD 10     \/*[ms]*\/<\/code><\/pre>\n<p>4.TICK\u914d\u7f6e<br \/>\n&emsp;&emsp;\u4f7f\u80fd LV_TICK_CUSTOM \uff0c\u9009\u62e9\u5728\u5e94\u7528\u7a0b\u5e8f\u4e2d\u81ea\u5b9a\u4e49 Tick \u5b9a\u65f6\u5668\u914d\u7f6e\u51fd\u6570\u3002<br \/>\n&emsp;&emsp;\u539f\u5185\u5bb9\uff1a<\/p>\n<pre><code class=\"language-c\">#define LV_TICK_CUSTOM 0#if LV_TICK_CUSTOM\n#define LV_TICK_CUSTOM_INCLUDE \"Arduino.h\"  \/*Header for the system time function*\/\n#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) \/*Expression evaluating to current system time in ms*\/\n#endif \/*LV_TICK_CUSTOM*\/<\/code><\/pre>\n<p>&emsp;&emsp;\u66f4\u6539\u4e3a\uff1a<\/p>\n<pre><code class=\"language-c\">#define LV_TICK_CUSTOM 1\n#if LV_TICK_CUSTOM    \n   #define LV_TICK_CUSTOM_INCLUDE <stdint.h>         \/*Header for the system time function*\/    \n   #define LV_TICK_CUSTOM_SYS_TIME_EXPR (custom_tick_get())    \/*Expression evaluating to current system time in ms*\/\n#endif   \/*LV_TICK_CUSTOM*\/<\/code><\/pre>\n<p>lv_drv_conf.h<br \/>\n1.\u4f7f\u80fd<br \/>\n&emsp;&emsp;\u5c06\u4e00\u5f00\u59cb\u7684 #if 0 \u6539\u6210 #if 1\u3002<\/p>\n<pre><code class=\"language-c\">\/* clang-format off *\/\n#if 1 \/*Set it to \"1\" to enable the content*\/<\/code><\/pre>\n<p>2.\u652f\u6301\u8bbe\u5907<br \/>\n&emsp;&emsp;\u4f7f\u80fd USE_FBDEV \uff0c\u652f\u6301Framebuffer\u8bbe\u5907\u3002<\/p>\n<pre><code class=\"language-c\">\/*----------------------------------------- *  Linux frame buffer device (\/dev\/fbx) *-----------------------------------------*\/\n#ifndef USE_FBDEV\n#  define USE_FBDEV           1\n#endif\n#if USE_FBDEV#  define FBDEV_PATH          \"\/dev\/fb0\"\n#endif<\/code><\/pre>\n<p>Makefile<br \/>\n&emsp;&emsp;\u66ff\u6362\u539f Makefile \u5185\u5bb9\uff0c\u5c06 Makefile \u4e2d <SDK Directory> \u4fee\u6539\u4e3a\u81ea\u5df1\u7684 SDK \u8def\u5f84\uff0c\u5982 \/home\/luckfox\/luckfox-pico\/\u3002<\/p>\n<pre><code class=\"language-makefile\">#\n# Makefile\n#\nCC = <SDK Directory>\/tools\/linux\/toolchain\/arm-rockchip830-linux-uclibcgnueabihf\/bin\/arm-rockchip830-linux-uclibcgnueabihf-gcc\nLVGL_DIR_NAME   ?= lvgl\nLVGL_DIR        ?= .\n\nWARNINGS        := -Wall -Wshadow -Wundef -Wmissing-prototypes -Wno-discarded-qualifiers -Wall -Wextra -Wno-unused-function -Wno-error=strict-prototypes -Wpointer-arith \\\n                    -fno-strict-aliasing -Wno-error=cpp -Wuninitialized -Wmaybe-uninitialized -Wno-unused-parameter -Wno-missing-field-initializers -Wtype-limits -Wsizeof-pointer-memaccess \\\n                    -Wno-format-nonliteral -Wno-cast-qual -Wunreachable-code -Wno-switch-default -Wreturn-type -Wmultichar -Wformat-security -Wno-ignored-qualifiers -Wno-error=pedantic \\\n                    -Wno-sign-compare -Wno-error=missing-prototypes -Wdouble-promotion -Wclobbered -Wdeprecated -Wempty-body -Wtype-limits -Wshift-negative-value -Wstack-usage=2048 \\\n                    -Wno-unused-value -Wno-unused-parameter -Wno-missing-field-initializers -Wuninitialized -Wmaybe-uninitialized -Wall -Wextra -Wno-unused-parameter \\\n                    -Wno-missing-field-initializers -Wtype-limits -Wsizeof-pointer-memaccess -Wno-format-nonliteral -Wpointer-arith -Wno-cast-qual -Wmissing-prototypes \\\n                    -Wunreachable-code -Wno-switch-default -Wreturn-type -Wmultichar -Wno-discarded-qualifiers -Wformat-security -Wno-ignored-qualifiers -Wno-sign-compare -std=c99\nCFLAGS          ?= -O3 -g0 -I$(LVGL_DIR)\/ $(WARNINGS)\nLDFLAGS         ?= -lm\nBIN             = demo\nBUILD_DIR       = .\/build\nBUILD_OBJ_DIR   = $(BUILD_DIR)\/obj\nBUILD_BIN_DIR   = $(BUILD_DIR)\/bin\n\nprefix          ?= \/usr\nbindir          ?= $(prefix)\/bin\n\n#Collect the files to compile\nMAINSRC = $(wildcard .\/*.c)\n\ninclude $(LVGL_DIR)\/lvgl\/lvgl.mk\ninclude $(LVGL_DIR)\/lv_drivers\/lv_drivers.mk\n\n# CSRCS             +=$(LVGL_DIR)\/mouse_cursor_icon.c \n\nOBJEXT          ?= .o\n\nAOBJS           = $(ASRCS:.S=$(OBJEXT))\nCOBJS           = $(CSRCS:.c=$(OBJEXT))\n\nMAINOBJ         = $(MAINSRC:.c=$(OBJEXT))\n\nSRCS            = $(ASRCS) $(CSRCS) $(MAINSRC)\nOBJS            = $(AOBJS) $(COBJS) $(MAINOBJ)\nTARGET          = $(addprefix $(BUILD_OBJ_DIR)\/, $(patsubst .\/%, %, $(OBJS)))\n\n## MAINOBJ -> OBJFILES\n\nall: default\n\n$(BUILD_OBJ_DIR)\/%.o: %.c\n    @mkdir -p $(dir $@)\n    @$(CC)  $(CFLAGS) -c $< -o $@\n    @echo \"CC $<\"\ndefault: $(TARGET)\n    @mkdir -p $(dir $(BUILD_BIN_DIR)\/)\n    $(CC) -o $(BUILD_BIN_DIR)\/$(BIN) $(TARGET) $(LDFLAGS)\n\nclean: \n    rm -rf $(BUILD_DIR)\n\ninstall:\n    install -d $(DESTDIR)$(bindir)\n    install $(BUILD_BIN_DIR)\/$(BIN) $(DESTDIR)$(bindir)\n\nuninstall:\n    $(RM) -r $(addprefix $(DESTDIR)$(bindir)\/,$(BIN))<\/code><\/pre>\n<p>main.c<br \/>\n1.\u6ce8\u91ca\u5934\u6587\u4ef6<\/p>\n<pre><code class=\"language-c\">\/\/ #include \"lvgl\/demos\/lv_demos.h\"\n\/\/ #include \"lv_drivers\/indev\/evdev.h\"<\/code><\/pre>\n<p>1.\u4fee\u6539\u5c4f\u5e55\u5206\u8fa8\u7387<\/p>\n<pre><code class=\"language-c\">#define DISP_BUF_SIZE (240 * 240)...disp_drv.hor_res    = 240;disp_drv.ver_res    = 240;<\/code><\/pre>\n<p>&emsp;&emsp;\u7167\u7740\u505a\u5b8c\u540e\uff0c\u56e0\u4e3a\u5c4f\u5e55\u5c3a\u5bf8\u95ee\u9898\uff0c\u6240\u4ee5\u8fd9\u91cc\u4fee\u6539\u4e00\u4e0b\u3002<\/p>\n<pre><code class=\"language-c\">\/\/#include \"lv_demos\/lv_demo.h\"\n#define DISP_BUF_SIZE (480 * 320)<\/code><\/pre>\n<p>2.\u6ce8\u91ca\u4e0b\u9762\u4ee3\u7801<br \/>\n&emsp;&emsp;\u65e0\u5916\u90e8\u8f93\u5165\u8bbe\u5907\uff0c\u6ce8\u91ca\u4e0b\u9762\u4ee3\u7801\uff1a<\/p>\n<pre><code class=\"language-c\">evdev_init();\nstatic lv_indev_drv_t indev_drv_1;\nlv_indev_drv_init(&indev_drv_1); \/*Basic initialization*\/indev_drv_1.type = LV_INDEV_TYPE_POINTER;\n\/*This function will be called periodically (by the library) to get the mouse position and state*\/\nindev_drv_1.read_cb = evdev_read;\nlv_indev_t *mouse_indev = lv_indev_drv_register(&indev_drv_1);<\/code><\/pre>\n<p>&emsp;&emsp;\u672a\u79fb\u690d\u9f20\u6807\u6837\u5f0f\uff0c\u6ce8\u91ca\u4e0b\u9762\u4ee3\u7801\uff1a<\/p>\n<pre><code class=\"language-c\">\/*Set a cursor for the mouse*\/\nLV_IMG_DECLARE(mouse_cursor_icon)lv_obj_t * cursor_obj = lv_img_create(lv_scr_act()); \/*Create an image object for the cursor *\/\nlv_img_set_src(cursor_obj, &mouse_cursor_icon);\/*Set the image source*\/lv_indev_set_cursor(mouse_indev, cursor_obj);  \/*Connect the image  object to the driver*\/<\/code><\/pre>\n<p>&emsp;&emsp;\u4e0d\u4f7f\u7528\u5b98\u65b9demo\uff0c\u6ce8\u91ca\u4e0b\u9762\u4ee3\u7801\uff1a<\/p>\n<pre><code class=\"language-c\">\/*Create a Demo*\/lv_demo_widgets();<\/code><\/pre>\n<h3>2.1.5 \u7f16\u8bd1\u548c\u8fd0\u884c<\/h3>\n<p>&emsp;&emsp;\u4e0a\u8ff0\u6587\u4ef6\u4fee\u6539\u5b8c\u6210\u540e\uff0c\u5728\u547d\u4ee4\u884c\u8f93\u5165make\u547d\u4ee4\u7f16\u8bd1\u5de5\u7a0b\uff0c\u7f16\u8bd1\u5b8c\u6210\u540e\u4f1a\u5728\/build\/bin\u76ee\u5f55\u4e0b\u751f\u6210\u4e00\u4e2a\u53ef\u6267\u884c\u6587\u4ef6demo\uff0c\u7f16\u8bd1\u540e\u7684\u76ee\u5f55\u7ed3\u6784\u5982\u4e0b\uff1a<\/p>\n<pre><code class=\"language-c\">project_01\/\n\u251c\u2500\u2500 build\n\u2502   \u251c\u2500\u2500 bin\n\u2502   \u2502   \u2514\u2500\u2500 demo\n\u2502   \u2514\u2500\u2500 obj\n\u2502       \u251c\u2500\u2500 lv_drivers\n\u2502       \u251c\u2500\u2500 lvgl\n\u2502       \u2514\u2500\u2500 ...\n\u251c\u2500\u2500 lv_conf.h\n\u251c\u2500\u2500 lv_drivers\n\u251c\u2500\u2500 lv_drv_conf.h\n\u251c\u2500\u2500 lvgl\n\u251c\u2500\u2500 main.c\n\u2514\u2500\u2500 Makefile<\/code><\/pre>\n<p>&emsp;&emsp;\u6211\u4eec\u53ea\u9700\u8981\u5c06demo\u62f7\u8d1d\u81f3\u5f00\u53d1\u677f\uff0c\u5373\u53ef\u5728\u677f\u5b50\u4e0a\u8fd0\u884c\u7a0b\u5e8f\u3002\u540e\u7eed\u53ef\u4ee5\u6839\u636e\u9700\u6c42\u81ea\u884c\u4fee\u6539 main.c \u6587\u4ef6\u548c\u6dfb\u52a0\u6587\u4ef6\uff0c\u5b9e\u73b0\u81ea\u5df1\u60f3\u8981\u7684\u663e\u793a\u6548\u679c\u3002<\/p>\n<h2>2.2 \u914d\u7f6e\u81ea\u5df1\u7684\u9879\u76ee<\/h2>\n<h3>2.2.1 \u63d2\u5165\u56fe\u7247<\/h3>\n<p>&emsp;&emsp;\u56e0\u4e3alvgl\u663e\u793a\u7684\u56fe\u7247\u9700\u8981\u7279\u6b8a\u5904\u7406\uff0c\u9700\u8981\u53bb\u5b98\u7f51\u8f6c\u6362\u683c\u5f0f\uff08<a href=\"https:\/\/lvgl.io\/tools\/imageconverter\" target=\"_blank\" rel=\"noopener\">\u70b9\u6211\u8df3\u8f6c<\/a>\uff09\u3002<br \/>\n\uff08\u6ce8\u610f\uff0cPNG\u56fe\u7247\u989c\u8272\u683c\u5f0f\u9009\u62e9CF_TRUE_COLOR_ALPHA\uff0cJPG\u56fe\u7247\u989c\u8272\u683c\u5f0f\u9009\u62e9CF_TRUE_COLOR\uff0c\u8f6c\u6362\u5b8c\u6210\u540e\u5c06c\u6587\u4ef6\u62f7\u8d1d\u81f3\u5de5\u7a0b\u76ee\u5f55\u3002\uff09<\/p>\n<p><center><br \/>\n<div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/www.yanwenkai.com:7777\/images\/2025\/02\/28\/20250227-1.png'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" data-original=\"https:\/\/www.yanwenkai.com:7777\/images\/2025\/02\/28\/20250227-1.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" width=\"400\" height=\"200\"><\/div><br \/>\n<\/center><\/p>\n<p>&emsp;&emsp;\u5982\u4e0b\u662f\u6211\u5b9e\u9645\u5b58\u653e\u56fe\u7247\u7684\u8def\u5f84:<\/p>\n<pre><code class=\"language-c\">lvgl_project\/project_01\/yuanse.c<\/code><\/pre>\n<h3>2.2.2 \u7f16\u5199\u81ea\u5df1\u7684mian.c\u4e3b\u6587\u4ef6<\/h3>\n<p>&emsp;&emsp;\u5982\u4e0b\u662f\u6211\u81ea\u5df1\u57fa\u4e8e\u6211\u7684\u5c4f\u5e55\u7f16\u5199\u7684\u4e3b\u6587\u4ef6\u4ee3\u7801\uff0c\u4e3b\u8981\u529f\u80fd\u662f\u663e\u793a\u81ea\u5df1\u7684\u56fe\u7247\u548c\u6309\u952e\u3002<br \/>\nmain.c<\/p>\n<pre><code class=\"language-c\">#include \"lvgl\/lvgl.h\"\n\/\/#include \"DEV_Config.h\"\n#include \"lv_drivers\/display\/fbdev.h\"\n#include <unistd.h>\n#include <pthread.h>\n#include <time.h>\n#include <sys\/time.h>\n\/\/#include \"lv_demos\/lv_demo.h\"\n#define DISP_BUF_SIZE (480 * 320)\n\n\/*Image declare*\/\nLV_IMG_DECLARE(zhuomian);  \nLV_IMG_DECLARE(cat);  \nLV_IMG_DECLARE(galaxy);  \nLV_IMG_DECLARE(saint);  \n\nvoid fbdev_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_p);\n\n\/**\n * A meter with multiple arcs\n *\/\n\nvoid lv_show_img(lv_obj_t * img,const lv_img_dsc_t img_dat){\n    lv_obj_clean(img);\n    lv_img_set_src(img, &img_dat);\n    lv_obj_center(img);\n}\n\nint main(void)\n{\n    \/*LittlevGL init*\/\n    lv_init();\n\n    \/*Linux frame buffer device init*\/\n    fbdev_init();\n\n    \/*A small buffer for LittlevGL to draw the screen's content*\/\n    static lv_color_t buf[DISP_BUF_SIZE];\n\n    \/*Initialize a descriptor for the buffer*\/\n    static lv_disp_draw_buf_t disp_buf;\n    lv_disp_draw_buf_init(&disp_buf, buf, NULL, DISP_BUF_SIZE);\n\n    \/*Initialize and register a display driver*\/\n    static lv_disp_drv_t disp_drv;\n    lv_disp_drv_init(&disp_drv);\n    disp_drv.draw_buf   = &disp_buf;\n    disp_drv.flush_cb   = fbdev_flush;\n    disp_drv.hor_res    = 320;\n    disp_drv.ver_res    = 480;\n    lv_disp_drv_register(&disp_drv);\n\n    \/*Initialize pin*\/\n\/\/    DEV_ModuleInit();\n\n    \/*Show an image*\/\n    lv_obj_t *scr = lv_disp_get_scr_act(NULL);\n    lv_obj_t *img = lv_img_create(scr);\n    printf(\"\u663e\u793azhuomian\u7684\u56fe\u7247\\n\");\n    lv_show_img(img,zhuomian);\n    lv_obj_center(img);\n    printf(\"\u663e\u793azhuomian\u7684\u56fe\u7247\u5b8c\u6210\\n\");\n\n    \/\/ \/*Create a cursor*\/\n    \/\/ lv_obj_t *cursor = lv_img_create(scr);\n    \/\/ lv_img_set_src(cursor, LV_SYMBOL_GPS);\n    \/\/ lv_obj_set_pos(cursor, 70, 120);\n    \/\/ int x=70,y=120,move=0;\n\/\/lv_demo_widgets();\n\n   \/\/ lv_show_img(img,zhuomian);\n    \/*Handle LitlevGL tasks (tickless mode)*\/\n\/\/lv_demo_widgets();\n\/\/\u521b\u5efa\u6309\u952e\n    lv_obj_t *obj = lv_obj_create(lv_scr_act());\n    lv_obj_set_size(obj,40,40);\n    lv_obj_set_pos(obj,240,150);\n    while(1) {\n      \/\/  printf(\"\u8fdb\u5165while\u6b7b\u5faa\u73af\\n\");\n     lv_show_img(img,zhuomian);\n        lv_timer_handler();\n        usleep(5000);\n    }\n    return 0;\n}\n\n\/*Set in lv_conf.h as <code>LV_TICK_CUSTOM_SYS_TIME_EXPR<\/code>*\/\nuint32_t custom_tick_get(void)\n{\n    static uint64_t start_ms = 0;\n    if(start_ms == 0) {\n        struct timeval tv_start;\n        gettimeofday(&tv_start, NULL);\n        start_ms = (tv_start.tv_sec * 1000000 + tv_start.tv_usec) \/ 1000;\n    }\n\n    struct timeval tv_now;\n    gettimeofday(&tv_now, NULL);\n    uint64_t now_ms;\n    now_ms = (tv_now.tv_sec * 1000000 + tv_now.tv_usec) \/ 1000;\n\n    uint32_t time_ms = now_ms - start_ms;\n    return time_ms;\n}<\/code><\/pre>\n<p>&emsp;&emsp;\u81f3\u6b64\u5c31\u53ef\u4ee5\u7b80\u5355\u7684\u663e\u793a\u4e00\u4e2a\u56fe\u7247\uff0c\u521b\u5efa\u4e00\u4e2a\u81ea\u5df1\u7684\u6309\u94ae\u4e86\u3002\u5982\u4e0b\u662f\u663e\u793a\u6548\u679c\uff1a<\/p>\n<p><center><br \/>\n<div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/www.yanwenkai.com:7777\/images\/2025\/02\/28\/20250227-3.png'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" data-original=\"https:\/\/www.yanwenkai.com:7777\/images\/2025\/02\/28\/20250227-3.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" width=\"400\" height=\"200\"><\/div><br \/>\n<\/center><\/p>\n<h2>2.3 \u9002\u914dlvgl\u7684\u6ce8\u610f\u4e8b\u9879<\/h2>\n<h3>2.3.1 \u989c\u8272\u6570\u636e\u8f6c\u6362<\/h3>\n<p>&emsp;&emsp;\u5728\u8bfbili9488\u7684\u4ea7\u54c1\u624b\u518c\u65f6\u53d1\u73b0\u5c4f\u5e55\u9ed8\u8ba4\u4f7f\u7528\u7684\u662f\u5927\u7aef\u5e8f\uff0c\u800c\u673a\u5668\u9ed8\u8ba4\u4f7f\u7528\u7684\u662f\u5c0f\u7aef\u5e8f\uff08\u8fd9\u91cc\u5728\u786c\u4ef6\u7bc7\u505a\u4e86\u8be6\u7ec6\u89e3\u91ca\uff09\uff1b\u7528\u6237\u9700\u8981\u989d\u5916\u7f16\u5199\u8f6c\u6362\u4ee3\u7801\u8c03\u6574\u6570\u636e\u987a\u5e8f\u3002lvgl\u9488\u5bf9\u5c4f\u5e55\u505a\u4e86\u4e13\u95e8\u7684\u4f18\u5316\uff0c\u5982\u679c\u9a71\u52a8\u6ca1\u6709\u7f16\u5199\u7279\u5b9a\u7684\u8f6c\u6362\u51fd\u6570\uff0c\u53ef\u4ee5\u4f7f\u7528lvgl\u9644\u5e26\u7684\u5982\u4e0b\u63a5\u53e3\uff08\u5185\u6838\u7684\u63a5\u53e3\u5728framebuffer\u9a71\u52a8\u7bc7\u91cc\u6709\u63d0\uff09\u3002\u6211\u89c9\u5f97\u4e0d\u7528\u5185\u6838\u63a5\u53e3\u5c31\u7528\u5b98\u65b9\u63a5\u53e3\uff0c\u56e0\u4e3a\u81ea\u5df1\u5199\u7684\u8f6c\u6362\u6570\u636e\u4ee3\u7801\u6548\u7387\u5927\u6982\u7387\u662f\u4f4e\u4e8e\u5b98\u65b9\u5185\u5d4c\u4ee3\u7801\u7684\uff01<\/p>\n<pre><code class=\"language-c\">\/*Swap the 2 bytes of RGB565 color. Useful if the display has an 8-bit interface (e.g. SPI)*\/\n#define LV_COLOR_16_SWAP 0<\/code><\/pre>\n<h3>2.3.2 lvgl\u652f\u6301\u989c\u8272\u683c\u5f0f\u95ee\u9898<\/h3>\n<p>&emsp;&emsp;\u67e5\u8be2lv_conf.h\u6587\u4ef6\uff0c\u53ef\u4ee5\u770b\u5230lvgl\u652f\u6301\u7684\u989c\u8272\u683c\u5f0f\uff0c\u6211\u4f7f\u7528\u7684\u662fRGB565\u3002\u9700\u8981\u6ce8\u610f\u7684\u662f\u6ca1\u5199\u4ee3\u8868\u4e0d\u652f\u6301\uff0clvgl\u4e0d\u652f\u6301\u7684\u989c\u8272\u6570\u636e\u683c\u5f0f\u670918\u4f4d\uff08rgb666\uff09\u300124\u4f4d\uff08rgb888\uff09\uff1b\u5982\u679c\u60f3\u4f7f\u7528\u8fd9\u4e24\u79cd\u683c\u5f0f\uff0c\u9700\u8981\u989d\u5916\u8fdb\u884c\u6570\u636e\u8f6c\u6362\uff0c\u8fd9\u4f1a\u5bfc\u81f4\u4f20\u8f93\u6548\u7387\u7684\u964d\u4f4e\uff0c\u8fdb\u800c\u5f71\u54cd\u663e\u793a\u6548\u679c\uff0c\u6240\u4ee5\u6700\u597d\u5728\u4e00\u5f00\u59cb\u9009\u578b\u9636\u6bb5\u5c31\u907f\u514d\u6b64\u95ee\u9898\u3002<\/p>\n<pre><code class=\"language-c\">\/*Color depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)*\/\n#define LV_COLOR_DEPTH 16<\/code><\/pre>\n<p>&emsp;&emsp;\u6ce8\u610f\u5728\u56fe\u7247\u663e\u793a\u65e0\u95ee\u9898\u540e\uff0c\u5efa\u8bae\u5728\u7f51\u4e0a\u627e\u4e2a\u4e09\u539f\u8272\u7684\u56fe\u7247\u7528lvgl\u663e\u793a\u4e00\u4e0b\uff1b\u67e5\u770b\u81ea\u5df1\u79fb\u690d\u7684\u4ee3\u7801\u6709\u6ca1\u6709\u95ee\u9898\uff0c\u4e09\u539f\u8272\u663e\u793a\u6709\u6ca1\u6709\u504f\u5dee\u3002\u5426\u5219\u82b1\u8d39\u534a\u5929\u65f6\u95f4\u8bbe\u8ba1\u51fa\u7684\u5404\u79cd\u6548\u679c\uff0c\u4f1a\u56e0\u4e3a\u8fd9\u4e2a\u95ee\u9898\u91cd\u65b0\u8fd4\u5de5\uff08\u56fe\u7247\u662f\u56e0\u4e3a\u5c3a\u5bf8\u95ee\u9898\u624d\u663e\u793a\u4e0d\u5bf9\u7684\uff0c\u53ea\u662f\u4e3a\u4e86\u770b\u4e09\u539f\u8272\uff09\u3002<\/p>\n<p><center><br \/>\n<div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/www.yanwenkai.com:7777\/images\/2025\/02\/28\/20250227-2.png'><img class=\"lazyload lazyload-style-1\" src=\"data:image\/svg+xml;base64,PCEtLUFyZ29uTG9hZGluZy0tPgo8c3ZnIHdpZHRoPSIxIiBoZWlnaHQ9IjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgc3Ryb2tlPSIjZmZmZmZmMDAiPjxnPjwvZz4KPC9zdmc+\"  loading=\"lazy\" decoding=\"async\" data-original=\"https:\/\/www.yanwenkai.com:7777\/images\/2025\/02\/28\/20250227-2.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" width=\"400\" height=\"200\"><\/div><br \/>\n<\/center><\/p>\n<p>&emsp;&emsp;\u81f3\u6b64\u663e\u793a\u529f\u80fd\u989c\u8272\u65e0\u504f\u5dee\u3001\u56fe\u7247\u6b63\u5e38\u663e\u793a\uff0c\u5b8c\u6210\u4e86lvgl\u663e\u793a\u90e8\u5206\u79fb\u690d\u5de5\u4f5c\u3002<\/p>\n<h1>3 \u79fb\u690d\u89e6\u6478\u529f\u80fd<\/h1>\n<p>&emsp;&emsp;\u56e0\u4e3a\u5de5\u4f5c\u95ee\u9898\uff0c\u6ca1\u6709\u5b8c\u5168\u9002\u914d\u5b8c\u89e6\u6478\u529f\u80fd\uff0c\u8fd9\u91cc\u7b80\u5355\u4ecb\u7ecd\u4e00\u4e0b\u5b98\u65b9\u7684\u89e6\u6478\u5c4f\u9a71\u52a8\u63a5\u53e3\u3002<\/p>\n<h2>3.1 xpt2046\u6846\u67b6\u57fa\u672c\u4ecb\u7ecd<\/h2>\n<p>&emsp;&emsp;\u5982\u4e0b\u662flv_drivers\/indev\/XPT2046.c\u4e2d\u7684\u89e6\u6478\u9a71\u52a8\u6846\u67b6\uff0c\u53ea\u9700\u8981\u5b9e\u73b0\u51e0\u4e2a\u63a5\u53e3\u51fd\u6570\u5373\u53ef\u5b9e\u73b0\u89e6\u6478\u529f\u80fd\u3002<\/p>\n<pre><code class=\"language-c\">\/**\n * @file XPT2046.c\n *\n *\/\n\n\/*********************\n *      INCLUDES\n *********************\/\n#include \"XPT2046.h\"\n#if USE_XPT2046\n\n#include <stddef.h>\n#include LV_DRV_INDEV_INCLUDE\n#include LV_DRV_DELAY_INCLUDE\n\n\/*********************\n *      DEFINES\n *********************\/\n#define CMD_X_READ  0b10010000  \/\/\u82af\u7247x\u8f74\u8bfb\u53d6\u547d\u4ee40x90\n#define CMD_Y_READ  0b11010000  \/\/\u82af\u7247y\u8f74\u8bfb\u53d6\u547d\u4ee40xd0\n\n\/**********************\n *      TYPEDEFS\n **********************\/\n\n\/**********************\n *  STATIC PROTOTYPES\n **********************\/\nstatic void xpt2046_corr(int16_t * x, int16_t * y);\nstatic void xpt2046_avg(int16_t * x, int16_t * y);\n\n\/**********************\n *  STATIC VARIABLES\n **********************\/\nint16_t avg_buf_x[XPT2046_AVG];\nint16_t avg_buf_y[XPT2046_AVG];\nuint8_t avg_last;\n\n\/**********************\n *      MACROS\n **********************\/\n\n\/**********************\n *   GLOBAL FUNCTIONS\n **********************\/\n\n\/**\n * Initialize the XPT2046\n\/\/ \u89e6\u6478\u9a71\u52a8\u7684\u521d\u59cb\u5316\u51fd\u6570\uff0c\u9700\u8981\u81ea\u5df1\u586b\u5145\u3002\n *\/\nvoid xpt2046_init(void)\n{\n\n}\n\n\/**\n * Get the current position and state of the touchpad\n * @param data store the read data here\n * @return false: because no ore data to be read\n \/\/\u5750\u6807\u8bfb\u53d6\u51fd\u6570\n *\/\nbool xpt2046_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data)\n{\n    static int16_t last_x = 0;\n    static int16_t last_y = 0;\n    uint8_t buf;\n\n    int16_t x = 0;\n    int16_t y = 0;\n\n    uint8_t irq = LV_DRV_INDEV_IRQ_READ; \/\/\u4e2d\u65ad\u7684\u5b8f\uff0c\u8fd9\u4e2a\u83b7\u53d6\u4e2d\u65ad\u7684\u5b8f\u51fd\u6570\u9700\u8981\u81ea\u5df1\u5b9e\u73b0\n\n    if(irq == 0) {\n        \/\/\u5411\u5185\u6838\u9a71\u52a8\u53d1\u9001\u7247\u9009\u4fe1\u53f7\uff0c\u9009\u62e9\u89e6\u6478\u5c4f\uff0c\u5b8f\u51fd\u6570\u81ea\u5df1\u5b9e\u73b0\n        LV_DRV_INDEV_SPI_CS(0);\n        \/\/\u5411\u5185\u6838\u9a71\u52a8\u53d1\u9001\u8bfb\u53d6x\u8f74\u7684\u547d\u4ee4\uff0c\u5b8f\u51fd\u6570\u81ea\u5df1\u5b9e\u73b0\n        LV_DRV_INDEV_SPI_XCHG_BYTE(CMD_X_READ);         \/*Start x read*\/\n                \/\/\u8bfb\u53d6x\u8f74\u6570\u636e\uff0c\u5b8f\u51fd\u6570\u81ea\u5df1\u5b9e\u73b0\n        buf = LV_DRV_INDEV_SPI_XCHG_BYTE(0);           \/*Read x MSB*\/\n        x = buf << 8;\n        buf = LV_DRV_INDEV_SPI_XCHG_BYTE(CMD_Y_READ);  \/*Until x LSB converted y command can be sent*\/\n        x += buf;\n\n        buf =  LV_DRV_INDEV_SPI_XCHG_BYTE(0);   \/*Read y MSB*\/\n        y = buf << 8;\n\n        buf =  LV_DRV_INDEV_SPI_XCHG_BYTE(0);   \/*Read y LSB*\/\n        y += buf;\n\n        \/*Normalize Data*\/\n        x = x >> 3;\n        y = y >> 3;\n        xpt2046_corr(&x, &y);\n        xpt2046_avg(&x, &y);\n\n        last_x = x;\n        last_y = y;\n        data->state = LV_INDEV_STATE_PR;\/\/\u66f4\u65b0\u72b6\u6001\u4e3a\u6309\u4e0b\n\n        LV_DRV_INDEV_SPI_CS(1);\n    } else {\n        x = last_x;\n        y = last_y;\n        avg_last = 0;\n        data->state = LV_INDEV_STATE_REL;\n    }\n\n    data->point.x = x;\n    data->point.y = y;\n\n    return false;\n}\n\n\/**********************\n *   STATIC FUNCTIONS\n **********************\/\nstatic void xpt2046_corr(int16_t * x, int16_t * y)\n{\n#if XPT2046_XY_SWAP != 0\n    int16_t swap_tmp;\n    swap_tmp = *x;\n    *x = *y;\n    *y = swap_tmp;\n#endif\n\n    if((*x) > XPT2046_X_MIN)(*x) -= XPT2046_X_MIN;\n    else(*x) = 0;\n\n    if((*y) > XPT2046_Y_MIN)(*y) -= XPT2046_Y_MIN;\n    else(*y) = 0;\n\n    (*x) = (uint32_t)((uint32_t)(*x) * XPT2046_HOR_RES) \/\n           (XPT2046_X_MAX - XPT2046_X_MIN);\n\n    (*y) = (uint32_t)((uint32_t)(*y) * XPT2046_VER_RES) \/\n           (XPT2046_Y_MAX - XPT2046_Y_MIN);\n\n#if XPT2046_X_INV != 0\n    (*x) =  XPT2046_HOR_RES - (*x);\n#endif\n\n#if XPT2046_Y_INV != 0\n    (*y) =  XPT2046_VER_RES - (*y);\n#endif\n\n}\n\/\/\u5e73\u5747\u6ee4\u6ce2\u51fd\u6570\uff0c\u5bf9\u8bfb\u53d6\u5230\u7684\u5750\u6807\u6570\u636e\u8fdb\u884c\u5e73\u5747\u6ee4\u6ce2\uff0c\u51cf\u5c11\u566a\u58f0\u548c\u63d0\u9ad8\u7a33\u5b9a\u6027\u3002\n\/\/\u8bf4\u767d\u4e86\u5c31\u662f\u6d88\u6296\nstatic void xpt2046_avg(int16_t * x, int16_t * y)\n{\n    \/*Shift out the oldest data*\/\n    uint8_t i;\n    for(i = XPT2046_AVG - 1; i > 0 ; i--) {\n        avg_buf_x[i] = avg_buf_x[i - 1];\n        avg_buf_y[i] = avg_buf_y[i - 1];\n    }\n\n    \/*Insert the new point*\/\n    avg_buf_x[0] = *x;\n    avg_buf_y[0] = *y;\n    if(avg_last < XPT2046_AVG) avg_last++;\n\n    \/*Sum the x and y coordinates*\/\n    int32_t x_sum = 0;\n    int32_t y_sum = 0;\n    for(i = 0; i < avg_last ; i++) {\n        x_sum += avg_buf_x[i];\n        y_sum += avg_buf_y[i];\n    }\n\n    \/*Normalize the sums*\/\n    (*x) = (int32_t)x_sum \/ avg_last;\n    (*y) = (int32_t)y_sum \/ avg_last;\n}\n\n#endif<\/code><\/pre>\n<p>&emsp;&emsp;\u901a\u8bfb\u4e0a\u9762\u7684\u4ee3\u7801\u53ef\u77e5\uff0c\u9700\u8981\u81ea\u5df1\u5b9e\u73b0\u4e0e\u5185\u6838\u9a71\u52a8\u4ea4\u4e92\u7684\u63a5\u53e3\u3002\u5177\u4f53\u7684\u63a5\u53e3\u5982\u4e0b:<\/p>\n<pre><code class=\"language-c\">lv_drv_conf.h\n\/*----------\n *  Common\n *----------*\/\n#define LV_DRV_INDEV_INCLUDE     <stdint.h>             \/*Dummy include by default*\/\n#define LV_DRV_INDEV_RST(val)    \/*pin_x_set(val)*\/     \/*Set the reset pin to 'val'*\/\n#define LV_DRV_INDEV_IRQ_READ    0 \/*pn_x_read()*\/      \/*Read the IRQ pin*\/\n\n\/*---------\n *  SPI\n *---------*\/\n#define LV_DRV_INDEV_SPI_CS(val)            \/*spi_cs_set(val)*\/     \/*Set the SPI's Chip select to 'val'*\/\n#define LV_DRV_INDEV_SPI_XCHG_BYTE(data)    0 \/*spi_xchg(val)*\/     \/*Write 'val' to SPI and give the read value*\/<\/code><\/pre>\n<p>&emsp;&emsp;\u8fd9\u90e8\u5206\u4ee3\u7801\u6211\u6ca1\u5b9e\u73b0\uff1b\u5982\u679c\u8fd9\u4e9b\u51fd\u6570\u5b9e\u5728\u4e0d\u77e5\u9053\u548b\u5199\u7684\uff0c\u53ef\u4ee5\u501f\u9274\u5b98\u65b9framebuffer\u6846\u67b6\u4e0e\u5185\u6838\u63a5\u53e3\u7684\u5199\u6cd5\uff08\u6ce8\u610f\uff1a\u5982\u679c\u501f\u9274\u4e86\u63a5\u53e3\u7684\u5199\u6cd5\uff0cxpt2046\u7684\u5185\u6838\u9a71\u52a8\u64cd\u4f5c\u65b9\u6cd5\u7ed3\u6784\u4f53\u4e5f\u8981\u505a\u76f8\u5e94\u7684\u6539\u52a8\uff09\u3002<\/p>\n<h2>3.2 lvgl\u89e6\u6478\u5c4f\u4e2d\u65ad\u903b\u8f91\u5206\u6790<\/h2>\n<p>&emsp;&emsp;\u5982\u679c\u770b\u4e86\u6211\u4e2d\u65ad\u7684\u535a\u5ba2\u53ef\u4ee5\u77e5\u9053\u9a71\u52a8\u5c42\u83b7\u53d6\u4e2d\u65ad\u7684\u65b9\u6cd5\uff0c\u800c\u9a71\u52a8\u5f80\u5e94\u7528\u5c42\u4f20\u8f93\u4e2d\u65ad\u72b6\u6001\u7684\u65b9\u6cd5\u65e0\u5916\u4e4e\u5c31\u662f\u64cd\u4f5c\u65b9\u6cd5\u7ed3\u6784\u4f53\u7684\u90a3\u51e0\u4e2a\u51fd\u6570\u3002\u6240\u4ee5\u8bfb\u5b8c\u9a71\u52a8\u6a21\u5757\u7684\u4ee3\u7801\u540e\uff0c\u6211\u6709\u4e2a\u95ee\u9898\u662f\u6211\u4f20\u8fc7\u6765\u7684\u4e2d\u65ad\u4fe1\u53f7lvgl\u4ec0\u4e48\u65f6\u5019\u8bfb\u53d6\u5462\uff1f<br \/>\n&emsp;&emsp;\u5982\u4e0b\u662f\u4e0a\u9762xpt2046\u5173\u4e8e\u4e2d\u65ad\u7684\u5b8f\u63a5\u53e3\uff0c\u662f\u4e2d\u65ad\u4ee3\u7801\u7684\u5206\u6790\u8d77\u70b9\u3002\u5b83\u7684\u4f5c\u7528\u662f\u83b7\u53d6\u4e2d\u65ad\u7684\u72b6\u6001\uff08\u524d\u6587\u5df2\u8bf4\u9700\u8981\u81ea\u5df1\u5b9e\u73b0\u9a71\u52a8\u5230\u5e94\u7528\u5c42\u7684\u903b\u8f91\uff09\u3002<\/p>\n<pre><code class=\"language-c\">lv_drv_conf.h:61:#define LV_DRV_INDEV_IRQ_READ    0 \/*pn_x_read()*\/      \/*Read the IRQ pin*\/<\/code><\/pre>\n<p>&emsp;&emsp;\u5982\u4e0b\u662fxpt2046_read\u51fd\u6570\u4e2d\u5bf9\u4e8e\u4e2d\u65ad\u72b6\u6001\u5224\u65ad\u7684\u4ee3\u7801\uff0c\u90a3\u4e48\u8c01\u8c03\u7528\u5b83\uff1f\u4ec0\u4e48\u65f6\u5019\u8c03\u7528\u5462\uff1f<br \/>\nxpt2046.c<\/p>\n<pre><code class=\"language-c\">    uint8_t irq = LV_DRV_INDEV_IRQ_READ; \/\/\u4e2d\u65ad\u7684\u5b8f\uff0c\u8fd9\u4e2a\u83b7\u53d6\u4e2d\u65ad\u7684\u5b8f\u51fd\u6570\u9700\u8981\u81ea\u5df1\u5b9e\u73b0\n\n    if(irq == 0) {<\/code><\/pre>\n<p>&emsp;&emsp;\u7ee7\u7eed\u67e5\u627e\u4ee3\u7801\u53d1\u73b0\u6ca1\u6709\u4efb\u4f55\u51fd\u6570\u8c03\u7528\u5b83\u3002\u67e5\u9605\u5404\u79cd\u8d44\u6599\u53d1\u73b0\u662f\u5728main.c\u4e2d\u88ab\u8c03\u7528\uff0c\u56e0\u4e3a\u6211\u8fd8\u6ca1\u6709\u5b9e\u73b0\u89e6\u6478\u529f\u80fd\uff0c\u6240\u4ee5\u67e5\u627e\u4e0d\u5230\u8c03\u7528\uff1b\u518d\u8bfb\u53d6\u5b98\u65b9\u7684lvgl\/docs\/porting\/indev.md\u6587\u6863\uff0c\u5b66\u4e60\u89e6\u6478\u4e8b\u4ef6\u7684\u4f7f\u7528\u65b9\u5f0f\uff0c\u53d1\u73b0\u548c\u4e0a\u6587\u91cc\u6211\u90a3\u4e9bframebuffer\u548c\u6309\u952e\u4e8b\u4ef6\u5199\u6cd5\u4e00\u6837\uff0c\u9700\u8981\u521d\u59cb\u5316\u3001\u8d4b\u503c\u3001\u6ce8\u518c\u7b49\u64cd\u4f5c\u3002\uff08\u8d8a\u7814\u7a76lvlg\u8d8a\u53d1\u73b0\u548cqt\u795e\u4f3c\u554a\uff09<br \/>\n&emsp;&emsp;\u5982\u4e0b\u662f\u5b98\u65b9\u6587\u6863\u7ed9\u51fa\u7684\u57fa\u7840\u5199\u6cd5\uff1a<\/p>\n<pre><code class=\"language-c\">indev.md\n\nstatic lv_indev_drv_t indev_drv;\nlv_indev_drv_init(&indev_drv);      \/*Basic initialization*\/\nindev_drv.type =...                 \/*See below.*\/\nindev_drv.read_cb =...              \/*See below.*\/\n\/*Register the driver in LVGL and save the created input device object*\/\nlv_indev_t * my_indev = lv_indev_drv_register(&indev_drv);<\/code><\/pre>\n<p>&emsp;&emsp;\u4e86\u89e3\u89e6\u6478\u4e8b\u4ef6\u7684\u5199\u6cd5\u540e\uff0c\u53d1\u73b0xpt2046_read\u662f\u88ab\u8d4b\u503c\u7ed9\u4e86indev_drv.read_cb\uff0c\u7136\u540e\u6ce8\u518c\u89e6\u6478\u4e8b\u4ef6\u3002\u90a3\u4e48\u4f1a\u4e0d\u4f1a\u662f\u6ce8\u518c\u540e\uff0c\u5b83\u4f1a\u50cfframebuffer\u548c\u6309\u952e\u4e8b\u4ef6\u4e00\u6837\u540e\u53f0\u8fd0\u884c\u5462\uff1f\u7ee7\u7eed\u5206\u6790lv_indev_drv_register\u51fd\u6570\uff1a<br \/>\nlvgl\/src\/hal\/lv_hal_indev.c<\/p>\n<pre><code class=\"language-c\">lv_indev_t * lv_indev_drv_register(lv_indev_drv_t * driver)\n{\n\n    if(driver->disp == NULL) driver->disp = lv_disp_get_default();\n\n    if(driver->disp == NULL) {\n        LV_LOG_WARN(\"lv_indev_drv_register: no display registered hence can't attach the indev to \"\n                    \"a display\");\n        return NULL;\n    }\n\n    lv_indev_t * indev = _lv_ll_ins_head(&LV_GC_ROOT(_lv_indev_ll));\n    if(!indev) {\n        LV_ASSERT_MALLOC(indev);\n        return NULL;\n    }\n\n    lv_memset_00(indev, sizeof(lv_indev_t));\n    indev->driver = driver;\n\n    indev->proc.reset_query  = 1;\n    \/\/\u5982\u4e0b\u662f\u5b9a\u65f6\u5668\u521b\u5efa\u51fd\u6570\n    indev->driver->read_timer = lv_timer_create(lv_indev_read_timer_cb, LV_INDEV_DEF_READ_PERIOD, indev);\n\n    return indev;\n}<\/code><\/pre>\n<p>&emsp;&emsp;\u4ece\u4e0a\u9762\u53ef\u4ee5\u770b\u51fa\u5b98\u65b9\u5728\u6ce8\u518c\u51fd\u6570\u5185\u5df2\u7ecf\u4f7f\u7528\u5b9a\u65f6\u5668\u51fd\u6570\u5c06\u89e6\u6478\u4e8b\u4ef6\u4e0e\u5b9a\u65f6\u5668\u7ed1\u5b9a\uff08\u6709\u5174\u8da3\u7684\u53ef\u4ee5\u7ee7\u7eed\u6df1\u6252\u5b9e\u73b0\u4ee3\u7801\uff09\u3002<br \/>\n&emsp;&emsp;\u800c\u5b98\u65b9\u5728main.c\u4e2d\u7684while\u5faa\u73af\u4e2d\u5df2\u7ecf\u6dfb\u52a0\u7684\u5982\u4e0b\u7684\u5b9a\u65f6\u5668\u76f8\u5173\u7684\u4ee3\u7801\uff0c\u4f5c\u7528\u5c31\u662f\u904d\u5386\u5b9a\u65f6\u5668\u94fe\u8868\uff0c\u6267\u884c\u6bcf\u4e2a\u5b9a\u65f6\u5668\u7684\u56de\u8c03\u51fd\u6570\u3002<\/p>\n<pre><code class=\"language-c\">    while(1) {\n        lv_timer_handler();\n        usleep(5000);\n    }<\/code><\/pre>\n<p>&emsp;&emsp;\u81f3\u6b64\u4e5f\u5c31\u57fa\u672c\u660e\u767d\u4e86\u5c4f\u5e55\u5237\u65b0\u3001\u89e6\u6478\u5224\u65ad\u7684\u540e\u53f0\u5b9e\u65f6\u8c03\u7528\u903b\u8f91\u4e86\u3002\u5c31\u662f\u5728while\u5faa\u73af\u91cc\u5b9a\u65f6\u8c03\u7528\u7ed1\u5b9a\u7684\u76f8\u5173\u51fd\u6570\uff0c\u7136\u540e\u8bfb\u53d6\u4e2d\u65ad\u72b6\u6001\uff0c\u4e00\u65e6\u4e2d\u65ad\u503c\u53d8\u5316\uff0c\u5c31\u4f1a\u8fdb\u4e00\u6b65\u8bfb\u53d6\/dev\/input\/event0\u6587\u4ef6\u4e2d\u7684\u5750\u6807\u503c\u3002<\/p>\n<h2>3.3 \u5b98\u65b9\u89e6\u6478\u4ee3\u7801\u793a\u4f8b<\/h2>\n<p>&emsp;&emsp;\u5982\u4e0b\u662f\u5b98\u65b9\u4f8b\u7a0b\u91cc\u6ce8\u91ca\u7684\u89e6\u6478\u76f8\u5173\u4ee3\u7801\uff0c\u4e3b\u8981\u529f\u80fd\u5c31\u662f\u6ce8\u518c\u4e00\u4e2a\u89e6\u6478\u4e8b\u4ef6\u3002<\/p>\n<pre><code class=\"language-c\">evdev_init();\/\/\u521d\u59cb\u5316\u89e6\u6478\u9a71\u52a8\nstatic lv_indev_drv_t indev_drv_1;\/\/\u5b9a\u4e49\u89e6\u6478\u4e8b\u4ef6\u53d8\u91cf\nlv_indev_drv_init(&indev_drv_1); \/*Basic initialization*\/  \/\/\u521d\u59cb\u5316\u53d8\u91cf\nindev_drv_1.type = LV_INDEV_TYPE_POINTER;  \/\/\u5c06\u53d8\u91cf\u5b9a\u4e49\u4e3a\u6307\u9488\u7c7b\u578b\uff08\u89e6\u6478\u5c4f\/\u9f20\u6807\uff09\n\n    \/*This function will be called periodically (by the library) to get the mouse position and state*\/\nindev_drv_1.read_cb = evdev_read;\/\/\u8bbe\u7f6e\u8bfb\u53d6\u56de\u8c03\u51fd\u6570\uff0c\u8fd9\u4e5f\u662f\u9700\u8981\u81ea\u5df1\u5b9e\u73b0\u7684\u8bfb\u53d6\u903b\u8f91\nlv_indev_t *mouse_indev = lv_indev_drv_register(&indev_drv_1); \/\/\u6ce8\u518c\u89e6\u6478\u4e8b\u4ef6<\/code><\/pre>\n<p>&emsp;&emsp;\u4ece\u4e0a\u9762\u4ee3\u7801\u53ef\u4ee5\u770b\u51fa\uff0c\u9700\u8981\u81ea\u5df1\u5b9e\u73b0\u7684\u5c31\u662fevdev_init()\u51fd\u6570\u548cevdev_read\u51fd\u6570\u3002<br \/>\n&emsp;&emsp;\u9996\u5148\u5206\u6790evdev_init()\u51fd\u6570\u3002\u5176\u5728lv_drivers\/indev\/evdev.c\u4e0b\uff0c\u4e0expt2046.c\u6587\u4ef6\u540c\u4e00\u5c42\u7ea7\uff1b\u518d\u7ed3\u5408\u5b83\u7684\u540d\u5b57\u5c31\u53ef\u4ee5\u77e5\u9053\u5b83\u662f\u4e00\u4e2a\u901a\u7528\u7684\u89e6\u6478\u9a71\u52a8\uff0c\u56e0\u6b64\u53ef\u4ee5\u987a\u4fbf\u770b\u770b\u5b83\u7684\u521d\u59cb\u5316\u662f\u600e\u4e48\u5199\u7684\uff0c\u53ef\u4ee5\u62ff\u6765\u7f16\u5199\u81ea\u5df1\u7684xpt2046\u7684\u521d\u59cb\u5316\u63a5\u53e3\u3002<\/p>\n<pre><code class=\"language-c\">\/**\n * Initialize the evdev interface\n *\/\nvoid evdev_init(void)\n{\n#if USE_BSD_EVDEV\n    evdev_fd = open(EVDEV_NAME, O_RDWR | O_NOCTTY);\n    \/\/\u7cfb\u7edf\u8c03\u7528\u6253\u5f00\u8f93\u5165\u8bbe\u5907\u8282\u70b9\/dev\/input\/eventX\n    \/\/O_RDWR\uff1a\u4ee5\u8bfb\u5199\u6a21\u5f0f\u6253\u5f00\u8bbe\u5907\uff08\u67d0\u4e9b\u8bbe\u5907\u9700\u8981\u53cc\u5411\u901a\u4fe1\uff09\u3002\n    \/\/O_NOCTTY\uff1a\u7981\u6b62\u5c06\u8bbe\u5907\u4f5c\u4e3a\u63a7\u5236\u7ec8\u7aef\u3002\n    \/\/O_NDELAY\uff08\u975eBSD\u7cfb\u7edf\uff09\uff1a\u975e\u963b\u585e\u6a21\u5f0f\uff0c\u907f\u514d\u8bfb\u53d6\u65f6\u7a0b\u5e8f\u5361\u4f4f\u3002\n#else\n    evdev_fd = open(EVDEV_NAME, O_RDWR | O_NOCTTY | O_NDELAY);\n#endif\n    if(evdev_fd == -1) {\n        perror(\"unable open evdev interface:\");\n        return;\n    }\n\n#if USE_BSD_EVDEV\n    fcntl(evdev_fd, F_SETFL, O_NONBLOCK);\n    \/\/\u8bbe\u7f6e\u6587\u4ef6\u63cf\u8ff0\u7b26\u4e3a\u975e\u963b\u585e\u6a21\u5f0f\u3002\n    \/\/O_NONBLOCK\uff1a\u786e\u4fddread()\u64cd\u4f5c\u7acb\u5373\u8fd4\u56de\uff0c\u907f\u514d\u963b\u585e\u4e3b\u7ebf\u7a0b\u3002\n#else\n    fcntl(evdev_fd, F_SETFL, O_ASYNC | O_NONBLOCK);\n    \/\/O_ASYNC\uff08\u975eBSD\u7cfb\u7edf\uff09\uff1a\u542f\u7528\u5f02\u6b65I\/O\uff0c\u5141\u8bb8\u4fe1\u53f7\u9a71\u52a8I\/O\uff08\u5982SIGIO\uff09\u3002\n    \/\/\u9002\u914d\u9ad8\u5b9e\u65f6\u6027\u573a\u666f\uff08\u5982\u5d4c\u5165\u5f0fGUI\uff09\uff0c\u907f\u514d\u8f93\u5165\u4e8b\u4ef6\u5904\u7406\u5ef6\u8fdf\u3002\n#endif\n\/\/\u521d\u59cb\u5316\u53d8\u91cf\n    evdev_root_x = 0;\n    evdev_root_y = 0;\n    evdev_key_val = 0;\n    evdev_button = LV_INDEV_STATE_REL;\/\/\u521d\u59cb\u5316\u8f93\u5165\u8bbe\u5907\u72b6\u6001\u4e3a\u91ca\u653e\uff08LV_INDEV_STATE_REL\uff09\uff0c\u5bf9\u5e94LVGL\u7684\u91ca\u653e\u72b6\u6001\u5b8f\n\n#if USE_XKB\n    xkb_init();\n#endif\n}<\/code><\/pre>\n<p>&emsp;&emsp;\u89e6\u6478\u8282\u70b9\u7684\u540d\u5b57\u662f\u9ed8\u8ba4\u7684\uff0c\u5728lv_drv_conf.h\u4e0b\u5df2\u7ecf\u5b9a\u4e49\u8fc7\u4e86\u3002\u5982\u679c\u6709\u591a\u4e2a\u8282\u70b9\uff0c\u53ef\u4ee5\u81ea\u884c\u6539\u6b63\u8282\u70b9\u540d\u5b57\u3002<\/p>\n<pre><code class=\"language-c\">#if USE_EVDEV || USE_BSD_EVDEV\n#  define EVDEV_NAME   \"\/dev\/input\/event0\"        \/*You can use the \"evtest\" Linux tool to get the list of devices and test them*\/\n#  define EVDEV_SWAP_AXES         0               \/*Swap the x and y axes of the touchscreen*\/<\/code><\/pre>\n<p>&emsp;&emsp;\u63a5\u7740\u5206\u6790evdev_read\u51fd\u6570,\u5982\u4e0b\u622a\u53d6\u4e86\u4e3b\u8981\u7684\u4ee3\u7801\uff0c\u5176\u903b\u8f91\u662f\u5faa\u73af\u8bfb\u53d6\u8282\u70b9\u6587\u4ef6\u7684\u5185\u5bb9\u8d4b\u503c\u7ed9xy\u5750\u6807\u3002<\/p>\n<pre><code class=\"language-c\">\/**\n * Get the current position and state of the evdev\n * @param data store the evdev data here\n *\/\nvoid evdev_read(lv_indev_drv_t * drv, lv_indev_data_t * data)\n{\n    struct input_event in;\n\n    while(read(evdev_fd, &in, sizeof(struct input_event)) > 0) {\n        if(in.type == EV_REL) {\n            if(in.code == REL_X)\n                #if EVDEV_SWAP_AXES\n                    evdev_root_y += in.value;\n                #else\n                    evdev_root_x += in.value;\n                #endif\n            else if(in.code == REL_Y)\n                #if EVDEV_SWAP_AXES\n                    evdev_root_x += in.value;\n                #else\n                    evdev_root_y += in.value;\n                #endif<\/code><\/pre>\n<p>&emsp;&emsp;\u5230\u8fd9\uff0c\u6574\u4e2a\u89e6\u6478\u529f\u80fd\u7684\u903b\u8f91\u94fe\u5c31\u634b\u6e05\u4e86\uff0c\u5269\u4e0b\u7684\u5c31\u662f\u7b80\u5355\u7684\u53e0\u4ee3\u7801\u4ee5\u53ca\u8c03\u8bd5\u5de5\u4f5c\u4e86\u3002<\/p>\n<h1>4 \u603b\u7ed3<\/h1>\n<p>&emsp;&emsp;\u8fd9\u51e0\u5929\u7684\u6574\u7406\u8ba9\u6211\u628a\u4e4b\u524d\u7684\u9879\u76ee\u590d\u4e60\u4e00\u904d\uff0c\u53c8\u627e\u5230\u4e86\u4e0d\u5c11\u76f2\u70b9\uff0c\u679c\u7136\u6e29\u6545\u77e5\u65b0\u7684\u53e4\u8bdd\u6ca1\u9a97\u4eba\u5450\uff01<br \/>\n&emsp;&emsp;\u8fd8\u6709\uff0c\u56e0\u4e3a\u65f6\u95f4\u5b89\u6392\u95ee\u9898\uff0c\u89e6\u6478\u9a71\u52a8\u6ca1\u6709\u65f6\u95f4\u505a\u5f7b\u5e95\u9002\u914d\u3002\u540e\u9762\u6709\u7a7a\u4ee5\u540e\u4f1a\u5b8c\u6210\u9002\u914d\u5206\u4eab\u7ed9\u5927\u5bb6\uff01\u6709\u5565\u95ee\u9898\u53ef\u4ee5\u7559\u8a00\u53d1\u90ae\u7bb1\u5927\u5bb6\u4e00\u8d77\u8ba8\u8bba\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>1 \u524d\u8a00 &emsp;&emsp;\u514b\u670d\u4e86\u8fd9\u4e48\u591a\u56f0\u96be\u7ec8\u4e8e\u4f7f\u7528lvgl\u70b9\u4eae\u5c4f\u5e55\u4e86\uff0c\u5230\u4e86\u8fd9\u6b65\u4e5f\u7b97\u662f\u62e8\u5f00\u4e91\u96fe\u89c1\u5929\u65e5\u4e86\u3002 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":742,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[10,39,54,35,11],"class_list":["post-693","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-flushbonading-lcd","tag-lcd","tag-linux","tag-lvgl","tag-35","tag-11"],"_links":{"self":[{"href":"https:\/\/www.yanwenkai.com\/index.php?rest_route=\/wp\/v2\/posts\/693","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.yanwenkai.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.yanwenkai.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.yanwenkai.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.yanwenkai.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=693"}],"version-history":[{"count":51,"href":"https:\/\/www.yanwenkai.com\/index.php?rest_route=\/wp\/v2\/posts\/693\/revisions"}],"predecessor-version":[{"id":745,"href":"https:\/\/www.yanwenkai.com\/index.php?rest_route=\/wp\/v2\/posts\/693\/revisions\/745"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.yanwenkai.com\/index.php?rest_route=\/wp\/v2\/media\/742"}],"wp:attachment":[{"href":"https:\/\/www.yanwenkai.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=693"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.yanwenkai.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=693"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.yanwenkai.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=693"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}