从0开始使用面对对象C语言搭建一个基于OLED的图形显示框架(基础组件实现)

news2025/1/31 20:35:01

目录

基础组件实现

如何将图像和文字显示到OLED上

如何绘制图像

如何绘制文字

如何获取字体?

如何正确的访问字体

如何抽象字体

如何绘制字符串

绘制方案

文本绘制

更加方便的绘制

字体附录

ascii 6x8字体

ascii 8 x 16字体


基础组件实现

我们现在离手搓一个动态的多级菜单越来越近了。终于!我们来到了最基础的组件实现,我们现在搓的东西的代码库放到了:MCU_Libs/OLED/library/Graphic/widgets/base at main · Charliechen114514/MCU_Libs (github.com)当中,也就是手搓图像显示和文字显示。如果你对这篇博客所属的集合有任何疑问,可以到从0开始使用面对对象C语言搭建一个基于OLED的图形显示框架-CSDN博客阅读。

如何将图像和文字显示到OLED上

三个字:画出来!带上一个KeysKing大跌手搓的取码地址:波特律动LED字模生成器 (baud-dance.com),实际上,你的悟性足够高,已经可以离开这篇博客自己继续手搓了。

好吧,你继续往下看了,那我就详细的好好说明。

如何绘制图像

绘制图像之前,我们还要遵循老步骤,思考一下如何设计我们的抽象。

我们如何描述一个给定的图像呢?我们可能着急于描述这个图像表达了什么,也就是图像的资源,在OLED中,我们习惯于阐述为一个字节的数组,这个数组描述了我们的图像,只要把它传递上去,一个图像就显示出来我们可以看了。

但是还是有问题:你这个图像放到哪里呢?画的要多大呢?这就是我们需要设计一个结构体抽象的原因了。请看VCR:

typedef struct __CCGraphic_Image{
    CCGraphic_Point point;
    CCGraphic_Size  image_size;
    uint8_t*        sources_register;
}CCGraphic_Image;

关于CCGraphic_Size,并不复杂,可以到MCU_Libs/OLED/library/Graphic/widgets/common/CCGraphic_Size at main · Charliechen114514/MCU_Libs (github.com)中看到源码,实际上就是宽和高的一个封装,没什么大不了的。

此外,我们对图像的操作就是绘制了

void CCGraphicWidget_init_image(
    CCGraphic_Image*    image,
    CCGraphic_Point     tl_point,
    CCGraphic_Size      image_size,
    uint8_t*      sources_register
);
​
void CCGraphicWidget_draw_image(
    CCDeviceHandler*    handler,
    CCGraphic_Image*    image
);

出乎你意料的是。绘制图像远远比你想象的简单的多

#include "Graphic/widgets/base/CCGraphic_Image/CCGraphic_Image.h"
#include "Graphic/CCGraphic_device_adapter.h"
void CCGraphicWidget_init_image(
    CCGraphic_Image*    image,
    CCGraphic_Point     tl_point,
    CCGraphic_Size      image_size,
    uint8_t*      sources_register
)
{
    image->image_size = image_size;
    image->point = tl_point;
    image->sources_register = sources_register;
}
​
void CCGraphicWidget_draw_image(
    CCDeviceHandler*    handler,
    CCGraphic_Image*    image
)
{
    if(!image->sources_register) return;
    handler->operations.draw_area_device_function(
        handler, image->point.x, image->point.y,
        image->image_size.width, image->image_size.height, image->sources_register
    );
}

我们直接使用设备draw_area的方法,将图像资源传递上去了。

CCGraphicWidget_draw_image -> draw_area_device_function(draw_area_device_oled) -> oled_helper_draw_area

你看,干净利落!完事。

如何绘制文字

现在这个事情就需要深思熟虑了,设计到文字,就必然需要考虑字体大小,以及解析字符串的问题。笔者这里没有实现UTF-8字符的打印实现,但是笔者提示你,仍然是画出来字符。让我们看看该咋做。

typedef struct __CCGraphic_TextHandle{
    char*               sources_borrowed;       // 这个就是所持有的字体资源指针
    CCGraphic_Point     tl_point;               // 这个是所占有的左上角的绘制起点
    CCGraphic_Point     indexed_point;          // 这个是现在的绘制指针,表明现在我们绘制到了那个地方
    CCGraphic_Size      TexthandleSize;         // 整个Text所在的BoundingRect大小
    Ascii_Font_Size     font_size;              // 字体多大?
}CCGraphic_AsciiTextItem;
如何获取字体?

关于ASCII字体的获取,笔者放到了附录里,值得一提的是,江科大的OLED_Data.h中对字体数组的初始化时不严谨的,不规范的,正确的初始化方案已经放到了附录,不再赘述。

如何正确的访问字体

C语言中,有一个著名的关键字叫extern,他随了汇编语言的关键字extern,在所属权层面上表达的同static完全相反,即这个资源的定义需要到其他文件中寻找。所以,当我们想要引用字体(这个字体被存放到了其他的C源文件中)的时候,只需要手动的extern一下,而且确保资源被正确的编译进来就OK了。

extern const uint8_t ascii6x8_sources[][6];
如何抽象字体

很简单,虽然说正常而言只需要抽象一个TextFont结构体即可,但是笔者认为这里更多看重的是方法,而且,没有必要对用户暴露一个Font结构体,选择结构体更加不如暴露的是一个枚举和公开的方法。

#ifndef CCGraphic_TextConfig_H
#define CCGraphic_TextConfig_H
#include "Graphic/config/CCGraphic_config.h"
#include "Graphic/CCGraphic_common.h"
#include "Graphic/widgets/common/CCGraphic_Size/CCGraphic_Size.h"
/*
    current version we only support
    6x8 and 8x16. to register more, u should
    provide the source and implement the functions
*/
typedef enum {
#if ENABLE_ASCII_6x8_SOURCES
    ASCII_6x8,
#endif
​
#if ENABLE_ASCII_8x16_SOURCES
    ASCII_8x16,
#endif
    NO_ASCII_SIZE 
}Ascii_Font_Size;
​
typedef enum {
    Unicode_16x16
}Unicode_Font_Size;
​
#define UNSUPPORTIVE_FONT_SOURCE    ((void*)0)
​
/**
 * @brief Selects the font data array based on the specified font size.
 *
 * This function receives an `Ascii_Font_Size` value 
 * and returns a pointer to the corresponding font data array. 
 * The function helps in selecting
 * the appropriate font data for display purposes, allowing for different
 * font sizes (e.g., 8x16, 6x8, etc.).
 *
 * @param s The font size to be selected 
 *          (from the `Ascii_Font_Size` enum).
 * @param ch the character wanna display
 * @return  A pointer to the font data array corresponding to the selected font size.
 *          If an invalid font size is passed, 
 *          the function returns UNSUPPORTIVE_FONT_SOURCE.
 */
uint8_t*        __select_from_ascii_font_size(const Ascii_Font_Size s, const char ch);
​
​
CCGraphic_Size  __fetch_font_size(const Ascii_Font_Size s);
​
#endif
#include "Graphic/widgets/base/CCGraphic_TextItem/CCGraphic_TextConfig.h"
​
extern const uint8_t ascii8x16_sources[][16];
extern const uint8_t ascii6x8_sources[][6];
​
uint8_t* __select_from_ascii_font_size(
    const Ascii_Font_Size s, const char ch)
{
    switch(s)
    {
#if ENABLE_ASCII_6x8_SOURCES
        case ASCII_6x8:
            return (uint8_t*)(ascii6x8_sources[ch - ' ']);
#endif
#if ENABLE_ASCII_8x16_SOURCES       
        case ASCII_8x16:
            return (uint8_t*)(ascii8x16_sources[ch - ' ']);
#endif
        /* 
            To programmers, if new ascii like sources is
            registered, please implement follows
        */
        default:
            return UNSUPPORTIVE_FONT_SOURCE;
    }
}
​
CCGraphic_Size  __fetch_font_size(const Ascii_Font_Size s)
{
    CCGraphic_Size size = {0, 0};
    switch(s)
    {
#if ENABLE_ASCII_6x8_SOURCES
        case ASCII_6x8:
            size.height     =   8;
            size.width      =   6;
            break;
#endif
​
#if ENABLE_ASCII_8x16_SOURCES  
        case ASCII_8x16:
            size.height     =   16;
            size.width      =   8;
            break;
#endif
        default:
            break;
    }
    return size;
}

题外话:使用编译宏控制资源编译:GCC是一个智能的编译器,对于任何没有使用到的资源,概不参与编译,所以,对于使用GCC的编译器,只需要确保自己不额外使用其他资源,就不会将冗余的C符号纳入编译。

但还是那句话,为了确保语义更加清晰,仍然使用控制宏对资源进行编译控制和符号控制,让自己的代码语义更加的明确,是一件事半功倍的举措

如何绘制字符串

绘制字符串是一个复杂的活。但是在那之前,把杂活做了。

#include "Graphic/widgets/base/CCGraphic_TextItem/CCGraphic_TextItem.h"
#include "Graphic/widgets/base/CCGraphic_TextItem/CCGraphic_TextConfig.h"
#include "Graphic/widgets/base/CCGraphic_Image/CCGraphic_Image.h"
#include "Graphic/CCGraphic_device_adapter.h"
#include <string.h>
​
/**
 * 初始化一个ASCII文本项。
 * @param item 指向CCGraphic_AsciiTextItem的指针。
 * @param tl_point 文本项的左上角起始坐标。
 * @param textHandleSize 文本项的尺寸信息(宽度和高度)。
 * @param text_size 字体大小枚举类型。
 */
void CCGraphicWidget_init_AsciiTextItem(
    CCGraphic_AsciiTextItem* item,
    CCGraphic_Point tl_point,
    CCGraphic_Size textHandleSize,
    Ascii_Font_Size text_size
)
{
    item->font_size = text_size;
    item->sources_borrowed = "";  // 初始化为空字符串,表示未设置内容。
    item->tl_point = tl_point;
    item->indexed_point = tl_point;
    item->TexthandleSize = textHandleSize;
}
​
/**
 * 设置ASCII文本项的内容。
 * @param item 指向CCGraphic_AsciiTextItem的指针。
 * @param text 待设置的文本内容字符串。
 */
void CCGraphicWidget_AsciiTextItem_setAsciiText(
    CCGraphic_AsciiTextItem* item,
    char* text
)
{
    item->sources_borrowed = text;
}
​
/**
 * 设置ASCII文本项的索引点。
 * @param item 指向CCGraphic_AsciiTextItem的指针。
 * @param p 索引点的指针。
 */
void CCGraphicWidget_AsciiTextItem_setIndexedPoint(
    CCGraphic_AsciiTextItem* item,
    CCGraphic_Point* p
)
{
    item->indexed_point = *p;
}
​
/**
 * 重新定位ASCII文本项。
 * @param item 指向CCGraphic_AsciiTextItem的指针。
 * @param tl_point 新的左上角起始坐标。
 * @param textHandleSize 新的尺寸信息(宽度和高度)。
 */
void CCGraphicWidget_AsciiTextItem_relocate(
    CCGraphic_AsciiTextItem* item,
    CCGraphic_Point tl_point,
    CCGraphic_Size textHandleSize
)
{
    // 这个函数的一个重要的目的就是重定位文本框,为之后的文本显示做铺垫。
    item->tl_point = tl_point;
    item->TexthandleSize = textHandleSize;
}

绘制一个字符串本身就是绘制一串字符,掌握整个原理,事情就会变得非常简单,我们线讨论如何绘制字符本身

/**
 * 绘制ASCII字符到设备。
 * @param device_handle 设备句柄。
 * @param borrowing_image 临时用于绘制的图像对象。
 * @param ch 要绘制的字符。
 * @param size 字体大小枚举类型。
 */
static void __pvt_draw_char_each(
    CCDeviceHandler* device_handle, 
    CCGraphic_Image* borrowing_image, 
    const char ch, Ascii_Font_Size size
)
{
    borrowing_image->image_size = __fetch_font_size(size);
    uint8_t* ascii = __select_from_ascii_font_size(size, ch);
    borrowing_image->sources_register = ascii;
    CCGraphicWidget_draw_image(device_handle, borrowing_image);
#if CCGraphic_TextDebug
    device_handle->operations.update_device_function(device_handle);
#endif
}

我们将一个字符的字体绘制文件放置到Image中,所以我强调:字符是画出来的

设计缺陷:注意到,我这里并没有设置绘制的位置,这是因为这件事情在上层做好了,所以我也在参变量中警示自己:整个变量是部分初始化的。

绘制方案

我们绘制的时候,更多会去在乎:是在之前的文本基础上继续绘制呢?还是换一行继续绘制,还是直接清空文本重新绘制?为了防止反复的刷新,笔者设计了三个函数完成整个工作。

首先,设置游标点:

CCGraphic_Point     indexed_point;          // 这个是现在的绘制指针,表明现在我们绘制到了那个地方

整个在Text的结构体中,不由用户直接设置。

下面,就是依赖设置:

/**
 * 判断当前字符是否需要换行。
 * @param device_handle 设备句柄。
 * @param brpoint 右下角边界点。
 * @param cur_draw_p 当前绘制点的指针。
 * @param s 字体大小枚举类型。
 * @return 如果需要换行,返回非零值;否则返回零。
 */
static uint8_t inline __pvt_should_be_next_line(
    CCDeviceHandler* device_handle,
    CCGraphic_Point* brpoint,
    CCGraphic_Point* cur_draw_p, Ascii_Font_Size s 
)
{
    return cur_draw_p->x + 
        (int16_t)(1.5 * __fetch_font_size(s).width) >= brpoint->x;
}
/**
 * 计算有效的右下角点。
 * @param device_handle 设备句柄。
 * @param size 文本项的尺寸信息。
 * @param tl 文本项的左上角起始点。
 * @return 计算后的右下角点。
 */
static CCGraphic_Point inline __pvt_fetch_valid_final_point(
    CCDeviceHandler* device_handle,
    CCGraphic_Size* size, CCGraphic_Point* tl
) 
{
    CCGraphic_Point br;
    int16_t device_width = 0;
    device_handle->operations.property_function(
        device_handle, &device_width, CommonProperty_WIDTH
    );
    int16_t device_height = 0;
    device_handle->operations.property_function(
        device_handle, &device_height, CommonProperty_HEIGHT
    );
    // 上面我们获取了设备的宽高,现在我们开获取最大的合法右下角的点
    br.x = tl->x + size->width;
    br.y = tl->y + size->height;
    if(device_width < br.x) { br.x = device_width; }
    if(device_height < br.y) { br.y = device_height; }
    return br;
}
文本绘制

绘制文本的本质是绘图。这一点务必注意。下面的整个函数实现了自动的文本换行!

/**
 * 绘制ASCII文本项。
 * @param device_handle 设备句柄,用于控制绘制设备。
 * @param item 要绘制的ASCII文本项,包含文本内容、位置及尺寸信息。
 */
void CCGraphicWidget_drawAsciiTextItem(
    CCDeviceHandler* device_handle,
    CCGraphic_AsciiTextItem* item)
{
    // 如果文本内容为空,直接返回,不进行绘制。
    if(strcmp(item->sources_borrowed, "") == 0) {
        return;
    }
​
    // 定义用于绘制的图像结构体。
    CCGraphic_Image handle_draw_image;
​
    // 初始化绘制的起始点为当前索引位置。
    CCGraphic_Point draw_tl_point = item->indexed_point;
​
    // 获取当前文本字体的尺寸(宽度和高度)。
    const Ascii_Font_Size font_size = item->font_size;
    const CCGraphic_Size size = __fetch_font_size(font_size);
    const SizeBaseType font_width = size.width;
    const SizeBaseType font_height = size.height;
​
    // 计算文本绘制区域的有效右下角点(即绘制边界)。
    CCGraphic_Point br = __pvt_fetch_valid_final_point(
        device_handle, &(item->TexthandleSize), &(item->tl_point) 
    );
​
    // 定义x方向和y方向的字符偏移量,用于逐字符定位绘制。
    uint8_t offseterx = 0;
    uint8_t offsetery = 0;
​
    // 遍历文本中的每个字符并绘制。
    for(uint8_t i = 0; item->sources_borrowed[i] != '\0'; i++) {
        // 计算当前字符的绘制位置。
        draw_tl_point.x = item->indexed_point.x + offseterx * font_width;
        draw_tl_point.y = item->indexed_point.y + offsetery * font_height;
​
        // 设置图像绘制的左上角点。
        handle_draw_image.point = draw_tl_point;
​
        // 绘制当前字符到目标设备上。
        __pvt_draw_char_each(
            device_handle, 
            &handle_draw_image, 
            item->sources_borrowed[i], 
            item->font_size
        );
​
        // 判断是否需要换行绘制。
        if(__pvt_should_be_next_line(device_handle, &br, &draw_tl_point, font_size)) {
            // 如果需要换行,将x偏移量归零,并增加y方向的行数。
            offseterx = 0;
            offsetery++;
            // 重置x方向的起点位置为文本的左上角点。
            item->indexed_point.x = item->tl_point.x;
        } else {
            // 否则继续绘制当前行的下一个字符。
            offseterx++;
        }
    }
​
    // 更新文本项的索引点位置为最后一个字符的右侧位置。
    item->indexed_point = draw_tl_point;
    item->indexed_point.x += font_width;
}
更加方便的绘制

当然,还可以为了之后的组件方便生成一个返回绘制点的方便函数:

/**
 * 绘制ASCII文本项,并返回绘制后的点。
 * @param device_handle 设备句柄,用于控制绘制设备。
 * @param item 要绘制的ASCII文本项,包含文本内容、位置及尺寸信息。
 * @param method 文本追加方式,指示绘制后是否换行或连续追加。
 * @return 绘制后的坐标点,表示下一个绘制位置。
 */
CCGraphic_Point CCGraphicWidget_drawAsciiTextItem_with_finPoint(
    CCDeviceHandler* device_handle,
    CCGraphic_AsciiTextItem* item,
    AppendMethod method
)
{
    // 如果文本内容为空,直接返回文本的初始左上角点。
    if(strcmp(item->sources_borrowed, "") == 0) {
        return item->tl_point;
    }
​
    // 定义绘制图像和绘制位置。
    CCGraphic_Image handle_draw_image;
    CCGraphic_Point draw_tl_point = item->indexed_point;
​
    // 获取字体尺寸。
    const Ascii_Font_Size font_size = item->font_size;
    const CCGraphic_Size size = __fetch_font_size(font_size);
    const SizeBaseType font_width = size.width;
    const SizeBaseType font_height = size.height;
​
    // 获取有效绘制区域的右下角点。
    CCGraphic_Point br = __pvt_fetch_valid_final_point(
        device_handle, &(item->TexthandleSize), &(item->tl_point) 
    );
​
    // x方向和y方向的偏移量,用于字符定位。
    uint8_t offseterx = 0;
    uint8_t offsetery = 0;
​
    // 遍历文本中的每个字符。
    for(uint8_t i = 0; item->sources_borrowed[i] != '\0'; i++) {
        // 计算当前字符的绘制位置。
        draw_tl_point.x = item->indexed_point.x + offseterx * font_width;
        draw_tl_point.y = item->indexed_point.y + offsetery * font_height;
​
        // 设置图像的绘制点。
        handle_draw_image.point = draw_tl_point;
​
        // 绘制当前字符。
        __pvt_draw_char_each(
            device_handle, 
            &handle_draw_image, 
            item->sources_borrowed[i], 
            item->font_size
        );
​
        // 判断是否需要换行绘制。
        if(__pvt_should_be_next_line(device_handle, &br, &draw_tl_point, font_size)) {
            offseterx = 0; // x方向偏移归零
            offsetery++;   // y方向增加一行
            item->indexed_point.x = item->tl_point.x; // 重置x起点
        } else {
            offseterx++; // 继续绘制当前行的下一个字符
        }
    }
​
    // 更新文本项的索引点为最后一个字符位置。
    item->indexed_point = draw_tl_point;
    item->indexed_point.x += font_width;
​
    // 根据文本追加方式调整返回的最终坐标点。
    switch(method) {
        case CCGraphic_AsciiTextItem_AppendNextLine:
            // 追加到下一行开始位置。
            draw_tl_point.x = item->tl_point.x;
            draw_tl_point.y += font_height;
            break;
        case CCGraphic_AsciiTextItem_AppendContinously:
            // 继续追加到同一行的下一个位置。
            draw_tl_point.x += font_width;
            break;
        default:
            break;
    }
​
    // 返回绘制完成后的坐标点。
    return draw_tl_point;
}
​
​
/**
 * 获取当前文本项的附加点(追加位置)。
 * @param item ASCII文本项。
 * @return 当前索引位置坐标点。
 */
CCGraphic_Point CCGraphicWidget_AsciiTextItem_on_append_point(CCGraphic_AsciiTextItem* item)
{
    return item->indexed_point;
}
​
/**
 * 获取文本项换行后的新行起点。
 * @param item ASCII文本项。
 * @return 新行的起始坐标点。
 */
CCGraphic_Point CCGraphicWidget_AsciiTextItem_on_newLine_point(CCGraphic_AsciiTextItem* item)
{
    CCGraphic_Point draw_tl_point;
    draw_tl_point.x = item->tl_point.x;
    const CCGraphic_Size size = __fetch_font_size(item->font_size);
    draw_tl_point.y = item->indexed_point.y + size.height;
    return draw_tl_point;    
}

为什么要给函数标记为inline

对于现代的编译器,inline只是起到了一种劝说的作用,他将调用转换为直接插入函数的汇编代码,节约了流水线刷新和代码跳转,这样来看,是一个不错的关键字,但是,一个过于庞大的函数标记为inline是一个无效的举措(几乎没有节约开销,所以编译器有的时候不会理睬,对于GCC,尝试使用force_inline标记符强制内联),现代的inline更加像是一种允许重复定义的关键字(因为他直接将汇编代码插入到了调用者上,符号直接被替换消失了)

字体附录

或者,你可以访问Github地址:MCU_Libs/OLED/library/Graphic/resources/default at main · Charliechen114514/MCU_Libs (github.com)

ascii 6x8字体

#include "Graphic/CCGraphic_common.h"
#include "Graphic/config/CCGraphic_config.h"
//  This is an array of font data for a 
//  6x8 OLED display using 6x8 pixel font representation.
//  Each character in this font set is defined by an 
//  6x8 pixel matrix (8 pixels wide, 16 pixels high).
​
/* 
    sources should be externed copy this for 
    the usage in application level
*/
​
// ---------------------------------------------
// extern const uint8_t ascii6x8_sources[][6];
// ---------------------------------------------
#if ENABLE_ASCII_6x8_SOURCES
const uint8_t ascii6x8_sources[][6] = 
{
    {0x00,0x00,0x00,0x00,0x00,0x00}, // 0
    {0x00,0x00,0x00,0x2F,0x00,0x00}, // ! 1
    {0x00,0x00,0x07,0x00,0x07,0x00}, // " 2
    {0x00,0x14,0x7F,0x14,0x7F,0x14}, // # 3
    {0x00,0x24,0x2A,0x7F,0x2A,0x12}, // $ 4
    {0x00,0x23,0x13,0x08,0x64,0x62}, // % 5
    {0x00,0x36,0x49,0x55,0x22,0x50}, // & 6
    {0x00,0x00,0x00,0x07,0x00,0x00}, // ' 7
    {0x00,0x00,0x1C,0x22,0x41,0x00}, // ( 8
    {0x00,0x00,0x41,0x22,0x1C,0x00}, // ) 9
    {0x00,0x14,0x08,0x3E,0x08,0x14}, // * 10
    {0x00,0x08,0x08,0x3E,0x08,0x08}, // + 11
    {0x00,0x00,0x00,0xA0,0x60,0x00}, // , 12
    {0x00,0x08,0x08,0x08,0x08,0x08}, // - 13
    {0x00,0x00,0x60,0x60,0x00,0x00}, // . 14
    {0x00,0x20,0x10,0x08,0x04,0x02}, // / 15
    {0x00,0x3E,0x51,0x49,0x45,0x3E}, // 0 16
    {0x00,0x00,0x42,0x7F,0x40,0x00}, // 1 17
    {0x00,0x42,0x61,0x51,0x49,0x46}, // 2 18
    {0x00,0x21,0x41,0x45,0x4B,0x31}, // 3 19
    {0x00,0x18,0x14,0x12,0x7F,0x10}, // 4 20
    {0x00,0x27,0x45,0x45,0x45,0x39}, // 5 21
    {0x00,0x3C,0x4A,0x49,0x49,0x30}, // 6 22
    {0x00,0x01,0x71,0x09,0x05,0x03}, // 7 23
    {0x00,0x36,0x49,0x49,0x49,0x36}, // 8 24
    {0x00,0x06,0x49,0x49,0x29,0x1E}, // 9 25
    {0x00,0x00,0x36,0x36,0x00,0x00}, // : 26
    {0x00,0x00,0x56,0x36,0x00,0x00}, // ; 27
    {0x00,0x08,0x14,0x22,0x41,0x00}, // < 28
    {0x00,0x14,0x14,0x14,0x14,0x14}, // = 29
    {0x00,0x00,0x41,0x22,0x14,0x08}, // > 30
    {0x00,0x02,0x01,0x51,0x09,0x06}, // ? 31
    {0x00,0x3E,0x49,0x55,0x59,0x2E}, // @ 32
    {0x00,0x7C,0x12,0x11,0x12,0x7C}, // A 33
    {0x00,0x7F,0x49,0x49,0x49,0x36}, // B 34
    {0x00,0x3E,0x41,0x41,0x41,0x22}, // C 35
    {0x00,0x7F,0x41,0x41,0x22,0x1C}, // D 36
    {0x00,0x7F,0x49,0x49,0x49,0x41}, // E 37
    {0x00,0x7F,0x09,0x09,0x09,0x01}, // F 38
    {0x00,0x3E,0x41,0x49,0x49,0x7A}, // G 39
    {0x00,0x7F,0x08,0x08,0x08,0x7F}, // H 40
    {0x00,0x00,0x41,0x7F,0x41,0x00}, // I 41
    {0x00,0x20,0x40,0x41,0x3F,0x01}, // J 42
    {0x00,0x7F,0x08,0x14,0x22,0x41}, // K 43
    {0x00,0x7F,0x40,0x40,0x40,0x40}, // L 44
    {0x00,0x7F,0x02,0x0C,0x02,0x7F}, // M 45
    {0x00,0x7F,0x04,0x08,0x10,0x7F}, // N 46
    {0x00,0x3E,0x41,0x41,0x41,0x3E}, // O 47
    {0x00,0x7F,0x09,0x09,0x09,0x06}, // P 48
    {0x00,0x3E,0x41,0x51,0x21,0x5E}, // Q 49
    {0x00,0x7F,0x09,0x19,0x29,0x46}, // R 50
    {0x00,0x46,0x49,0x49,0x49,0x31}, // S 51
    {0x00,0x01,0x01,0x7F,0x01,0x01}, // T 52
    {0x00,0x3F,0x40,0x40,0x40,0x3F}, // U 53
    {0x00,0x1F,0x20,0x40,0x20,0x1F}, // V 54
    {0x00,0x3F,0x40,0x38,0x40,0x3F}, // W 55
    {0x00,0x63,0x14,0x08,0x14,0x63}, // X 56
    {0x00,0x07,0x08,0x70,0x08,0x07}, // Y 57
    {0x00,0x61,0x51,0x49,0x45,0x43}, // Z 58
    {0x00,0x00,0x7F,0x41,0x41,0x00}, // [ 59
    {0x00,0x02,0x04,0x08,0x10,0x20}, // \ 60
    {0x00,0x00,0x41,0x41,0x7F,0x00}, // ] 61
    {0x00,0x04,0x02,0x01,0x02,0x04}, // ^ 62
    {0x00,0x40,0x40,0x40,0x40,0x40}, // _ 63
    {0x00,0x00,0x01,0x02,0x04,0x00}, // ` 64
    {0x00,0x20,0x54,0x54,0x54,0x78}, // a 65
    {0x00,0x7F,0x48,0x44,0x44,0x38}, // b 66
    {0x00,0x38,0x44,0x44,0x44,0x20}, // c 67
    {0x00,0x38,0x44,0x44,0x48,0x7F}, // d 68
    {0x00,0x38,0x54,0x54,0x54,0x18}, // e 69
    {0x00,0x08,0x7E,0x09,0x01,0x02}, // f 70
    {0x00,0x18,0xA4,0xA4,0xA4,0x7C}, // g 71
    {0x00,0x7F,0x08,0x04,0x04,0x78}, // h 72
    {0x00,0x00,0x44,0x7D,0x40,0x00}, // i 73
    {0x00,0x40,0x80,0x84,0x7D,0x00}, // j 74
    {0x00,0x7F,0x10,0x28,0x44,0x00}, // k 75
    {0x00,0x00,0x41,0x7F,0x40,0x00}, // l 76
    {0x00,0x7C,0x04,0x18,0x04,0x78}, // m 77
    {0x00,0x7C,0x08,0x04,0x04,0x78}, // n 78
    {0x00,0x38,0x44,0x44,0x44,0x38}, // o 79
    {0x00,0xFC,0x24,0x24,0x24,0x18}, // p 80
    {0x00,0x18,0x24,0x24,0x18,0xFC}, // q 81
    {0x00,0x7C,0x08,0x04,0x04,0x08}, // r 82
    {0x00,0x48,0x54,0x54,0x54,0x20}, // s 83
    {0x00,0x04,0x3F,0x44,0x40,0x20}, // t 84
    {0x00,0x3C,0x40,0x40,0x20,0x7C}, // u 85
    {0x00,0x1C,0x20,0x40,0x20,0x1C}, // v 86
    {0x00,0x3C,0x40,0x30,0x40,0x3C}, // w 87
    {0x00,0x44,0x28,0x10,0x28,0x44}, // x 88
    {0x00,0x1C,0xA0,0xA0,0xA0,0x7C}, // y 89
    {0x00,0x44,0x64,0x54,0x4C,0x44}, // z 90
    {0x00,0x00,0x08,0x7F,0x41,0x00}, // { 91
    {0x00,0x00,0x00,0x7F,0x00,0x00}, // | 92
    {0x00,0x00,0x41,0x7F,0x08,0x00}, // } 93
    {0x00,0x08,0x04,0x08,0x10,0x08}, // ~ 94
};
#endif

ascii 8 x 16字体

#include "Graphic/CCGraphic_common.h"
#include "Graphic/config/CCGraphic_config.h"
//  This is an array of font data for a 
//  8x16 OLED display using 8x16 pixel font representation.
//  Each character in this font set is defined by an 
//  8x16 pixel matrix (8 pixels wide, 16 pixels high).
​
/* 
    sources should be externed copy this for 
    the usage in application level
*/
​
// ---------------------------------------------
// extern const uint8_t ascii8x16_sources[][16];
// ---------------------------------------------
#if ENABLE_ASCII_8x16_SOURCES
const uint8_t ascii8x16_sources[][16] =
{
    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},//   0
    {0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00},// ! 1
    {0x00,0x16,0x0E,0x00,0x16,0x0E,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},// " 2
    {0x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,
    0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00},// # 3
    {0x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,
    0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00},// $ 4
    {0xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,
    0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00},// % 5
    {0x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,
    0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10},// & 6
    {0x00,0x00,0x00,0x16,0x0E,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},// ' 7
    {0x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,
    0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00},// ( 8
    {0x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,
    0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00},// ) 9
    {0x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,
    0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00},// * 10
    {0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,
    0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00},// + 11
    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0xB0,0x70,0x00,0x00,0x00,0x00,0x00},// , 12
    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01},// - 13
    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00},// . 14
    {0x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,
    0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00},// / 15
    {0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,
    0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00},// 0 16
    {0x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,
    0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},// 1 17
    {0x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,
    0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00},// 2 18
    {0x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,
    0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00},// 3 19
    {0x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,
    0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00},// 4 20
    {0x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,
    0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00},// 5 21
    {0x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,
    0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00},// 6 22
    {0x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,
    0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00},// 7 23
    {0x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,
    0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00},// 8 24
    {0x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,
    0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00},// 9 25
    {0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,
    0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00},// : 26
    {0x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,
    0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00},// ; 27
    {0x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,
    0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00},// < 28
    {0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,
    0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00},// = 29
    {0x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,
    0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00},// > 30
    {0x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,
    0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00},// ? 31
    {0xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,
    0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00},// @ 32
    {0x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,
    0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20},// A 33
    {0x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,
    0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00},// B 34
    {0xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,
    0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00},// C 35
    {0x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,
    0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00},// D 36
    {0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,
    0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00},// E 37
    {0x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,
    0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00},// F 38
    {0xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,
    0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00},// G 39
    {0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,
    0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20},// H 40
    {0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,
    0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},// I 41
    {0x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,
    0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00},// J 42
    {0x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,
    0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00},// K 43
    {0x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,
    0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00},// L 44
    {0x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,
    0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00},// M 45
    {0x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,
    0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00},// N 46
    {0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,
    0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00},// O 47
    {0x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,
    0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00},// P 48
    {0xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,
    0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00},// Q 49
    {0x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,
    0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20},// R 50
    {0x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,
    0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00},// S 51
    {0x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,
    0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00},// T 52
    {0x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,
    0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00},// U 53
    {0x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,
    0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00},// V 54
    {0xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,
    0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00},// W 55
    {0x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,
    0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20},// X 56
    {0x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,
    0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00},// Y 57
    {0x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,
    0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00},// Z 58
    {0x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,
    0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00},// [ 59
    {0x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00},// \ 60
    {0x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,
    0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00},// ] 61
    {0x00,0x20,0x10,0x08,0x04,0x08,0x10,0x20,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},// ^ 62
    {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80},// _ 63
    {0x00,0x02,0x04,0x08,0x00,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00},// ` 64
    {0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,
    0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20},// a 65
    {0x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,
    0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00},// b 66
    {0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,
    0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00},// c 67
    {0x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,
    0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20},// d 68
    {0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,
    0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00},// e 69
    {0x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,
    0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},// f 70
    {0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,
    0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00},// g 71
    {0x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,
    0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20},// h 72
    {0x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,
    0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},// i 73
    {0x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,
    0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00},// j 74
    {0x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,
    0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00},// k 75
    {0x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,
    0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00},// l 76
    {0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,
    0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F},// m 77
    {0x00,0x80,0x80,0x00,0x80,0x80,0x00,0x00,
    0x00,0x20,0x3F,0x21,0x00,0x20,0x3F,0x20},// n 78
    {0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,
    0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00},// o 79
    {0x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,
    0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00},// p 80
    {0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,
    0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80},// q 81
    {0x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,
    0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00},// r 82
    {0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,
    0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00},// s 83
    {0x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,
    0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00},// t 84
    {0x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,
    0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20},// u 85
    {0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,
    0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00},// v 86
    {0x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,
    0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00},// w 87
    {0x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,
    0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00},// x 88
    {0x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,
    0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00},// y 89
    {0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,
    0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00},// z 90
    {0x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,
    0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40},// { 91
    {0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,
    0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00},// | 92
    {0x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,
    0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00},// } 93
    {0x00,0x80,0x40,0x40,0x80,0x00,0x00,0x80,
    0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x00},// ~ 94
};
#endif

目录导览

总览

协议层封装

OLED设备封装

绘图设备抽象

基础图形库封装

基础组件实现

动态菜单组件实现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2288051.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

论文笔记(六十三)Understanding Diffusion Models: A Unified Perspective(五)

Understanding Diffusion Models: A Unified Perspective&#xff08;五&#xff09; 文章概括基于得分的生成模型&#xff08;Score-based Generative Models&#xff09; 文章概括 引用&#xff1a; article{luo2022understanding,title{Understanding diffusion models: A…

ThinkPHP 8模型与数据的插入、更新、删除

【图书介绍】《ThinkPHP 8高效构建Web应用》-CSDN博客 《2025新书 ThinkPHP 8高效构建Web应用 编程与应用开发丛书 夏磊 清华大学出版社教材书籍 9787302678236 ThinkPHP 8高效构建Web应用》【摘要 书评 试读】- 京东图书 使用VS Code开发ThinkPHP项目-CSDN博客 编程与应用开…

项目升级Sass版本或升级Element Plus版本遇到的问题

项目升级Sass版本或升级Element Plus版本遇到的问题 如果项目有需求需要用到高版本的Element Plus组件&#xff0c;则需要升级相对应的sass版本&#xff0c;Element 文档中有提示&#xff0c;2.8.5及以后得版本&#xff0c;sass最低支持的版本为1.79.0&#xff0c;所升级sass、…

基于OSAL的嵌入式裸机事件驱动框架——整体架构调度机制

参考B站up主【架构分析】嵌入式祼机事件驱动框架 感谢大佬分享 任务ID &#xff1a; TASK_XXX TASK_XXX 在系统中每个任务的ID是唯一的&#xff0c;范围是 0 to 0xFFFE&#xff0c;0xFFFF保留为SYS_TSK_INIT。 同时任务ID的大小也充当任务调度的优先级&#xff0c;ID越大&#…

Three.js 后期处理(Post-Processing)详解

目录 前言 一、什么是后期处理&#xff1f; 二、Three.js 后期处理的工作流程 2.1 创建 EffectComposer 2.2 添加渲染通道&#xff08;Render Pass&#xff09; 2.3 应用最终渲染 三、后期处理实现示例 3.1 基础代码 四、常见的后期处理效果 4.1 辉光效果&#xf…

HTML特殊符号的使用示例

目录 一、基本特殊符号的使用 1、空格符号&#xff1a; 2、小于号 和 大于号&#xff1a; 3、引号&#xff1a; 二、版权、注册商标符号的使用 1、版权符号&#xff1a;© 2、注册商标符号&#xff1a; 三、数学符号的使用 四、箭头符号的使用 五、货币符号的使用…

JAVA实战开源项目:在线文档管理系统(Vue+SpringBoot) 附源码

本文项目编号 T 038 &#xff0c;文末自助获取源码 \color{red}{T038&#xff0c;文末自助获取源码} T038&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…

快速分析LabVIEW主要特征进行判断

在LabVIEW中&#xff0c;快速分析程序特征进行判断是提升开发效率和减少调试时间的重要技巧。本文将介绍如何高效地识别和分析程序的关键特征&#xff0c;从而帮助开发者在编写和优化程序时做出及时的判断&#xff0c;避免不必要的错误。 ​ 数据流和并行性分析 LabVIEW的图形…

UE学习日志#15 C++笔记#1 基础复习

1.C20的import 看看梦开始的地方&#xff1a; import <iostream>;int main() {std::cout << "Hello World!\n"; } 经过不仔细观察发现梦开始的好像不太一样&#xff0c;这个import是C20的模块特性 如果是在VS里编写的话&#xff0c;要用这个功能需要新…

Deep Seek R1本地化部署

目录 说明 一、下载ollama 二、在ollama官网下载模型 三、使用 后记 说明 操作系统&#xff1a;win10 使用工具&#xff1a;ollama 一、下载ollama 从官网下载ollama&#xff1a; ollama默认安装在C盘&#xff0c;具体位置为C:\Users\用户名\AppData\Local\Programs\O…

C# Winform制作一个登录系统

using System; using System.Collections; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace 登录 {p…

动态规划DP 最长上升子序列模型 总览

最长上升子序列模型 1. 最长上升子序列 1.1 怪盗基德的滑翔伞 1.1.1 登山 1.1.2 合唱队形 1.2 友好城市 1.3 最长上升子序列和 1.4 导弹拦截

怎样在PPT中启用演讲者视图功能?

怎样在PPT中启用演讲者视图功能&#xff1f; 如果你曾经参加过重要的会议或者演讲&#xff0c;你就会知道&#xff0c;演讲者视图&#xff08;Presenter View&#xff09;对PPT展示至关重要。它不仅能帮助演讲者更好地掌控演讲节奏&#xff0c;还能提供额外的提示和支持&#…

论文阅读(七):贝叶斯因果表型网络解释遗传变异和生物学知识

1.论文链接&#xff1a;Bayesian Causal Phenotype Network Incorporating Genetic Variation and Biological Knowledge 摘要&#xff1a; 在分离群体中&#xff0c;数量性状基因座&#xff08;QTL&#xff09;定位可以确定对表型有因果效应的QTL。这些方法的一个共同特点是Q…

1.27补题 回训练营

E 智乃的小球 题目描述 在一条无限长的水平直线上&#xff0c;有 n 个小球&#xff0c;每个小球的质量相同&#xff0c;体积可以忽略不计。这些小球初始时位于直线上的不同位置&#xff0c;并且每个小球有一个初始速度&#xff0c;速度为 -1 m/s 或 1 m/s。速度为 -1 m/s 表示…

INCOSE需求编写指南-附录 B: 首字母缩略词和缩写

附录 Appendix B: 首字母缩略词和缩写ACRONYMS AND ABBREVIATIONS AD 难易程度的进阶 Advancement Degree of Difficulty AI 人工智能 Artificial Intelligence CM 配置管理 Configuration Management ConOps 运作理念 Concept of Operations COTS 商业现货 Comme…

B站吴恩达机器学习笔记

机器学习视频地址&#xff1a; 4.5 线性回归中的梯度下降_哔哩哔哩_bilibili 损失函数学习地址&#xff1a; 损失函数选择 选凸函数的话&#xff0c;会收敛到全局最小值。证明凸函数用Hessian矩阵。凸函数定义&#xff1a;两点连线比线上所有点都大。 batch理解&#xff1…

Vscode编辑器下 Markdown无法显示图片

1.问题 在vscode 编辑器中无法预览 markdon 文件中的图片 2.解决方案 大部分出现这种情况是因为新版本的vscode会阻拦有风险的资源显示&#xff0c;将安全等级调低即可。 方式一&#xff1a; 1.打开任意 MD 文件&#xff0c;ctrl&#xff0c;调出设置 2. 输入 markdown.ch…

mysql重学(一)mysql语句执行流程

思考 一条查询语句如何执行&#xff1f;mysql语句中若列不存在&#xff0c;则在哪个阶段报错一条更新语句如何执行&#xff1f;redolog和binlog的区别&#xff1f;为什么要引入WAL什么是Changbuf&#xff1f;如何工作写缓冲一定好吗&#xff1f;什么情况会引发刷脏页删除语句会…

国产650V碳化硅MOSFET在通信电源应用中全面取代超结MOSFET

在通信电源应用中&#xff0c;国产650V碳化硅&#xff08;SiC&#xff09;MOSFET全面取代超结MOSFET&#xff08;如硅基CoolMOS&#xff09;&#xff0c;是技术迭代、政策推动、市场需求和国产产业链成熟共同作用的结果。倾佳电子杨茜从以下多个维度解析这一趋势&#xff1a; 倾…