聯盛德 HLK-W806 (八): 4線SPI驅動SSD1306/SSD1315 128x64 OLED液晶屏
阿新 • • 發佈:2021-12-12
0.96的128x64 OLED液晶屏是嵌入式應用中最常見的一種螢幕, 這種螢幕常見的pin腳型別有兩種: I2C和SPI, 驅動通常是SSD1306, 最近會有一些是SSD1315, I2C型別的OLED只有4個pin腳, 不可修改連線模式, 比較好辨認, SPI型別的OLED有6/7/8pin幾種型別, 最常見的是7pin, 帶協議選項的模組, 這種模組的背面PCB會有三種模式的選擇說明, 後面列出的Rx代表那些位置需要焊接電阻, 通常這些電阻阻值都是5KR, 默認出廠都是4線SPI的模式. 在SPI模式下, SSD1306和SSD1315的驅動方式是一樣的. 因為W806可以使用硬體SPI, 重新整理速度比I2C方式要快將近10倍, 這裡介紹的是4線SPI模式的驅動
目錄
- 聯盛德 HLK-W806 (一): Ubuntu20.04下的開發環境配置, 編譯和燒錄說明
- 聯盛德 HLK-W806 (二): Win10下的開發環境配置, 編譯和燒錄說明
- 聯盛德 HLK-W806 (三): 免按鍵自動下載和復位
- 聯盛德 HLK-W806 (四): 軟體SPI和硬體SPI驅動ST7735液晶LCD
- 聯盛德 HLK-W806 (五): W801開發板上手報告
- 聯盛德 HLK-W806 (六): I2C驅動SSD1306 128x64 OLED液晶屏
- 聯盛德 HLK-W806 (七): 相容開發板 LuatOS Air103
- 聯盛德 HLK-W806 (八): 4線SPI驅動SSD1306/SSD1315 128x64 OLED液晶屏
SSD1306/SSD1315 OLED
0.96的128x64 OLED液晶屏是嵌入式應用中最常見的一種螢幕, 這種螢幕常見的pin腳型別有兩種: I2C和SPI, 驅動通常是SSD1306, 最近會有一些是SSD1315
- I2C型別的OLED只有4個pin腳, 不可修改連線模式, 比較好辨認
- SPI型別的OLED有6/7/8pin幾種型別, 最常見的是7pin, 帶協議選項的模組, 這種模組的背面PCB會有三種模式的選擇說明, 後面列出的Rx代表那些位置需要焊接電阻, 通常這些電阻阻值都是5KR, 默認出廠都是4線SPI的模式
在SPI模式下, SSD1306和SSD1315的驅動方式是一樣的. 因為W806可以使用硬體SPI, 重新整理速度比I2C方式要快將近10倍, 下面介紹的是4線SPI模式的驅動
連線
雖然是4線SPI, 也需要連全部7根線, 4線沒算上VCC, GND和Reset, 對應本演示的連線方式為
- PB14 -> CS
- PB15 -> SCK/CLK/D0
- PB17 -> MOSI/SDA/D1
- PB10 -> RES(Reset)
- PB11 -> DC
- GND -> GND
- 3.3V -> VCC
庫檔案
本示例由I2C的示例改進得到, 增加了SPI傳輸方法, 順帶更新了一下演示功能, 這個庫檔案支援
- 畫點
- 畫線
- 畫圓
- 輸出文字(需要軟字型檔)
- 畫圖
使用
驅動SSD1306/SSD1315時, 需要引入的檔案為
- ssd1306.c
- ssd1306.h
- ssd1306_fonts.c
- ssd1306_fonts.h
在main.c中加入標頭檔案並初始化 SPI_HandleTypeDef
#include "ssd1306.h"
SPI_HandleTypeDef hspi;
static void SPI_Init(void)
{
hspi.Instance = SPI;
hspi.Init.Mode = SPI_MODE_MASTER;
hspi.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi.Init.CLKPhase = SPI_PHASE_1EDGE;
hspi.Init.NSS = SPI_NSS_SOFT;
hspi.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_40;
hspi.Init.FirstByte = SPI_LITTLEENDIAN;
if (HAL_SPI_Init(&hspi) != HAL_OK)
{
Error_Handler();
}
}
static void GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
__HAL_RCC_GPIO_CLK_ENABLE();
GPIO_InitStruct.Pin = SSD1306_RES_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(SSD1306_RES_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pin = SSD1306_DC_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(SSD1306_DC_PORT, &GPIO_InitStruct);
}
在ssd1306.h中, 確認設定的模式為SPI
/**
* Mode switch: 0 - SPI, 1 - I2C
*/
#define SSD1306_MODE_I2C 0
修改當前螢幕對應的引數: 寬度, 高度
/* SSD1306 settings */
/* SSD1306 width in pixels */
#ifndef SSD1306_WIDTH
#define SSD1306_WIDTH 128
#endif
/* SSD1306 LCD height in pixels */
#ifndef SSD1306_HEIGHT
#define SSD1306_HEIGHT 64
#endif
然後就可以在程式碼中使用了
# 初始化
GPIO_Init();
SPI_Init();
uint8_t res = SSD1306_Init();
printf("OLED init: %d\n", res);
# 定位繪畫起點
SSD1306_GotoXY(5, 5);
# 輸出字元
SSD1306_Puts("OLED:11x18", &Font_11x18, 1);
# 更新顯示
SSD1306_UpdateScreen(); // display
清屏
SSD1306_Fill(0); // clear oled
畫線
int y1 = 64, y2 = 0;
while (y1 > 0)
{
SSD1306_DrawLine(0, y1, 128, y2, 1);
SSD1306_UpdateScreen();
y1 -= 2;
y2 += 2;
}
填充反色, 畫圓
SSD1306_Fill(1); // clear oled
SSD1306_UpdateScreen();
SSD1306_DrawCircle(64, 32, 25, 0);
SSD1306_UpdateScreen();
SSD1306_DrawCircle(128, 32, 25, 0);
SSD1306_UpdateScreen();
SSD1306_DrawCircle(0, 32, 25, 0);
SSD1306_UpdateScreen();
SSD1306_DrawCircle(32, 32, 25, 0);
SSD1306_UpdateScreen();
SSD1306_DrawCircle(96, 32, 25, 0);
SSD1306_UpdateScreen();
相關程式碼
程式碼已經更新到SDK的I2C示例(同時支援I2C和SPI)
- Github: wm-sdk-w806/tree/main/demo/i2c/ssd1306_oled
- Gitee: wm-sdk-w806/tree/main/demo/i2c/ssd1306_oled
參考
- OLED displays (SSD1306 and SSD1315) http://cholla.mmto.org/electronics/displays/oled/