从0开始使用面对对象C语言搭建一个基于OLED的图形显示框架(基础组件实现)
目录
基础组件实现
如何将图像和文字显示到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 support6x8 and 8x16. to register more, u shouldprovide the source and implement the functions
*/
typedef enum {
#if ENABLE_ASCII_6x8_SOURCESASCII_6x8,
#endif
#if ENABLE_ASCII_8x16_SOURCESASCII_8x16,
#endifNO_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_SOURCEScase 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 isregistered, 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_SOURCEScase 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;
#endifdefault: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_TextDebugdevice_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设备封装
绘图设备抽象
基础图形库封装
基础组件实现
动态菜单组件实现
相关文章:

从0开始使用面对对象C语言搭建一个基于OLED的图形显示框架(基础组件实现)
目录 基础组件实现 如何将图像和文字显示到OLED上 如何绘制图像 如何绘制文字 如何获取字体? 如何正确的访问字体 如何抽象字体 如何绘制字符串 绘制方案 文本绘制 更加方便的绘制 字体附录 ascii 6x8字体 ascii 8 x 16字体 基础组件实现 我们现在离手…...

windows系统如何检查是否开启了mongodb服务
windows系统如何检查是否开启了mongodb服务!我们有很多软件开发,网站开发时候需要使用到这个mongodb数据库,下面我们看看,如何在windows系统内排查,是否已经启动了本地服务。 在 Windows 系统上,您可以通过…...

VS安卓仿真器下载失败怎么办?
如果网络不稳定,则VS的安卓仿真器很容易下载失败,如下 Downloaded file <USER_HOME>\AppData\Local\Temp\xamarin-android-sdk\x86_64-35_r08.zip not found for Android SDK archive https://dl.google.com/android/repository/sys-img/google_a…...

计算机网络一点事(24)
TCP可靠传输,流量控制 可靠传输:每字节对应一个序号 累计确认:收到ack则正确接收 返回ack推迟确认(不超过0.5s) 两种ack:专门确认(只有首部无数据) 捎带确认(带数据…...

视频拼接,拼接时长版本
目录 视频较长,分辨率较大,这个效果很好,不耗用内存 ffmpeg imageio,适合视频较短 视频较长,分辨率较大,这个效果很好,不耗用内存 ffmpeg import subprocess import glob import os from nats…...

制造企业的成本核算
一、生产成本与制造费用的区别 (1)生产成本,是直接用于产品生产,构成产品实体的材料成本。 包括企业在生产经营过程中实际消耗的原材料、辅助材料、备品备件、外购半成品、燃料、动力包装物以及其它直接材料,和直接参加产品生产的工人工资,以及按生产工人的工资总额和规…...

doris:高并发导入优化(Group Commit)
在高频小批量写入场景下,传统的导入方式存在以下问题: 每个导入都会创建一个独立的事务,都需要经过 FE 解析 SQL 和生成执行计划,影响整体性能每个导入都会生成一个新的版本,导致版本数快速增长,增加了后台…...

LLMs之WebRAG:STORM/Co-STORM的简介、安装和使用方法、案例应用之详细攻略
LLMs之WebRAG:STORM/Co-STORM的简介、安装和使用方法、案例应用之详细攻略 目录 STORM系统简介 1、Co-STORM 2、更新新闻 STORM系统安装和使用方法 1、安装 pip安装 直接克隆GitHub仓库 2、模型和数据集 两个数据集 FreshWiki数据集 WildSeek数据集 支持…...

鸿蒙HarmonyOS实战-ArkUI动画(页面转场动画)_鸿蒙arkui tab 切换动画
PageTransitionExit({type?: RouteType,duration?: number,curve?: Curve | string,delay?: number}) 在HarmonyOS中,PageTransitionEnter和PageTransitionExit是用于控制页面切换动画的参数。它们分别表示页面进入和退出时的动画。1. type(动画类型…...

图漾相机-ROS2-SDK-Ubuntu版本编译(新版本)
文章目录 前言1.Camport ROS2 SDK 介绍1.1 Camport ROS2 SDK源文件介绍1.2 Camport ROS2 SDK工作流程1.2.1 包含头文件1.2.2 2 初始化 ROS 2 节点1.2.3 创建节点对象1.2.4 创建发布者对象并实现发布逻辑1.2.5 启动 ROS 2 1.3 ROS2 SDK环境配置与编译1.3.1 Ubuntu 20.04 下ROS2 …...

小程序的协同工作与发布
1.小程序API的三大分类 2.小程序管理的概念,以及成员管理两个方面 3.开发者权限说明以及如何维护项目成员 4.小程序版本...

解锁维特比算法:探寻复杂系统的最优解密码
引言 在复杂的技术世界中,维特比算法以其独特的魅力和广泛的应用,成为通信、自然语言处理、生物信息学等领域的关键技术。今天,让我们一同深入探索维特比算法的奥秘。 一、维特比算法的诞生背景 维特比算法由安德鲁・维特比在 1967 年提出…...

计算机网络一点事(20)
IEEE802.11 无线局域网 分类有无基础设施 星型拓扑,基本服务集BSS一基站多移动站,服务集标识符SSID不超过32b,可接入802.3 漫游:移动站从一个基本服务集切换到另一个(类似换联WiFi) 802.11帧࿱…...

java求职学习day23
MySQL 单表 & 约束 & 事务 1. DQL操作单表 1.1 创建数据库,复制表 1) 创建一个新的数据库 db2 CREATE DATABASE db2 CHARACTER SET utf8; 2) 将 db1 数据库中的 emp 表 复制到当前 db2 数据库 1.2 排序 通过 ORDER BY 子句 , 可以将查询出的结果进行排序 ( 排序只…...

Vue-cli 脚手架搭建
安装node.js 官网下载node.js安装包,地址:Node.js — Download Node.js 先在node.js即将要安装的路径下创建两个文件夹:node_cache(缓存)、node_global(全局) 点击安装包…...

认识小程序的基本组成结构
1.基本组成结构 2.页面的组成部分 3.json配置文件 4.app.json文件(全局配置文件) 5.project.config.json文件 6.sitemap.json文件 7.页面的.json配置文件 通过window节点可以控制小程序的外观...

Spring Boot 热部署实现指南
在开发 Spring Bot 项目时,热部署功能能够显著提升开发效率,让开发者无需频繁重启服务器就能看到代码修改后的效果。下面为大家详细介绍一种实现 Spring Boot 热部署的方法,同时也欢迎大家补充其他实现形式。 步骤一、开启 IDEA 自动编译功能…...

深度学习编译器的演进:从计算图到跨硬件部署的自动化之路
第一章 问题的诞生——深度学习部署的硬件困境 1.1 计算图的理想化抽象 什么是计算图? 想象你正在组装乐高积木。每个积木块代表一个数学运算(如加法、乘法),积木之间的连接代表数据流动。深度学习框架正是用这种"积木拼接…...

【数据结构】_顺序表经典算法OJ(力扣版)
目录 1. 移除元素 1.1 题目描述及链接 1.2 解题思路 1.3 程序 2. 合并两个有序数组 1.1 原题链接及题目描述 1.2 解题思路 1.3 程序 1. 移除元素 1.1 题目描述及链接 原题链接:27. 移除元素 - 力扣(LeetCode) 题目描述:…...

数据结构:队列篇
图均为手绘,代码基于vs2022实现 系列文章目录 数据结构初探: 顺序表 数据结构初探:链表之单链表篇 数据结构初探:链表之双向链表篇 链表特别篇:链表经典算法问题 数据结构:栈篇 文章目录 系列文章目录前言一.队列的概念和结构1.1概念一、动态内存管理优势二、操作效率与安全性…...

第05章 17 Contour 过滤器介绍与例子
vtkContourFilter 是 VTK(Visualization Toolkit)中的一个关键类,用于从输入数据生成等值线或等值面。它是基于阈值的过滤器,可以从标量字段中提取等值线或等值面。vtkContourFilter 的核心功能是根据用户指定的值生成等值线或等值…...

【落羽的落羽 数据结构篇】顺序表
文章目录 一、线性表二、顺序表1. 概念与分类2. 准备工作3. 静态顺序表4. 动态顺序表4.1 定义顺序表结构4.2 顺序表的初始化4.3 检查空间是否足够4.3 尾部插入数据4.4 头部插入数据4.5 尾部删除数据4.6 头部删除数据4.7 在指定位置插入数据4.8 在指定位置删除数据4.9 顺序表的销…...

AI编程:如何编写提示词
这是小卷对AI编程工具学习的第2篇文章,今天讲讲如何编写AI编程的提示词,并结合实际功能需求案例来进行开发 1.编写提示词的技巧 好的提示词应该是:目标清晰明确,具有针对性,能引导模型理解问题 下面是两条提示词的对…...

DeepSeek-R1 论文解读 —— 强化学习大语言模型新时代来临?
近年来,人工智能(AI)领域发展迅猛,大语言模型(LLMs)为通用人工智能(AGI)的发展开辟了道路。OpenAI 的 o1 模型表现非凡,它引入的创新性推理时缩放技术显著提升了推理能力…...

高阶C语言|深入理解字符串函数和内存函数
文章目录 前言1.求字符串长度1.1 字符串长度函数:strlen模拟实现 2.长度不受限制的字符串函数2.1 字符串拷贝函数:strcpy模拟实现 2.2 字符串连接函数:strcat模拟实现 2.3 字符串比较函数:strcmp模拟实现 3.长度受限制的字符串函数…...

UE学习日志#17 C++笔记#3 基础复习3
19.2 [[maybe_unused]] 禁止编译器在未使用某些内容时发出警告 19.3 [[noreturn]] 永远不会把控制权返回给调用点 19.4 [[deprecated]] 标记为已弃用,仍然可以使用但是不鼓励使用 可以加参数表示弃用的原因[[deprecated("")]] 19.5 [[likely]]和[[un…...

团体程序设计天梯赛-练习集——L1-028 判断素数
前言 一道10分的题目,相对来说比较简单,思考的时候要仔细且活跃,有时候在写代码的时候一些代码的出现很多余,并且会影响最后的结果 L1-028 判断素数 本题的目标很简单,就是判断一个给定的正整数是否素数。 输入格式…...

从0开始使用面对对象C语言搭建一个基于OLED的图形显示框架(基础图形库实现)
目录 基础图形库的抽象 抽象图形 抽象点 设计我们的抽象 实现我们的抽象 测试 抽象线 设计我们的抽象 实现我们的抽象 绘制垂直的和水平的线 使用Bresenham算法完成任意斜率的绘制 绘制三角形和矩形 矩形 三角形 实现 绘制圆,圆弧和椭圆 继续我们的…...

创新创业计划书|建筑垃圾资源化回收
目录 第1部分 公司概况........................................................................ 1 第2部分 产品/服务...................................................................... 3 第3部分 研究与开发.................................................…...

反射、枚举以及lambda表达式
一.反射 1.概念:Java的反射(reflection)机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,既然能拿到那么&am…...