558 lines
22 KiB
C
558 lines
22 KiB
C
#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
|