聯盛德 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)

參考


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM