stm32h743_player/User/bsp/bsp_oled_sh1106.c
2024-04-05 00:36:26 +08:00

558 lines
22 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "bsp_oled_sh1106.h"
#include <string.h>
#include <stdlib.h>
#include "FreeRTOS.h"
#include "semphr.h"
#include "elog.h"
#include "heap.h"
#define BSP_OLED_WRITE_DATA 0x40
#define BSP_OLED_WRITE_CMD 0x00
static const char *TAG = "bsp_oled";
static const uint8_t OLED_FONT6x8[94][6];
static const uint8_t OLED_FONT8x16[94][16];
static const uint8_t OLED_INIT_REGS[23];
static SemaphoreHandle_t bsp_oled_i2c_tx_semphr = NULL;
static I2C_HandleTypeDef *bsp_oled_i2c_handle = NULL;
static uint8_t *bsp_oled_frame_buffer = NULL;
static uint32_t bsp_oled_updated_line = 0xFF;
static HAL_StatusTypeDef bsp_oled_send_cmd(const uint8_t *cmd_buf, uint8_t cmd_len);
static HAL_StatusTypeDef bsp_oled_send_dat(const uint8_t *dat_buf, uint16_t dat_len);
static HAL_StatusTypeDef bsp_oled_set_cursor(uint8_t column, uint8_t page);
static void bsp_oled_6x8_char(uint8_t y, uint8_t x, char ch);
static void bsp_oled_8x16_char(uint8_t y, uint8_t x, char ch);
void HAL_I2C_MemTxCpltCallback(I2C_HandleTypeDef *hi2c)
{
BaseType_t higher_task_woken = pdFALSE;
higher_task_woken |= bsp_oled_i2c_tx_done_cb(hi2c);
portYIELD_FROM_ISR(higher_task_woken);
}
BaseType_t bsp_oled_i2c_tx_done_cb(I2C_HandleTypeDef *hi2c)
{
BaseType_t higher_task_woken = pdFALSE;
if (hi2c == bsp_oled_i2c_handle && bsp_oled_i2c_tx_semphr != NULL) {
xSemaphoreGiveFromISR(bsp_oled_i2c_tx_semphr, &higher_task_woken);
}
return higher_task_woken;
}
/**
* @brief 内部函数向OLED写入命令
*
* @param cmd_buf 指向存放命令的缓冲区
* @param cmd_len 要发送命令的长度
*
* @return 错误代码
*/
static HAL_StatusTypeDef bsp_oled_send_cmd(const uint8_t *cmd_buf, uint8_t cmd_len)
{
if (bsp_oled_i2c_handle == NULL) {
elog_error(TAG, "i2c handle is null, call bsp_oled_init first");
return HAL_ERROR;
}
HAL_StatusTypeDef status = HAL_I2C_Mem_Write(bsp_oled_i2c_handle, BSP_OLED_I2C_ADDRESS << 1,
BSP_OLED_WRITE_CMD, 1, (uint8_t*)cmd_buf, cmd_len, BSP_OLED_I2C_TIMEOUT);
if (status != HAL_OK) {
elog_error(TAG, "error while writing register");
}
return status;
}
/**
* @brief 内部函数向OLED写入数据
*
* @param cmd_buf 指向存放数据的缓冲区
* @param cmd_len 要发送数据的长度
*
* @return 错误代码
*/
static HAL_StatusTypeDef bsp_oled_send_dat(const uint8_t *dat_buf, uint16_t dat_len)
{
if (bsp_oled_i2c_handle == NULL) {
elog_error(TAG, "i2c handle is null, call bsp_oled_init first");
return HAL_ERROR;
}
HAL_StatusTypeDef status = HAL_I2C_Mem_Write_DMA(bsp_oled_i2c_handle, BSP_OLED_I2C_ADDRESS << 1,
BSP_OLED_WRITE_DATA, 1, (uint8_t*)dat_buf, dat_len);
if (status != HAL_OK) {
elog_error(TAG, "error while writing data");
}
xSemaphoreTake(bsp_oled_i2c_tx_semphr, portMAX_DELAY); //等待传输完成
return status;
}
/**
* @brief 内部函数设置OLED页写入模式的显示位置
*
* @param column 下一次写入时光标的横向位置取值0-127
* @param page 下一次写入时光标的纵向Column取值0-7
*
* @return 错误代码
*/
static HAL_StatusTypeDef bsp_oled_set_cursor(uint8_t column, uint8_t page)
{
uint8_t cmds[3];
cmds[0] = 0xB0 + page; //设定page
cmds[1] = 0x0F & column; //设定column的高四位
cmds[2] = 0x10 + (column >> 4); //设定column的低四位
return bsp_oled_send_cmd(cmds, sizeof(cmds));
}
/**
* @brief 初始化OLED
*
* @return 错误代码
*/
HAL_StatusTypeDef bsp_oled_init(I2C_HandleTypeDef *hi2c)
{
if (hi2c == NULL) {
elog_error(TAG, "hi2c handle is null");
return HAL_ERROR;
}
bsp_oled_i2c_handle = hi2c;
HAL_StatusTypeDef ret = bsp_oled_send_cmd((uint8_t*)OLED_INIT_REGS, sizeof(OLED_INIT_REGS));
if(ret != HAL_OK) {
elog_error(TAG, "error while initializing registers");
goto ERROR;
}
bsp_oled_frame_buffer = malloc_ahb(BSP_OLED_X * BSP_OLED_Y);
if(bsp_oled_frame_buffer == NULL) {
elog_error(TAG, "error while allocating oled frame buffer");
ret = HAL_ERROR;
goto ERROR;
}
bsp_oled_i2c_tx_semphr = xSemaphoreCreateBinary();
if(bsp_oled_i2c_tx_semphr == NULL) {
elog_error(TAG, "error while creating oled i2c tx semphr");
ret = HAL_ERROR;
goto ERROR;
}
bsp_oled_clear_fb();
elog_info(TAG, "oled initialized");
return ret;
ERROR:
free_ahb(bsp_oled_frame_buffer);
if (bsp_oled_i2c_tx_semphr) {
vSemaphoreDelete(bsp_oled_i2c_tx_semphr);
}
bsp_oled_i2c_handle = NULL;
bsp_oled_frame_buffer = NULL;
bsp_oled_i2c_tx_semphr = NULL;
return ret;
}
/**
* @brief 内部函数在OLED上显示一个6x8的字符
*
* @param y 纵向显示的Column取值为0-7
* @param x 横向显示的位置取值为0-127
* @param ch 要显示的字符的ASCII码
*
* @return 错误代码
*/
static void bsp_oled_6x8_char(uint8_t y, uint8_t x, char ch)
{
if (bsp_oled_frame_buffer == NULL) {
elog_error(TAG, "bsp_oled_6x8_char: oled frame buffer is null, call bsp_oled_init first");
return;
}
if (y >= BSP_OLED_Y || x >= BSP_OLED_X) {
elog_error(TAG, "bsp_oled_6x8_char: invalid position");
return;
}
#ifdef BSP_OLED_CONTROLLER_SH1106
x += 2; //SH1106需要额外的显示偏移
#endif
memcpy(&bsp_oled_frame_buffer[y * BSP_OLED_X + x], &OLED_FONT6x8[(uint8_t)ch - 32][0], sizeof(OLED_FONT6x8[0]));
bsp_oled_updated_line |= 1 << y;
}
/**
* @brief 内部函数在OLED上显示一个8x16的字符
*
* @param y 纵向显示的Column取值为0-7
* @param x 横向显示的位置取值为0-127
* @param ch 要显示的字符的ASCII码
*
* @return 错误代码
*/
static void bsp_oled_8x16_char(uint8_t y, uint8_t x, char ch)
{
if (bsp_oled_frame_buffer == NULL) {
elog_error(TAG, "bsp_oled_8x16_char: oled frame buffer is null, call bsp_oled_init first");
return;
}
if (y >= BSP_OLED_Y || x >= BSP_OLED_X) {
elog_error(TAG, "bsp_oled_8x16_char: invalid position");
return;
}
#ifdef BSP_OLED_CONTROLLER_SH1106
x += 2; //SH1106需要额外的显示偏移
#endif
memcpy(&bsp_oled_frame_buffer[y * BSP_OLED_X + x], &OLED_FONT8x16[(uint8_t)ch - 32][0], sizeof(OLED_FONT8x16[0]) / 2);
bsp_oled_updated_line |= 1 << y;
memcpy(&bsp_oled_frame_buffer[++y * BSP_OLED_X + x], &OLED_FONT8x16[(uint8_t)ch - 32][8], sizeof(OLED_FONT8x16[0]) / 2);
bsp_oled_updated_line |= 1 << y;
}
/**
* @brief 清空OLED的显存
*
* @return 错误代码
*/
void bsp_oled_clear_fb(void)
{
if (bsp_oled_frame_buffer == NULL) {
return;
}
memset(bsp_oled_frame_buffer, 0, BSP_OLED_X * BSP_OLED_Y);
bsp_oled_updated_line = 0xFF;
}
/**
* @brief 在OLED上显示6x8的字符串
*
* @param y 字符串起始的纵向Column取值为0-7
* @param x 字符串起始的横向位置取值为0-127
* @param str 要显示的字符串
*
* @return 错误代码
*/
void bsp_oled_6x8(uint8_t y, uint8_t x, const char *str)
{
if (str == NULL) {
elog_error(TAG, "bsp_oled_6x8: invalid str pointer");
return;
}
while (*str != '\0') {
if (x > BSP_OLED_X - 6 || *str == '\n') {
x = 0;
++ y;
if (y >= BSP_OLED_Y) {
break;
}
} else if (*str < 32 || *str > 127) {
continue;
}
bsp_oled_6x8_char(y, x, *str);
x += 6;
++ str;
}
}
/**
* @brief 在OLED上显示8x16的字符串
*
* @param y 字符串起始的纵向Column取值为0-7
* @param x 字符串起始的横向位置取值为0-127
* @param str 要显示的字符串
*
* @return 错误代码
*/
void bsp_oled_8x16(uint8_t y, uint8_t x, const char *str)
{
if (str == NULL) {
elog_error(TAG, "bsp_oled_8x16: invaldid str pointer");
return;
}
while (*str) {
if (x > BSP_OLED_X-8 || *str == '\n') {
x = 0;
y += 2;
if (y >= BSP_OLED_Y) {
break;
}
} else if (*str < 32 || *str > 127) {
continue;
}
bsp_oled_8x16_char(y, x, *str);
x += 8;
++ str;
}
}
HAL_StatusTypeDef bsp_oled_update(void)
{
HAL_StatusTypeDef status = HAL_OK;
for (uint8_t line = 0; line < BSP_OLED_Y; line ++) {
if (bsp_oled_updated_line & (1 << line)) {
#ifdef BSP_OLED_CONTROLLER_SH1106
status = bsp_oled_set_cursor(2, line); //SH1106需要额外的显示偏移
#else
status = bsp_oled_set_cursor(0, line); //SH1106需要额外的显示偏移
#endif
if (status != HAL_OK) {
elog_error(TAG, "oled update: error while setting cursor");
break;
}
status = bsp_oled_send_dat(bsp_oled_frame_buffer + line * BSP_OLED_X, BSP_OLED_X);
if (status != HAL_OK) {
elog_error(TAG, "oled update: error while sending framebuffer");
break;
}
}
}
bsp_oled_updated_line = 0;
return status;
}
/**
* @brief 6*8的点阵字库
*
*/
static const uint8_t OLED_FONT6x8[94][6] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // ' '
{0x00, 0x00, 0x00, 0x2f, 0x00, 0x00}, // !
{0x00, 0x00, 0x07, 0x00, 0x07, 0x00}, // "
{0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14}, // #
{0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12}, // $
{0x00, 0x62, 0x64, 0x08, 0x13, 0x23}, // %
{0x00, 0x36, 0x49, 0x55, 0x22, 0x50}, // &
{0x00, 0x00, 0x05, 0x03, 0x00, 0x00}, // '
{0x00, 0x00, 0x1c, 0x22, 0x41, 0x00}, // (
{0x00, 0x00, 0x41, 0x22, 0x1c, 0x00}, // )
{0x00, 0x14, 0x08, 0x3E, 0x08, 0x14}, // *
{0x00, 0x08, 0x08, 0x3E, 0x08, 0x08}, // +
{0x00, 0x00, 0x00, 0xA0, 0x60, 0x00}, // ,
{0x00, 0x08, 0x08, 0x08, 0x08, 0x08}, // -
{0x00, 0x00, 0x60, 0x60, 0x00, 0x00}, // .
{0x00, 0x20, 0x10, 0x08, 0x04, 0x02}, // /
{0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E}, // 0
{0x00, 0x00, 0x42, 0x7F, 0x40, 0x00}, // 1
{0x00, 0x42, 0x61, 0x51, 0x49, 0x46}, // 2
{0x00, 0x21, 0x41, 0x45, 0x4B, 0x31}, // 3
{0x00, 0x18, 0x14, 0x12, 0x7F, 0x10}, // 4
{0x00, 0x27, 0x45, 0x45, 0x45, 0x39}, // 5
{0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30}, // 6
{0x00, 0x01, 0x71, 0x09, 0x05, 0x03}, // 7
{0x00, 0x36, 0x49, 0x49, 0x49, 0x36}, // 8
{0x00, 0x06, 0x49, 0x49, 0x29, 0x1E}, // 9
{0x00, 0x00, 0x36, 0x36, 0x00, 0x00}, // :
{0x00, 0x00, 0x56, 0x36, 0x00, 0x00}, // ;
{0x00, 0x08, 0x14, 0x22, 0x41, 0x00}, // <
{0x00, 0x14, 0x14, 0x14, 0x14, 0x14}, // =
{0x00, 0x00, 0x41, 0x22, 0x14, 0x08}, // >
{0x00, 0x02, 0x01, 0x51, 0x09, 0x06}, // ?
{0x00, 0x32, 0x49, 0x59, 0x51, 0x3E}, // @
{0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C}, // A
{0x00, 0x7F, 0x49, 0x49, 0x49, 0x36}, // B
{0x00, 0x3E, 0x41, 0x41, 0x41, 0x22}, // C
{0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C}, // D
{0x00, 0x7F, 0x49, 0x49, 0x49, 0x41}, // E
{0x00, 0x7F, 0x09, 0x09, 0x09, 0x01}, // F
{0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A}, // G
{0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F}, // H
{0x00, 0x00, 0x41, 0x7F, 0x41, 0x00}, // I
{0x00, 0x20, 0x40, 0x41, 0x3F, 0x01}, // J
{0x00, 0x7F, 0x08, 0x14, 0x22, 0x41}, // K
{0x00, 0x7F, 0x40, 0x40, 0x40, 0x40}, // L
{0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F}, // M
{0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F}, // N
{0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E}, // O
{0x00, 0x7F, 0x09, 0x09, 0x09, 0x06}, // P
{0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E}, // Q
{0x00, 0x7F, 0x09, 0x19, 0x29, 0x46}, // R
{0x00, 0x46, 0x49, 0x49, 0x49, 0x31}, // S
{0x00, 0x01, 0x01, 0x7F, 0x01, 0x01}, // T
{0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F}, // U
{0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F}, // V
{0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F}, // W
{0x00, 0x63, 0x14, 0x08, 0x14, 0x63}, // X
{0x00, 0x07, 0x08, 0x70, 0x08, 0x07}, // Y
{0x00, 0x61, 0x51, 0x49, 0x45, 0x43}, // Z
{0x00, 0x00, 0x7F, 0x41, 0x41, 0x00}, // [
{0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55}, // '\'
{0x00, 0x00, 0x41, 0x41, 0x7F, 0x00}, // ]
{0x00, 0x04, 0x02, 0x01, 0x02, 0x04}, // ^
{0x00, 0x40, 0x40, 0x40, 0x40, 0x40}, // _
{0x00, 0x00, 0x01, 0x02, 0x04, 0x00}, // '
{0x00, 0x20, 0x54, 0x54, 0x54, 0x78}, // a
{0x00, 0x7F, 0x48, 0x44, 0x44, 0x38}, // b
{0x00, 0x38, 0x44, 0x44, 0x44, 0x20}, // c
{0x00, 0x38, 0x44, 0x44, 0x48, 0x7F}, // d
{0x00, 0x38, 0x54, 0x54, 0x54, 0x18}, // e
{0x00, 0x08, 0x7E, 0x09, 0x01, 0x02}, // f
{0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C}, // g
{0x00, 0x7F, 0x08, 0x04, 0x04, 0x78}, // h
{0x00, 0x00, 0x44, 0x7D, 0x40, 0x00}, // i
{0x00, 0x40, 0x80, 0x84, 0x7D, 0x00}, // j
{0x00, 0x7F, 0x10, 0x28, 0x44, 0x00}, // k
{0x00, 0x00, 0x41, 0x7F, 0x40, 0x00}, // l
{0x00, 0x7C, 0x04, 0x18, 0x04, 0x78}, // m
{0x00, 0x7C, 0x08, 0x04, 0x04, 0x78}, // n
{0x00, 0x38, 0x44, 0x44, 0x44, 0x38}, // o
{0x00, 0xFC, 0x24, 0x24, 0x24, 0x18}, // p
{0x00, 0x18, 0x24, 0x24, 0x18, 0xFC}, // q
{0x00, 0x7C, 0x08, 0x04, 0x04, 0x08}, // r
{0x00, 0x48, 0x54, 0x54, 0x54, 0x20}, // s
{0x00, 0x04, 0x3F, 0x44, 0x40, 0x20}, // t
{0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C}, // u
{0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C}, // v
{0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C}, // w
{0x00, 0x44, 0x28, 0x10, 0x28, 0x44}, // x
{0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C}, // y
{0x00, 0x44, 0x64, 0x54, 0x4C, 0x44}, // z
{0x00, 0x08, 0x3E, 0x41, 0x00, 0x00}, // {
{0x00, 0x00, 0x7F, 0x00, 0x00, 0x00}, // |
{0x00, 0x00, 0x41, 0x3E, 0x08, 0x00}, // }
};
/**
* @brief 8*16的点阵字库
*
*/
static const uint8_t OLED_FONT8x16[94][16] = {
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // ' '
{0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00}, // !
{0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // "
{0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00}, // #
{0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00}, // $
{0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00}, // %
{0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10}, // &
{0x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // '
{0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00}, // (
{0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00}, // )
{0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00}, // *
{0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00}, // +
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00}, // ,
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01}, // -
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00}, // .
{0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00}, // /
{0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00}, // 0
{0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00}, // 1
{0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00}, // 2
{0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00}, // 3
{0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00}, // 4
{0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00}, // 5
{0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00}, // 6
{0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00}, // 7
{0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00}, // 8
{0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00}, // 9
{0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00}, // :
{0x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00}, // ;
{0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00}, // <
{0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00}, // =
{0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00}, // >
{0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00}, // ?
{0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00}, // @
{0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20}, // A
{0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00}, // B
{0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00}, // C
{0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00}, // D
{0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00}, // E
{0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00}, // F
{0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00}, // G
{0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20}, // H
{0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00}, // I
{0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00}, // J
{0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00}, // K
{0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00}, // L
{0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00}, // M
{0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00}, // N
{0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00}, // O
{0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00}, // P
{0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00}, // Q
{0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20}, // R
{0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00}, // S
{0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00}, // T
{0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00}, // U
{0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00}, // V
{0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00}, // W
{0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20}, // X
{0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00}, // Y
{0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00}, // Z
{0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00}, // [
{0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00}, // '\'
{0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00}, // ]
{0x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // ^
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80}, // _
{0x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}, // `
{0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20}, // a
{0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00}, // b
{0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00}, // c
{0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20}, // d
{0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00}, // e
{0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00}, // f
{0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00}, // g
{0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20}, // h
{0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00}, // i
{0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00}, // j
{0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00}, // k
{0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00}, // l
{0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F}, // m
{0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20}, // n
{0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00}, // o
{0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00}, // p
{0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80}, // q
{0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00}, // r
{0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00}, // s
{0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00}, // t
{0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20}, // u
{0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00}, // v
{0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00}, // w
{0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00}, // x
{0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00}, // y
{0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00}, // z
{0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40}, // {
{0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00}, // |
{0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00}, // }
};
#ifdef BSP_OLED_CONTROLLER_SH1106
static const uint8_t OLED_INIT_REGS[23] = {
0xA1, //左右不反置(0xA0左右反置 0xA1正常)
0xC8, //上下不反置(0xC0上下反置 0xC8正常)
0xA6, //不反显(A6正常A7反显)
0xA4, //正常显示(A4正常显示 A5全屏亮)
0x40, //显示RAM第0行对应纵向COM1(硬件连接的起始)
0x33, //设定内置电荷泵电压为9v
0x81, 0x80, //设置亮度为最高
0xA8, 0x3F, //设置刷新率倍数 默认值1/64
0xAD, 0x8B, //使用DC-DC模式
0xD3, 0x00, //设置显示偏移 不偏移(0-63)
0xD5, 0x80, //振荡器和分频 低四位为分频比率,高四位为振荡器频率
0xD9, 0x22, //设定预充电 预充电2时钟周期放电2时钟周期
0xDA, 0x01, //设定管脚排列为默认顺序
0xDB, 0x40, //设定列驱动电流级别为默认值
0xAF //开显示
};
#endif