简介
最近一直在研究ESP-IDF框架的使用, 最近发现了一个非常好的SSD1306的库, 支持 128 * 32 和 128 * 64的屏幕. 同时支持I2C和SPI通讯. 通过在ESP-IDF中进行简单配置即可快速的点亮OLED显示屏. 本文将会带着大家来使用SSD1306的库来测试两种不同大小的屏幕,并且分别展示测试的效果.
在开始之前让我先简单的介绍一下乐鑫的组件管理. IDF 组件管理器工具用于下载 ESP-IDF CMake 项目的依赖项,该下载在 CMake 运行期间自动完成。IDF 组件管理器可以从 组件注册表 或 Git 仓库获取组件。大概的意思就是说, 乐鑫的组件管理可以使用类似Arduino库的方式进行安装和使用. 其依赖的组件是在 idf_component.yml 中进行定义的.
上图为一个示例的组件配置文件
那么当程序运行 idf.py build 的时候, IDF的构建工具会自动的从其配置的组件仓库中下载所定义的组件库. 然后把对应的组件库下载到项目目录的 components 目录下.
但是我们本次使用的这个组件并没有被ESP-IDF官方所托管,所以需要我们手动下载这个仓库,并且引入到我们的项目中.
所使用的组件是esp-idf-ssd1306-master (如下图所示)
但是由于这个组件并不是由IDF的组件管理器自动下载的, 因此我们需要在顶层的CmakeList中手动指向这个仓库.
set(EXTRA_COMPONENT_DIRS components/ssd1306)
至此, 初始化工作完成!
驱动屏幕
由于这个组件使用了Kconfig 来管理和配置, 因此我们可以直接使用menuconfig来配置当前的驱动信息. 如下图所示,我们可以在这里配置我们使用的驱动方式, 比如说使用I2C驱动或者是SPI驱动, 同时可以根据定义的宏信息配置使用的I2C的端口号,或者是SCL和SDA的引脚.
在配置完毕之后我们便可以在主程序中初始化SSD1306, 如下所示
void init_ssd1306() { i2c_master_init(&dev, CONFIG_SDA_GPIO, CONFIG_SCL_GPIO, CONFIG_RESET_GPIO); i2c_num = dev._i2c_num; ESP_LOGI(tag, "Panel is 128x32"); ssd1306_init(&dev, 128, 32); }
这里定义的PIN信息已经在上述的menuconfig中配置过了, 所以可以直接初始化.
然后我们可以调用测试函数来测试OLED的效果.
void ssd1306_test() { int center, top, bottom; char lineChar[20]; ssd1306_clear_screen(&dev, false); ssd1306_contrast(&dev, 0xff); ssd1306_display_text_x3(&dev, 0, "Hello", 5, false); vTaskDelay(3000 / portTICK_PERIOD_MS); top = 1; center = 1; bottom = 4; ssd1306_display_text(&dev, 0, "SSD1306 128x32", 14, false); ssd1306_display_text(&dev, 1, "Hello World!!", 13, false); // ssd1306_clear_line(&dev, 2, true); // ssd1306_clear_line(&dev, 3, true); ssd1306_display_text(&dev, 2, "SSD1306 128x32", 14, true); ssd1306_display_text(&dev, 3, "Hello World!!", 13, true); vTaskDelay(3000 / portTICK_PERIOD_MS); // Display Count Down uint8_t image[24]; memset(image, 0, sizeof(image)); ssd1306_display_image(&dev, top, (6 * 8 - 1), image, sizeof(image)); ssd1306_display_image(&dev, top + 1, (6 * 8 - 1), image, sizeof(image)); ssd1306_display_image(&dev, top + 2, (6 * 8 - 1), image, sizeof(image)); for (int font = 0x39; font > 0x30; font--) { memset(image, 0, sizeof(image)); ssd1306_display_image(&dev, top + 1, (7 * 8 - 1), image, 8); memcpy(image, font8x8_basic_tr[font], 8); if (dev._flip) ssd1306_flip(image, 8); ssd1306_display_image(&dev, top + 1, (7 * 8 - 1), image, 8); vTaskDelay(1000 / portTICK_PERIOD_MS); } // Scroll Up ssd1306_clear_screen(&dev, false); ssd1306_contrast(&dev, 0xff); ssd1306_display_text(&dev, 0, "---Scroll UP---", 16, true); // ssd1306_software_scroll(&dev, 7, 1); ssd1306_software_scroll(&dev, (dev._pages - 1), 1); for (int line = 0; line < bottom + 10; line++) { lineChar[0] = 0x01; sprintf(&lineChar[1], " Line %02d", line); ssd1306_scroll_text(&dev, lineChar, strlen(lineChar), false); vTaskDelay(500 / portTICK_PERIOD_MS); } vTaskDelay(3000 / portTICK_PERIOD_MS); // Scroll Down ssd1306_clear_screen(&dev, false); ssd1306_contrast(&dev, 0xff); ssd1306_display_text(&dev, 0, "--Scroll DOWN--", 16, true); // ssd1306_software_scroll(&dev, 1, 7); ssd1306_software_scroll(&dev, 1, (dev._pages - 1)); for (int line = 0; line < bottom + 10; line++) { lineChar[0] = 0x02; sprintf(&lineChar[1], " Line %02d", line); ssd1306_scroll_text(&dev, lineChar, strlen(lineChar), false); vTaskDelay(500 / portTICK_PERIOD_MS); } vTaskDelay(3000 / portTICK_PERIOD_MS); // Page Down ssd1306_clear_screen(&dev, false); ssd1306_contrast(&dev, 0xff); ssd1306_display_text(&dev, 0, "---Page DOWN---", 16, true); ssd1306_software_scroll(&dev, 1, (dev._pages - 1)); for (int line = 0; line < bottom + 10; line++) { // if ( (line % 7) == 0) ssd1306_scroll_clear(&dev); if ((line % (dev._pages - 1)) == 0) ssd1306_scroll_clear(&dev); lineChar[0] = 0x02; sprintf(&lineChar[1], " Line %02d", line); ssd1306_scroll_text(&dev, lineChar, strlen(lineChar), false); vTaskDelay(500 / portTICK_PERIOD_MS); } vTaskDelay(3000 / portTICK_PERIOD_MS); // Horizontal Scroll ssd1306_clear_screen(&dev, false); ssd1306_contrast(&dev, 0xff); ssd1306_display_text(&dev, center, "Horizontal", 10, false); ssd1306_hardware_scroll(&dev, SCROLL_RIGHT); vTaskDelay(5000 / portTICK_PERIOD_MS); ssd1306_hardware_scroll(&dev, SCROLL_LEFT); vTaskDelay(5000 / portTICK_PERIOD_MS); ssd1306_hardware_scroll(&dev, SCROLL_STOP); // Vertical Scroll ssd1306_clear_screen(&dev, false); ssd1306_contrast(&dev, 0xff); ssd1306_display_text(&dev, center, "Vertical", 8, false); ssd1306_hardware_scroll(&dev, SCROLL_DOWN); vTaskDelay(5000 / portTICK_PERIOD_MS); ssd1306_hardware_scroll(&dev, SCROLL_UP); vTaskDelay(5000 / portTICK_PERIOD_MS); ssd1306_hardware_scroll(&dev, SCROLL_STOP); // Invert ssd1306_clear_screen(&dev, true); ssd1306_contrast(&dev, 0xff); ssd1306_display_text(&dev, center, " Good Bye!!", 12, true); vTaskDelay(5000 / portTICK_PERIOD_MS); // Fade Out ssd1306_fadeout(&dev); esp_restart(); }
测试效果如下所示(只截取了部分画面)
上图为菜单上下滚动
上图为退出画面图像逐渐消失
附件代码