{"id":416,"date":"2025-07-17T00:33:32","date_gmt":"2025-07-16T16:33:32","guid":{"rendered":"https:\/\/yin.nnneri.me\/?p=416"},"modified":"2025-07-17T00:33:32","modified_gmt":"2025-07-16T16:33:32","slug":"ssd1306-%e7%ae%80%e5%8d%95%e9%a9%b1%e5%8a%a8%ef%bc%88dma%e6%97%a7%e7%89%88%ef%bc%89","status":"publish","type":"post","link":"https:\/\/yin.nnneri.me\/?p=416","title":{"rendered":"ssd1306 \u7b80\u5355\u9a71\u52a8\uff08dma\u65e7\u7248\uff09"},"content":{"rendered":"<h2>\u7b80\u4ecb<\/h2>\n<p>\u4e00\u4e2a\u9002\u7528\u4e8eesp32\u7cfb\u5217\u7684oled12864 iic \uff08ssd1306\uff09\u9a71\u52a8\u7a0b\u5e8f\uff0c\u53ea\u9700\u8981\u7a0d\u5fae\u90e8\u7f72\u5373\u53ef\u4f7f\u7528<\/p>\n<h2>\u4f7f\u7528\u65b9\u6cd5<\/h2>\n<ol>\n<li>\u5c06\u9644\u4ef6\u91cc\u7684\u7a0b\u5e8f\u52a0\u5165\u5230\u5de5\u7a0b\u4e2d<\/li>\n<li>\u4fee\u6539.h\u6587\u4ef6\u5185\u7684\u5f15\u811a\u4e0e\u5b9e\u9645\u60c5\u51b5\u5bf9\u5e94<\/li>\n<li>\u4f7f\u7528\u51fd\u6570 <code>ssd1306IICInit()<\/code> \u548c <code>ssd1306DeviceInit()<\/code> \u5206\u522b\u521d\u59cb\u5316iic\u548c\u5c4f\u5e55\uff08<strong>\u5206\u5148\u540e\u987a\u5e8f\uff01<\/strong>\uff09<\/li>\n<li>\u5f15\u51fa\u5185\u5b58\u7f13\u51b2\u533avBuf\uff0c\u4fee\u6539\u5185\u90e8\u7684\u503c<\/li>\n<li>\u8c03\u7528<code>ssd1306FreshScreen()<\/code>\u5237\u65b0\u5c4f\u5e55\uff08\u4e0a\u4e00\u4e2a\u5237\u65b0\u82e5\u6ca1\u6709\u5b8c\u6210\u7a0b\u5e8f\u4f1a\u8fdb\u5165\u963b\u585e\u6001\uff09<\/li>\n<\/ol>\n<h2>\u9644\u4ef6<\/h2>\n<h3>c<\/h3>\n<pre><code class=\"language-c line-numbers\">#include \"ssd1306_driver.h\"\n\nSemaphoreHandle_t ssd1306Semaphore;\n\nuint8_t vMemory[1024+1] = {0x40,0x00};\nuint8_t* vBuf = vMemory + 1; \/\/ \u6d41\u51fa\u53bb\u7684\u63a5\u53e3\n\nvoid ssd1306IICInit(){\n    esp_err_t err;\n    i2c_config_t ssd1306IICConfig = {\n       .mode = I2C_MODE_MASTER,\n       .sda_io_num = SSD1306_SDA,\n       .scl_io_num = SSD1306_SCL,\n       .sda_pullup_en = SSD1306_IIC_PULLUP_ENABLE,\n       .scl_pullup_en = SSD1306_IIC_PULLUP_ENABLE,\n       .master.clk_speed = SSD1306_IIC_SPEED,\n    };\n    ESP_ERROR_CHECK(i2c_param_config(SSD1306_IIC_PORT, &amp;ssd1306IICConfig));\n    ESP_ERROR_CHECK(i2c_driver_install(SSD1306_IIC_PORT, I2C_MODE_MASTER, 0, 0, 0));\n    ssd1306Semaphore = xSemaphoreCreateMutex();\n    vMemory[0] = 0x40;\n}\n\nstatic esp_err_t ssd1306Write(uint8_t *data,uint16_t len){\n    xSemaphoreTake(ssd1306Semaphore,portMAX_DELAY);\n    esp_err_t ret = 0;\n    ret = i2c_master_write_to_device(I2C_NUM_0,SSD1306_ADDR1,data,len,500\/portTICK_PERIOD_MS);\n    xSemaphoreGive(ssd1306Semaphore);\n    return ret;\n}\n\nstatic void ssd1306WriteBytes(uint8_t data1,uint8_t data2){\n    uint8_t *buf = (uint8_t*)malloc(3);\n    buf[0] = 0x00;\n    buf[1] = data1;\n    buf[2] = data2;\n    ssd1306Write(buf,3);\n    free(buf);\n}\n\nstatic void ssd1306WriteByte(uint8_t data1){\n    uint8_t *buf = (uint8_t*)malloc(2);\n    buf[0] = 0x00;\n    buf[1] = data1;\n    ssd1306Write(buf,2);\n    free(buf);\n}\n\nstatic void SSD1306SetColumnRange(uint8_t start,uint8_t end){\n    uint8_t ssd1306CommandTemp[4] = {0x00};\n    ssd1306CommandTemp[1] = SSD1306_SET_COLUMN_ADDRESS;\n    ssd1306CommandTemp[2] = start;\n    ssd1306CommandTemp[3] = end;\n    ssd1306Write(ssd1306CommandTemp,4);\n}\n\nstatic void SSD1306SetPageRange(uint8_t start,uint8_t end){\n    uint8_t ssd1306CommandTemp[4] = {0x00};\n    ssd1306CommandTemp[1] = SSD1306_SET_PAGE_ADDRESS;\n    ssd1306CommandTemp[2] = start;\n    ssd1306CommandTemp[3] = end;\n    ssd1306Write(ssd1306CommandTemp,4);\n}\n\nvoid ssd1306FreshScreen(){\n    ssd1306Write(vMemory,1025);\n    memset(vBuf,0x00,1024);\n}\n\n\n\nvoid ssd1306DeviceInit(){\n    ssd1306WriteByte(SSD1306_DISPLAY_OFF);\n    ssd1306WriteBytes(SSD1306_SET_DISPLAY_CLOCK,0x80);\n    ssd1306WriteBytes(SSD1306_SET_MULTIPLEX,0x3F);\n    ssd1306WriteBytes(SSD1306_SET_DISPLAY_OFFSET,0x00);\n    ssd1306WriteByte(SSD1306_SET_DISPLAY_START_LINE|0x00);\n    ssd1306WriteBytes(SSD1306_SET_CHARGE_PUMP_STATUS,SSD1306_SET_CHARGE_PUMP_STATUS_SET);\n    ssd1306WriteByte(0xA1);\n    ssd1306WriteByte(0xC8);\n    ssd1306WriteBytes(0xDA,0x12);\n    ssd1306WriteBytes(SSD1306_SET_CONTRAST,0x01);\n    ssd1306WriteBytes(0xD9,0xF1);\n    ssd1306WriteBytes(SSD1306_SET_VCOMH,SSD1306_SET_VCOMH_0_65);\n    ssd1306WriteByte(SSD1306_DISPLAY_MEMORY_ON);\n    ssd1306WriteByte(SSD1306_DISPLAY_ON);\n    ssd1306WriteBytes(SSD1306_SET_ADDRESS_METHOD,SSD1306_ADDRESS_VERTICAL);\n    SSD1306SetPageRange(0,7);\n    SSD1306SetColumnRange(0,127);\n}\n<\/code><\/pre>\n<h3>h<\/h3>\n<pre><code class=\"language-c line-numbers\">#ifndef _SSD1306_DRIVER_H_\n#define _SSD1306_DRIVER_H_\n\n#include \"driver\/i2c.h\"\n#include \"driver\/i2c_master.h\"\n#include \"esp_err.h\"\n#include \"esp_log.h\"\n\n#include &lt;string.h&gt;\n#include &lt;stdio.h&gt;\n#include &lt;stdarg.h&gt;\n\n#include \"freertos\/FreeRTOS.h\"\n#include \"freertos\/task.h\"\n\n\n#define SSD1306_SDA GPIO_NUM_1\n#define SSD1306_SCL GPIO_NUM_0\n#define SSD1306_IIC_SPEED 600000\n#define SSD1306_IIC_PULLUP_ENABLE true\n#define SSD1306_IIC_PORT I2C_NUM_0\n\n#define SSD1306_ADDR1 0x3C\n#define SSD1306_ADDR0 0x3D\n\n#define SSD1306_SET_CONTRAST 0x81 \/\/\u5bf9\u6bd4\u5ea6\n#define SSD1306_DISPLAY_MEMORY_ON 0xA4\n#define SSD1306_DISPLAY_MEMORY_OFF 0xA5\n#define SSD1306_DISPLAY_NORMAL 0xA6\n#define SSD1306_DISPLAY_INVERSE 0xA7\n#define SSD1306_DISPLAY_OFF 0xAE\n#define SSD1306_DISPLAY_ON 0xAF\n\n#define SSD1306_SET_DISPLAY_OFFSET 0xD3\n#define SSD1306_SET_DISPLAY_CLOCK 0xD5\n#define SSD1306_SET_CHARGE_PUMP_STATUS 0x8D\n#define SSD1306_SET_VCOMH 0xDB\n#define SSD1306_SET_MULTIPLEX 0xA8\n#define SSD1306_SET_DISPLAY_START_LINE 0x40\n\n#define SSD1306_SET_CHARGE_PUMP_STATUS_RESET 0x10\n#define SSD1306_SET_CHARGE_PUMP_STATUS_SET 0x14\n\n#define SSD1306_SET_VCOMH_0_65 0x00\n#define SSD1306_SET_VCOMH_0_77 0x20\n#define SSD1306_SET_VCOMH_0_83 0x30\n\n#define SSD1306_SET_ADDRESS_METHOD 0x20\n#define SSD1306_ADDRESS_PAGE 0x10\n#define SSD1306_ADDRESS_HORIZONTAL 0x00\n#define SSD1306_ADDRESS_VERTICAL 0x01\n\n#define SSD1306_SET_COLUMN_ADDRESS 0x21\n#define SSD1306_SET_PAGE_ADDRESS 0x22\n\nvoid ssd1306IICInit();\nvoid ssd1306DeviceInit();\nvoid ssd1306FreshScreen();\n\n#endif\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u7b80\u4ecb \u4e00\u4e2a\u9002\u7528\u4e8eesp32\u7cfb\u5217\u7684oled12864 iic \uff08ssd1306\uff09\u9a71\u52a8\u7a0b\u5e8f\uff0c\u53ea\u9700\u8981\u7a0d\u5fae\u90e8\u7f72\u5373\u53ef\u4f7f\u7528 \u4f7f\u7528\u65b9\u6cd5 \u5c06\u9644\u4ef6\u91cc &#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-416","post","type-post","status-publish","format-standard","hentry","category-esp32"],"_links":{"self":[{"href":"https:\/\/yin.nnneri.me\/index.php?rest_route=\/wp\/v2\/posts\/416","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=416"}],"version-history":[{"count":1,"href":"https:\/\/yin.nnneri.me\/index.php?rest_route=\/wp\/v2\/posts\/416\/revisions"}],"predecessor-version":[{"id":417,"href":"https:\/\/yin.nnneri.me\/index.php?rest_route=\/wp\/v2\/posts\/416\/revisions\/417"}],"wp:attachment":[{"href":"https:\/\/yin.nnneri.me\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=416"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/yin.nnneri.me\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=416"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/yin.nnneri.me\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=416"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}