{"id":419,"date":"2025-07-17T00:55:31","date_gmt":"2025-07-16T16:55:31","guid":{"rendered":"https:\/\/yin.nnneri.me\/?p=419"},"modified":"2025-07-17T00:55:31","modified_gmt":"2025-07-16T16:55:31","slug":"ssd1306%e6%97%a5%e5%bf%97%e6%89%93%e5%8d%b0%e6%9c%ba%ef%bc%88%e5%b8%a6%e5%8a%a8%e7%94%bb%ef%bc%89","status":"publish","type":"post","link":"https:\/\/yin.nnneri.me\/?p=419","title":{"rendered":"ssd1306\u65e5\u5fd7\u6253\u5370\u673a\uff08\u5e26\u52a8\u753b\uff09"},"content":{"rendered":"<h2>\u7b80\u4ecb<\/h2>\n<p>\u4e00\u4e2a\u9002\u7528\u4e8eesp32\u7cfb\u5217\u7684oled12864 iic \uff08ssd1306\uff09\u7684\u65e5\u5fd7\u6253\u5370\u7a0b\u5e8f\uff08\u5e26\u6709\u52a8\u753b\uff09<\/p>\n<h2>\u4f7f\u7528\u65b9\u6cd5<\/h2>\n<ol>\n<li>\u5c06\u9644\u4ef6\u5185\u7684\u5de5\u7a0b\u4ee5\u53ca\u4e24\u4e2a\u5b57\u5e93\u590d\u5236\u5230\u5de5\u7a0b\u5185<\/li>\n<li>\u4f7f\u7528\u7f51\u7ad9\u5185\u7684<code>ssd1306\u7b80\u5355\u9a71\u52a8<\/code> \u6216\u8005\u81ea\u884c\u5b9e\u73b0\u9a71\u52a8<br \/>\n\u81ea\u884c\u5b9e\u73b0\u9700\u8981\u4e00\u4e2a\u5237\u65b0\u51fd\u6570\uff0c\u4e00\u4e2a\u5237\u65b0\u7f13\u51b2\u533a<\/li>\n<li>\u8c03\u7528<code>logAutoInit()<\/code>\u521d\u59cb\u5316<\/li>\n<li>\u4f7f\u7528consoleLog(bool isInvert,const char *format, ...)\u53d1\u9001\u65e5\u5fd7\uff0c\u65e5\u5fd7\u4f1a\u81ea\u884c\u663e\u793a\u5230\u5c4f\u5e55\u4e0a<br \/>\n\u5176\u4e2d\uff0cisInvert\u51b3\u5b9a\u65e5\u5fd7\u662f\u5426\u53cd\u8272<\/li>\n<\/ol>\n<h2>\u9644\u4ef61<\/h2>\n<h3>C<\/h3>\n<pre><code class=\"language-c line-numbers\">#include \"esp_log.h\"\n#include \"esp_timer.h\"\n#include \"zpix.h\"\n#include \"tinyFont.h\"\n#include &lt;stdbool.h&gt;\n#include &lt;stdarg.h&gt;\n#include &lt;stdio.h&gt;\n#include &lt;math.h&gt;\n#include \"ssd1306_driver.h\"  \/\/\u9700\u8981\u4e00\u4e2a\u51fd\u6570\u7528\u4e8e\u5237\u65b0\u5c4f\u5e55\uff0c\u8fd8\u9700\u8981\u9884\u7559\u4e00\u4e2a\u63a5\u53e3\u7528\u4e8e\u76f4\u63a5\u8bbf\u95ee\u5c4f\u5e55\u7f13\u51b2\u533a\n\nextern uint8_t* vBuf;       \/\/ \u5916\u754c\u7684\u5c4f\u5e55\u63a5\u53e3\nuint8_t vBuf2[1024];\nSemaphoreHandle_t vBuf2Mutex;\n\nQueueHandle_t updateRectQueue;\ntypedef struct {\n    uint8_t width;\n    uint8_t height;\n} UpdateRectQueuePack_t;\n\n\nvoid putChar(uint8_t* vFrame, uint8_t row, uint8_t column, uint8_t code, bool isInvert)\n{\n    if (code &lt; ' ' || code &gt; '~') return;\n    row = row%8;\n    row = 7 - row;\n    if (isInvert) {\n        for (uint8_t i = 0; i &lt; 12; i++) {\n            vFrame[row + ((column + i) &lt;&lt; 3)] = ~zpix_ascii[(code - ' ') * 12 + i];\n        }\n    } else {\n        for (uint8_t i = 0; i &lt; 12; i++) {\n            vFrame[row + ((column + i) &lt;&lt; 3)] = zpix_ascii[(code - ' ') * 12 + i];\n        }\n    }\n\n}\n\n\/\/ \u5168\u5c40\u9884\u8ba1\u7b97\u63a9\u7801\u8868\uff08\u5e38\u91cf\u6570\u7ec4\uff09\nconst uint8_t BIT_MASK[8] = {\n    0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80\n};\n\nvoid setPixel(uint8_t* vFrame,uint8_t x, uint8_t y, bool isTrue) {\n    uint8_t row = y &gt;&gt; 3;         \/\/ \u884c\u7d22\u5f15\uff08y\/8\uff09\n    uint16_t pos = x; \n    pos &lt;&lt;= 3;\n    pos += row;\n    uint8_t mask = BIT_MASK[y &amp; 0x07]; \/\/ \u76f4\u63a5\u67e5\u8868\u83b7\u53d6\u4f4d\u63a9\u7801\n\n    if (isTrue) {\n        vFrame[pos] |= mask;       \/\/ \u7f6e\u4f4d\u50cf\u7d20\n    } else {\n        vFrame[pos] &amp;= ~mask;      \/\/ \u6e05\u9664\u50cf\u7d20\n    }\n}\n\n\/** \n * \u9ad8\u6548\u7ed8\u5236\u77e9\u5f62\uff08\u7a7a\u5fc3\u6216\u5b9e\u5fc3\uff09\n * @param x0, y0  \u77e9\u5f62\u5de6\u4e0a\u89d2\u5750\u6807\n * @param x1, y1  \u77e9\u5f62\u53f3\u4e0b\u89d2\u5750\u6807\n * @param isFilled true=\u5b9e\u5fc3\u586b\u5145, false=\u4ec5\u8fb9\u6846\n * @param isTrue   true=\u7f6e\u4f4d\u50cf\u7d20, false=\u6e05\u9664\u50cf\u7d20\n *\/\nvoid drawRectangle(uint8_t* vFrame,uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, bool isTrue) {\n    \/\/ 1. \u53c2\u6570\u6821\u9a8c\uff1a\u786e\u4fdd x0&lt;=x1, y0&lt;=y1\n    if (x0 &gt; x1) { uint8_t tmp = x0; x0 = x1; x1 = tmp; }\n    if (y0 &gt; y1) { uint8_t tmp = y0; y0 = y1; y1 = tmp; }\n\n    for (uint16_t i = x0;i &lt;= x1;i++){\n        for (uint16_t j = y0;j &lt;= y1;j++) {\n            setPixel(vFrame, i, j, isTrue);\n        }\n    }\n}\n\nvoid drawRectangle_Optimized(uint8_t* vFrame,uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, bool isFilled, bool isRoundCorner,bool isTrue) {\n    \/\/ 1. \u53c2\u6570\u6821\u9a8c\u4e0e\u5750\u6807\u5f52\u4e00\u5316\n    if (x0 &gt; x1) { uint8_t tmp = x0; x0 = x1; x1 = tmp; }\n    if (y0 &gt; y1) { uint8_t tmp = y0; y0 = y1; y1 = tmp; }\n    if (x0 == x1 || y0 == y1) return;\n    \/\/ 2. \u7ed8\u5236\u7a7a\u5fc3\u77e9\u5f62\u8fb9\u6846\uff08\u4ec5\u56db\u6761\u8fb9\uff09\n    \/\/ \u4e0a\/\u4e0b\u6c34\u5e73\u8fb9\u6846\uff08\u6574\u884c\u5904\u7406\uff09\n    for (uint8_t x = x0 + ((isRoundCorner) ? 1 : 0); x &lt;= x1 - ((isRoundCorner) ? 1 : 0); x++) {\n        setPixel(vFrame, x, y0, isTrue); \/\/ \u4e0a\u8fb9\u6846\n        setPixel(vFrame, x, y1, isTrue); \/\/ \u4e0b\u8fb9\u6846\n    }\n    \/\/ \u5de6\/\u53f3\u8fb9\u6846\uff08\u6309\u9875\u5904\u7406\uff09\n    uint8_t start_page = y0 &gt;&gt; 3;\n    uint8_t end_page = y1 &gt;&gt; 3;\n\n    for (uint8_t i = y0 + 1; i &lt;= y1 - 1; i++) {\n        setPixel(vFrame, x0, i, isTrue); \/\/ \u5de6\u8fb9\u6846\n        setPixel(vFrame, x1, i, isTrue); \/\/ \u53f3\u8fb9\u6846\n    }\n\n    \/\/ 3. \u5b9e\u5fc3\u586b\u5145\u4f18\u5316\uff08\u6309\u5217\u6279\u91cf\u64cd\u4f5c\uff09\n    if (isFilled) {\n        for (uint16_t x = x0 + 1; x &lt; x1; x++) { \/\/ \u904d\u5386\u6bcf\u4e00\u5217\n            for (uint8_t page = start_page; page &lt;= end_page; page++) {\n                uint8_t *col_ptr = &amp;vFrame[(x &lt;&lt; 3) + page]; \/\/ \u5f53\u524d\u5217\u663e\u5b58\u5730\u5740\n                uint8_t fill_mask = 0xFF; \/\/ \u9ed8\u8ba4\u586b\u5145\u6574\u9875\n\n                \/\/ \u8ba1\u7b97\u5f53\u524d\u9875\u7684\u5782\u76f4\u63a9\u7801\uff08\u9996\u5c3e\u9875\u88c1\u526a\uff09\n                if (page == start_page) \n                    fill_mask &amp;= (0xFF &lt;&lt; (y0 &amp; 0x07));   \/\/ \u9996\u9875\uff1a\u5c4f\u853d\u9876\u90e8\u65e0\u6548\u4f4d\n                if (page == end_page) \n                    fill_mask &amp;= (0xFF &gt;&gt; (7 - (y1 &amp; 0x07))); \/\/ \u5c3e\u9875\uff1a\u5c4f\u853d\u5e95\u90e8\u65e0\u6548\u4f4d\n\n                \/\/ \u6574\u5b57\u8282\u5199\u5165\u663e\u5b58\n                if (isTrue) *col_ptr |= fill_mask;\n                else        *col_ptr &amp;= ~fill_mask;\n            }\n        }\n    }\n}\n\nvoid testPutChar(uint8_t* vFrame,uint8_t x, uint8_t y, uint8_t code, uint8_t zoom, bool isInvert)\n{\n    if (code &lt; ' ' || code &gt; '~') return;\n    for (uint8_t i = 0; i &lt; 12; i++) {\n        uint8_t mask = zpix_ascii[(code - ' ') * 12 + i];\n        if (isInvert) mask = ~mask;\n        for (uint8_t j = 0; j &lt; 8; j++) {\n            uint8_t color = mask &amp; (0x80 &gt;&gt; j);\n            if (color || 1) {\n                if(zoom &lt;= 1) setPixel(vFrame, j + x, i + y, color);\n                else drawRectangle (vFrame, j * zoom + x, i * zoom + y,(j + 1) * zoom + x - 1, (i + 1) * zoom + y - 1, color);\n            }\n        }\n    }\n}\n\nvoid testPutTinyChar(uint8_t* vFrame,uint8_t x, uint8_t y, uint8_t code, uint8_t zoom, bool isInvert)\n{\n    y += 1;\n    if (code &lt; ' ' || code &gt; '~') return;\n    for (uint8_t i = 0; i &lt; 5; i++) {\n        uint8_t mask = tinyFont_ascii[(code - ' ') * 5 + i];\n        if (isInvert) mask = ~mask;\n        for (uint8_t j = 0; j &lt; 5; j++) {\n            uint8_t color = mask &amp; (0x80 &gt;&gt; j);\n            if (color || 1) {\n                if(zoom &lt;= 1) setPixel(vFrame, j + x, i + y, color);\n                else drawRectangle (vFrame, j * zoom + x, i * zoom + y,(j + 1) * zoom + x - 1, (i + 1) * zoom + y - 1, color);\n            }\n        }\n    }\n    y -= 1;\n    for (uint8_t i = 0; i &lt; 5; i++) {\n        setPixel(vFrame, i + x, y, isInvert);\n    }\n}\n\nvoid frameBufferCopy(int16_t x,int16_t y, int16_t w, int16_t h)\n{\n    if (h &lt; 1 || w &lt; 1) return;\n    uint16_t start_page = y &gt;&gt; 3;\n    uint16_t end_page = (y + h) &gt;&gt; 3;\n    for (uint16_t i = x; i &lt;= (w + x) ; i++) {\n        for (uint16_t page = start_page; page &lt;= end_page; page++) {\n            uint8_t *col_ptr = &amp;vBuf[(i &lt;&lt; 3) + page]; \/\/ \u5f53\u524d\u5217\u663e\u5b58\u5730\u5740\n            uint16_t fill_mask = (vBuf2[((i - x) &lt;&lt; 3) + page - start_page]);\n            fill_mask &lt;&lt;= 8;\n            if (page != start_page) {\n                fill_mask += (vBuf2[((i - x) &lt;&lt; 3) + page - start_page - 1]);\n                fill_mask &gt;&gt;= 8 - (y% 8);\n            } else {\n                fill_mask += (vBuf2[((i - x) &lt;&lt; 3) + page - start_page]);\n                fill_mask &lt;&lt;= (y% 8);\n            }\n            uint8_t maskUint8 = fill_mask &amp; 0x00FF;\n            \/\/ \u8ba1\u7b97\u5f53\u524d\u9875\u7684\u5782\u76f4\u63a9\u7801\uff08\u9996\u5c3e\u9875\u88c1\u526a\uff09\n                if (page == start_page) \n                    maskUint8 &amp;= (0xFF &lt;&lt; (y &amp; 0x07));   \/\/ \u9996\u9875\uff1a\u5c4f\u853d\u9876\u90e8\u65e0\u6548\u4f4d\n                if (page == end_page) \n                    maskUint8 &amp;= (0xFF &gt;&gt; (7 - ((y + h) &amp; 0x07))); \/\/ \u5c3e\u9875\uff1a\u5c4f\u853d\u5e95\u90e8\u65e0\u6548\u4f4d\n\n                \/\/ \u6574\u5b57\u8282\u5199\u5165\u663e\u5b58\n                *col_ptr |= maskUint8;\n        }\n    }\n}\n\ntypedef struct {\n    uint16_t currFrame;\n    uint16_t totalFrame;\n    int16_t targetWidth;\n    int16_t targetHeight;\n    int16_t currWidth;\n    int16_t currHeight;\n    int16_t startWidth;\n    int16_t startHeight;\n\n} UpdateRect_t;\n\nUpdateRect_t rectInfo;\nSemaphoreHandle_t rectMutex;\n\n#define MIN(a, b) ((a) &lt; (b) ? (a) : (b))\n#define MAX(a, b) ((a) &gt; (b) ? (a) : (b))\n\nfloat animationCalc(float t);\nvoid updateRect(TimerHandle_t xTimer)\n{\n    static bool isRunning = false;\n    if (isRunning) return;\n    isRunning = true;\n    xSemaphoreTake(rectMutex, portMAX_DELAY);\n    xSemaphoreTake(vBuf2Mutex, portMAX_DELAY);\n    \/* \u68c0\u67e5\u5408\u6cd5\u6027 *\/\n    \/\/ rectInfo.targetWidth = MAX (0, rectInfo.targetWidth);\n    \/\/ rectInfo.targetWidth = MIN (127, rectInfo.targetWidth);\n    \/\/ rectInfo.targetHeight = MAX (0, rectInfo.targetHeight);\n    \/\/ rectInfo.targetHeight = MIN (63, rectInfo.targetHeight);\n    \/\/ rectInfo.currWidth = MAX (0, rectInfo.currWidth);\n    \/\/ rectInfo.currWidth = MIN (127, rectInfo.currWidth);\n    \/\/ rectInfo.currHeight = MAX (0, rectInfo.currHeight);\n    \/\/ rectInfo.currHeight = MIN (63, rectInfo.currHeight);\n    \/\/ rectInfo.startWidth = MAX (0, rectInfo.startWidth);\n    \/\/ rectInfo.startWidth = MIN (127, rectInfo.startWidth);\n    \/\/ rectInfo.startHeight = MAX (0, rectInfo.startHeight);\n    \/\/ rectInfo.startHeight = MIN (63, rectInfo.startHeight);\n\n    float time = 1.0f * rectInfo.currFrame \/ rectInfo.totalFrame;\n    if (rectInfo.currFrame &gt; rectInfo.totalFrame || time &gt; 1.0f) {\n        xTimerStop(xTimer, 0);\n        xSemaphoreGive(rectMutex);\n        xSemaphoreGive(vBuf2Mutex);\n        isRunning = false;\n        return;\n    }\n    float div = animationCalc(time);\n    if (div &gt; 1.0) div = 1.0;\n    int16_t newHeight = rectInfo.startHeight + (rectInfo.targetHeight - rectInfo.startHeight) * div;\n    int16_t newWidth = rectInfo.startWidth + (rectInfo.targetWidth - rectInfo.startWidth) * div;\n    if (newHeight &gt; 63 || newWidth &gt; 127)\n    ESP_LOGW(__func__,\"%d,%d,%d,%d,%f\",newWidth, rectInfo.currWidth, rectInfo.startWidth, rectInfo.targetWidth,time);\n\n    \/\/ drawRectangle_Optimized(vBuf, 0,0,newWidth,newHeight,false,true,true);\n\n\n    if (rectInfo.currHeight != newHeight || rectInfo.currWidth != newWidth || rectInfo.currFrame != 0) {\n        drawRectangle_Optimized(vBuf, \n        63 - (newWidth &gt;&gt; 1), \n        31 - (newHeight &gt;&gt; 1), \n        63 + newWidth - (newWidth &gt;&gt; 1),\n        31 + newHeight - (newHeight &gt;&gt; 1),\n        false,true,true);\n        rectInfo.currHeight = newHeight;\n        rectInfo.currWidth = newWidth;\n        if(newWidth &gt;= 1 &amp;&amp; newHeight &gt;= 1 &amp;&amp; newWidth &lt;= 126 &amp;&amp; newHeight &lt;= 62) {\n            frameBufferCopy(63 - (newWidth &gt;&gt; 1) + 2, 31 - (newHeight &gt;&gt; 1) + 2,newWidth - 4,newHeight - 4);\n        }\n        ssd1306FreshScreen();\n    }\n    rectInfo.currFrame++;\n    xSemaphoreGive(rectMutex);\n    xSemaphoreGive(vBuf2Mutex);\n    isRunning = false;\n}\n\nTaskHandle_t logAutoHandler = NULL;\nesp_timer_handle_t timer_handle;\n\nfloat animationCalc(float t) {\n    if (t &lt; 0.5) \n        return 0.5f * pow(2*t, 2);\n    else if (t != 1.0)\n        return 1.0f - 0.5f * pow(2*(1-t), 2); \/\/ \u540e\u534a\u6bb5\u51cf\u901f\n    else return 1.0f;\n}\n\nvoid setNewRectAnimation(int16_t targetWidth, int16_t targetHeight, int16_t frame)\n{\n    rectInfo.currFrame = 0;\n    rectInfo.targetHeight = targetHeight;\n    rectInfo.targetWidth = targetWidth;\n    rectInfo.totalFrame = frame;\n    rectInfo.startHeight = rectInfo.currHeight;\n    rectInfo.startWidth = rectInfo.currWidth;\n}\n\nstatic void logAuto()\n{\n    rectInfo.startHeight = 0;\n    rectInfo.startWidth = 0;\n    TimerHandle_t xTimer = xTimerCreate(\n        \"updateRect\",                  \/\/ \u5b9a\u65f6\u5668\u540d\u79f0\uff08\u8c03\u8bd5\u7528\uff09\n        pdMS_TO_TICKS(33),            \/\/ \u5468\u671f\uff1a20ms \n        pdTRUE,                       \/\/ \u81ea\u52a8\u91cd\u8f7d\uff08\u5468\u671f\u6027\uff09\n        (void *)0,          \/\/ \u5b9a\u65f6\u5668 ID\uff08\u53ef\u4f20\u9012\u53c2\u6570\uff09\n        updateRect                \/\/ \u56de\u8c03\u51fd\u6570\n    );\n    bool isClose = true;\n    uint8_t skipCount = 0;\n    UpdateRectQueuePack_t queueData = {\n        .height = 0,\n        .width = 0\n    };\n    while (true) {\n        if (xQueueReceive(updateRectQueue, &amp;queueData, (isClose) ? portMAX_DELAY : 10000\/portTICK_PERIOD_MS) == pdTRUE) {\n            isClose = false;\n            queueData.height += 4;\n            queueData.width += 4;\n        } else {\n            ESP_LOGI(__func__,\"timeout\");\n            queueData.height = 0;\n            queueData.width = 0;\n            skipCount = 0;\n            isClose = true;\n        }\n        if (true) {\n            xSemaphoreTake(rectMutex, portMAX_DELAY);\n            if (rectInfo.currFrame &lt; rectInfo.totalFrame) {\n                if (skipCount &lt; 9)\n                    skipCount ++;\n            } else {\n                if (skipCount) skipCount --;\n            }\n            xTimerStop(xTimer, 0);\n            setNewRectAnimation(queueData.width,queueData.height, 40 \/ (skipCount + 1));\n            xSemaphoreGive(rectMutex);\n            xTimerStart(xTimer, 0); \n        }\n        vTaskDelay (200\/portTICK_PERIOD_MS);\n    }\n}\n\nvoid setRect(uint8_t width, uint8_t height) \n{\n    UpdateRectQueuePack_t sendData = {\n        .width = width,\n        .height = height,\n    };\n    ESP_LOGI(__func__,\"W: %d, H: %d\", width,height);\n    xQueueSend(updateRectQueue, &amp;sendData, 0);\n}\n\nQueueHandle_t updateConsoleQueue;\ntypedef struct {\n    uint8_t flag;\n    uint16_t len;\n    uint8_t str[224];\n} ConsoleQueuePack_t;\nvoid consoleLogDeamon()\n{\n    ConsoleQueuePack_t ret;\n    while (true) {\n        if (xQueueReceive(updateConsoleQueue, (void*)&amp;ret, portMAX_DELAY) == pdTRUE) {\n            xSemaphoreTake(vBuf2Mutex, portMAX_DELAY);\n            \/\/ memset(vBuf2, 0x00, 1024);\n            uint8_t* recvBuf = ret.str;\n            uint16_t len = ret.len;\n            uint8_t isInvert = ret.flag;\n            uint8_t row = 0;\n            uint8_t maxRow = 0;\n            uint8_t column = 0;\n            if (len &gt; 44) {\n                for (uint16_t i = 0; i &lt; len; i++) {\n                    if (recvBuf[i] == '\\n') {\n                        row = 0;\n                        column++;\n                    } else {\n                        testPutTinyChar(vBuf2,row * 5, 6 * column, recvBuf[i], 1,isInvert);\n                    }\n                    maxRow = (row &gt; maxRow) ? row : maxRow;\n                    row++;\n                    if (row &gt; 20) {\n                        column++;\n                        row = 0;\n                    }\n                }\n                setRect((1 + maxRow) * 5,(column + 1) * 6);\n            } else {\n                for (uint16_t i = 0; i &lt; len; i++) {\n                    if (recvBuf[i] == '\\n') {\n                        row = 0;\n                        column++;\n                    } else {\n                        testPutChar(vBuf2,row * 8, 12 * column, recvBuf[i], 1,isInvert);\n                    }\n                    maxRow = (row &gt; maxRow) ? row : maxRow;\n                    row++;\n                    if (row &gt; 14) {\n                        column++;\n                        row = 0;\n                    }\n                }\n                setRect((1 + maxRow) * 8,(column + 1) * 12);\n            }\n\n            \/\/ uint8_t width = (len \/ 25) ? 25 : (len % 25);\n            \/\/ uint8_t height = (len \/ 25) * 5 + 5;\n            \/\/ setRect(width * 5,height);\n            xSemaphoreGive(vBuf2Mutex);\n        }\n    }\n}\n\nvoid logAutoInit() \n{\n    \/\/ for (uint16_t i = 0; i &lt; 1024; i++) {\n    \/\/     if((i &gt;&gt; 3) % 2) {\n    \/\/         vBuf2[i] = 0x55;\n    \/\/     } else {\n    \/\/         vBuf2[i] = 0xAA;\n    \/\/     }\n    \/\/ }\n    \/\/ drawRectangle_Optimized(vBuf2,1,1,10,10,true,false,true);\n    updateRectQueue = xQueueCreate(3, sizeof(UpdateRectQueuePack_t));\n    updateConsoleQueue = xQueueCreate(2, sizeof(ConsoleQueuePack_t));\n    rectMutex = xSemaphoreCreateMutex();\n    vBuf2Mutex = xSemaphoreCreateMutex();\n    xTaskCreatePinnedToCore(logAuto, \"logAuto\", 8192, NULL, 6, &amp;logAutoHandler,0);\n    xTaskCreatePinnedToCore(consoleLogDeamon, \"consoleLogDeamon\", 3072, NULL, 7, NULL,0);\n}\n\n\nvoid consoleLog(bool isInvert,const char *format, ...) \n{\n    ConsoleQueuePack_t ret = {\n        .flag = isInvert,\n    };\n    va_list args;\n    va_start(args, format);\n    ret.len = vsnprintf((char*)ret.str, sizeof(ret.str), format, args);\n    va_end(args);\n    ret.str[223] = 0x00;\n    xQueueSend(updateConsoleQueue, &amp;ret, 0);\n}\n\n<\/code><\/pre>\n<h3>h<\/h3>\n<pre><code class=\"language-c line-numbers\">#ifndef SSD1306_GRAPHICS_H\n#define SSD1306_GRAPHICS_H\n\n#include \"esp_log.h\"\n#include &lt;stdbool.h&gt;\n\nvoid consoleLog(bool isInvert,const char *format, ...);\nvoid logAutoInit();\n\n#endif\n\n<\/code><\/pre>\n<h2>\u9644\u4ef62<\/h2>\n<h3>zpix (github\u5f00\u6e90)<\/h3>\n<pre><code class=\"language-c line-numbers\">#ifndef ZPIX_H\n#define ZPIX_H\n\n#include &lt;stdint.h&gt;\n\nuint8_t zpix_ascii[] = {\n\/*   [0x0020]    8x12 *\/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n\/*  ![0x0021]    8x12 *\/ 0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x10,0x10,0x00,\n\/*  \"[0x0022]    8x12 *\/ 0x00,0x00,0x28,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n\/*  #[0x0023]    8x12 *\/ 0x00,0x00,0x28,0x28,0x7C,0x28,0x28,0x28,0x7C,0x28,0x28,0x00,\n\/*  $[0x0024]    8x12 *\/ 0x00,0x00,0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x38,0x10,0x00,\n\/*  %[0x0025]    8x12 *\/ 0x00,0x00,0x00,0x24,0x54,0x58,0x28,0x14,0x1A,0x2A,0x24,0x00,\n\/*  &amp;[0x0026]    8x12 *\/ 0x00,0x00,0x30,0x48,0x48,0x30,0x20,0x54,0x54,0x48,0x34,0x00,\n\/*  '[0x0027]    8x12 *\/ 0x00,0x00,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n\/*  ([0x0028]    8x12 *\/ 0x00,0x08,0x10,0x10,0x20,0x20,0x20,0x20,0x20,0x10,0x10,0x08,\n\/*  )[0x0029]    8x12 *\/ 0x00,0x20,0x10,0x10,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,\n\/*  *[0x002A]    8x12 *\/ 0x00,0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x28,0x00,0x00,0x00,\n\/*  +[0x002B]    8x12 *\/ 0x00,0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00,\n\/*  ,[0x002C]    8x12 *\/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08,\n\/*  -[0x002D]    8x12 *\/ 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,\n\/*  .[0x002E]    8x12 *\/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x00,\n\/*  \/[0x002F]    8x12 *\/ 0x00,0x00,0x08,0x08,0x08,0x10,0x10,0x10,0x20,0x20,0x20,0x00,\n\/*  0[0x0030]    8x12 *\/ 0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,\n\/*  1[0x0031]    8x12 *\/ 0x00,0x00,0x08,0x18,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00,\n\/*  2[0x0032]    8x12 *\/ 0x00,0x00,0x38,0x44,0x44,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,\n\/*  3[0x0033]    8x12 *\/ 0x00,0x00,0x38,0x44,0x44,0x04,0x18,0x04,0x44,0x44,0x38,0x00,\n\/*  4[0x0034]    8x12 *\/ 0x00,0x00,0x08,0x18,0x18,0x28,0x28,0x48,0x7C,0x08,0x08,0x00,\n\/*  5[0x0035]    8x12 *\/ 0x00,0x00,0x7C,0x40,0x40,0x78,0x44,0x04,0x04,0x44,0x38,0x00,\n\/*  6[0x0036]    8x12 *\/ 0x00,0x00,0x38,0x44,0x40,0x78,0x44,0x44,0x44,0x44,0x38,0x00,\n\/*  7[0x0037]    8x12 *\/ 0x00,0x00,0x7C,0x44,0x04,0x08,0x08,0x10,0x10,0x10,0x10,0x00,\n\/*  8[0x0038]    8x12 *\/ 0x00,0x00,0x38,0x44,0x44,0x44,0x38,0x44,0x44,0x44,0x38,0x00,\n\/*  9[0x0039]    8x12 *\/ 0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x3C,0x04,0x44,0x38,0x00,\n\/*  :[0x003A]    8x12 *\/ 0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x10,0x10,0x00,\n\/*  ;[0x003B]    8x12 *\/ 0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x00,0x00,0x08,0x08,0x10,\n\/*  &lt;[0x003C]    8x12 *\/ 0x00,0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00,\n\/*  =[0x003D]    8x12 *\/ 0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00,\n\/*  &gt;[0x003E]    8x12 *\/ 0x00,0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00,\n\/*  ?[0x003F]    8x12 *\/ 0x00,0x00,0x38,0x44,0x04,0x08,0x10,0x10,0x00,0x10,0x10,0x00,\n\/*  @[0x0040]    8x12 *\/ 0x00,0x00,0x38,0x44,0x4C,0x54,0x54,0x54,0x5C,0x40,0x38,0x00,\n\/*  A[0x0041]    8x12 *\/ 0x00,0x00,0x10,0x10,0x28,0x28,0x28,0x38,0x44,0x44,0x44,0x00,\n\/*  B[0x0042]    8x12 *\/ 0x00,0x00,0x78,0x44,0x44,0x44,0x78,0x44,0x44,0x44,0x78,0x00,\n\/*  C[0x0043]    8x12 *\/ 0x00,0x00,0x38,0x44,0x44,0x40,0x40,0x40,0x44,0x44,0x38,0x00,\n\/*  D[0x0044]    8x12 *\/ 0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x78,0x00,\n\/*  E[0x0045]    8x12 *\/ 0x00,0x00,0x7C,0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0x7C,0x00,\n\/*  F[0x0046]    8x12 *\/ 0x00,0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x40,0x00,\n\/*  G[0x0047]    8x12 *\/ 0x00,0x00,0x38,0x44,0x44,0x40,0x5C,0x44,0x44,0x4C,0x34,0x00,\n\/*  H[0x0048]    8x12 *\/ 0x00,0x00,0x44,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00,\n\/*  I[0x0049]    8x12 *\/ 0x00,0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,\n\/*  J[0x004A]    8x12 *\/ 0x00,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x44,0x44,0x38,0x00,\n\/*  K[0x004B]    8x12 *\/ 0x00,0x00,0x44,0x48,0x48,0x50,0x60,0x50,0x48,0x48,0x44,0x00,\n\/*  L[0x004C]    8x12 *\/ 0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00,\n\/*  M[0x004D]    8x12 *\/ 0x00,0x00,0x44,0x44,0x6C,0x6C,0x54,0x54,0x44,0x44,0x44,0x00,\n\/*  N[0x004E]    8x12 *\/ 0x00,0x00,0x44,0x64,0x64,0x54,0x54,0x4C,0x4C,0x44,0x44,0x00,\n\/*  O[0x004F]    8x12 *\/ 0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,\n\/*  P[0x0050]    8x12 *\/ 0x00,0x00,0x78,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x40,0x00,\n\/*  Q[0x0051]    8x12 *\/ 0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x54,0x38,0x04,\n\/*  R[0x0052]    8x12 *\/ 0x00,0x00,0x78,0x44,0x44,0x44,0x78,0x48,0x44,0x44,0x44,0x00,\n\/*  S[0x0053]    8x12 *\/ 0x00,0x00,0x38,0x44,0x44,0x20,0x10,0x08,0x44,0x44,0x38,0x00,\n\/*  T[0x0054]    8x12 *\/ 0x00,0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,\n\/*  U[0x0055]    8x12 *\/ 0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,\n\/*  V[0x0056]    8x12 *\/ 0x00,0x00,0x44,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x10,0x00,\n\/*  W[0x0057]    8x12 *\/ 0x00,0x00,0x54,0x54,0x54,0x54,0x54,0x54,0x28,0x28,0x28,0x00,\n\/*  X[0x0058]    8x12 *\/ 0x00,0x00,0x44,0x44,0x28,0x28,0x10,0x28,0x28,0x44,0x44,0x00,\n\/*  Y[0x0059]    8x12 *\/ 0x00,0x00,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x10,0x10,0x00,\n\/*  Z[0x005A]    8x12 *\/ 0x00,0x00,0x7C,0x04,0x08,0x08,0x10,0x20,0x20,0x40,0x7C,0x00,\n\/*  [[0x005B]    8x12 *\/ 0x00,0x18,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x18,\n\/*  \\[0x005C]    8x12 *\/ 0x00,0x00,0x20,0x20,0x20,0x10,0x10,0x10,0x08,0x08,0x08,0x00,\n\/*  ][0x005D]    8x12 *\/ 0x00,0x18,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x18,\n\/*  ^[0x005E]    8x12 *\/ 0x00,0x00,0x18,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n\/*  _[0x005F]    8x12 *\/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,\n\/*  `[0x0060]    8x12 *\/ 0x00,0x00,0x10,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n\/*  a[0x0061]    8x12 *\/ 0x00,0x00,0x00,0x00,0x78,0x04,0x04,0x3C,0x44,0x44,0x3C,0x00,\n\/*  b[0x0062]    8x12 *\/ 0x00,0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x00,\n\/*  c[0x0063]    8x12 *\/ 0x00,0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x40,0x44,0x38,0x00,\n\/*  d[0x0064]    8x12 *\/ 0x00,0x00,0x04,0x04,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x00,\n\/*  e[0x0065]    8x12 *\/ 0x00,0x00,0x00,0x00,0x38,0x44,0x44,0x7C,0x40,0x44,0x38,0x00,\n\/*  f[0x0066]    8x12 *\/ 0x00,0x00,0x0C,0x10,0x10,0x3C,0x10,0x10,0x10,0x10,0x10,0x00,\n\/*  g[0x0067]    8x12 *\/ 0x00,0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x3C,0x04,0x44,0x38,\n\/*  h[0x0068]    8x12 *\/ 0x00,0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x44,0x00,\n\/*  i[0x0069]    8x12 *\/ 0x00,0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x38,0x00,\n\/*  j[0x006A]    8x12 *\/ 0x00,0x00,0x08,0x00,0x18,0x08,0x08,0x08,0x08,0x08,0x08,0x30,\n\/*  k[0x006B]    8x12 *\/ 0x00,0x00,0x40,0x40,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00,\n\/*  l[0x006C]    8x12 *\/ 0x00,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,\n\/*  m[0x006D]    8x12 *\/ 0x00,0x00,0x00,0x00,0x68,0x54,0x54,0x54,0x54,0x54,0x54,0x00,\n\/*  n[0x006E]    8x12 *\/ 0x00,0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x44,0x00,\n\/*  o[0x006F]    8x12 *\/ 0x00,0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x38,0x00,\n\/*  p[0x0070]    8x12 *\/ 0x00,0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40,\n\/*  q[0x0071]    8x12 *\/ 0x00,0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x3C,0x04,0x04,\n\/*  r[0x0072]    8x12 *\/ 0x00,0x00,0x00,0x00,0x2C,0x30,0x20,0x20,0x20,0x20,0x20,0x00,\n\/*  s[0x0073]    8x12 *\/ 0x00,0x00,0x00,0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x38,0x00,\n\/*  t[0x0074]    8x12 *\/ 0x00,0x00,0x10,0x10,0x3C,0x10,0x10,0x10,0x10,0x10,0x0C,0x00,\n\/*  u[0x0075]    8x12 *\/ 0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x3C,0x00,\n\/*  v[0x0076]    8x12 *\/ 0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x00,\n\/*  w[0x0077]    8x12 *\/ 0x00,0x00,0x00,0x00,0x54,0x54,0x54,0x54,0x38,0x28,0x28,0x00,\n\/*  x[0x0078]    8x12 *\/ 0x00,0x00,0x00,0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00,\n\/*  y[0x0079]    8x12 *\/ 0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x60,\n\/*  z[0x007A]    8x12 *\/ 0x00,0x00,0x00,0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,\n\/*  {[0x007B]    8x12 *\/ 0x00,0x08,0x10,0x10,0x10,0x10,0x20,0x10,0x10,0x10,0x10,0x08,\n\/*  |[0x007C]    8x12 *\/ 0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,\n\/*  }[0x007D]    8x12 *\/ 0x00,0x20,0x10,0x10,0x10,0x10,0x08,0x10,0x10,0x10,0x10,0x20,\n\/*  ~[0x007E]    8x12 *\/ 0x00,0x34,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n\/*  [0x007F]    8x12 *\/ 0x00,0x00,0xFF,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFF,0x00,\n};\n\n\n#endif\n<\/code><\/pre>\n<h3>tinyFont (\u81ea\u5df1\u505a\u7684\uff0c\u65e0\u7248\u6743)<\/h3>\n<pre><code class=\"language-c line-numbers\">#ifndef TINYFONT_H\n#define TINYFONT_H \n\n#include &lt;stdint.h&gt;\n\nuint8_t tinyFont_ascii[] = {\n\/*   [0x0020]    4x5  *\/0x00,0x00,0x00,0x00,0x00,\n\/*  ![0x0021]    4x5  *\/0x20,0x20,0x20,0x00,0x20,\n\/*  \"[0x0022]    4x5  *\/0x50,0x50,0x00,0x00,0x00,\n\/*  #[0x0023]    4x5  *\/0x50,0xF0,0xA0,0xF0,0xA0,\n\/*  $[0x0024]    4x5  *\/0x70,0xA0,0x70,0x20,0xF0,\n\/*  %[0x0025]    4x5  *\/0x00,0xD0,0xE0,0x70,0xB0,\n\/*  &amp;[0x0026]    4x5  *\/0x40,0xA0,0x40,0xA0,0x50,\n\/*  '[0x0027]    4x5  *\/0x20,0x20,0x00,0x00,0x00,\n\/*  ([0x0028]    4x5  *\/0x20,0x40,0x40,0x40,0x20,\n\/*  )[0x0029]    4x5  *\/0x20,0x10,0x10,0x10,0x20,\n\/*  *[0x002A]    4x5  *\/0x50,0x20,0x70,0x20,0x50,\n\/*  +[0x002B]    4x5  *\/0x00,0x20,0x70,0x20,0x00,\n\/*  ,[0x002C]    4x5  *\/0x00,0x00,0x20,0x20,0x40,\n\/*  -[0x002D]    4x5  *\/0x00,0x00,0x70,0x00,0x00,\n\/*  .[0x002E]    4x5  *\/0x00,0x00,0x20,0x20,0x00,\n\/*  \/[0x002F]    4x5  *\/0x00,0x10,0x20,0x40,0x00,\n\/*  0[0x0030]    4x5  *\/0x60,0xB0,0xD0,0x90,0x60,\n\/*  1[0x0031]    4x5  *\/0xC0,0x40,0x40,0x40,0xE0,\n\/*  2[0x0032]    4x5  *\/0x60,0x10,0x60,0x80,0xE0,\n\/*  3[0x0033]    4x5  *\/0x60,0x10,0x60,0x10,0x60,\n\/*  4[0x0034]    4x5  *\/0x20,0x60,0xA0,0xF0,0x20,\n\/*  5[0x0035]    4x5  *\/0xF0,0x80,0x60,0x10,0x60,\n\/*  6[0x0036]    4x5  *\/0x60,0x80,0xE0,0x90,0x60,\n\/*  7[0x0037]    4x5  *\/0xF0,0x10,0x20,0x20,0x20,\n\/*  8[0x0038]    4x5  *\/0x60,0x90,0x60,0x90,0x60,\n\/*  9[0x0039]    4x5  *\/0x60,0x90,0x70,0x10,0x60,\n\/*  :[0x003A]    4x5  *\/0x20,0x20,0x00,0x20,0x20,\n\/*  ;[0x003B]    4x5  *\/0x20,0x20,0x00,0x20,0x40,\n\/*  &lt;[0x003C]    4x5  *\/0x10,0x20,0x40,0x20,0x10,\n\/*  =[0x003D]    4x5  *\/0x00,0x70,0x00,0x70,0x00,\n\/*  &gt;[0x003E]    4x5  *\/0x40,0x20,0x10,0x20,0x40,\n\/*  ?[0x003F]    4x5  *\/0x60,0x10,0x20,0x00,0x20,\n\/*  @[0x0040]    4x5  *\/0x60,0x90,0xB0,0x80,0x70,\n\/*  A[0x0041]    4x5  *\/0x60,0x90,0x90,0xF0,0x90,\n\/*  B[0x0042]    4x5  *\/0xE0,0x90,0xE0,0x90,0xE0,\n\/*  C[0x0043]    4x5  *\/0x70,0x80,0x80,0x80,0x70,\n\/*  D[0x0044]    4x5  *\/0xE0,0x90,0x90,0x90,0xE0,\n\/*  E[0x0045]    4x5  *\/0xF0,0x80,0xE0,0x80,0xF0,\n\/*  F[0x0046]    4x5  *\/0xF0,0x80,0xE0,0x80,0x80,\n\/*  G[0x0047]    4x5  *\/0x70,0x80,0xB0,0x90,0x70,\n\/*  H[0x0048]    4x5  *\/0x90,0x90,0xF0,0x90,0x90,\n\/*  I[0x0049]    4x5  *\/0x70,0x20,0x20,0x20,0x70,\n\/*  J[0x004A]    4x5  *\/0x30,0x10,0x10,0x90,0x60,\n\/*  K[0x004B]    4x5  *\/0x90,0xA0,0xC0,0xA0,0x90,\n\/*  L[0x004C]    4x5  *\/0x80,0x80,0x80,0x80,0xF0,\n\/*  M[0x004D]    4x5  *\/0x90,0xF0,0xF0,0x90,0x90,\n\/*  N[0x004E]    4x5  *\/0x90,0xD0,0xB0,0x90,0x90,\n\/*  O[0x004F]    4x5  *\/0x60,0x90,0x90,0x90,0x60,\n\/*  P[0x0050]    4x5  *\/0xE0,0x90,0x90,0xE0,0x80,\n\/*  Q[0x0051]    4x5  *\/0x60,0x90,0x90,0xA0,0x50,\n\/*  R[0x0052]    4x5  *\/0x60,0x90,0xE0,0xA0,0x90,\n\/*  S[0x0053]    4x5  *\/0x70,0x80,0x60,0x10,0xE0,\n\/*  T[0x0054]    4x5  *\/0x70,0x20,0x20,0x20,0x20,\n\/*  U[0x0055]    4x5  *\/0x90,0x90,0x90,0x90,0x60,\n\/*  V[0x0056]    4x5  *\/0x90,0x90,0x90,0xA0,0x40,\n\/*  W[0x0057]    4x5  *\/0x90,0x90,0xF0,0xF0,0x90,\n\/*  X[0x0058]    4x5  *\/0x90,0x90,0x60,0x90,0x90,\n\/*  Y[0x0059]    4x5  *\/0x50,0x50,0x20,0x20,0x20,\n\/*  Z[0x005A]    4x5  *\/0xF0,0x20,0x40,0x80,0xF0,\n\/*  [[0x005B]    4x5  *\/0x70,0x40,0x40,0x40,0x70,\n\/*  \\[0x005C]    4x5  *\/0x80,0x40,0x20,0x10,0x00,\n\/*  ][0x005D]    4x5  *\/0x70,0x10,0x10,0x10,0x70,\n\/*  ^[0x005E]    4x5  *\/0x20,0x50,0x00,0x00,0x00,\n\/*  _[0x005F]    4x5  *\/0x00,0x00,0x00,0x00,0x70,\n\/*  `[0x0060]    4x5  *\/0x40,0x20,0x00,0x00,0x00,\n\/*  a[0x0061]    4x5  *\/0x60,0x10,0x70,0x90,0x70,\n\/*  b[0x0062]    4x5  *\/0x80,0xE0,0x90,0x90,0xE0,\n\/*  c[0x0063]    4x5  *\/0x00,0x60,0x80,0x80,0x60,\n\/*  d[0x0064]    4x5  *\/0x10,0x70,0x90,0x90,0x70,\n\/*  e[0x0065]    4x5  *\/0x00,0x60,0xB0,0xC0,0x60,\n\/*  f[0x0066]    4x5  *\/0x20,0x40,0xE0,0x40,0x40,\n\/*  g[0x0067]    4x5  *\/0x70,0x90,0x70,0x10,0x60,\n\/*  h[0x0068]    4x5  *\/0x80,0xE0,0x90,0x90,0x90,\n\/*  i[0x0069]    4x5  *\/0x20,0x00,0x20,0x20,0x20,\n\/*  j[0x006A]    4x5  *\/0x20,0x00,0x60,0x20,0xC0,\n\/*  k[0x006B]    4x5  *\/0x80,0xB0,0xC0,0xA0,0x90,\n\/*  l[0x006C]    4x5  *\/0x40,0x40,0x40,0x40,0x20,\n\/*  m[0x006D]    4x5  *\/0x00,0x90,0xF0,0x90,0x90,\n\/*  n[0x006E]    4x5  *\/0x00,0x60,0x90,0x90,0x90,\n\/*  o[0x006F]    4x5  *\/0x00,0x60,0x90,0x90,0x60,\n\/*  p[0x0070]    4x5  *\/0xE0,0x90,0x90,0xE0,0x80,\n\/*  q[0x0071]    4x5  *\/0x70,0x90,0x90,0x70,0x10,\n\/*  r[0x0072]    4x5  *\/0x30,0x40,0x40,0x40,0x40,\n\/*  s[0x0073]    4x5  *\/0x60,0x80,0x60,0x10,0x60,\n\/*  t[0x0074]    4x5  *\/0x40,0xE0,0x40,0x40,0x30,\n\/*  u[0x0075]    4x5  *\/0x00,0x90,0x90,0x90,0x60,\n\/*  v[0x0076]    4x5  *\/0x00,0x90,0x90,0xA0,0x40,\n\/*  w[0x0077]    4x5  *\/0x00,0x90,0x90,0xF0,0x90,\n\/*  x[0x0078]    4x5  *\/0x00,0x50,0x20,0x20,0x50,\n\/*  y[0x0079]    4x5  *\/0x50,0x50,0x30,0x10,0x60,\n\/*  z[0x007A]    4x5  *\/0xF0,0x10,0x20,0x40,0xF0,\n\/*  {[0x007B]    4x5  *\/0x30,0x20,0x40,0x20,0x30,\n\/*  |[0x007C]    4x5  *\/0x20,0x20,0x20,0x20,0x20,\n\/*  }[0x007D]    4x5  *\/0x60,0x20,0x10,0x20,0x60,\n\/*  ~[0x007E]    4x5  *\/0x00,0x40,0xF0,0x20,0x00,\n\/*  [0x007F]    4x5  *\/0x00,0x00,0x00,0x00,0x00,\n\n};\n\n#endif\n\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u7b80\u4ecb \u4e00\u4e2a\u9002\u7528\u4e8eesp32\u7cfb\u5217\u7684oled12864 iic \uff08ssd1306\uff09\u7684\u65e5\u5fd7\u6253\u5370\u7a0b\u5e8f\uff08\u5e26\u6709\u52a8\u753b\uff09 \u4f7f\u7528\u65b9\u6cd5 \u5c06\u9644\u4ef6\u5185\u7684\u5de5\u7a0b &#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"emotion":"","emotion_color":"","title_style":"","license":"","footnotes":""},"categories":[4],"tags":[],"class_list":["post-419","post","type-post","status-publish","format-standard","hentry","category-esp32"],"_links":{"self":[{"href":"https:\/\/yin.nnneri.me\/index.php?rest_route=\/wp\/v2\/posts\/419","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/yin.nnneri.me\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/yin.nnneri.me\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/yin.nnneri.me\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/yin.nnneri.me\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=419"}],"version-history":[{"count":1,"href":"https:\/\/yin.nnneri.me\/index.php?rest_route=\/wp\/v2\/posts\/419\/revisions"}],"predecessor-version":[{"id":420,"href":"https:\/\/yin.nnneri.me\/index.php?rest_route=\/wp\/v2\/posts\/419\/revisions\/420"}],"wp:attachment":[{"href":"https:\/\/yin.nnneri.me\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=419"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/yin.nnneri.me\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=419"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/yin.nnneri.me\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=419"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}