简介
一个适用于esp32系列的oled12864 iic (ssd1306)的日志打印程序(带有动画)
使用方法
- 将附件内的工程以及两个字库复制到工程内
- 使用网站内的
ssd1306简单驱动或者自行实现驱动
自行实现需要一个刷新函数,一个刷新缓冲区 - 调用
logAutoInit()初始化 - 使用consoleLog(bool isInvert,const char *format, ...)发送日志,日志会自行显示到屏幕上
其中,isInvert决定日志是否反色
附件1
C
#include "esp_log.h"
#include "esp_timer.h"
#include "zpix.h"
#include "tinyFont.h"
#include <stdbool.h>
#include <stdarg.h>
#include <stdio.h>
#include <math.h>
#include "ssd1306_driver.h" //需要一个函数用于刷新屏幕,还需要预留一个接口用于直接访问屏幕缓冲区
extern uint8_t* vBuf; // 外界的屏幕接口
uint8_t vBuf2[1024];
SemaphoreHandle_t vBuf2Mutex;
QueueHandle_t updateRectQueue;
typedef struct {
uint8_t width;
uint8_t height;
} UpdateRectQueuePack_t;
void putChar(uint8_t* vFrame, uint8_t row, uint8_t column, uint8_t code, bool isInvert)
{
if (code < ' ' || code > '~') return;
row = row%8;
row = 7 - row;
if (isInvert) {
for (uint8_t i = 0; i < 12; i++) {
vFrame[row + ((column + i) << 3)] = ~zpix_ascii[(code - ' ') * 12 + i];
}
} else {
for (uint8_t i = 0; i < 12; i++) {
vFrame[row + ((column + i) << 3)] = zpix_ascii[(code - ' ') * 12 + i];
}
}
}
// 全局预计算掩码表(常量数组)
const uint8_t BIT_MASK[8] = {
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80
};
void setPixel(uint8_t* vFrame,uint8_t x, uint8_t y, bool isTrue) {
uint8_t row = y >> 3; // 行索引(y/8)
uint16_t pos = x;
pos <<= 3;
pos += row;
uint8_t mask = BIT_MASK[y & 0x07]; // 直接查表获取位掩码
if (isTrue) {
vFrame[pos] |= mask; // 置位像素
} else {
vFrame[pos] &= ~mask; // 清除像素
}
}
/**
* 高效绘制矩形(空心或实心)
* @param x0, y0 矩形左上角坐标
* @param x1, y1 矩形右下角坐标
* @param isFilled true=实心填充, false=仅边框
* @param isTrue true=置位像素, false=清除像素
*/
void drawRectangle(uint8_t* vFrame,uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, bool isTrue) {
// 1. 参数校验:确保 x0<=x1, y0<=y1
if (x0 > x1) { uint8_t tmp = x0; x0 = x1; x1 = tmp; }
if (y0 > y1) { uint8_t tmp = y0; y0 = y1; y1 = tmp; }
for (uint16_t i = x0;i <= x1;i++){
for (uint16_t j = y0;j <= y1;j++) {
setPixel(vFrame, i, j, isTrue);
}
}
}
void drawRectangle_Optimized(uint8_t* vFrame,uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, bool isFilled, bool isRoundCorner,bool isTrue) {
// 1. 参数校验与坐标归一化
if (x0 > x1) { uint8_t tmp = x0; x0 = x1; x1 = tmp; }
if (y0 > y1) { uint8_t tmp = y0; y0 = y1; y1 = tmp; }
if (x0 == x1 || y0 == y1) return;
// 2. 绘制空心矩形边框(仅四条边)
// 上/下水平边框(整行处理)
for (uint8_t x = x0 + ((isRoundCorner) ? 1 : 0); x <= x1 - ((isRoundCorner) ? 1 : 0); x++) {
setPixel(vFrame, x, y0, isTrue); // 上边框
setPixel(vFrame, x, y1, isTrue); // 下边框
}
// 左/右边框(按页处理)
uint8_t start_page = y0 >> 3;
uint8_t end_page = y1 >> 3;
for (uint8_t i = y0 + 1; i <= y1 - 1; i++) {
setPixel(vFrame, x0, i, isTrue); // 左边框
setPixel(vFrame, x1, i, isTrue); // 右边框
}
// 3. 实心填充优化(按列批量操作)
if (isFilled) {
for (uint16_t x = x0 + 1; x < x1; x++) { // 遍历每一列
for (uint8_t page = start_page; page <= end_page; page++) {
uint8_t *col_ptr = &vFrame[(x << 3) + page]; // 当前列显存地址
uint8_t fill_mask = 0xFF; // 默认填充整页
// 计算当前页的垂直掩码(首尾页裁剪)
if (page == start_page)
fill_mask &= (0xFF << (y0 & 0x07)); // 首页:屏蔽顶部无效位
if (page == end_page)
fill_mask &= (0xFF >> (7 - (y1 & 0x07))); // 尾页:屏蔽底部无效位
// 整字节写入显存
if (isTrue) *col_ptr |= fill_mask;
else *col_ptr &= ~fill_mask;
}
}
}
}
void testPutChar(uint8_t* vFrame,uint8_t x, uint8_t y, uint8_t code, uint8_t zoom, bool isInvert)
{
if (code < ' ' || code > '~') return;
for (uint8_t i = 0; i < 12; i++) {
uint8_t mask = zpix_ascii[(code - ' ') * 12 + i];
if (isInvert) mask = ~mask;
for (uint8_t j = 0; j < 8; j++) {
uint8_t color = mask & (0x80 >> j);
if (color || 1) {
if(zoom <= 1) setPixel(vFrame, j + x, i + y, color);
else drawRectangle (vFrame, j * zoom + x, i * zoom + y,(j + 1) * zoom + x - 1, (i + 1) * zoom + y - 1, color);
}
}
}
}
void testPutTinyChar(uint8_t* vFrame,uint8_t x, uint8_t y, uint8_t code, uint8_t zoom, bool isInvert)
{
y += 1;
if (code < ' ' || code > '~') return;
for (uint8_t i = 0; i < 5; i++) {
uint8_t mask = tinyFont_ascii[(code - ' ') * 5 + i];
if (isInvert) mask = ~mask;
for (uint8_t j = 0; j < 5; j++) {
uint8_t color = mask & (0x80 >> j);
if (color || 1) {
if(zoom <= 1) setPixel(vFrame, j + x, i + y, color);
else drawRectangle (vFrame, j * zoom + x, i * zoom + y,(j + 1) * zoom + x - 1, (i + 1) * zoom + y - 1, color);
}
}
}
y -= 1;
for (uint8_t i = 0; i < 5; i++) {
setPixel(vFrame, i + x, y, isInvert);
}
}
void frameBufferCopy(int16_t x,int16_t y, int16_t w, int16_t h)
{
if (h < 1 || w < 1) return;
uint16_t start_page = y >> 3;
uint16_t end_page = (y + h) >> 3;
for (uint16_t i = x; i <= (w + x) ; i++) {
for (uint16_t page = start_page; page <= end_page; page++) {
uint8_t *col_ptr = &vBuf[(i << 3) + page]; // 当前列显存地址
uint16_t fill_mask = (vBuf2[((i - x) << 3) + page - start_page]);
fill_mask <<= 8;
if (page != start_page) {
fill_mask += (vBuf2[((i - x) << 3) + page - start_page - 1]);
fill_mask >>= 8 - (y% 8);
} else {
fill_mask += (vBuf2[((i - x) << 3) + page - start_page]);
fill_mask <<= (y% 8);
}
uint8_t maskUint8 = fill_mask & 0x00FF;
// 计算当前页的垂直掩码(首尾页裁剪)
if (page == start_page)
maskUint8 &= (0xFF << (y & 0x07)); // 首页:屏蔽顶部无效位
if (page == end_page)
maskUint8 &= (0xFF >> (7 - ((y + h) & 0x07))); // 尾页:屏蔽底部无效位
// 整字节写入显存
*col_ptr |= maskUint8;
}
}
}
typedef struct {
uint16_t currFrame;
uint16_t totalFrame;
int16_t targetWidth;
int16_t targetHeight;
int16_t currWidth;
int16_t currHeight;
int16_t startWidth;
int16_t startHeight;
} UpdateRect_t;
UpdateRect_t rectInfo;
SemaphoreHandle_t rectMutex;
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
float animationCalc(float t);
void updateRect(TimerHandle_t xTimer)
{
static bool isRunning = false;
if (isRunning) return;
isRunning = true;
xSemaphoreTake(rectMutex, portMAX_DELAY);
xSemaphoreTake(vBuf2Mutex, portMAX_DELAY);
/* 检查合法性 */
// rectInfo.targetWidth = MAX (0, rectInfo.targetWidth);
// rectInfo.targetWidth = MIN (127, rectInfo.targetWidth);
// rectInfo.targetHeight = MAX (0, rectInfo.targetHeight);
// rectInfo.targetHeight = MIN (63, rectInfo.targetHeight);
// rectInfo.currWidth = MAX (0, rectInfo.currWidth);
// rectInfo.currWidth = MIN (127, rectInfo.currWidth);
// rectInfo.currHeight = MAX (0, rectInfo.currHeight);
// rectInfo.currHeight = MIN (63, rectInfo.currHeight);
// rectInfo.startWidth = MAX (0, rectInfo.startWidth);
// rectInfo.startWidth = MIN (127, rectInfo.startWidth);
// rectInfo.startHeight = MAX (0, rectInfo.startHeight);
// rectInfo.startHeight = MIN (63, rectInfo.startHeight);
float time = 1.0f * rectInfo.currFrame / rectInfo.totalFrame;
if (rectInfo.currFrame > rectInfo.totalFrame || time > 1.0f) {
xTimerStop(xTimer, 0);
xSemaphoreGive(rectMutex);
xSemaphoreGive(vBuf2Mutex);
isRunning = false;
return;
}
float div = animationCalc(time);
if (div > 1.0) div = 1.0;
int16_t newHeight = rectInfo.startHeight + (rectInfo.targetHeight - rectInfo.startHeight) * div;
int16_t newWidth = rectInfo.startWidth + (rectInfo.targetWidth - rectInfo.startWidth) * div;
if (newHeight > 63 || newWidth > 127)
ESP_LOGW(__func__,"%d,%d,%d,%d,%f",newWidth, rectInfo.currWidth, rectInfo.startWidth, rectInfo.targetWidth,time);
// drawRectangle_Optimized(vBuf, 0,0,newWidth,newHeight,false,true,true);
if (rectInfo.currHeight != newHeight || rectInfo.currWidth != newWidth || rectInfo.currFrame != 0) {
drawRectangle_Optimized(vBuf,
63 - (newWidth >> 1),
31 - (newHeight >> 1),
63 + newWidth - (newWidth >> 1),
31 + newHeight - (newHeight >> 1),
false,true,true);
rectInfo.currHeight = newHeight;
rectInfo.currWidth = newWidth;
if(newWidth >= 1 && newHeight >= 1 && newWidth <= 126 && newHeight <= 62) {
frameBufferCopy(63 - (newWidth >> 1) + 2, 31 - (newHeight >> 1) + 2,newWidth - 4,newHeight - 4);
}
ssd1306FreshScreen();
}
rectInfo.currFrame++;
xSemaphoreGive(rectMutex);
xSemaphoreGive(vBuf2Mutex);
isRunning = false;
}
TaskHandle_t logAutoHandler = NULL;
esp_timer_handle_t timer_handle;
float animationCalc(float t) {
if (t < 0.5)
return 0.5f * pow(2*t, 2);
else if (t != 1.0)
return 1.0f - 0.5f * pow(2*(1-t), 2); // 后半段减速
else return 1.0f;
}
void setNewRectAnimation(int16_t targetWidth, int16_t targetHeight, int16_t frame)
{
rectInfo.currFrame = 0;
rectInfo.targetHeight = targetHeight;
rectInfo.targetWidth = targetWidth;
rectInfo.totalFrame = frame;
rectInfo.startHeight = rectInfo.currHeight;
rectInfo.startWidth = rectInfo.currWidth;
}
static void logAuto()
{
rectInfo.startHeight = 0;
rectInfo.startWidth = 0;
TimerHandle_t xTimer = xTimerCreate(
"updateRect", // 定时器名称(调试用)
pdMS_TO_TICKS(33), // 周期:20ms
pdTRUE, // 自动重载(周期性)
(void *)0, // 定时器 ID(可传递参数)
updateRect // 回调函数
);
bool isClose = true;
uint8_t skipCount = 0;
UpdateRectQueuePack_t queueData = {
.height = 0,
.width = 0
};
while (true) {
if (xQueueReceive(updateRectQueue, &queueData, (isClose) ? portMAX_DELAY : 10000/portTICK_PERIOD_MS) == pdTRUE) {
isClose = false;
queueData.height += 4;
queueData.width += 4;
} else {
ESP_LOGI(__func__,"timeout");
queueData.height = 0;
queueData.width = 0;
skipCount = 0;
isClose = true;
}
if (true) {
xSemaphoreTake(rectMutex, portMAX_DELAY);
if (rectInfo.currFrame < rectInfo.totalFrame) {
if (skipCount < 9)
skipCount ++;
} else {
if (skipCount) skipCount --;
}
xTimerStop(xTimer, 0);
setNewRectAnimation(queueData.width,queueData.height, 40 / (skipCount + 1));
xSemaphoreGive(rectMutex);
xTimerStart(xTimer, 0);
}
vTaskDelay (200/portTICK_PERIOD_MS);
}
}
void setRect(uint8_t width, uint8_t height)
{
UpdateRectQueuePack_t sendData = {
.width = width,
.height = height,
};
ESP_LOGI(__func__,"W: %d, H: %d", width,height);
xQueueSend(updateRectQueue, &sendData, 0);
}
QueueHandle_t updateConsoleQueue;
typedef struct {
uint8_t flag;
uint16_t len;
uint8_t str[224];
} ConsoleQueuePack_t;
void consoleLogDeamon()
{
ConsoleQueuePack_t ret;
while (true) {
if (xQueueReceive(updateConsoleQueue, (void*)&ret, portMAX_DELAY) == pdTRUE) {
xSemaphoreTake(vBuf2Mutex, portMAX_DELAY);
// memset(vBuf2, 0x00, 1024);
uint8_t* recvBuf = ret.str;
uint16_t len = ret.len;
uint8_t isInvert = ret.flag;
uint8_t row = 0;
uint8_t maxRow = 0;
uint8_t column = 0;
if (len > 44) {
for (uint16_t i = 0; i < len; i++) {
if (recvBuf[i] == '\n') {
row = 0;
column++;
} else {
testPutTinyChar(vBuf2,row * 5, 6 * column, recvBuf[i], 1,isInvert);
}
maxRow = (row > maxRow) ? row : maxRow;
row++;
if (row > 20) {
column++;
row = 0;
}
}
setRect((1 + maxRow) * 5,(column + 1) * 6);
} else {
for (uint16_t i = 0; i < len; i++) {
if (recvBuf[i] == '\n') {
row = 0;
column++;
} else {
testPutChar(vBuf2,row * 8, 12 * column, recvBuf[i], 1,isInvert);
}
maxRow = (row > maxRow) ? row : maxRow;
row++;
if (row > 14) {
column++;
row = 0;
}
}
setRect((1 + maxRow) * 8,(column + 1) * 12);
}
// uint8_t width = (len / 25) ? 25 : (len % 25);
// uint8_t height = (len / 25) * 5 + 5;
// setRect(width * 5,height);
xSemaphoreGive(vBuf2Mutex);
}
}
}
void logAutoInit()
{
// for (uint16_t i = 0; i < 1024; i++) {
// if((i >> 3) % 2) {
// vBuf2[i] = 0x55;
// } else {
// vBuf2[i] = 0xAA;
// }
// }
// drawRectangle_Optimized(vBuf2,1,1,10,10,true,false,true);
updateRectQueue = xQueueCreate(3, sizeof(UpdateRectQueuePack_t));
updateConsoleQueue = xQueueCreate(2, sizeof(ConsoleQueuePack_t));
rectMutex = xSemaphoreCreateMutex();
vBuf2Mutex = xSemaphoreCreateMutex();
xTaskCreatePinnedToCore(logAuto, "logAuto", 8192, NULL, 6, &logAutoHandler,0);
xTaskCreatePinnedToCore(consoleLogDeamon, "consoleLogDeamon", 3072, NULL, 7, NULL,0);
}
void consoleLog(bool isInvert,const char *format, ...)
{
ConsoleQueuePack_t ret = {
.flag = isInvert,
};
va_list args;
va_start(args, format);
ret.len = vsnprintf((char*)ret.str, sizeof(ret.str), format, args);
va_end(args);
ret.str[223] = 0x00;
xQueueSend(updateConsoleQueue, &ret, 0);
}
h
#ifndef SSD1306_GRAPHICS_H
#define SSD1306_GRAPHICS_H
#include "esp_log.h"
#include <stdbool.h>
void consoleLog(bool isInvert,const char *format, ...);
void logAutoInit();
#endif
附件2
zpix (github开源)
#ifndef ZPIX_H
#define ZPIX_H
#include <stdint.h>
uint8_t zpix_ascii[] = {
/* [0x0020] 8x12 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* ![0x0021] 8x12 */ 0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x10,0x10,0x00,
/* "[0x0022] 8x12 */ 0x00,0x00,0x28,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* #[0x0023] 8x12 */ 0x00,0x00,0x28,0x28,0x7C,0x28,0x28,0x28,0x7C,0x28,0x28,0x00,
/* $[0x0024] 8x12 */ 0x00,0x00,0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x38,0x10,0x00,
/* %[0x0025] 8x12 */ 0x00,0x00,0x00,0x24,0x54,0x58,0x28,0x14,0x1A,0x2A,0x24,0x00,
/* &[0x0026] 8x12 */ 0x00,0x00,0x30,0x48,0x48,0x30,0x20,0x54,0x54,0x48,0x34,0x00,
/* '[0x0027] 8x12 */ 0x00,0x00,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* ([0x0028] 8x12 */ 0x00,0x08,0x10,0x10,0x20,0x20,0x20,0x20,0x20,0x10,0x10,0x08,
/* )[0x0029] 8x12 */ 0x00,0x20,0x10,0x10,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,
/* *[0x002A] 8x12 */ 0x00,0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x28,0x00,0x00,0x00,
/* +[0x002B] 8x12 */ 0x00,0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00,
/* ,[0x002C] 8x12 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08,
/* -[0x002D] 8x12 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,
/* .[0x002E] 8x12 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x00,
/* /[0x002F] 8x12 */ 0x00,0x00,0x08,0x08,0x08,0x10,0x10,0x10,0x20,0x20,0x20,0x00,
/* 0[0x0030] 8x12 */ 0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,
/* 1[0x0031] 8x12 */ 0x00,0x00,0x08,0x18,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x00,
/* 2[0x0032] 8x12 */ 0x00,0x00,0x38,0x44,0x44,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,
/* 3[0x0033] 8x12 */ 0x00,0x00,0x38,0x44,0x44,0x04,0x18,0x04,0x44,0x44,0x38,0x00,
/* 4[0x0034] 8x12 */ 0x00,0x00,0x08,0x18,0x18,0x28,0x28,0x48,0x7C,0x08,0x08,0x00,
/* 5[0x0035] 8x12 */ 0x00,0x00,0x7C,0x40,0x40,0x78,0x44,0x04,0x04,0x44,0x38,0x00,
/* 6[0x0036] 8x12 */ 0x00,0x00,0x38,0x44,0x40,0x78,0x44,0x44,0x44,0x44,0x38,0x00,
/* 7[0x0037] 8x12 */ 0x00,0x00,0x7C,0x44,0x04,0x08,0x08,0x10,0x10,0x10,0x10,0x00,
/* 8[0x0038] 8x12 */ 0x00,0x00,0x38,0x44,0x44,0x44,0x38,0x44,0x44,0x44,0x38,0x00,
/* 9[0x0039] 8x12 */ 0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x3C,0x04,0x44,0x38,0x00,
/* :[0x003A] 8x12 */ 0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x10,0x10,0x00,
/* ;[0x003B] 8x12 */ 0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x00,0x00,0x08,0x08,0x10,
/* <[0x003C] 8x12 */ 0x00,0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00,
/* =[0x003D] 8x12 */ 0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00,
/* >[0x003E] 8x12 */ 0x00,0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00,
/* ?[0x003F] 8x12 */ 0x00,0x00,0x38,0x44,0x04,0x08,0x10,0x10,0x00,0x10,0x10,0x00,
/* @[0x0040] 8x12 */ 0x00,0x00,0x38,0x44,0x4C,0x54,0x54,0x54,0x5C,0x40,0x38,0x00,
/* A[0x0041] 8x12 */ 0x00,0x00,0x10,0x10,0x28,0x28,0x28,0x38,0x44,0x44,0x44,0x00,
/* B[0x0042] 8x12 */ 0x00,0x00,0x78,0x44,0x44,0x44,0x78,0x44,0x44,0x44,0x78,0x00,
/* C[0x0043] 8x12 */ 0x00,0x00,0x38,0x44,0x44,0x40,0x40,0x40,0x44,0x44,0x38,0x00,
/* D[0x0044] 8x12 */ 0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x78,0x00,
/* E[0x0045] 8x12 */ 0x00,0x00,0x7C,0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0x7C,0x00,
/* F[0x0046] 8x12 */ 0x00,0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x40,0x00,
/* G[0x0047] 8x12 */ 0x00,0x00,0x38,0x44,0x44,0x40,0x5C,0x44,0x44,0x4C,0x34,0x00,
/* H[0x0048] 8x12 */ 0x00,0x00,0x44,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00,
/* I[0x0049] 8x12 */ 0x00,0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,
/* J[0x004A] 8x12 */ 0x00,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x44,0x44,0x38,0x00,
/* K[0x004B] 8x12 */ 0x00,0x00,0x44,0x48,0x48,0x50,0x60,0x50,0x48,0x48,0x44,0x00,
/* L[0x004C] 8x12 */ 0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00,
/* M[0x004D] 8x12 */ 0x00,0x00,0x44,0x44,0x6C,0x6C,0x54,0x54,0x44,0x44,0x44,0x00,
/* N[0x004E] 8x12 */ 0x00,0x00,0x44,0x64,0x64,0x54,0x54,0x4C,0x4C,0x44,0x44,0x00,
/* O[0x004F] 8x12 */ 0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,
/* P[0x0050] 8x12 */ 0x00,0x00,0x78,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x40,0x00,
/* Q[0x0051] 8x12 */ 0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x54,0x38,0x04,
/* R[0x0052] 8x12 */ 0x00,0x00,0x78,0x44,0x44,0x44,0x78,0x48,0x44,0x44,0x44,0x00,
/* S[0x0053] 8x12 */ 0x00,0x00,0x38,0x44,0x44,0x20,0x10,0x08,0x44,0x44,0x38,0x00,
/* T[0x0054] 8x12 */ 0x00,0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,
/* U[0x0055] 8x12 */ 0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,
/* V[0x0056] 8x12 */ 0x00,0x00,0x44,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x10,0x00,
/* W[0x0057] 8x12 */ 0x00,0x00,0x54,0x54,0x54,0x54,0x54,0x54,0x28,0x28,0x28,0x00,
/* X[0x0058] 8x12 */ 0x00,0x00,0x44,0x44,0x28,0x28,0x10,0x28,0x28,0x44,0x44,0x00,
/* Y[0x0059] 8x12 */ 0x00,0x00,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x10,0x10,0x00,
/* Z[0x005A] 8x12 */ 0x00,0x00,0x7C,0x04,0x08,0x08,0x10,0x20,0x20,0x40,0x7C,0x00,
/* [[0x005B] 8x12 */ 0x00,0x18,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x18,
/* \[0x005C] 8x12 */ 0x00,0x00,0x20,0x20,0x20,0x10,0x10,0x10,0x08,0x08,0x08,0x00,
/* ][0x005D] 8x12 */ 0x00,0x18,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x18,
/* ^[0x005E] 8x12 */ 0x00,0x00,0x18,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* _[0x005F] 8x12 */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,
/* `[0x0060] 8x12 */ 0x00,0x00,0x10,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* a[0x0061] 8x12 */ 0x00,0x00,0x00,0x00,0x78,0x04,0x04,0x3C,0x44,0x44,0x3C,0x00,
/* b[0x0062] 8x12 */ 0x00,0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x00,
/* c[0x0063] 8x12 */ 0x00,0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x40,0x44,0x38,0x00,
/* d[0x0064] 8x12 */ 0x00,0x00,0x04,0x04,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x00,
/* e[0x0065] 8x12 */ 0x00,0x00,0x00,0x00,0x38,0x44,0x44,0x7C,0x40,0x44,0x38,0x00,
/* f[0x0066] 8x12 */ 0x00,0x00,0x0C,0x10,0x10,0x3C,0x10,0x10,0x10,0x10,0x10,0x00,
/* g[0x0067] 8x12 */ 0x00,0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x3C,0x04,0x44,0x38,
/* h[0x0068] 8x12 */ 0x00,0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x44,0x00,
/* i[0x0069] 8x12 */ 0x00,0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x38,0x00,
/* j[0x006A] 8x12 */ 0x00,0x00,0x08,0x00,0x18,0x08,0x08,0x08,0x08,0x08,0x08,0x30,
/* k[0x006B] 8x12 */ 0x00,0x00,0x40,0x40,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00,
/* l[0x006C] 8x12 */ 0x00,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,
/* m[0x006D] 8x12 */ 0x00,0x00,0x00,0x00,0x68,0x54,0x54,0x54,0x54,0x54,0x54,0x00,
/* n[0x006E] 8x12 */ 0x00,0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x44,0x00,
/* o[0x006F] 8x12 */ 0x00,0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x38,0x00,
/* p[0x0070] 8x12 */ 0x00,0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40,
/* q[0x0071] 8x12 */ 0x00,0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x3C,0x04,0x04,
/* r[0x0072] 8x12 */ 0x00,0x00,0x00,0x00,0x2C,0x30,0x20,0x20,0x20,0x20,0x20,0x00,
/* s[0x0073] 8x12 */ 0x00,0x00,0x00,0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x38,0x00,
/* t[0x0074] 8x12 */ 0x00,0x00,0x10,0x10,0x3C,0x10,0x10,0x10,0x10,0x10,0x0C,0x00,
/* u[0x0075] 8x12 */ 0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x3C,0x00,
/* v[0x0076] 8x12 */ 0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x00,
/* w[0x0077] 8x12 */ 0x00,0x00,0x00,0x00,0x54,0x54,0x54,0x54,0x38,0x28,0x28,0x00,
/* x[0x0078] 8x12 */ 0x00,0x00,0x00,0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00,
/* y[0x0079] 8x12 */ 0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x60,
/* z[0x007A] 8x12 */ 0x00,0x00,0x00,0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,
/* {[0x007B] 8x12 */ 0x00,0x08,0x10,0x10,0x10,0x10,0x20,0x10,0x10,0x10,0x10,0x08,
/* |[0x007C] 8x12 */ 0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,
/* }[0x007D] 8x12 */ 0x00,0x20,0x10,0x10,0x10,0x10,0x08,0x10,0x10,0x10,0x10,0x20,
/* ~[0x007E] 8x12 */ 0x00,0x34,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
/* [0x007F] 8x12 */ 0x00,0x00,0xFF,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xFF,0x00,
};
#endif
tinyFont (自己做的,无版权)
#ifndef TINYFONT_H
#define TINYFONT_H
#include <stdint.h>
uint8_t tinyFont_ascii[] = {
/* [0x0020] 4x5 */0x00,0x00,0x00,0x00,0x00,
/* ![0x0021] 4x5 */0x20,0x20,0x20,0x00,0x20,
/* "[0x0022] 4x5 */0x50,0x50,0x00,0x00,0x00,
/* #[0x0023] 4x5 */0x50,0xF0,0xA0,0xF0,0xA0,
/* $[0x0024] 4x5 */0x70,0xA0,0x70,0x20,0xF0,
/* %[0x0025] 4x5 */0x00,0xD0,0xE0,0x70,0xB0,
/* &[0x0026] 4x5 */0x40,0xA0,0x40,0xA0,0x50,
/* '[0x0027] 4x5 */0x20,0x20,0x00,0x00,0x00,
/* ([0x0028] 4x5 */0x20,0x40,0x40,0x40,0x20,
/* )[0x0029] 4x5 */0x20,0x10,0x10,0x10,0x20,
/* *[0x002A] 4x5 */0x50,0x20,0x70,0x20,0x50,
/* +[0x002B] 4x5 */0x00,0x20,0x70,0x20,0x00,
/* ,[0x002C] 4x5 */0x00,0x00,0x20,0x20,0x40,
/* -[0x002D] 4x5 */0x00,0x00,0x70,0x00,0x00,
/* .[0x002E] 4x5 */0x00,0x00,0x20,0x20,0x00,
/* /[0x002F] 4x5 */0x00,0x10,0x20,0x40,0x00,
/* 0[0x0030] 4x5 */0x60,0xB0,0xD0,0x90,0x60,
/* 1[0x0031] 4x5 */0xC0,0x40,0x40,0x40,0xE0,
/* 2[0x0032] 4x5 */0x60,0x10,0x60,0x80,0xE0,
/* 3[0x0033] 4x5 */0x60,0x10,0x60,0x10,0x60,
/* 4[0x0034] 4x5 */0x20,0x60,0xA0,0xF0,0x20,
/* 5[0x0035] 4x5 */0xF0,0x80,0x60,0x10,0x60,
/* 6[0x0036] 4x5 */0x60,0x80,0xE0,0x90,0x60,
/* 7[0x0037] 4x5 */0xF0,0x10,0x20,0x20,0x20,
/* 8[0x0038] 4x5 */0x60,0x90,0x60,0x90,0x60,
/* 9[0x0039] 4x5 */0x60,0x90,0x70,0x10,0x60,
/* :[0x003A] 4x5 */0x20,0x20,0x00,0x20,0x20,
/* ;[0x003B] 4x5 */0x20,0x20,0x00,0x20,0x40,
/* <[0x003C] 4x5 */0x10,0x20,0x40,0x20,0x10,
/* =[0x003D] 4x5 */0x00,0x70,0x00,0x70,0x00,
/* >[0x003E] 4x5 */0x40,0x20,0x10,0x20,0x40,
/* ?[0x003F] 4x5 */0x60,0x10,0x20,0x00,0x20,
/* @[0x0040] 4x5 */0x60,0x90,0xB0,0x80,0x70,
/* A[0x0041] 4x5 */0x60,0x90,0x90,0xF0,0x90,
/* B[0x0042] 4x5 */0xE0,0x90,0xE0,0x90,0xE0,
/* C[0x0043] 4x5 */0x70,0x80,0x80,0x80,0x70,
/* D[0x0044] 4x5 */0xE0,0x90,0x90,0x90,0xE0,
/* E[0x0045] 4x5 */0xF0,0x80,0xE0,0x80,0xF0,
/* F[0x0046] 4x5 */0xF0,0x80,0xE0,0x80,0x80,
/* G[0x0047] 4x5 */0x70,0x80,0xB0,0x90,0x70,
/* H[0x0048] 4x5 */0x90,0x90,0xF0,0x90,0x90,
/* I[0x0049] 4x5 */0x70,0x20,0x20,0x20,0x70,
/* J[0x004A] 4x5 */0x30,0x10,0x10,0x90,0x60,
/* K[0x004B] 4x5 */0x90,0xA0,0xC0,0xA0,0x90,
/* L[0x004C] 4x5 */0x80,0x80,0x80,0x80,0xF0,
/* M[0x004D] 4x5 */0x90,0xF0,0xF0,0x90,0x90,
/* N[0x004E] 4x5 */0x90,0xD0,0xB0,0x90,0x90,
/* O[0x004F] 4x5 */0x60,0x90,0x90,0x90,0x60,
/* P[0x0050] 4x5 */0xE0,0x90,0x90,0xE0,0x80,
/* Q[0x0051] 4x5 */0x60,0x90,0x90,0xA0,0x50,
/* R[0x0052] 4x5 */0x60,0x90,0xE0,0xA0,0x90,
/* S[0x0053] 4x5 */0x70,0x80,0x60,0x10,0xE0,
/* T[0x0054] 4x5 */0x70,0x20,0x20,0x20,0x20,
/* U[0x0055] 4x5 */0x90,0x90,0x90,0x90,0x60,
/* V[0x0056] 4x5 */0x90,0x90,0x90,0xA0,0x40,
/* W[0x0057] 4x5 */0x90,0x90,0xF0,0xF0,0x90,
/* X[0x0058] 4x5 */0x90,0x90,0x60,0x90,0x90,
/* Y[0x0059] 4x5 */0x50,0x50,0x20,0x20,0x20,
/* Z[0x005A] 4x5 */0xF0,0x20,0x40,0x80,0xF0,
/* [[0x005B] 4x5 */0x70,0x40,0x40,0x40,0x70,
/* \[0x005C] 4x5 */0x80,0x40,0x20,0x10,0x00,
/* ][0x005D] 4x5 */0x70,0x10,0x10,0x10,0x70,
/* ^[0x005E] 4x5 */0x20,0x50,0x00,0x00,0x00,
/* _[0x005F] 4x5 */0x00,0x00,0x00,0x00,0x70,
/* `[0x0060] 4x5 */0x40,0x20,0x00,0x00,0x00,
/* a[0x0061] 4x5 */0x60,0x10,0x70,0x90,0x70,
/* b[0x0062] 4x5 */0x80,0xE0,0x90,0x90,0xE0,
/* c[0x0063] 4x5 */0x00,0x60,0x80,0x80,0x60,
/* d[0x0064] 4x5 */0x10,0x70,0x90,0x90,0x70,
/* e[0x0065] 4x5 */0x00,0x60,0xB0,0xC0,0x60,
/* f[0x0066] 4x5 */0x20,0x40,0xE0,0x40,0x40,
/* g[0x0067] 4x5 */0x70,0x90,0x70,0x10,0x60,
/* h[0x0068] 4x5 */0x80,0xE0,0x90,0x90,0x90,
/* i[0x0069] 4x5 */0x20,0x00,0x20,0x20,0x20,
/* j[0x006A] 4x5 */0x20,0x00,0x60,0x20,0xC0,
/* k[0x006B] 4x5 */0x80,0xB0,0xC0,0xA0,0x90,
/* l[0x006C] 4x5 */0x40,0x40,0x40,0x40,0x20,
/* m[0x006D] 4x5 */0x00,0x90,0xF0,0x90,0x90,
/* n[0x006E] 4x5 */0x00,0x60,0x90,0x90,0x90,
/* o[0x006F] 4x5 */0x00,0x60,0x90,0x90,0x60,
/* p[0x0070] 4x5 */0xE0,0x90,0x90,0xE0,0x80,
/* q[0x0071] 4x5 */0x70,0x90,0x90,0x70,0x10,
/* r[0x0072] 4x5 */0x30,0x40,0x40,0x40,0x40,
/* s[0x0073] 4x5 */0x60,0x80,0x60,0x10,0x60,
/* t[0x0074] 4x5 */0x40,0xE0,0x40,0x40,0x30,
/* u[0x0075] 4x5 */0x00,0x90,0x90,0x90,0x60,
/* v[0x0076] 4x5 */0x00,0x90,0x90,0xA0,0x40,
/* w[0x0077] 4x5 */0x00,0x90,0x90,0xF0,0x90,
/* x[0x0078] 4x5 */0x00,0x50,0x20,0x20,0x50,
/* y[0x0079] 4x5 */0x50,0x50,0x30,0x10,0x60,
/* z[0x007A] 4x5 */0xF0,0x10,0x20,0x40,0xF0,
/* {[0x007B] 4x5 */0x30,0x20,0x40,0x20,0x30,
/* |[0x007C] 4x5 */0x20,0x20,0x20,0x20,0x20,
/* }[0x007D] 4x5 */0x60,0x20,0x10,0x20,0x60,
/* ~[0x007E] 4x5 */0x00,0x40,0xF0,0x20,0x00,
/* [0x007F] 4x5 */0x00,0x00,0x00,0x00,0x00,
};
#endif
Comments NOTHING