{"id":213,"date":"2024-03-01T13:48:25","date_gmt":"2024-03-01T05:48:25","guid":{"rendered":"https:\/\/www.yanwenkai.com\/?p=213"},"modified":"2024-09-11T15:34:04","modified_gmt":"2024-09-11T07:34:04","slug":"luckfox%e5%bc%80%e5%8f%91%e6%9d%bf%e7%a7%bb%e6%a4%8d0-96%e5%af%b8oled%e5%b1%8f%e5%b9%95-%e5%ba%94%e7%94%a8%e5%b1%82%e7%af%87","status":"publish","type":"post","link":"https:\/\/www.yanwenkai.com\/?p=213","title":{"rendered":"Luckfox\u5f00\u53d1\u677f\u79fb\u690d0.96\u5bf8oled\u5c4f\u5e55&#8212;\u5e94\u7528\u5c42\u7bc7"},"content":{"rendered":"<h1>1 \u524d\u8a00<\/h1>\n<p>&emsp;&emsp;\u5e94\u7528\u5c42\u7684\u7a0b\u5e8f\u6bd4\u8f83\u7b80\u5355\uff0c\u4e0d\u50cf\u5e95\u5c42\u9a71\u52a8\u5305\u542b\u7684\u77e5\u8bc6\u592a\u591a\uff0c\u4f1aC\u8bed\u8a00\u5c31\u80fd\u770b\u61c2\u3002\u5b98\u65b9\u7684\u7a0b\u5e8f\u4e3a\u4e86\u517c\u5bb9\u8bbe\u5907\u5206\u4e86\u5f88\u591a\u5c42\uff0c\u6709\u5f88\u591a\u7528\u4e0d\u4e0a\u7684\u4ee3\u7801\uff0c\u6240\u4ee5\u6211\u5220\u9664\u4e86\u4e00\u4e9b\u4ee3\u7801\uff0c\u53c8\u91cd\u5199\u4e86\u4e00\u90e8\u5206\u4ee3\u7801\u7684\u903b\u8f91\u3002<br \/>\n&emsp;&emsp;\u7b80\u5316\u540e\u7684\u4ee3\u7801\u53ea\u9700\u8981\u641e\u6e05\u695aspi\u4f20\u9012\u53c2\u6570\u7684\u6d41\u7a0b\u3001oled\u5c4f\u5e55\u70b9\u4eae\u7684\u903b\u8f91\u3001\u663e\u793a\u7ebf\u6bb5\u548c\u5706\u7684\u903b\u8f91\u3001\u663e\u793a\u4e2d\u6587\u7684\u903b\u8f91\u5c31\u884c\u4e86\u3002<\/p>\n<h1>2 \u5e94\u7528\u5c42dc\u548crst\u5f15\u811a\u7684\u91cd\u5199<\/h1>\n<p>&emsp;&emsp;\u8fd9\u91cc\u91cd\u5199\u4e86rst\u548cdc\u5f15\u811a\u7684\u7684\u9a71\u52a8\uff0c\u6240\u4ee5\u5e94\u7528\u5c42\u7684\u63a7\u5236\u903b\u8f91\u4e5f\u5bf9\u4e8e\u4fee\u6539\u4e86\u3002\u5982\u4e0b\u662f\u65b0\u7684\u63a7\u5236\u4ee3\u7801\u3002<\/p>\n<h2>2.1 \u6839\u636e\u5f15\u811a\u7f16\u53f7\u914d\u7f6e\u5b8f<\/h2>\n<pre><code class=\"language-c\">\/\/gpio\u5f15\u811a\n#define OLED_RST_PIN 51  \/\/\u590d\u4f4d\u5f15\u811a\n#define OLED_DC_PIN 34  \/\/\u6570\u636e\u548c\u547d\u4ee4\u5207\u6362\u5f15\u811a<\/code><\/pre>\n<h2>2.2 \u63a7\u5236\u5f15\u811a\u521d\u59cb\u5316\u786c\u4ef6\u3002<\/h2>\n<pre><code class=\"language-c\">static void oled_reset(void)\n{\n    dev_digital_write(OLED_RST_PIN, '1'); \/\/ \u542f\u52a8\u590d\u4f4d\n    delay_ms(100);\n    dev_digital_write(OLED_RST_PIN, '0'); \/\/ \u5173\u95ed\u590d\u4f4d\n    delay_ms(100);\n    dev_digital_write(OLED_RST_PIN, '1'); \/\/ \u542f\u52a8\u590d\u4f4d\n}<\/code><\/pre>\n<h2>2.3 \u6253\u5f00\u9a71\u52a8\u4f20\u9012\u53c2\u6570<\/h2>\n<p>&emsp;&emsp;\u8ffd\u8e2adev_digital_write\u51fd\u6570\uff0c\u8df3\u8f6c\u81f3\u64cd\u63a7\u9a71\u52a8\u4f20\u8f93\u6570\u636e\u7684\u51fd\u6570\u3002\u8fd9\u91cc\u4f7f\u7528\u7cfb\u7edf\u8c03\u7528\u7684\u65b9\u5f0f\u6253\u5f00\u9a71\u52a8\u6587\u4ef6\uff0c\u5411\u5185\u6838\u4f20\u9012\u53c2\u6570\uff0c\u7531\u5185\u6838\u9a71\u52a8\u63a7\u5236\u5f15\u811a\u7684\u7535\u5e73\u53d8\u5316\u3002<\/p>\n<pre><code class=\"language-c\">int dev_digital_write(uint16_t pin, uint8_t value)\n{\n    int fd, ret = -1;\n    do\n    {\n        if (pin != OLED_RST_PIN && pin != OLED_DC_PIN)\n        {\n            break;\n        }\n        if ((fd = open(pin == OLED_RST_PIN ? \"\/dev\/gpiodevrst\" : \"\/dev\/gpiodevdc\", O_RDWR)) < 0)\n        {\n            printf(\"\u6253\u5f00\u6587\u4ef6\u5931\u8d25\\r\\n\");\n            break;\n        }\n        if (write(fd, &#038;value, sizeof(value)) < 0)\n        {\n            printf(\"dc\u5199\u6570\u636e\u5931\u8d25\\r\\n\");\n            break;\n        }\n        if (fd > 0)\n        {\n            close(fd);\n        }\n        ret = 0;\n    } while (0);\n    return ret;\n}<\/code><\/pre>\n<p>&emsp;&emsp;\u4e0a\u9762\u5c31\u662f\u7b80\u5316\u540e\u7684\u63a7\u5236dc\u548crst\u7684\u6d41\u7a0b\u4e86\uff0c\u5bf9\u6bd4sysfs\u64cd\u4f5c\u4ee3\u7801\u91cf\u548c\u64cd\u4f5c\u903b\u8f91\u90fd\u7b80\u5316\u5f88\u591a\u3002<\/p>\n<h1>3 spi\u4f20\u8f93\u6570\u636e<\/h1>\n<p>&emsp;&emsp;\u5e94\u7528\u5c42\u7684spi\u4f20\u8f93\u6570\u636e\u7684\u6574\u4e2a\u6d41\u7a0b\u903b\u8f91\u5f88\u6e05\u6670\u5408\u7406\uff0c\u6ca1\u5fc5\u8981\u66f4\u6539\uff0c\u6211\u53ea\u505a\u4e86\u6ce8\u91ca\u548c\u903b\u8f91\u68b3\u7406\u3002<\/p>\n<h2>3.1 \u5b9a\u4e49spi\u7684\u53d8\u91cf<\/h2>\n<p>&emsp;&emsp;\u4f7f\u7528spi\u4f20\u8f93\u6570\u636e\u524d\u8981\u914d\u7f6espi\u7684\u4f20\u8f93\u901f\u7387\u3001\u6a21\u5f0f\u3001\u53d1\u9001\u65f6\u95f4\u95f4\u9694\u7b49\u53c2\u6570\u3002\u5982\u4e0b\u662f\u6839\u636e\u9700\u6c42\u914d\u7f6e\u7684\u5404\u7c7b\u53c2\u6570\u3002<\/p>\n<pre><code class=\"language-c\">struct spi_ioc_transfer tr; \/\/ \u5b98\u65b9\u914d\u7684spi\u4f20\u8f93\u6570\u636e\u7ed3\u6784\u4f53\n\n\/\/ \/***************************\n\/\/  *\n\/\/  * struct spi_ioc_transfer \n\/\/  *__u64 tx_buf; \u5199\u6570\u636e\u7f13\u51b2  \n\/\/  *__u64 rx_buf;  \u8bfb\u6570\u636e\u7f13\u51b2  \n\/\/  *__u32 len;       \u7f13\u51b2\u7684\u957f\u5ea6 \n\/\/  *__u32 speed_hz; \u901a\u4fe1\u7684\u65f6\u949f\u9891\u7387 \n\/\/  *__u16 delay_usecs;  \u4e24\u4e2aspi_ioc_transfer\u4e4b\u95f4\u7684\u5ef6\u65f6 \n\/\/  *__u8 bits_per_word;  \u5b57\u957f\uff08\u6bd4\u7279\u6570\uff09  \n\/\/  *__u8 cs_change;      \u662f\u5426\u6539\u53d8\u7247\u9009 \n\/\/  *__u32 pad;\n\/\/ *********************************\/\n\n#define SPI_CPHA 0x01\n#define SPI_CPOL 0x02\n\n#define mySPI_MODE_0 (0 | 0)\n#define mySPI_MODE_1 (0 | SPI_CPHA)\n#define mySPI_MODE_2 (SPI_CPOL | 0)\n#define mySPI_MODE_3 (SPI_CPOL | SPI_CPHA)\n\ntypedef enum{\n  SPI_MODE0 = mySPI_MODE_0, \/\/ 00\n  SPI_MODE1 = mySPI_MODE_1, \/\/ 01\n  SPI_MODE2 = mySPI_MODE_2, \/\/ 10\n  SPI_MODE3 = mySPI_MODE_3  \/\/ 11\n} SPIMode;\n\n    \/\/ \u5b9a\u4e49spi\u5c5e\u6027\ntypedef struct SPIstruct{\n  uint16_t SCLK_PIN;\n  uint16_t MOSI_PIN;\n  uint16_t MISO_PIN;\n\n  uint16_t CS0_PIN;\n  uint16_t CS1_PIN;\n\n  uint32_t speed;\n  uint16_t mode;\n  uint16_t delay;\n  int fd;\n} HARDWARE_SPI;\n\ntypedef enum\n{\n  SPI_CS_MODE_LOW = 0,  \/\/ \u7247\u90090\n  SPI_CS_MODE_HIGH = 1, \/\/ \u7247\u90091\n  SPI_CS_MODE_NONE = 3  \/\/ \u6ca1\u6709\u7247\u9009\uff0c\u81ea\u5df1\u63a7\u5236\n\n} SPIChipSelect;\n\nHARDWARE_SPI hardware_spi;\n\nstatic uint8_t bits = 8;\n\n#define SPI_CS_HIGH 0x04 \/\/ \u82af\u7247\u9009\u9ad8\n\/\/ #define SPI_LSB_FIRST\n\/\/ #define SPI_3WIRE\n\/\/#define SPI_LOOP\n#define SPI_NO_CS 0x40 \/\/ \u5355\u4e2a\u8bbe\u5907\u5360\u7528\u4e00\u6761SPI\u603b\u7ebf\uff0c\u6ca1\u6709\u82af\u7247\u9009\u62e9\n#define SPI_READY 0x80 \/\/ \u4ece\u673a\u62c9\u4f4e\u4ee5\u505c\u6b62\u6570\u636e\u4f20\u8f93<\/code><\/pre>\n<h2>3.2 spi\u4f20\u8f93\u6570\u636e\u7684\u65b9\u5f0f<\/h2>\n<p>&emsp;&emsp;\u4f7f\u7528ioctl\u5f80\u5185\u6838\u4f20\u9012\u53c2\u6570\u65f6\uff0c\u5185\u6838\u9700\u8981\u77e5\u9053\u8fd9\u4e2a\u53c2\u6570\u7684\u4f5c\u7528\u662f\u4ec0\u4e48\u624d\u80fd\u5f80\u4e0b\u914d\u7f6e\uff0c\u6240\u4ee5\u6807\u5fd7\u4f4d\u7684\u9700\u6c42\u8bde\u751f\u4e86\u3002\u5982\u4e0b\u6240\u793aioctl\u7684\u7b2c\u4e8c\u4e2a\u53c2\u6570\u662f\u5b98\u65b9\u5b9a\u4e49\u7684\u6807\u5fd7\u4f4d\uff0c\u6709\u5982\u4e0b\u51e0\u79cd\uff1a<\/p>\n<pre><code class=\"language-c\">SPI_IOC_WR_MODE\uff1a\u8bbe\u7f6e SPI \u8bbe\u5907\u7684\u6a21\u5f0f\uff0c\u5305\u62ec\u65f6\u949f\u6781\u6027\uff08CPOL\uff09\u548c\u76f8\u4f4d\uff08CPHA\uff09\u7b49\u3002\nSPI_IOC_RD_MODE\uff1a\u8bfb\u53d6 SPI \u8bbe\u5907\u7684\u5f53\u524d\u6a21\u5f0f\u3002\nSPI_IOC_WR_BITS_PER_WORD\uff1a\u8bbe\u7f6e SPI \u8bbe\u5907\u7684\u6bcf\u4e2a\u6570\u636e\u4f20\u8f93\u7684\u4f4d\u6570\u3002\nSPI_IOC_RD_BITS_PER_WORD\uff1a\u8bfb\u53d6 SPI \u8bbe\u5907\u7684\u6bcf\u4e2a\u6570\u636e\u4f20\u8f93\u7684\u4f4d\u6570\u3002\nSPI_IOC_WR_MAX_SPEED_HZ\uff1a\u8bbe\u7f6e SPI \u8bbe\u5907\u7684\u6700\u5927\u65f6\u949f\u9891\u7387\u3002\nSPI_IOC_RD_MAX_SPEED_HZ\uff1a\u8bfb\u53d6 SPI \u8bbe\u5907\u7684\u6700\u5927\u65f6\u949f\u9891\u7387\u3002<\/code><\/pre>\n<h2>3.3 spi\u914d\u7f6e\u51fd\u6570<\/h2>\n<h3>3.3.1 \u8bbe\u7f6espi\u7684\u6a21\u5f0f<\/h3>\n<pre><code class=\"language-c\">\/****************************************\n *\n * \u8bbe\u7f6espi\u6a21\u5f0f\n *  SPI_MODE0 = SPI_MODE_0, \/\/00\n *  SPI_MODE1 = SPI_MODE_1, \/\/01\n *  SPI_MODE2 = SPI_MODE_2, \/\/10\n *  SPI_MODE3 = SPI_MODE_3, \/\/11\n *\n * return\uff1a\n *  return 1 success\n *  return -1  failed\n *\n *  SPI_IOC_WR_MODE \u8bbe\u7f6e\u603b\u7ebf\u7684\u6781\u6027\u548c\u76f8\u4f4d\n * **************************************\/\nint dev_spi_mode(SPIMode mode)\n{\n    hardware_spi.mode &= 0xfc; \/\/ \u6e05\u9664\u4f4e2\u4f4d\u6570\n    hardware_spi.mode |= mode; \/\/ \u8bbe\u7f6e\u6a21\u5f0f\uff0c\u770b\u4e0a\u9762\u5b8f\u503c\uff0c\u53ea\u67092\u4f4d\u6709\u6548\n    \/\/ \u5199\u5230\u9a71\u52a8\u4e2d\n    if (ioctl(hardware_spi.fd, SPI_IOC_WR_MODE, &hardware_spi.mode) == -1)\n    {\n        DEV_SPI_DEBUG(\"\u8bbe\u7f6espi\u6a21\u5f0f\u5931\u8d25\\r\\n\");\n        return -1;\n    }\n    return 1;\n}<\/code><\/pre>\n<h3>3.3.2 spi\u7247\u9009<\/h3>\n<p>&emsp;&emsp;\u8bbe\u7f6espi\u7684\u7247\u9009\uff0c\u8fd9\u91cc\u5c31\u4e00\u4e2a\u8bbe\u5907\uff0c\u5e94\u8be5\u8d70SPI_NO_CS\u5206\u652f\u3002<\/p>\n<pre><code class=\"language-c\">int dev_spi_chipselect(SPIChipSelect cs_mode)\n{\n    if (cs_mode == SPI_CS_MODE_HIGH)\n    {\n        hardware_spi.mode |= SPI_CS_HIGH;\n        hardware_spi.mode &= ~SPI_NO_CS;\n        DEV_SPI_DEBUG(\"\u7247\u9009\u62c9\u9ad8\\r\\n\");\n    }\n    else if (cs_mode == SPI_CS_MODE_LOW)\n    {\n        hardware_spi.mode &= ~SPI_CS_HIGH;\n        hardware_spi.mode &= ~SPI_NO_CS;\n    }\n    else if (cs_mode == SPI_CS_MODE_NONE)\n    {\n        hardware_spi.mode |= SPI_NO_CS;\n    }\n\n    if (ioctl(hardware_spi.fd, SPI_IOC_WR_MODE, &hardware_spi.mode) == -1)\n    {\n        DEV_SPI_DEBUG(\"\u4e0d\u80fd\u8bbe\u7f6espi\u7684\u6a21\u5f0f\\r\\n\");\n        return -1;\n    }\n    return 1;\n}<\/code><\/pre>\n<h3>3.3.3 spi\u4f20\u8f93\u9891\u7387<\/h3>\n<p>&emsp;&emsp;\u8bbe\u7f6espi\u7684\u4f20\u8f93\u9891\u7387\u3002<\/p>\n<pre><code class=\"language-c\">int dev_spi_set_speed(uint32_t speed)\n{\n    uint32_t speed1 = hardware_spi.speed;\n    hardware_spi.speed = speed;\n\n    \/\/ \u5199\u9891\u7387\n    if (ioctl(hardware_spi.fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) == -1)\n    {\n        DEV_SPI_DEBUG(\"\u4e0d\u80fd\u8bbe\u7f6e\u6700\u5927\u9891\u7387\\r\\n\");\n        hardware_spi.speed = speed1; \/\/ \u8bbe\u7f6e\u6545\u969c\u9891\u7387\u4e0d\u53d8\n        return -1;\n    }\n\n    \/\/ \u8bfb\u9891\u7387\n    if (ioctl(hardware_spi.fd, SPI_IOC_RD_MAX_SPEED_HZ, &speed) == -1)\n    {\n        DEV_SPI_DEBUG(\"\u4e0d\u80fd\u83b7\u53d6\u6700\u5927\u9891\u7387\\r\\n\");\n        hardware_spi.speed = speed1; \/\/ \u8bbe\u7f6e\u6545\u969c\u9891\u7387\u4e0d\u53d8\n        return -1;\n    }\n    hardware_spi.speed = speed;\n    tr.speed_hz = hardware_spi.speed; \/\/(\u76ee\u524d\u770b\u53ea\u662f\u8d4b\u503c\uff0c\u6ca1\u770b\u5230\u5e94\u7528)\n    return 1;\n}<\/code><\/pre>\n<h3>3.3.4 spi\u4f20\u8f93\u6570\u636e\u65f6\u95f4\u95f4\u9694<\/h3>\n<p>&emsp;&emsp;\u8bbe\u7f6espi\u53d1\u9001\u6570\u636e\u7684\u65f6\u95f4\u95f4\u9694\u3002<\/p>\n<pre><code class=\"language-c\">void dev_spi_set_data_interval(uint16_t us)\n{\n    hardware_spi.delay = us;\n    tr.delay_usecs = hardware_spi.delay;\/\/\uff08\u8fd9\u91cc\u672a\u76f4\u63a5\u53d1\u9001\u6570\u636e\uff0c\u5224\u65ad\u5728\u5176\u4ed6\u4f4d\u7f6e\u53d1\u9001\uff0c\u9a8c\u8bc1\uff09\n}<\/code><\/pre>\n<h3>3.3.5 \u914d\u7f6espi\u7684\u8bfb\u5199\u4f4d<\/h3>\n<p>&emsp;&emsp;\u5728\u6b64\u51fd\u6570\u4e2d\u8c03\u7528\u4e0a\u9762\u7684\u914d\u7f6e\u51fd\u6570\uff0c\u540c\u65f6\u914d\u7f6espi\u4f20\u8f93\u6570\u636e\u65f6\u6bcf\u6b21\u4f20\u8f93\u7684\u4f4d\u6570\u3002<\/p>\n<pre><code class=\"language-c\">\/****************************************\n *\n * \u8bbe\u7f6espi\u53c2\u6570\uff0cspi\u8bbe\u5907\u540d\u79f0\uff0cspi\u6a21\u5f0f\uff0c\u4f20\u8f93\u9891\u7387\n *\n * SPI_IOC_WR_BITS_PER_WORD \/\/\u5199 \u6bcf\u5b57\u591a\u5c11\u4f4d\n * SPI_IOC_RD_BITS_PER_WORD \/\/\u8bfb\u6bcf\u5b57\u591a\u5c11\u4f4d\n * SPI_IOC_RD_MAX_SPEED_HZ \/\/\u8bfb \u6700\u5927\u901f\u7387\n * SPI_IOC_WR_MAX_SPEED_HZ \/\/\u5199 \u6700\u5927\u901f\u7387\n * **************************************\/\nvoid dev_hardware_spi_beginset(char *spi_device, SPIMode mode, uint32_t speed) \/\/ \u8bbe\u7f6espi\u9a71\u52a8\u53c2\u6570\n{\n    int ret = 0;\n    hardware_spi.mode = 0;\n    if ((hardware_spi.fd = open(spi_device, O_RDWR)) < 0)\n    {\n        perror(\"\u6253\u5f00spi\u9a71\u52a8\u5931\u8d25\\n\");\n        exit(1);\n    }\n    else\n    {\n        DEV_SPI_DEBUG(\"\u6253\u5f00\u9a71\u52a8\uff1a%s\\r\\n\", spi_device);\n    }\n\n    ret = ioctl(hardware_spi.fd, SPI_IOC_WR_BITS_PER_WORD, &#038;bits);\n    \/\/ \u8bbe\u7f6espi\u603b\u7ebf\u5199\u6bcf\u5b57\u591a\u5c11\u4f4d\uff0c\u5b8f\u547d\u4ee4\uff0c+\u6570\u503cbits\n    if (ret == -1)\n    {\n        DEV_SPI_DEBUG(\"\u4e0d\u80fd\u8bbe\u7f6espi\u5199\u6bcf\u5b57\u7684\u4f4d\u6570\\r\\n\");\n    }\n    ret = ioctl(hardware_spi.fd, SPI_IOC_RD_BITS_PER_WORD, &#038;bits);\n    \/\/ \u5199 \u6bcf\u5b57\u591a\u5c11\u4f4d\n    if (ret == -1)\n    {\n        DEV_SPI_DEBUG(\"\u4e0d\u80fd\u8bbe\u7f6espi\u8bfb\u6bcf\u5b57\u7684\u4f4d\u6570\\r\\n\");\n    }\n    dev_spi_mode(mode);\n    dev_spi_chipselect(SPI_CS_MODE_LOW);\n    dev_spi_set_speed(speed);\n    dev_spi_set_data_interval(0);\n}<\/code><\/pre>\n<p>&emsp;&emsp;\u4e0b\u9762\u662f\u6211\u5b9e\u9645\u4f7f\u7528\u65f6\u7684spi\u914d\u7f6e\u53c2\u6570\u3002<\/p>\n<pre><code class=\"language-c\">dev_hardware_spi_beginset(\"\/dev\/spidev0.0\",mySPI_MODE_3,10000000);<\/code><\/pre>\n<h2>3.4 spi\u70b9\u4eae\u5c4f\u5e55<\/h2>\n<p>&emsp;&emsp;\u81f3\u6b64spi\u53c2\u6570\u7684\u914d\u7f6e\u57fa\u672c\u5b8c\u6210\u3002\u53ef\u4ee5\u8c03\u7528spi\u521d\u59cb\u5316oled\u5c4f\u5e55\u4e86\u3002<\/p>\n<h3>3.4.1 \u786c\u4ef6\u521d\u59cb\u5316\u5c4f\u5e55<\/h3>\n<p>&emsp;&emsp;\u8c03\u7528\u5199\u51fd\u6570\u901a\u8fc7\u9a71\u52a8\u5f80oled\u5c4f\u5e55\u4f20\u9012\u521d\u59cb\u5316\u547d\u4ee4\u3002<\/p>\n<pre><code class=\"language-c\">\/\/\u8282\u9009\u5176\u4e2d\u4e00\u4e2a\u547d\u4ee4\u5c55\u793a\noled_write_reg(0xae); \/\/ \u5173\u95ed\u663e\u793a<\/code><\/pre>\n<h3>3.4.2 \u4f20\u9012\u547d\u4ee4\u53ca\u5f15\u811a\u7f16\u53f7<\/h3>\n<p>&emsp;&emsp;\u8df3\u8f6c\u81f3\u5199\u51fd\u6570\u3002\u6839\u636e\u5c4f\u5e55\u9a71\u52a8\u8bbe\u5b9a\uff0c\u53d1\u9001\u547d\u4ee4\u6216\u6570\u636e\u524d\u9700\u8981\u914d\u7f6edc\u5f15\u811a\u7684\u7535\u5e73\uff0c\u7136\u540e\u5c4f\u5e55\u624d\u80fd\u77e5\u9053\u63a5\u6536\u7684\u6570\u636e\u662f\u547d\u4ee4\u8fd8\u662f\u70b9\u4eae\u5c4f\u5e55\u7684\u5750\u6807\u3002dc\u5f15\u811a\u7684\u51fd\u6570\u4e0a\u6587\u5df2\u6709\u4e0d\u518d\u8d58\u8ff0\u3002\u53ef\u4ee5\u770b\u5230\u547d\u4ee4\u88abdev_spi_transfer_byte\u51fd\u6570\u8fdb\u4e00\u6b65\u4f20\u9012\u3002<\/p>\n<pre><code class=\"language-c\">static void oled_write_reg(uint8_t reg)\n{\n    dev_digital_write(OLED_DC_PIN, '0'); \/\/ \u7ed9dc\u5f15\u811a\u7f6e\u96f6\uff0c\u5207\u6362\u4e3a\u8f93\u5165\u547d\u4ee4\n    dev_spi_transfer_byte(reg);        \/\/ \u4f7f\u7528ioctl\u4f20\u8f93\u6570\u636e\n}<\/code><\/pre>\n<h3>3.4.3 \u5411\u9a71\u52a8\u4f20\u9012\u6570\u636e<\/h3>\n<p>&emsp;&emsp;\u8ffd\u8e2adev_spi_transfer_byte\u51fd\u6570\uff0c\u8fd9\u4e2a\u5c31\u662f\u5e94\u7528\u5c42\u5f80\u5185\u6838\u4f20\u9012\u6570\u636e\u7684\u6700\u7ec8\u51fd\u6570\u4e86\u3002\u5f88\u7b80\u5355\u8c03\u7528\u4e0a\u9762\u5b98\u65b9\u5b9a\u4e49\u7684tr\u7ed3\u6784\u4f53\u586b\u5145\u8981\u5f80\u5185\u6838\u4f20\u9012\u7684\u6570\u636e\uff0c\u4f7f\u7528ioctl\u5f80\u5185\u6838\u4f20\u9012\u3002<\/p>\n<pre><code class=\"language-c\">uint8_t dev_spi_transfer_byte(uint8_t buf)\n{\n    uint8_t rbuf[1];\n    tr.len = 1;\n    tr.tx_buf = (unsigned long)&buf; \/\/ \u53d1\u9001\u7f13\u51b2\u533a\n    tr.rx_buf = (unsigned long)rbuf; \/\/ \u63a5\u53d7\u7f13\u51b2\u533a\n\n    \/\/ ioctl \u64cd\u4f5c\uff0c\u4f20\u8f93\u6570\u636e\n    if (ioctl(hardware_spi.fd, SPI_IOC_MESSAGE(1), &tr) < 1)\n    \/\/\u4e0a\u6587\u7684\u65f6\u95f4\u95f4\u9694\u901a\u8fc7\u8fd9\u4e2atr\u7ed3\u6784\u4f53\u4f20\u8f93\u5230\u5185\u6838\n    \/\/ cmd SPI_IOC_MESSAGE(N) \u5176\u4e2dN\u662fspi_ioc_transfer\u7ed3\u6784\u6570\u7ec4\u5143\u7d20\u4e2a\u6570\n    \/\/ \u8fd9\u91cc\u53ea\u5b9a\u4e49\u4e86\u4e00\u4e2a\u7ed3\u6784\u4f53tr,\u6240\u4ee5\u662f1\n    \/\/ \u8fd9\u4e2aSPI_IOC_MESSAGE(1) \u547d\u4ee4\uff0c\u8868\u793a\u8981\u4f20\u8f93\u4e00\u4e2a SPI \u6d88\u606f\u3002\n    \/\/ \u5168\u53cc\u5de5\u5de5\u4f5c\uff0c SPI \u9a71\u52a8\u6267\u884c\u4e00\u6b21\u6570\u636e\u4f20\u8f93\uff0c\n    \/\/ \u5e76\u5c06\u53d1\u9001\u7f13\u51b2\u533a\uff08tr.tx_buf\uff09\u4e2d\u7684\u6570\u636e\u53d1\u9001\u5230 SPI \u8bbe\u5907\u3002\n    \/\/ \u540c\u65f6\uff0cSPI \u9a71\u52a8\u4e5f\u4f1a\u5c06\u63a5\u6536\u5230\u7684\u6570\u636e\u5b58\u50a8\u5728\u63a5\u6536\u7f13\u51b2\u533a\uff08tr.rx_buf\uff09\u4e2d\u3002\n    {\n        DEV_SPI_DEBUG(\"can't send spi message\\r\\n\");\n    }\n \/\/    printf(\"\u786c\u4ef6\u5199\u6570\u636e\u6210\u529f\\r\\n\");\n    return rbuf[0];\n}<\/code><\/pre>\n<h1>4 \u6e05\u5c4f<\/h1>\n<p>&emsp;&emsp;\u4e0a\u8ff0\u6d41\u7a0b\u5b8c\u6210\u540e\u5c31\u53ef\u4ee5\u70b9\u4eae\u5c4f\u5e55\u4e86,\u70b9\u4eae\u524d\u8f6f\u4ef6\u6e05\u5c4f\uff0c\u82e5\u4e0d\u6e05\u5c4f\u53ef\u80fd\u4f1a\u51fa\u73b0\u96ea\u82b1\u5c4f\uff0c\u5f71\u54cd\u540e\u9762\u7684\u53c2\u6570\u5b9e\u73b0\u3002\u540c\u65f6\u4e5f\u53ef\u4ee5\u628a\u4f20\u8f93\u7684\u6570\u636e\u8bbe\u7f6e\u62100xff\uff0c\u8fd9\u6837\u53ef\u4ee5\u770b\u5c4f\u5e55\u548c\u70b9\u4eae\u51fd\u6570\u662f\u5426\u6709\u95ee\u9898\u3002<br \/>\n\u9047\u5230\u8fd9\u4e2a\u95ee\u9898\u7684\u65f6\u5019\u6ca1\u4fdd\u5b58\u56fe\u7247\uff0c\u7f51\u4e0a\u968f\u4fbf\u627e\u7684\u4e00\u5f20\u51d1\u5408\u770b\u5427\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\/2024\/03\/02\/240302-luckfox-9.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\/2024\/03\/02\/240302-luckfox-9.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" width=\"400\" height=\"400\"><\/div><br \/>\n<\/center><\/p>\n<pre><code class=\"language-c\">void oled_clear()\n{\n    uint16_t width, height, column, i, j;\n    width = oled_width; \/\/ \u503c\u662f128\u5217\n    height = (oled_height % 8 == 0) ? (oled_height \/ 8) : (oled_height \/ 8 + 1);\n    oled_write_reg(0xb0); \/\/ \u8bbe\u7f6e\u884c\u7684\u8d77\u59cb\u5730\u5740\uff0c\u4f7f\u7528\u547d\u4ee4\u8bbe\u7f6e\u663e\u793a\u4f4d\u7f6e\u7684\u76ee\u6807\u8d77\u59cb\u4f4d\u7f6e\u662fb0-b7\n    for (j = 0; j < height; j++)\n    {\n       oled_write_reg(0xb0 + j);\n        for (i = 0; i < width; i++)\n        {\n          column = 0 + i;\n          oled_write_reg(0x00 + (column &#038; 0x0f)); \/\/ \u8bbe\u7f6e\u5217\u7684\u4f4e\u8d77\u59cb\u5730\u5740\n          oled_write_reg(0x10 + (column >> 4));   \/\/ \u8bbe\u7f6e\u5217\u7684\u9ad8\u8d77\u59cb\u5730\u5740\n          oled_write_data(0x01); \/\/ \u5c06\u5bf9\u5e94\u7684\u5217\u7f6e\u62100\n        }\n    }\n}<\/code><\/pre>\n<h1>5 \u753b\u56fe<\/h1>\n<h2>5.1 \u753b\u70b9<\/h2>\n<p>&emsp;&emsp;\u82e5\u65e0\u95ee\u9898\uff0c\u8fdb\u5165\u4e0b\u4e00\u6b65\u5b9e\u73b0\u7cbe\u786e\u70b9\u4eae\u67d0\u4e00\u4e2aoled\u5c4f\u5e55\u50cf\u7d20\u70b9\u3002\u56e0\u4e3a\u6574\u4f53\u4ee3\u7801\u592a\u957f\uff0c\u4e14\u90fd\u7528\u4e0d\u4e0a\uff0c\u6240\u4ee5\u53ea\u653e\u7f6e\u4e86\u6838\u5fc3\u4ee3\u7801\u3002<br \/>\n&emsp;&emsp;\u753b\u70b9\u51fd\u6570\u3002\u6838\u5fc3\u601d\u60f3\u662f\u70b9\u4eae\u4e00\u4e2a\u50cf\u7d20\u662f1X1\u7684\u77e9\u9635\uff0c\u70b9\u4eae4\u4e2a\u50cf\u7d20\u662f2X2\u7684\u77e9\u9635\uff0c\u90a3\u4e48\u5c31\u53ef\u4ee5\u51cf\u5c11\u7ed8\u5236\u5176\u4ed6\u56fe\u50cf\u5bbd\u5ea6\u7b49\u65b9\u9762\u7684\u4ee3\u7801\u590d\u6742\u5ea6\u3002\u5176\u5b9e\u73b0\u7684\u539f\u7406\u5f88\u7b80\u5355\u3002\u53cc\u5c42for\u5faa\u73af\u904d\u5386\u6574\u4e2a128X64\u7684\u6574\u4e2a\u5c4f\u5e55\u7684\u50cf\u7d20\u70b9\u3002color\u8868\u793a\u70b9\u4eae\u4e0e\u5426\uff0c\u9ed1\u8272\u662f\u706d\u767d\u8272\u662f\u4eae\uff1b\u7136\u540e\u5c06\u6bcf\u4e2a\u50cf\u7d20\u70b9\u7684\u5750\u6807\u548c\u72b6\u6001\u4f20\u9012\u7ed9paint_set_pixel\u51fd\u6570\uff0c\u7531\u6b64\u51fd\u6570\u505a\u8fdb\u4e00\u6b65\u5904\u7406\u3002<\/p>\n<pre><code class=\"language-c\">    int16_t xdir_num, ydir_num;\n    if (dot_style == DOT_FILL_AROUND)\n    {\n       for (xdir_num = 0; xdir_num <  dot_pixel ; xdir_num++)\n        {\n           \/\/ printf(\"xdir_num[%d],ydir_num[%d]\\r\\n\",xdir_num,ydir_num);\n            for (ydir_num = 0; ydir_num < dot_pixel; ydir_num++)\n            {\n                if (xpoint + xdir_num - dot_pixel < 0 || ypoint + ydir_num - dot_pixel < 0)\n                {\n                    break;\n                }\n                \/\/ \u8fd9\u91cc\u5faa\u73af\u662f\uff0c\u56e0\u4e3a\u63a7\u5236\u7684\u50cf\u7d20\u82e5\u662f\u77e9\u9635\uff0c\u4e00\u6b21\u53ea\u80fd\u64cd\u63a7\u4e00\u4e2a\u50cf\u7d20\u70b9\uff0c\n                \/\/ \u82e5\u60f3\u64cd\u63a7\u77e9\u9635\uff0c\u9700\u8981\u591a\u6b21\u5faa\u73af\uff0c\u59822*2\u77e9\u9635\n                \/\/ a= xpoint + xdir_num - dot_pixel;\n                \/\/ b=ypoint + ydir_num - dot_pixel;\n                \/\/ printf(\"a[%d],b[%d]\\r\\n\",a,b);\n                paint_set_pixel(xpoint + xdir_num , ypoint + ydir_num, color);\/\/2\n                \/\/paint_set_pixel(xpoint + xdir_num - dot_pixel, ypoint + ydir_num - dot_pixel, color);\/\/2\n            }\n        }\n\n    }<\/code><\/pre>\n<p>&emsp;&emsp;paint_set_pixel\u51fd\u6570\u7684\u4f5c\u7528\u662f\u5c06\u6bcf\u4e2a\u51fd\u6570\u7684\u72b6\u6001\u5199\u5230\u4e00\u4e2a\u5177\u4f53\u7684\u5177\u4f53\u7684\u6570\u7ec4\u4e2d\uff0c\u5b83\u7684\u957f\u5ea6\u662f1024\u4e2a\u4e14\u662fchar\u7c7b\u578b\u7684\uff0c\u6b63\u597d\u8868\u793a\u6574\u4e2a\u5c4f\u5e55\u7684\u6bcf\u4e00\u4e2a\u50cf\u7d20\u70b9\u3002\u5411\u6570\u7ec4\u4e2d\u5199\u5165\u6570\u636e\u3002\u5b9a\u4e49\u5730\u5740addr\u548c\u663e\u793a\u6570\u636erdata\uff0c\u5730\u5740\u8ba1\u7b97\u65b9\u5f0f\u5982\u4e0a\u6587\u6240\u8ff0\uff0crdata\u662f8\u4f4d\u7684\u6570\u636e\uff0c\u4ee3\u8868\u4e00\u5217\uff1b\u8fd9\u65f6black\u662f0\u3001white\u662f1\uff0c\u6839\u636e\u5177\u4f53\u7684\u4e0a\u9762\u51fd\u6570\u7684\u904d\u5386\u53ef\u4ee5\u77e5\u9053\u6bcf\u4e00\u70b9\u662f0\/1\uff0c\u8fd9\u65f6\u5373\u53ef\u5bf9rdata\u7cbe\u786e\u7684\u8d4b\u503c\u3002<\/p>\n<pre><code class=\"language-c\">void paint_set_pixel(uint16_t xpoint, uint16_t ypoint, uint16_t color)\n{\n    uint32_t addr = 0;\n    uint8_t rdata = 0;\n       addr = x + ((y\/8)*128);\n        rdata = paint.image[addr];\n        if (color == BLACK)\n        {\n            paint.image[addr] = rdata & ~(0x80 >> (y % 8));\n        }\n        else\n        {\n            paint.image[addr] = rdata | (0x80 >> (y % 8));\n            printf(\"22222rdata[%d],x[%d],y[%d],addr[%d]\\r\\n\",paint.image[addr],x,y,addr);\n        }\n}<\/code><\/pre>\n<p>&emsp;&emsp;\u6bcf\u753b\u5b8c\u4e00\u7ec4\u56fe\u50cf\uff0c\u5373\u53ef\u8c03\u7528oled_display\u51fd\u6570\u5411\u9a71\u52a8\u4f20\u8f93\u6570\u636e\u3002<\/p>\n<pre><code class=\"language-c\">void oled_display(uint8_t *image)\n{\n    uint16_t width, height, column, temp, i, j;\n    width = oled_width; \/\/ \u503c\u662f128\u5217\n    height = (oled_height % 8 == 0) ? (oled_height \/ 8) : (oled_height \/ 8 + 1);\n    oled_write_reg(0xb0); \/\/ \u8bbe\u7f6e\u884c\u7684\u8d77\u59cb\u5730\u5740\uff0c\u4f7f\u7528\u547d\u4ee4\u8bbe\u7f6e\u663e\u793a\u4f4d\u7f6e\u7684\u76ee\u6807\u8d77\u59cb\u4f4d\u7f6e\u662fb0-b7\n    for (j = 0; j < height; j++)\n    {\n        oled_write_reg(0xb0 + j);\n        for (i = 0; i < width; i++)\n        {\n        column = 0 + i;\n        oled_write_reg(0x00 + (column &#038; 0x0f)); \/\/ \u8bbe\u7f6e\u5217\u7684\u4f4e\u8d77\u59cb\u5730\u5740\n        oled_write_reg(0x10 + (column >> 4));   \/\/ \u8bbe\u7f6e\u5217\u7684\u9ad8\u8d77\u59cb\u5730\u5740\n        temp = image[i + j* width ]; \/\/ \u5728\u5176\u4ed6\u4f4d\u7f6e\u5b9a\u4e49\u5e76\u5206\u914d\u7a7a\u95f4,\u8d8a\u754c\u6700\u540e\u5904\u7406\n        temp = reverse(temp);\/\/\u7ffb\u8f6c\u51fd\u6570\uff0c\u4f5c\u7528\u89e3\u51b3\u753b\u5706\u51fa\u73b0\u4e24\u4e2a\u534a\u5706\u7ffb\u8f6c\u7684\u95ee\u9898\n        oled_write_data(temp);\n        }\n    }\n}<\/code><\/pre>\n<p>&emsp;&emsp;\u5982\u4e0b\u662f\u70b9\u4eae\u4ee5\u4e0b5\u4e2a\u5750\u6807\u7684\u60c5\u51b5\uff1a<br \/>\n&emsp;&emsp;(0,0)\u3001(127,0)\u3001(63,0)\u3001(63,127)\u3001(6,19)<\/p>\n<p><center><br \/>\n<div class='fancybox-wrapper lazyload-container-unload' data-fancybox='post-images' href='https:\/\/www.yanwenkai.com:7777\/images\/2024\/03\/02\/240302-luckfox-10.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\/2024\/03\/02\/240302-luckfox-10.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" width=\"400\" height=\"400\"><\/div><br \/>\n<\/center><\/p>\n<h2>5.2 \u753b\u7ebf<\/h2>\n<p>&emsp;&emsp;\u6211\u770b\u5b98\u65b9\u7ed9\u51fa\u7684\u7b97\u6cd5\u753b\u7ebf\u6bb5\u53ea\u6709\u76f4\u7ebf\uff0c\u6ca1\u6709\u659c\u7ebf\u3002\u8fd9\u91cc\u7ed9\u51fa\u4e86Bresenham\u7b97\u6cd5(\u4efb\u610f\u659c\u7387)\u3002\u6838\u5fc3\u601d\u60f3\u5c31\u662f\u770b\u4e0b\u4e00\u70b9\u7684\u5b9e\u9645\u5750\u6807\u8ddd\u79bb\u5c4f\u5e55\u4e0a\u4e24\u70b9\u5750\u6807\u54ea\u4e2a\u8fd1\uff0c\u9009\u62e9\u8fd1\u7684\u90a3\u4e00\u70b9\uff1b\u5faa\u73af\u5f80\u590d\u76f4\u5230\u5c3d\u5934\u3002\u5177\u4f53\u7b97\u6cd5\u6211\u5f00\u4e86\u5355\u7ae0\u8bb2\u89e3\uff0c\u6709\u5174\u8da3\u53ef\u4ee5\u770b\u770b\u3002<\/p>\n<pre><code class=\"language-c\">void paint_draw_slope_line(uint16_t xstart, uint16_t ystart, uint16_t xend, uint16_t yend,\n                     uint16_t color, DOT_PIXEL line_width, LINE_STYLE line_style){\n    uint16_t temp = 0;\n    uint16_t xpoint = xstart;\n    uint16_t ypoint = ystart;\n    \/\/\u7b97\u51fa2\u70b9\u95f4\u8ddd\u79bb\uff0c\u786e\u4fdd\u503c\u4e3a\u975e\u8d1f\u503c\uff08abs\u51fd\u6570\u662f\u83b7\u53d6\u7edd\u5bf9\u503c\uff09\n    int dx = (int)xend - (int)xstart >= 0 ? xend - xstart : xstart - xend; \/\/ \u7b97\u51fa\u4e24\u70b9\u8ddd\u79bb\n    int dy = (int)yend - (int)ystart >= 0 ? yend - ystart : ystart - yend;\n    if(dy>dx)\/\/\u4e3a\u771f\u8bc1\u660e\u659c\u7387\u7edd\u5bf9\u503c\u5927\u4e8e1\uff0c\u4e3b\u8981\u4ee5y\u8f74\u65b9\u5411\u9012\u589e\n    {\n       temp = xstart; \/\/x,y\u503c\u4e92\u6362\n        xstart = ystart;\n        ystart = temp;\n        temp = 0;\n    }\n    if(xstart >xend)\/\/\u4e3a\u771f\uff0c\u8bf4\u660e\u8d77\u70b9\u5927\u4e8e\u7ec8\u70b9\uff0c\u4ea4\u6362\u65b9\u5411\n    {\n       temp = xstart;\n       xstart = xend;\n       xend = temp;\n       temp = 0;\n       temp = ystart;\n       ystart = yend;\n       yend = temp;\n       temp = 0; \n    }\n    uint16_t delta_x = xend -xstart;\/\/\u4e0a\u9762\u6362\u7b97\u5224\u65ad\uff0c\u8fd9\u6b65xend\u4e00\u5b9a\u5927\u4e8exstart\n    uint16_t delta_y =  (int)yend - (int)ystart >= 0 ? yend - ystart : ystart - yend;\n    uint16_t error = 0; \/\/\u8bef\u5dee\u91cf\n    uint16_t delta_error = delta_x\/delta_y;\/\/\u659c\u7387\n    uint16_t yk = ystart;\n    uint16_t y_step = 0;\n    if(ystart < yend)\n    {\n        y_step = 1;\n    }else{\n        y_step = -1;\n    }\n    for(uint16_t xk = xstart; xk <= xend; xk++)\n    {\n        if(dy>dx)\n        {\n           paint_draw_point(yk, xk, color, line_width, DOT_FILL_AROUND); \n        }else{\n           paint_draw_point(xk, yk, color, line_width, DOT_FILL_AROUND);\n        }\n        error = error +delta_error;\n        if(error >= 0.5)\n        {\n            yk=yk+y_step;\n            error = error -1;\n        }\n    }\n}<\/code><\/pre>\n<p>\u5982\u4e0b\u662f\u4f7f\u7528\u65b0\u7b97\u6cd5\u7ed8\u5236\u7684\u76f4\u7ebf\u548c\u659c\u7ebf\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\/2024\/03\/02\/240302-luckfox-11.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\/2024\/03\/02\/240302-luckfox-11.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" width=\"400\" height=\"400\"><\/div><br \/>\n<\/center><\/p>\n<h2>5.3 \u753b\u5706<\/h2>\n<p>&emsp;&emsp;\u753b\u5706\u4e00\u6837\u662f\u4f7f\u7528Bresenham\u753b\u5706\u7b97\u6cd5\uff0c\u6838\u5fc3\u601d\u60f3\u662f\u7ed8\u5236\u516b\u5206\u4e4b\u4e00\u5706\uff0c\u5269\u4f59\u90e8\u5206\u901a\u8fc7\u5bf9\u79f0\u83b7\u53d6\u70b9\u7684\u5750\u6807\u4fe1\u606f\u3002\u5177\u4f53\u7b97\u6cd5\u601d\u60f3\u6211\u5f00\u4e86\u5355\u7ae0\u8bb2\u89e3\uff0c\u53ef\u4ee5\u770b\u770b\u3002<\/p>\n<pre><code class=\"language-c\">void paint_draw_circle(uint16_t x_center, uint16_t y_center, uint16_t radius,\nuint16_t color, DOT_PIXEL line_width, DRAW_FILL draw_fill)\n{\nif (x_center > 128 || y_center > 64)\n{\nDebug(\"\u8d85\u51fa\u6b63\u5e38\u663e\u793a\u8303\u56f4\\r\\n\");\nreturn;\n}\n\/\/ \u753b\u4e00\u4e2a\u5706\u4ece\uff080,r\uff09\u5904\u4f5c\u4e3a\u4e00\u4e2a\u8d77\u70b9\nint16_t xcurrent, ycurrent;\nxcurrent = 0;\nycurrent = radius;\n    \/\/ \u7d2f\u8ba1\u8bef\u5dee\uff0c\u5224\u65ad\u4e0b\u4e00\u4e2a\u70b9\u7684\u4f4d\u7f6e\n    int16_t esp = 3 - (radius << 1);\n\/\/ \u753b\u4e00\u4e2a\u7a7a\u5fc3\u5706\nwhile (xcurrent <= ycurrent)\n{\npaint_draw_point(x_center + xcurrent, y_center + ycurrent, color, line_width, DOT_FILL_AROUND); \/\/ 1\npaint_draw_point(x_center - xcurrent, y_center + ycurrent, color, line_width, DOT_FILL_AROUND); \/\/ 2\npaint_draw_point(x_center - ycurrent, y_center + xcurrent, color, line_width, DOT_FILL_AROUND); \/\/ 3\npaint_draw_point(x_center - ycurrent, y_center - xcurrent, color, line_width, DOT_FILL_AROUND); \/\/ 4\npaint_draw_point(x_center - xcurrent, y_center - ycurrent, color, line_width, DOT_FILL_AROUND); \/\/ 5\npaint_draw_point(x_center + xcurrent, y_center - ycurrent, color, line_width, DOT_FILL_AROUND); \/\/ 6\npaint_draw_point(x_center + ycurrent, y_center - xcurrent, color, line_width, DOT_FILL_AROUND); \/\/ 7\npaint_draw_point(x_center + ycurrent, y_center + xcurrent, color, line_width, DOT_FILL_AROUND); \/\/ 0\n\n            if (esp <0)\n            {\n                esp += 4 * xcurrent + 6;\n            }\n            else\n            {\n                esp += 10 + 4 * (xcurrent - ycurrent);\n                ycurrent--;\n            }\n            xcurrent++;\n        }\n}<\/code><\/pre>\n<p>&emsp;&emsp;\u5982\u4e0b\u662f\u7ed8\u5236\u7684\u5706\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\/2024\/03\/02\/240302-luckfox-12.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\/2024\/03\/02\/240302-luckfox-12.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" width=\"400\" height=\"400\"><\/div><br \/>\n<\/center><\/p>\n<h2>5.4 \u663e\u793a\u5b57\u7b26<\/h2>\n<p>&emsp;&emsp;\u663e\u793a\u4e2d\u6587\u3001\u82f1\u6587\u3001\u6570\u5b57\u7b49\uff0c\u8fd9\u91cc\u89c9\u5f97\u5b98\u65b9\u7684\u65b9\u5f0f\u5c31\u5f88\u597d\u7528\uff0c\u4ed6\u5c06\u5e38\u7528\u5b57\u7b26\u53d6\u6a21\u540e\u5236\u4f5c\u6210\u5b57\u5e93\u6587\u4ef6\uff0c\u68c0\u6d4b\u5b57\u7b26\u4e32\u53ca\u5b57\u5e93\u7f16\u53f7\uff0c\u663e\u793a\u4e0d\u540c\u5c3a\u5bf8\u7684\u4e2d\u82f1\u6587\u3002\u663e\u793a\u539f\u7406\u5c31\u662f\u5bf9\u6bd4\u5b57\u7b26\uff0c\u5982\u679c\u89e3\u6790\u7684ascii\u7801\u5c0f\u4e8e126\u8bc1\u660e\u662f\u6570\u5b57\u3001\u5b57\u6bcd\u3001\u7b26\u5408\uff0c\u5927\u4e8e\u7b49\u4e8e126\u5219\u662f\u6c49\u5b57\uff0c\u56e0\u4e3a\u6c49\u5b57\u662f\u53cc\u5b57\u8282\u8868\u793a\uff0c\u6240\u4ee5\u5bf9\u6bd4\u662f\u4e24\u4e2a\u53d8\u91cf\u3002<\/p>\n<pre><code class=\"language-c\">void paint_draw_string_cn(uint16_t xstart, uint16_t ystart, const char *pstring, cFONT *font,\n                          uint16_t color_foreground, uint16_t color_background)\n{\n    const char *p_text = pstring;\n    int x = xstart, y = ystart;\n    int i, j, num;\n    \/\/ \u5728EPD\u4e0a\u9010\u4e2a\u5b57\u7b26\u53d1\u9001\u5b57\u7b26\u4e32\n    while (*p_text != 0)\n    {\n        if (*p_text <= 0x7F) \/\/ ascii <126\n        {\n            for (num = 0; num < font->size; num++)\n            {\n                if (*p_text == font->table[num].index[0])\n                {\n                    const char *ptr = &font->table[num].matrix[0];\n                    for (j = 0; j < font->Height; j++)\n                    {\n                        for (i = 0; i < font->Width; i++)\n                        {\n                            if (WHITE == FONT_BACKGROUND) \/\/ \u52a0\u5feb\u626b\u63cf\u901f\u5ea6\n                            {\n                                if (*ptr & (0x80 >> (i % 8)))\n                                {\n                                    paint_set_pixel(x + i, y + j, color_foreground);\n                                }\n                                else\n                                {\n                                    paint_set_pixel(x + i, y + j, color_background);\n                                }\n                            }\n                            else\n                            {\n                                if (*ptr & (0x80 >> (i % 8)))\n                                {\n                                    paint_set_pixel(x + i, y + j, color_background);\n                                }\n                                else\n                                {\n                                    paint_set_pixel(x + i, y + j, color_foreground);\n                                }\n                            }\n                            if (i % 8 == 7) \/\/ \uff08\u7b49\u4e8e7\u8fd9\u91cc\u5b58\u7591\uff0c\u540e\u7eed\u6d4b\u8bd5\uff09\n                            {\n                                ptr++;\n                            }\n                        }\n                        if (font->Width % 8 != 0)\n                        {\n                            ptr++;\n                        }\n                    }\n                    break;\n                }\n            }\n            \/\/ \u6307\u5411\u4e0b\u4e00\u4e2a\u5b57\u7b26\n            p_text += 1;\n            \/\/ \u5c06\u5217\u7684\u4f4d\u7f6e\u51cf16\n            x += font->ASCII_Width;\n        }\n        else\n        {\n            for (num = 0; num < font->size; num++)\n            {\n                if ((*p_text == font->table[num].index[0]) && (*(p_text + 1) == font->table[num].index[1]))\n                {\n                    const char *ptr = &font->table[num].matrix[0];\n                    for (j = 0; j < font->Height; j++)\n                    {\n                        for (i = 0; i < font->Width; i++)\n                        {\n                            if (WHITE == FONT_BACKGROUND)\n                            {\n                                if (*ptr & (0x80 >> (i % 8)))\n                                {\n                                    paint_set_pixel(x + i, y + j, color_foreground);\n                                }\n                                else\n                                {\n                                    paint_set_pixel(x + i, y + j, color_background);\n                                }\n                            }\n                            else\n                            {\n                                if (*ptr & (0x80 >> (i % 8)))\n                                {\n                                    paint_set_pixel(x + i, y + j, color_background);\n                                }\n                                else\n                                {\n                                    paint_set_pixel(x + i, y + j, color_foreground);\n                                }\n                            }\n                            if (i % 8 == 7)\n                            {\n                                ptr++;\n                            }\n                        }\n                        if (font->Width % 8 != 0)\n                        {\n                            ptr++;\n                        }\n                    }\n                    break;\n                }\n            }\n            \/\/ \u6307\u5411\u4e0b\u4e00\u4e2a\u5b57\u7b26\n            p_text += 3;\n            \/\/ \u5c06\u5217\u4f4d\u7f6e\u51cf16\n            x += font->Width;\n        }\n    }\n}<\/code><\/pre>\n<p>&emsp;&emsp;\u5982\u4e0b\u662f\u663e\u793a\u7684\u4e2d\u82f1\u6587\u5b57\u7b26\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\/2024\/03\/02\/240302-luckfox-13.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\/2024\/03\/02\/240302-luckfox-13.png\" src=\"data:image\/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB\/AAffA0nNPuCLAAAAAElFTkSuQmCC\" width=\"400\" height=\"400\"><\/div><br \/>\n<\/center><\/p>\n<h2>5.5 \u6700\u7ec8\u8c03\u7528<\/h2>\n<p>&emsp;&emsp;\u6700\u540e\u6240\u6709\u64cd\u4f5c\u5b8c\u6210\u540e\uff0c\u8fd8\u6709\u5206\u914d\u7a7a\u95f4\u7684\u95ee\u9898\uff1b\u5176\u5b9e\u5c31\u662f\u521b\u5efa\u4e86\u4e00\u4e2a1024\u5b57\u8282\u5927\u5c0f\u7684\u7a7a\u95f4\u7528\u6765\u5b58\u50a8\u56fe\u7247\u6570\u636e\u4f7f\u7528\u3002\u6700\u540e\u5206\u6790\u53d1\u73b0\u5bf9\u4e8e\u8fd9\u4e2a\u7a7a\u95f4\u7684\u4f7f\u7528\u662f\u57fa\u4e8echar\u7c7b\u578b\u6570\u7ec4\u4f7f\u7528\u7684\u3002\u6240\u4ee5\u6211\u89c9\u5f97\u76f4\u63a5\u5b9a\u4e49\u6210\u4e00\u4e2achar\u7c7b\u578b\u7684\u6570\u7ec4\u66f4\u5408\u7406\u3002<\/p>\n<pre><code class=\"language-c\">    \/\/ 1.\u521b\u5efa\u4e00\u4e2a\u65b0\u7684\u56fe\u7247\u7f13\u5b58\n    uint8_t *blackimage;\n    uint16_t imagesize = ((oled_height % 8 == 0) ? (oled_height \/ 8) : (oled_height \/ 8 + 1)) * (oled_width);\n                         \/\/ \u5206\u914d\u7a7a\u95f4\uff0c1\u4e2a\u5b57\u8282\u8868\u793a8\u4e2a\u50cf\u7d20\u70b9\uff0c128*8= 1024\n                         \/\/ \u7a7a\u95f4\u662fchar\u7c7b\u578b\u7684\uff0c\u6b65\u957f\u4e3a1\u6b65\n    if ((blackimage = (uint8_t *)malloc(imagesize)) == NULL)\n    {\n        printf(\"\u7533\u8bf7\u5185\u5b58\u5931\u8d25\\r\\n\");\n        return -1;\n    }<\/code><\/pre>\n<h1>6 \u603b\u7ed3<\/h1>\n<p>&emsp;&emsp;\u81f3\u6b64\u6574\u4e2a\u79fb\u690d\u8fc7\u7a0b\u5c31\u7b97\u5b8c\u6210\u4e86\u3002\u4e2d\u95f4\u80af\u5b9a\u6709\u4e9b\u7455\u75b5\uff0c\u4f46\u6240\u6709\u529f\u80fd\u90fd\u5b9e\u73b0\u4e86\uff0c\u4e5f\u7b97\u662f\u8fd9\u4e2a\u76ee\u6807\u5b8c\u6210\u4e86\u3002\u4fee\u6539\u5b8c\u7684\u4ee3\u7801\u6211\u90fd\u653e\u5230\u6211gitee\u4e0a\u7684\u4ed3\u5e93\u4e0a\u4e86\uff0c\u6709\u9700\u8981\u7684\u53ef\u4ee5\u81ea\u53d6\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>1 \u524d\u8a00 &emsp;&emsp;\u5e94\u7528\u5c42\u7684\u7a0b\u5e8f\u6bd4\u8f83\u7b80\u5355\uff0c\u4e0d\u50cf\u5e95\u5c42\u9a71\u52a8\u5305\u542b\u7684\u77e5\u8bc6\u592a\u591a\uff0c\u4f1aC\u8bed\u8a00\u5c31\u80fd\u770b\u61c2\u3002\u5b98\u65b9\u7684\u7a0b [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":311,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6],"tags":[34,31,35],"class_list":["post-213","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-flushbonading-oled","tag-c-c","tag-oled","tag-35"],"_links":{"self":[{"href":"https:\/\/www.yanwenkai.com\/index.php?rest_route=\/wp\/v2\/posts\/213","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=213"}],"version-history":[{"count":12,"href":"https:\/\/www.yanwenkai.com\/index.php?rest_route=\/wp\/v2\/posts\/213\/revisions"}],"predecessor-version":[{"id":283,"href":"https:\/\/www.yanwenkai.com\/index.php?rest_route=\/wp\/v2\/posts\/213\/revisions\/283"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.yanwenkai.com\/index.php?rest_route=\/wp\/v2\/media\/311"}],"wp:attachment":[{"href":"https:\/\/www.yanwenkai.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=213"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.yanwenkai.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=213"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.yanwenkai.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=213"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}