stm32hal模块驱动(3)ssd1305 oled驱动

该文章已生成可运行项目,

SD1305 OLED 驱动芯片详细介绍

SSD1305 是 Solomon Systech 公司生产的一款 OLED 显示控制器/驱动器,专为 128x64 或 128x32 点阵的 OLED 显示屏设计。下面我将从多个方面详细介绍这款驱动芯片。

一、SSD1305 基本特性

  1. 显示分辨率

    • 最大支持 128 segments × 64 commons

    • 常用于 0.96 寸 128x64 OLED 屏幕

  2. 接口类型

    • 支持 6800/8080 并行接口

    • 支持 3/4 线 SPI 接口

    • 支持 I2C 接口(最常用)

    • 本文示例使用的是 I2C 接口

  3. 供电要求

    • 逻辑电压:1.65V~3.3V

    • OLED 驱动电压:7.0V~15V(芯片内部有电荷泵)

  4. 灰度控制

    • 支持 256 级亮度控制

    • 通过软件可调节对比度

  5. 显存管理

    • 内置 128x64 bits 的 GDDRAM(Graphic Display Data RAM)

    • 支持水平/垂直/页寻址模式

二、SSD1305 与 SSD1306 的区别

SSD1305 常被与 SSD1306 比较,主要区别如下:

特性SSD1305SSD1306
最大分辨率128x64128x64
接口I2C/SPI/并行I2C/SPI/并行
电荷泵内置内置
显存组织页模式(8页)页模式(8页)
对比度调节支持支持
封装COG (Chip On Glass)COG (Chip On Glass)
主要应用中小尺寸OLED中小尺寸OLED
指令集略有不同

更常用

头文件 (ssd1305.h)

#ifndef __SSD1305_H
#define __SSD1305_H

#include "stm32f1xx_hal.h"

// OLED参数定义
#define SSD1305_I2C_ADDR        0x3C  
#define SSD1305_WIDTH           128
#define SSD1305_HEIGHT          64
#define SSD1305_PAGE_NUM       (SSD1305_HEIGHT/8)

// 命令定义
#define SSD1305_SETCONTRAST     0x81
#define SSD1305_DISPLAYALLON_RESUME 0xA4
#define SSD1305_DISPLAYALLON    0xA5
#define SSD1305_NORMALDISPLAY   0xA6
#define SSD1305_INVERTDISPLAY   0xA7
#define SSD1305_DISPLAYOFF      0xAE
#define SSD1305_DISPLAYON       0xAF
#define SSD1305_SETDISPLAYOFFSET 0xD3
#define SSD1305_SETCOMPINS      0xDA
#define SSD1305_SETVCOMDETECT   0xDB
#define SSD1305_SETDISPLAYCLOCKDIV 0xD5
#define SSD1305_SETPRECHARGE    0xD9
#define SSD1305_SETMULTIPLEX    0xA8
#define SSD1305_SETLOWCOLUMN    0x00
#define SSD1305_SETHIGHCOLUMN   0x10
#define SSD1305_SETSTARTLINE    0x40
#define SSD1305_MEMORYMODE     0x20
#define SSD1305_COLUMNADDR      0x21
#define SSD1305_PAGEADDR        0x22
#define SSD1305_COMSCANINC      0xC0
#define SSD1305_COMSCANDEC      0xC8
#define SSD1305_SEGREMAP        0xA0
#define SSD1305_CHARGEPUMP      0x8D

// 函数声明
void SSD1305_Init(I2C_HandleTypeDef *hi2c);
void SSD1305_WriteCommand(uint8_t cmd);
void SSD1305_WriteData(uint8_t data);
void SSD1305_Clear(void);
void SSD1305_UpdateScreen(void);
void SSD1305_DrawPixel(uint8_t x, uint8_t y, uint8_t color);
void SSD1305_GotoXY(uint8_t x, uint8_t y);
void SSD1305_PutChar(char ch, uint8_t color);
void SSD1305_PutString(char *str, uint8_t color);
void SSD1305_DrawBitmap(const uint8_t *bitmap);

#endif

源文件 (ssd1305.c)

#include "ssd1305.h"
#include "font.h"  

static I2C_HandleTypeDef *hi2c_oled;
static uint8_t SSD1305_Buffer[SSD1305_WIDTH * SSD1305_PAGE_NUM];

// 写入命令
void SSD1305_WriteCommand(uint8_t cmd) {
    uint8_t buf[2] = {0x00, cmd};  // Co = 0, D/C = 0
    HAL_I2C_Master_Transmit(hi2c_oled, SSD1305_I2C_ADDR, buf, 2, HAL_MAX_DELAY);
}

// 写入数据
void SSD1305_WriteData(uint8_t data) {
    uint8_t buf[2] = {0x40, data};  // Co = 0, D/C = 1
    HAL_I2C_Master_Transmit(hi2c_oled, SSD1305_I2C_ADDR, buf, 2, HAL_MAX_DELAY);
}

// 初始化OLED
void SSD1305_Init(I2C_HandleTypeDef *hi2c) {
    hi2c_oled = hi2c;
    
    // 初始化序列
    SSD1305_WriteCommand(SSD1305_DISPLAYOFF);                    // 0xAE
    
    SSD1305_WriteCommand(SSD1305_SETDISPLAYCLOCKDIV);            // 0xD5
    SSD1305_WriteCommand(0x80);                                  // 建议比率
    
    SSD1305_WriteCommand(SSD1305_SETMULTIPLEX);                  // 0xA8
    SSD1305_WriteCommand(SSD1305_HEIGHT - 1);
    
    SSD1305_WriteCommand(SSD1305_SETDISPLAYOFFSET);              // 0xD3
    SSD1305_WriteCommand(0x00);                                  // 无偏移
    
    SSD1305_WriteCommand(SSD1305_SETSTARTLINE | 0x00);           // 0x40
    
    SSD1305_WriteCommand(SSD1305_CHARGEPUMP);                    // 0x8D
    SSD1305_WriteCommand(0x14);                                  // 使用内部VCC
    
    SSD1305_WriteCommand(SSD1305_MEMORYMODE);                    // 0x20
    SSD1305_WriteCommand(0x00);                                  // 水平寻址模式
    
    SSD1305_WriteCommand(SSD1305_SEGREMAP | 0x01);               // 0xA0/0xA1
    SSD1305_WriteCommand(SSD1305_COMSCANDEC);                    // 0xC8
    
    SSD1305_WriteCommand(SSD1305_SETCOMPINS);                    // 0xDA
    SSD1305_WriteCommand(0x12);                                  // 64行模式
    
    SSD1305_WriteCommand(SSD1305_SETCONTRAST);                   // 0x81
    SSD1305_WriteCommand(0xCF);                                  // 对比度值
    
    SSD1305_WriteCommand(SSD1305_SETPRECHARGE);                  // 0xD9
    SSD1305_WriteCommand(0xF1);                                  // 预充电周期
    
    SSD1305_WriteCommand(SSD1305_SETVCOMDETECT);                 // 0xDB
    SSD1305_WriteCommand(0x40);                                  // VCOMH电平
    
    SSD1305_WriteCommand(SSD1305_DISPLAYALLON_RESUME);           // 0xA4
    SSD1305_WriteCommand(SSD1305_NORMALDISPLAY);                 // 0xA6
    
    SSD1305_WriteCommand(SSD1305_DISPLAYON);                     // 0xAF
    
    // 清屏
    SSD1305_Clear();
    SSD1305_UpdateScreen();
}

// 清空显示缓冲区
void SSD1305_Clear(void) {
    memset(SSD1305_Buffer, 0, sizeof(SSD1305_Buffer));
}

// 更新屏幕显示
void SSD1305_UpdateScreen(void) {
    uint8_t i;
    for(i = 0; i < SSD1305_PAGE_NUM; i++) {
        SSD1305_WriteCommand(0xB0 + i);                          // 设置页地址
        SSD1305_WriteCommand(0x00);                              // 设置列地址低位
        SSD1305_WriteCommand(0x10);                              // 设置列地址高位
        
        HAL_I2C_Mem_Write(hi2c_oled, SSD1305_I2C_ADDR, 0x40, I2C_MEMADD_SIZE_8BIT, 
                         &SSD1305_Buffer[SSD1305_WIDTH * i], SSD1305_WIDTH, HAL_MAX_DELAY);
    }
}

// 绘制像素点
void SSD1305_DrawPixel(uint8_t x, uint8_t y, uint8_t color) {
    if(x >= SSD1305_WIDTH || y >= SSD1305_HEIGHT) {
        return;  // 超出范围
    }
    
    if(color) {
        SSD1305_Buffer[x + (y / 8) * SSD1305_WIDTH] |= 1 << (y % 8);
    } else {
        SSD1305_Buffer[x + (y / 8) * SSD1305_WIDTH] &= ~(1 << (y % 8));
    }
}

// 设置光标位置
void SSD1305_GotoXY(uint8_t x, uint8_t y) {
    // 这里可以添加自己的光标位置跟踪变量
}

// 显示单个字符
void SSD1305_PutChar(char ch, uint8_t color) {
    uint32_t i, b, j;
    
    // 检查剩余空间
    // 这里需要实现光标跟踪或使用全局变量
    
    // 只处理可打印字符
    if(ch < 32 || ch > 126) {
        ch = ' ';  // 不可打印字符显示为空格
    }
    
    // 从字体数据中获取字符
    for(i = 0; i < 6; i++) {
        if(i == 5) {
            b = 0x00;
        } else {
            b = Font[(ch - 32) * 5 + i];
        }
        
        for(j = 0; j < 8; j++) {
            if((b >> j) & 0x01) {
                SSD1305_DrawPixel(/*x + i*/, /*y + j*/, color);
            } else {
                SSD1305_DrawPixel(/*x + i*/, /*y + j*/, !color);
            }
        }
    }
    
    // 移动光标
    // 这里需要实现光标跟踪
}

// 显示字符串
void SSD1305_PutString(char *str, uint8_t color) {
    while(*str) {
        SSD1305_PutChar(*str++, color);
    }
}

// 显示位图
void SSD1305_DrawBitmap(const uint8_t *bitmap) {
    memcpy(SSD1305_Buffer, bitmap, sizeof(SSD1305_Buffer));
}

字体文件 (font.h) 

#ifndef __FONT_H
#define __FONT_H

#include <stdint.h>

// 标准ASCII 5x7字体
// 每个字符5字节宽,8像素高(最后1像素通常为空白行)
// 只包含可打印字符(32-126)
static const uint8_t Font[] = {
    0x00, 0x00, 0x00, 0x00, 0x00, // (space)
    0x00, 0x00, 0x5F, 0x00, 0x00, // !
    0x00, 0x07, 0x00, 0x07, 0x00, // "
    0x14, 0x7F, 0x14, 0x7F, 0x14, // #
    0x24, 0x2A, 0x7F, 0x2A, 0x12, // $
    0x23, 0x13, 0x08, 0x64, 0x62, // %
    0x36, 0x49, 0x55, 0x22, 0x50, // &
    0x00, 0x05, 0x03, 0x00, 0x00, // '
    0x00, 0x1C, 0x22, 0x41, 0x00, // (
    0x00, 0x41, 0x22, 0x1C, 0x00, // )
    0x08, 0x2A, 0x1C, 0x2A, 0x08, // *
    0x08, 0x08, 0x3E, 0x08, 0x08, // +
    0x00, 0x50, 0x30, 0x00, 0x00, // ,
    0x08, 0x08, 0x08, 0x08, 0x08, // -
    0x00, 0x60, 0x60, 0x00, 0x00, // .
    0x20, 0x10, 0x08, 0x04, 0x02, // /
    0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
    0x00, 0x42, 0x7F, 0x40, 0x00, // 1
    0x42, 0x61, 0x51, 0x49, 0x46, // 2
    0x21, 0x41, 0x45, 0x4B, 0x31, // 3
    0x18, 0x14, 0x12, 0x7F, 0x10, // 4
    0x27, 0x45, 0x45, 0x45, 0x39, // 5
    0x3C, 0x4A, 0x49, 0x49, 0x30, // 6
    0x01, 0x71, 0x09, 0x05, 0x03, // 7
    0x36, 0x49, 0x49, 0x49, 0x36, // 8
    0x06, 0x49, 0x49, 0x29, 0x1E, // 9
    0x00, 0x36, 0x36, 0x00, 0x00, // :
    0x00, 0x56, 0x36, 0x00, 0x00, // ;
    0x00, 0x08, 0x14, 0x22, 0x41, // <
    0x14, 0x14, 0x14, 0x14, 0x14, // =
    0x41, 0x22, 0x14, 0x08, 0x00, // >
    0x02, 0x01, 0x51, 0x09, 0x06, // ?
    0x32, 0x49, 0x79, 0x41, 0x3E, // @
    0x7E, 0x11, 0x11, 0x11, 0x7E, // A
    0x7F, 0x49, 0x49, 0x49, 0x36, // B
    0x3E, 0x41, 0x41, 0x41, 0x22, // C
    0x7F, 0x41, 0x41, 0x22, 0x1C, // D
    0x7F, 0x49, 0x49, 0x49, 0x41, // E
    0x7F, 0x09, 0x09, 0x09, 0x01, // F
    0x3E, 0x41, 0x49, 0x49, 0x7A, // G
    0x7F, 0x08, 0x08, 0x08, 0x7F, // H
    0x00, 0x41, 0x7F, 0x41, 0x00, // I
    0x20, 0x40, 0x41, 0x3F, 0x01, // J
    0x7F, 0x08, 0x14, 0x22, 0x41, // K
    0x7F, 0x40, 0x40, 0x40, 0x40, // L
    0x7F, 0x02, 0x04, 0x02, 0x7F, // M
    0x7F, 0x04, 0x08, 0x10, 0x7F, // N
    0x3E, 0x41, 0x41, 0x41, 0x3E, // O
    0x7F, 0x09, 0x09, 0x09, 0x06, // P
    0x3E, 0x41, 0x51, 0x21, 0x5E, // Q
    0x7F, 0x09, 0x19, 0x29, 0x46, // R
    0x46, 0x49, 0x49, 0x49, 0x31, // S
    0x01, 0x01, 0x7F, 0x01, 0x01, // T
    0x3F, 0x40, 0x40, 0x40, 0x3F, // U
    0x1F, 0x20, 0x40, 0x20, 0x1F, // V
    0x7F, 0x20, 0x18, 0x20, 0x7F, // W
    0x63, 0x14, 0x08, 0x14, 0x63, // X
    0x03, 0x04, 0x78, 0x04, 0x03, // Y
    0x61, 0x51, 0x49, 0x45, 0x43, // Z
    0x00, 0x7F, 0x41, 0x41, 0x00, // [
    0x02, 0x04, 0x08, 0x10, 0x20, // "\"
    0x00, 0x41, 0x41, 0x7F, 0x00, // ]
    0x04, 0x02, 0x01, 0x02, 0x04, // ^
    0x40, 0x40, 0x40, 0x40, 0x40, // _
    0x00, 0x01, 0x02, 0x04, 0x00, // `
    0x20, 0x54, 0x54, 0x54, 0x78, // a
    0x7F, 0x48, 0x44, 0x44, 0x38, // b
    0x38, 0x44, 0x44, 0x44, 0x20, // c
    0x38, 0x44, 0x44, 0x48, 0x7F, // d
    0x38, 0x54, 0x54, 0x54, 0x18, // e
    0x08, 0x7E, 0x09, 0x01, 0x02, // f
    0x08, 0x14, 0x54, 0x54, 0x3C, // g
    0x7F, 0x08, 0x04, 0x04, 0x78, // h
    0x00, 0x44, 0x7D, 0x40, 0x00, // i
    0x20, 0x40, 0x44, 0x3D, 0x00, // j
    0x00, 0x7F, 0x10, 0x28, 0x44, // k
    0x00, 0x41, 0x7F, 0x40, 0x00, // l
    0x7C, 0x04, 0x18, 0x04, 0x78, // m
    0x7C, 0x08, 0x04, 0x04, 0x78, // n
    0x38, 0x44, 0x44, 0x44, 0x38, // o
    0x7C, 0x14, 0x14, 0x14, 0x08, // p
    0x08, 0x14, 0x14, 0x18, 0x7C, // q
    0x7C, 0x08, 0x04, 0x04, 0x08, // r
    0x48, 0x54, 0x54, 0x54, 0x20, // s
    0x04, 0x3F, 0x44, 0x40, 0x20, // t
    0x3C, 0x40, 0x40, 0x20, 0x7C, // u
    0x1C, 0x20, 0x40, 0x20, 0x1C, // v
    0x3C, 0x40, 0x30, 0x40, 0x3C, // w
    0x44, 0x28, 0x10, 0x28, 0x44, // x
    0x0C, 0x50, 0x50, 0x50, 0x3C, // y
    0x44, 0x64, 0x54, 0x4C, 0x44, // z
    0x00, 0x08, 0x36, 0x41, 0x00, // {
    0x00, 0x00, 0x7F, 0x00, 0x00, // |
    0x00, 0x41, 0x36, 0x08, 0x00, // }
    0x08, 0x08, 0x2A, 0x1C, 0x08, // →
    0x08, 0x1C, 0x2A, 0x08, 0x08  // ←
};

#endif

使用示例 (main.c)

    // 初始化OLED
    SSD1305_Init(&hi2c1);
    
    // 显示内容
    SSD1305_Clear();
    SSD1305_GotoXY(0, 0);
    SSD1305_PutString("Hello OLED!", 1);
    
    SSD1305_GotoXY(0, 16);
    SSD1305_PutString("STM32 HAL I2C", 1);
    
    SSD1305_GotoXY(0, 32);
    SSD1305_PutString("SSD1305 Driver", 1);
    
    // 更新显示
    SSD1305_UpdateScreen();

本文章已经生成可运行项目
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值