STM32 控制 OLED 全攻略(二):实现字符和汉字的显示
目录
一 前言
二 OLED介绍
(一)SSD1306
(二)OLED屏幕
三 显示原理+结合代码解释
1 指令---0x00
2 数据---0x40
3 初始化oled函数
4 codetab.h
四 显示字符串的原理
🧾 ASCII 编码范围:
✅ OLED_ShowStr变量对照表
五 汉字显示的原理
六 源代码
一 前言
关于oled的一些基础介绍,我可能没有别的博主写的那么详细,代码所用到的知识会跟大家写明白,主要讲解oled显示字符串和汉字的具体操作,接上一篇文章“别急着点亮 OLED,先把 STM32 的 I2C 通信搞明白”。我们进行简单的知识回顾,已知oled四个引脚:
GND | GND |
VCC | 5v |
SCL | PB6 |
SDA | PB7 |
已知我们在oled.c中已经写了两个函数分别是
void I2C_Configuration(void)
//i2c的硬件配置
void I2C_WriteByte(uint8_t addr, uint8_t data)//写入i2c一个字节数据,输入参数为地址和“数据”
!!!这里的数据要打一个大大的引号,这里的数据,我会随后进行介绍,其实这里的数据其实并不是真正的数据,大家请耐心的看下去。
二 OLED介绍
(一)SSD1306
OLED是一个128*64的小灯的一个屏幕,但是如果一个引脚控制一个灯,为了控制一个OLED屏幕足足要有8000多个引脚,这显然是不可能的,所以在单片机芯片控制oled屏幕之间,加了一个芯片,这是SSD1306,OLED就是由“一个会发光的像素板 + 一个接收你指令的翻译官”构成的,而SSD1306就是翻译人的话给OLED来显示的翻译官。
(二)OLED屏幕
SSD1306把OLED的整块屏幕分成了八页,大家要知道这里的页并不是书几页的那个页。长是128,高是64,我们把高拆分成八块,每八小行128列,构成1页。Page是从0开始数一直到7,如图:
三 显示原理+结合代码解释
所以为了方便函数的调用,我将下面两个命令进行函数的封装。
1 指令---0x00
在写指令前,我们都需要先把0x78(OLED的地址),发送给SSD1306芯片,随后在发送0x00,代表接下来我要写一个指令,指令1、指令2
//写命令
void WriteCmd(unsigned char I2C_Command)
{I2C_WriteByte(0x00, I2C_Command);
}
2 数据---0x40
在写数据前,同样我们也需要把0x78(OLED的地址),发送给SSD1306芯片,随后在发送0x40,代表接下来我要写数据了,这里的数据就是要让某一页的某一列的八个灯进行亮灭。
//写数据
void WriteData(unsigned char I2C_Data)
{I2C_WriteByte(0x40, I2C_Data);
}
那我们这时候就要想了,那我如何告诉代码哪个位置进行写数据呢,那就是要重新创立一个起点坐标的函数:
//设置起点坐标
void OLED_SetPos(unsigned char x, unsigned char y)
{WriteCmd(0xb0 | y);WriteCmd((x & 0xF0) >> 4 | 0x10);WriteCmd((x&0x0f)|0x00);
}
我们并没有写数据,所以我们要在设置起始坐标的时候,只用到写指令:
先确定页(page几) > 再确定第几列,在这个确定第几列的时候有说法,我们不能直接去确定,我们需要将0x几几拆分成高四位和低四位,低四位是0x0几,高四位是0x1几
举个例子,我现在想要找到第3页,第90列的位置为起始坐标,那么我们就需要先将3转化为unsigned char类型,0000 0011(3),这个数或上0xb0,就会写成1011 0011(0xb3)现在锁定到了第三页,随后我们再将90转化为unsigned char为0x5A,但是我们在传输的时候要把0x5A拆分成高四位:0x15,低四位:0x0A。代码的第二行也很好理解,我们要先把高四位取出来,然后再将取出来的数向右移四位,最后可以发现成为了0001 xxxx,xxxx是曾经的数,并没有改变,把格式改成了0x1几,也就是高四位的指令,低四位同理。大家慢慢写出来即可~字有点丑,大家也可以看一下我写的~~
进行上述大家需要记得东西进行总结:
【【STM32入门教程-2024】第14集 如何在OLED屏幕上挥毫】 https://www.bilibili.com/video/BV19u4y197df/?share_source=copy_web&vd_source=644dca2ea0b8f1939321da41c0f40f7f
以下的代码大家也可以看懂啦,大家可以自行看一下吧,实现了全亮或者清屏全灭
/全屏填充
void OLED_Fill(unsigned char Fill_Data)
{unsigned char m, n;for (m = 0; m < 8; m++){WriteCmd(0xb0 + m);WriteCmd(0x00);WriteCmd(0x10);for (n = 0; n < 128; n++){WriteData(Fill_Data);}}
}//清屏
void OLED_CLS(void)
{OLED_Fill(0x00);
}
3 初始化oled函数
//OLED屏幕初始化
void OLED_Init(void)
{ms_delay(100);WriteCmd(0xAE); //display offWriteCmd(0x20); //Set Memory Addressing Mode WriteCmd(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,InvalidWriteCmd(0xb0); //Set Page Start Address for Page Addressing Mode,0-7WriteCmd(0xc8); //Set COM Output Scan DirectionWriteCmd(0x00); //---set low column addressWriteCmd(0x10); //---set high column addressWriteCmd(0x40); //--set start line addressWriteCmd(0x81); //--set contrast control registerWriteCmd(0xff); //亮度调节 0x00~0xffWriteCmd(0xa1); //--set segment re-map 0 to 127WriteCmd(0xa6); //--set normal displayWriteCmd(0xa8); //--set multiplex ratio(1 to 64)WriteCmd(0x3F); //WriteCmd(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM contentWriteCmd(0xd3); //-set display offsetWriteCmd(0x00); //-not offsetWriteCmd(0xd5); //--set display clock divide ratio/oscillator frequencyWriteCmd(0xf0); //--set divide ratioWriteCmd(0xd9); //--set pre-charge periodWriteCmd(0x22); //WriteCmd(0xda); //--set com pins hardware configurationWriteCmd(0x12);WriteCmd(0xdb); //--set vcomhWriteCmd(0x20); //0x20,0.77xVccWriteCmd(0x8d); //--set DC-DC enableWriteCmd(0x14); //WriteCmd(0xaf); //--turn on oled panel
}
上面这些代码大家不必深究,SSD1306的中文参考手册会给大家提供的
4 codetab.h
下面这些代码,给大家提供源代码:
const unsigned char F6x8[][6] =
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// sp0x00, 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,// 00x00, 0x00, 0x42, 0x7F, 0x40, 0x00,// 10x00, 0x42, 0x61, 0x51, 0x49, 0x46,// 20x00, 0x21, 0x41, 0x45, 0x4B, 0x31,// 30x00, 0x18, 0x14, 0x12, 0x7F, 0x10,// 40x00, 0x27, 0x45, 0x45, 0x45, 0x39,// 50x00, 0x3C, 0x4A, 0x49, 0x49, 0x30,// 60x00, 0x01, 0x71, 0x09, 0x05, 0x03,// 70x00, 0x36, 0x49, 0x49, 0x49, 0x36,// 80x00, 0x06, 0x49, 0x49, 0x29, 0x1E,// 90x00, 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,// A0x00, 0x7F, 0x49, 0x49, 0x49, 0x36,// B0x00, 0x3E, 0x41, 0x41, 0x41, 0x22,// C0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C,// D0x00, 0x7F, 0x49, 0x49, 0x49, 0x41,// E0x00, 0x7F, 0x09, 0x09, 0x09, 0x01,// F0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A,// G0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F,// H0x00, 0x00, 0x41, 0x7F, 0x41, 0x00,// I0x00, 0x20, 0x40, 0x41, 0x3F, 0x01,// J0x00, 0x7F, 0x08, 0x14, 0x22, 0x41,// K0x00, 0x7F, 0x40, 0x40, 0x40, 0x40,// L0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F,// M0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F,// N0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E,// O0x00, 0x7F, 0x09, 0x09, 0x09, 0x06,// P0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E,// Q0x00, 0x7F, 0x09, 0x19, 0x29, 0x46,// R0x00, 0x46, 0x49, 0x49, 0x49, 0x31,// S0x00, 0x01, 0x01, 0x7F, 0x01, 0x01,// T0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F,// U0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F,// V0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F,// W0x00, 0x63, 0x14, 0x08, 0x14, 0x63,// X0x00, 0x07, 0x08, 0x70, 0x08, 0x07,// Y0x00, 0x61, 0x51, 0x49, 0x45, 0x43,// Z0x00, 0x00, 0x7F, 0x41, 0x41, 0x00,// [0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55,// 550x00, 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,// a0x00, 0x7F, 0x48, 0x44, 0x44, 0x38,// b0x00, 0x38, 0x44, 0x44, 0x44, 0x20,// c0x00, 0x38, 0x44, 0x44, 0x48, 0x7F,// d0x00, 0x38, 0x54, 0x54, 0x54, 0x18,// e0x00, 0x08, 0x7E, 0x09, 0x01, 0x02,// f0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C,// g0x00, 0x7F, 0x08, 0x04, 0x04, 0x78,// h0x00, 0x00, 0x44, 0x7D, 0x40, 0x00,// i0x00, 0x40, 0x80, 0x84, 0x7D, 0x00,// j0x00, 0x7F, 0x10, 0x28, 0x44, 0x00,// k0x00, 0x00, 0x41, 0x7F, 0x40, 0x00,// l0x00, 0x7C, 0x04, 0x18, 0x04, 0x78,// m0x00, 0x7C, 0x08, 0x04, 0x04, 0x78,// n0x00, 0x38, 0x44, 0x44, 0x44, 0x38,// o0x00, 0xFC, 0x24, 0x24, 0x24, 0x18,// p0x00, 0x18, 0x24, 0x24, 0x18, 0xFC,// q0x00, 0x7C, 0x08, 0x04, 0x04, 0x08,// r0x00, 0x48, 0x54, 0x54, 0x54, 0x20,// s0x00, 0x04, 0x3F, 0x44, 0x40, 0x20,// t0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C,// u0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C,// v0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C,// w0x00, 0x44, 0x28, 0x10, 0x28, 0x44,// x0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C,// y0x00, 0x44, 0x64, 0x54, 0x4C, 0x44,// z0x14, 0x14, 0x14, 0x14, 0x14, 0x14,// horiz lines
};
const unsigned char F8X16[]=
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 00x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! 10x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" 20x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# 30x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ 40xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% 50x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& 60x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//' 70x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( 80x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) 90x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* 100x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ 110x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, 120x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- 130x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. 140x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// 150x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 160x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 170x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 180x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 190x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 200x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 210x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 220x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 230x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 240x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 250x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: 260x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,//; 270x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< 280x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= 290x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> 300x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? 310xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ 320x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A 330x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B 340xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C 350x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D 360x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E 370x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F 380xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G 390x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H 400x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I 410x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J 420x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K 430x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L 440x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M 450x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N 460xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O 470x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P 480xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q 490x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R 500x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S 510x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T 520x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U 530x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V 540xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,//W 550x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,//X 560x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//Y 570x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,//Z 580x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,//[ 590x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,//\ 600x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,//] 610x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^ 620x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,//_ 630x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//` 640x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a 650x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b 660x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,//c 670x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,//d 680x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,//e 690x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//f 700x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,//g 710x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//h 720x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//i 730x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,//j 740x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,//k 750x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//l 760x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,//m 770x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//n 780x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//o 790x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,//p 800x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,//q 810x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,//r 820x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,//s 830x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,//t 840x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,//u 850x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,//v 860x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,//w 870x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,//x 880x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,//y 890x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,//z 900x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,//{ 910x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,//| 920x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//} 930x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//~ 94
};
那么,如何将这个codetab.h的文件添加进去呢?
添加进去记得在oled.c文件的代码部分添加codetab的头文件哈
这个代码里面一共有两个结构体
const unsigned char F6x8[][6] //高8宽6,小字体
const unsigned char F8X16[] //高16宽8,大一点的字体
这里的高和宽很重要,高就是几行,宽就是几列(因为每一行最多128列,我们会通过这个进行计算每个发送的字符串有没有超过128列,超过了128列就不会显示)
四 显示字符串的原理
void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned TextSize)
{unsigned char c = 0, i = 0, j = 0;switch (TextSize){case 1:{while (ch[j] != '\0'){c = ch[j] - 32;if (x > 126){x = 0;y++;}OLED_SetPos(x, y);for (i = 0; i < 6; i++){WriteData(F6x8[c][i]);x += 1;}j++; // 增加 j 的值}}break;case 2:{while (ch[j] != '\0'){c = ch[j] - 32;if (x > 120){x = 0;y++;}OLED_SetPos(x, y);for (i = 0; i < 8; i++)WriteData(F8X16[c * 16 + i]);OLED_SetPos(x, y + 1);for (i = 0; i < 8; i++)WriteData(F8X16[c * 16 + i + 8]);x += 8;j++;}}break;}
}
对于这个OLED_ShowStr函数,有四个输入参数,起始点的横坐标x + 起始点的纵坐标y + 要显示的字符串 + 字体的尺寸大一点还是小一点,字体要大一点,就写2,字体要小一点就写1
大家现在请看case1(也就是字体小一点的)这几行代码,字符串最后的结尾是\0,所以如果传输字符串里面的字符的时候,如果传输到了\0,那就跳出循环,为什么要c = ch[j] - 32;呢??
🧠 背景知识:ASCII 与字模表的关系
🧾 ASCII 编码范围:
字符 | ASCII 值 |
---|---|
空格 ' ' | 32 |
数字 '0' ~ '9' | 48 ~ 57 |
大写字母 'A' ~ 'Z' | 65 ~ 90 |
小写字母 'a' ~ 'z' | 97 ~ 122 |
这里x为什么要大于126就要将x赋值成0呢?因为我们有128列,但是第一列是0,所以第128列是127,只要x等于127就让x等于0
对于SSD1306这个芯片来说,x自动加1,写完一列数据自动变到下一列。
因为你点阵数组是从 F6x8[0]
开始对应 ASCII 32(空格),所以我们要在这里减32,这里的x是几列,所以我们要进行换列
变量i有什么用呢?
每个字符是 6 列像素,每列是一个字节
F6x8[c][i]
表示第c
个字符的第i
列点阵数据
每显示完一个字符,我们就让j(j就是显示第几个字符)自动加1,整体字符串显示的原理就写完啦,给大家总结一下所用到的变量
✅ OLED_ShowStr变量对照表
变量名 | 类型 | 含义 | 示例值 | 作用说明 |
---|---|---|---|---|
x | unsigned char | 当前字符的起始 列坐标(横向) | 0 ~ 127 | 决定字符从哪一列开始显示,每显示一列 x++ |
y | unsigned char | 当前字符的 页坐标(纵向) | 0 ~ 7 | 每页表示 8 行像素,16 行要跨 2 页 |
ch[] | char[] | 要显示的 字符串数组 | "HELLO" | 外部传入,用来遍历显示 |
j | unsigned char | 当前字符串的位置索引 | 从 0 开始 | 遍历整个 ch[] 数组:ch[j] 表示当前字符 |
c | unsigned char | 当前字符在 字模数组中的索引 | 'A' → 65 - 32 = 33 | 用于访问 F6x8[c] 或 F8X16[c*16 + i] |
i | unsigned char | 当前字符的 列扫描计数器 | 0~5 (F6x8),0~7 (F8X16) | 控制每列点阵的写入(写一列,x++) |
case2的情况就不给大家做赘述了,简单说一下疑点:因为case2是大一点的字体,所以我们用到了高16宽8的像素点,所以我们写进去的列数据,得分两次,因为每次传进去只能传八位二进制的数,所以我们在这里需要添加两个for循环。在这里就不给大家进行过多赘述啦~
五 汉字显示的原理
大家如果了解了上面显示字符串的原理,那么接下来的汉字显示就很简单啦,因为汉字的个数要比英文字母要多得多,所以我们要安装一个软件是这个——PCtoLCD2002
点进去之后,要打开选项,我们进行配置,如图:
点左下角的确定,然后输入自己想要的汉字,比方说我输入的是小宋同学,
然后生成对应的字模,然后将这些字模复制,如图:
将这些代码复制粘贴到codetab.h当中,然后我们写成如图形式:
我们的字是16*16个像素的,所以我们在写数据的时候,一次写八个数据,我们需要写两次
六 源代码
大家现在给大家提供oled.c的源代码
#include "stm32f10x.h"
#include "oled.h"
#include "SysTick.h"
#include "codetab.h"void I2C_Configuration(void)
{I2C_InitTypeDef I2C_InitStructure;GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);//PB6--SCL: PB7--SDAGPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOB, &GPIO_InitStructure);I2C_DeInit(I2C1);I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = 400000;I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;I2C_InitStructure.I2C_OwnAddress1 = 0x30;I2C_Init(I2C1, &I2C_InitStructure);I2C_Cmd(I2C1, ENABLE);
}void I2C_WriteByte(uint8_t addr, uint8_t data)
{while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); //检查I2C总线是否繁忙 I2C_GenerateSTART(I2C1, ENABLE); //开启I2C1while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); //EV5,主模式I2C_Send7bitAddress(I2C1, OLED_ADDRESS, I2C_Direction_Transmitter); //发送器件地址while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));I2C_SendData(I2C1, addr); //寄存器地址while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING));I2C_SendData(I2C1, data);while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING));I2C_GenerateSTOP(I2C1, ENABLE); //关闭I2C1总线
}//写命令
void WriteCmd(unsigned char I2C_Command)
{I2C_WriteByte(0x00, I2C_Command);
}//写数据
void WriteData(unsigned char I2C_Data)
{I2C_WriteByte(0x40, I2C_Data);
}//OLED屏幕初始化
void OLED_Init(void)
{ms_delay(100);WriteCmd(0xAE); //display offWriteCmd(0x20); //Set Memory Addressing Mode WriteCmd(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,InvalidWriteCmd(0xb0); //Set Page Start Address for Page Addressing Mode,0-7WriteCmd(0xc8); //Set COM Output Scan DirectionWriteCmd(0x00); //---set low column addressWriteCmd(0x10); //---set high column addressWriteCmd(0x40); //--set start line addressWriteCmd(0x81); //--set contrast control registerWriteCmd(0xff); //亮度调节 0x00~0xffWriteCmd(0xa1); //--set segment re-map 0 to 127WriteCmd(0xa6); //--set normal displayWriteCmd(0xa8); //--set multiplex ratio(1 to 64)WriteCmd(0x3F); //WriteCmd(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM contentWriteCmd(0xd3); //-set display offsetWriteCmd(0x00); //-not offsetWriteCmd(0xd5); //--set display clock divide ratio/oscillator frequencyWriteCmd(0xf0); //--set divide ratioWriteCmd(0xd9); //--set pre-charge periodWriteCmd(0x22); //WriteCmd(0xda); //--set com pins hardware configurationWriteCmd(0x12);WriteCmd(0xdb); //--set vcomhWriteCmd(0x20); //0x20,0.77xVccWriteCmd(0x8d); //--set DC-DC enableWriteCmd(0x14); //WriteCmd(0xaf); //--turn on oled panel
}//设置起点坐标
void OLED_SetPos(unsigned char x, unsigned char y)
{WriteCmd(0xb0 | y);WriteCmd((x & 0xF0) >> 4 | 0x10);WriteCmd((x&0x0f)|0x00);
}//全屏填充
void OLED_Fill(unsigned char Fill_Data)
{unsigned char m, n;for (m = 0; m < 8; m++){WriteCmd(0xb0 + m);WriteCmd(0x00);WriteCmd(0x10);for (n = 0; n < 128; n++){WriteData(Fill_Data);}}
}//清屏
void OLED_CLS(void)
{OLED_Fill(0x00);
}//OLED打开
void OLED_ON(void)
{WriteCmd(0x8D); //设置电荷泵WriteCmd(0x14); //开启电荷泵WriteCmd(0xaf); //OLED唤醒
}//OLED关闭
void OLED_OFF(void)
{WriteCmd(0x8D); //设置电荷泵WriteCmd(0x10); //关闭电荷泵WriteCmd(0xae); //OLED关闭
}//显示字符串函数
void OLED_ShowStr(unsigned char x, unsigned char y, unsigned char ch[], unsigned TextSize)
{unsigned char c = 0, i = 0, j = 0;switch (TextSize){case 1:{while (ch[j] != '\0'){c = ch[j] - 32;if (x > 126){x = 0;y++;}OLED_SetPos(x, y);for (i = 0; i < 6; i++){WriteData(F6x8[c][i]);x += 1;}j++; // 增加 j 的值}}break;case 2:{while (ch[j] != '\0'){c = ch[j] - 32;if (x > 120){x = 0;y++;}OLED_SetPos(x, y);for (i = 0; i < 8; i++)WriteData(F8X16[c * 16 + i]);OLED_SetPos(x, y + 1);for (i = 0; i < 8; i++)WriteData(F8X16[c * 16 + i + 8]);x += 8;j++;}}break;}
}void OLED_ShowCN(unsigned char x,unsigned char y,unsigned char N) //N表示第几个汉字
{unsigned char wm = 0;unsigned int addr = 32*N;OLED_SetPos(x,y);for(wm = 0;wm < 16;wm++){WriteData(F16X16[addr]);addr += 1;}OLED_SetPos(x,y+1);for(wm = 0;wm < 16;wm++){WriteData(F16X16[addr]);addr += 1;}}
相关文章:
STM32 控制 OLED 全攻略(二):实现字符和汉字的显示
目录 一 前言 二 OLED介绍 (一)SSD1306 (二)OLED屏幕 三 显示原理结合代码解释 1 指令---0x00 2 数据---0x40 3 初始化oled函数 4 codetab.h 四 显示字符串的原理 🧾 ASCII 编码范围: ✅ OLED_S…...
c#将json字符串转换为对象数组
在C#中,将JSON字符串转换为对象数组是一个常见的需求,特别是在处理来自Web API的响应或需要反序列化本地文件内容时。这可以通过使用Newtonsoft.Json(也称为Json.NET)库或.NET Core内置的System.Text.Json来完成。以下是如何使用这…...
Cryosparc里头restack的妙用
在Cryosparc里头经常需要迁移job或者将particle打包成relion可以识别的模式,总是会遇到一个问题,我们需要的颗粒明明很少,但总是保存出一大堆东西来。原因就是,他会把最开初的particle都给你算进来,而不是某个作业对应…...
.bat文档如何运行Python程序
.bat文档如何运行Python程序 在Windows操作系统中,你可以通过几种方式来运行Python程序,即使是通过.bat批处理文件。.bat文件是一种批处理脚本,它允许你执行一系列命令。以下是一些步骤和示例,说明如何从.bat文件运行Python程序。…...
力扣HOT100之二叉树:230. 二叉搜索树中第 K 小的元素
这道题直接用最笨的办法来做的,用递归来做,我们定义一个全局变量vector<int> element,然后使用中序遍历,每当碰到一个非空节点就将其加入到向量中,这样依赖当向量中的元素小于k时,就返回0,…...
【Nextcloud】使用 LNMP 架构搭建私有云存储:Nextcloud 实战指南
目录 一、环境准备与基础配置 1. 系统环境要求 2. 初始化系统配置 二、搭建 LNMP 基础架构 1. 一键安装 LNMP 组件 2. 启动数据库服务 三、部署 Nextcloud 存储服务 1. 上传并解压安装包 2. 设置目录权限(测试环境配置) 3. 配置 MariaDB 数据库…...
已知6、7、8月月平均气温和标准差,求夏季季平均温度与标准差
由下面定理,得出平方和的公式:(即每天的温度平方和) 这样就可以推出季平均的算法: 举例:在Excel用公式算,不要手算: 因此季平均:(B2*C2B3*C3B4*C4)/SUM(B2:B4) 季标准差…...
【cursor指南】cursor免费续杯pro会员试用
背景 心血来潮(其实是被逼的),开始需要cursor里面的agent对话。cursor用着用着就会出现点数耗尽、试用到期等问题,于是自行开始找免费的cursor会员续用方法。 Part01:参考链接鸣谢 1. Cursor 全攻略:注册、使用到无限续杯&…...
Visual Studio解决方案构建三剑客:生成/重新生成/清理完全指南(实战经验总结)
文章目录 当你在VS里右键解决方案时...一、先看实战场景(老板发飙警告)二、三大命令解剖课(重点标记版)2.1 生成解决方案(F7)2.2 重新生成解决方案(CtrlAltF7)2.3 清理解决方案&…...
《JVM如何判断一个对象可以被回收?图文详解GC Root算法》
大家好呀!我是你们的老朋友Java技术博主👋 今天咱们来聊聊Java虚拟机(JVM)中一个超级重要的话题——垃圾回收机制(Garbage Collection)和GC Root可达性分析!这可是Java程序员必须掌握的核心知识点哦!😎 🌟…...
常用算法/机理模型演示平台搭建(一)
算法/机理模型演示平台搭建 一、算法列表(app/algorithms)二、行业机理模型 (app/models)三、如何使用本项目旨在为初学者提供 35种 常用算法和 9种 行业机理模型的简单Python实现或概念说明。每个算法都有其独特的应用场景,从数据预测、质量检测、过程控制到结构分析和优化问…...
一文详解红黑树
一文详解红黑树 前言一、基本概念与特性1.1 红黑树的定义1.2 红黑树的特性 二、红黑树的节点结构与表示三、红黑树的基本操作3.1 插入操作3.2 删除操作 四、红黑树的应用场景4.1 编程语言的集合类4.2 数据库索引4.3 Linux 内核进程调度 总结 前言 在数据结构的领域中ÿ…...
Windows 安装显卡驱动
1.第一步:打开Nvidia 官网驱动下载页面 2.第二步:选择相关信息, 玩游戏选择,GeForce Game Ready ,创意设计、摄影直播 选择 NVIDIA Studio 驱动程序 (NVIDIA Studio Driver - WHQL.) 2.第三步࿱…...
【C语言】易错题 经典题型
出错原因:之前运行起来的可执行程序没有关闭 关闭即可 平均数(average) 输入3个整数,输出它们的平均值,保留3位小数。 #include <stdio.h> int main() {int a, b, c;scanf("%d %d %d", &a, &…...
C++类与对象--5 运算符重载
对已有的运算符进行重新定义,赋予不同的功能,以适应不同的数据类型 5.1 加号运算符 实现两个自定义数据类型的加运算 (1)通过成员函数实现“”重载 class Number { public:Number(int a, int b):m_A(a),m_B(b){}Number(){}Number operator(Number &a…...
接口排查不能靠猜:实战中如何用抓包工具精准定位问题(含 Charles 使用示例)
几乎每个写代码的开发者都经历过这样的时刻:接口突然返回空、请求超时、前端数据没更新……你试过重启服务、翻查日志、改代码打印,最后还是无解。 我想说,其实很多问题的答案都藏在“网络请求”里,只是你没有去看。 这篇文章&a…...
【占融数科-注册/登录安全分析报告】
前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 暴力破解密码,造成用户信息泄露短信盗刷的安全问题,影响业务及导致用户投诉带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞…...
4.7 时间模块
时间模块: * 1. time:操作时间本身 2.datetime:主要用于设置某一时间 3.calendar:主要用于时间份量计算 import time # 1. actimr:把一个表示时间的元组转换为字符串。要是不给出参数则返回当前本地时间。 print(time.asctime())…...
SHIMADZU岛津 R300RC300 Operation Manual
SHIMADZU岛津 R300RC300 Operation Manual...
(C语言篇)处理字符串的四个基础函数
strlen、strcpy、strcat、strcmp使用以及注意事项 在C语言中,strlen、strcpy、strcat、strcmp是处理字符串的四个基础函数,都在<string.h>头文件中声明。下面为你详细介绍它们的功能、用法和注意事项。 1. strlen - 计算字符串长度 函数原型&am…...
mysql的安装方式
1.yum/apt安装 yum安装: 先搭建yum仓库,可以在清华源内找:mysql | 镜像站使用帮助 | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror vim /etc/yum.repos.d/mysql.repo[mysql-connectors-community] nameMySQL Connectors Communit…...
嵌入式(C语言篇)Day11
嵌入式Day11 一、动态内存分配核心函数 (一)函数列表 函数名功能头文件返回值malloc分配连续的size字节堆内存stdlib.h成功返回首地址(void*),失败返回NULLcalloc分配num个元素size字节/元素的堆内存,自…...
Java集合框架解析:从基础到底层源码
Java集合框架解析:从基础到底层源码 一、集合体系 1.1 两大核心接口深度解析 Collection 单列集合 List 系列 ArrayList:动态数组实现,初始容量10,扩容策略为 原容量的1.5倍// JDK17 扩容源码片段 int newCapacity oldCapacity…...
C语言实现android/linux按键模拟
C语言实现 input事件模拟 #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <linux/input.h>int main() {int fd open("/dev/input/event0", O_RDWR);if (fd < 0) {perror("Failed to open device");ret…...
VisionPro:轴承错位标识
找出轴承缺陷并标记:效果 1.打开导入图片 2.添加CogToolblock:方便后续写代码 3.对零件进行模板匹配 4.对图片进行预处理(重点) 5.添加找圆工具和展开工具 根据下图将线链接 6.添加模板匹配工具并运行 7.训练模板 好的全找出来 8.代码编写 红色框为添加的代码(下面有完整代码) …...
专题五:floodfill算法(扫雷游戏精讲)
以leetcode529题 题目解析: M表示:未挖出的地雷 E表示:未挖出的空白方块 什么叫未挖出,就是你没玩的时候,棋盘是什么样的,就是你站在上帝视角看待棋盘 B:表示挖出来是空白的,如…...
MySQL企业版免费开启,强先体验
近期Oracle突然宣布,MySQL企业版面向开发者免费开放下载,这一消息瞬间引爆DBA圈。作为数据库领域的“顶配车型”,企业版长期因高昂授权费让中小团队望而却步,如今免费开放无异于“劳斯莱斯开进菜市场”。 本文将深度拆解企业版的…...
React Contxt详解
React Contxt详解 React 的 Context API 是用于跨组件层级传递数据的解决方案,尤其适合解决「prop drilling」(多层组件手动传递 props)的问题。以下是关于 Context 的详细解析: 文章目录 React Contxt详解一、Context 核心概念二…...
前端工程的相关管理 git、branch、build
环境配置 标准环境打包 测试版:npm run build-test 预生产:npm run build-preview 正式版:npm run build 建议本地建里一个 .env.development.local 方便和后端联调时修改配置相关信息。 和 src 同级有一下区分环境的文件: .env.d…...
鸿蒙 Location Kit(位置服务)
移动终端设备已经深入人们日常生活的方方面面,如查看所在城市的天气、新闻轶事、出行打车、旅行导航、运动记录。这些习以为常的活动,都离不开定位用户终端设备的位置。 Location Kit 使用多种定位技术提供服务,可以准确地确定设备在室外/室…...
人工智能、机器学习与深度学习:概念解析与内在联系
人工智能、机器学习与深度学习:概念解析与内在联系 一、人工智能(Artificial Intelligence, AI) (一)人工智能的定义 人工智能的定义随着技术发展不断演变。从广义上讲,人工智能是指通过计算机技术实现的…...
【Linux学习】Ubuntu对用户进行管理
目录 写在前面 【Linux学习】Ubuntu对用户进行管理一、为什么需要用户管理?二、用户管理基础操作(一)用户管理1. 用户管理命令表格2. 关键操作场景说明场景一:创建用户并配置权限场景二:修改用户属性场景三:…...
JVM 垃圾回收器
以下是对主流 JVM 垃圾回收器的详细解析,涵盖 一、Serial GC(单线程串行回收器) 二、Parallel GC(吞吐量优先回收器) 三、CMS(Concurrent Mark Sweep,低延迟回收器) 四、G1&…...
JUC入门(三)
7、Callable 1、可以有返回值 2、可以抛出异常 3、方法不同 run()/call() 代码测试 老版本的应用 package com.yw.callable;public class Old {public static void main(String[] args) {new Thread(new MyThread()).start();} }class MyThread implements Runnable{Overri…...
RV1126多线程获取SMARTP的GOP模式数据和普通GOP模式数据
通过代码的方式同时获取SMARTP模式的VENC码流数据和普通GOP模式的VENC码流数据,并进行对比画质。 一.RV1126 VI采集摄像头数据并同时编码SMARTP模式和普通GOP模式的编码码流流程 RV1126利用多线程同时获取普通GOP的VENC码流数据和SMARTP的码流数据一般如上图&#…...
MySQL事务、视图、索引、备份和恢复
1. 事务 如果不使用事务,那么如果出现了张三账户汇款成功-500元,但是李四那边的服务器出现了故障没有接收到500元,那么就会出现张三账户里有500元但是李四那边的账户还是1元的情况,转账的500元被吞了。 创建事务 2. 视图 创建视图…...
yolov8训练模型优化模型【误检】
针对 YOLOv8 模型在电动车人脸检测中出现误检行人人脸的问题,结合最新研究与实践经验,以下提供多维度优化方案及具体实施步骤: 一、数据集优化 数据清洗与标注增强 剔除干扰样本:确保训练集中所有标注仅包含骑行状态的人脸&#x…...
初识MySQL · 索引
目录 前言: 重温磁盘 认识索引 为什么这么做,怎么做 重谈page 聚簇索引VS非聚簇索引 回表查询 索引分类 前言: 前文我们主要是介绍了MySQL的一些基本操作,增删查改一类的操作都介绍了,并且因为大多数情况下&am…...
Kubernetes in action-配置和应用升级
Kubernetes的配置和应用升级 1、配置1.1 configMap1.2 secret1.3 Downward API1.4 Kubernetes API 2、服务升级2.1 升级方式2.1.1 先删除所有的旧版pod,使用新版本pod替换2.1.2 先创建新版pod,再删除旧版本pod2.1.3 滚动优化 2.2 使用deployment声明式升…...
十三、面向对象底层逻辑-Dubbo序列化Serialization接口
一、引言:分布式通信的数据桥梁 在分布式服务调用中,参数的跨网络传输需要将对象转化为二进制流,这一过程直接影响系统的性能、兼容性与安全性。Dubbo通过Serialization接口构建了可扩展的序列化体系,支持多种序列化协议的无缝切…...
5.19 打卡
DAY 30 模块和库的导入 知识点回顾: 导入官方库的三种手段导入自定义库/模块的方式导入库/模块的核心逻辑:找到根目录(python解释器的目录和终端的目录不一致) 作业:自己新建几个不同路径文件尝试下如何导入...
MathType公式如何按照(1)(2)…编号
在word中使用mathtype插入公式,发现插入的公式编号默认为(1.1),(1.2)…,但论文中常用的公式编号是(1)(2)…,分享一下如何实现(1.1)→(1)。 ①word菜单找到“MathType”,点击“插入编号”-“格式化”。 ②取消勾选“章编号”和“节…...
解决即使安装了pageoffice网页还是无法跳转、点击按钮没有反应等问题
出现的现象: 安装了pageoffice网页还是无法跳转、点击按钮没有反应 网页提示的错误: 点击按钮之前右键检查网页发现的错误: 点击无效按钮之后右键检查出现的错误: 原因: 鉴于安全性的考虑,新版浏览器不支…...
正点原子STM32新建工程
MDK 源自德国的 KEIL 公司,是 RealView MDK 的简称。 MDK5 由两个部分组成: MDK Core 和 Software Packs。 MDK Core 又分成四个部分: uVision IDE with Editor(编辑器), ARMC/C Compiler(编译…...
计算机网络 第三章:运输层(一)
运输层位于应用层和网络层之间,是分层的网络体系结构的重要部分。该层为运行在不同主机上的应用进程提供直接的通信服务。通常特别关注因特网协议,即 TCP 和 UDP 运输层协议。 讨论运输层和网络层的关析,为研究运输层第一个关键功能ÿ…...
机器学习(14)——模型调参
文章目录 一、动态调参方法论1. 调参策略选择2. 千万数据优化原则 二、模型调参策略对比1. LightGBM调参路线2. XGBoost调参路线3. 随机森林调参策略 三、代码实现示例通用数据准备(适用于所有模型)1. LightGBM调参示例2. XGBoost调参示例3. 随机森林调参…...
基于PetaLinux的Zynq PS应用自启动全攻略
一、嵌入式Linux启动管理的艺术 在工业机器人、智能摄像头、边缘计算网关等场景中,开机自启动管理是系统可靠性的第一道关卡。本文将深入讲解Zynq PS端在PetaLinux环境下实现: Systemd服务深度定制启动时序精准控制启动速度优化技巧动态服务管理创新方案二、环境搭建与工程配…...
贪心算法:多处最优服务次序、删数问题
多处最优服务次序问题 问题描述:设有n个顾客同时等待一项服务。顾客i需要的服务时间为ti(1≤i≤n),共有s处可以提供此项服务。应如何安排n个顾客的服务次序,才能使平均等待时间达到最小?平均等待时间是n个顾客等待服务时间的总和除以n。 算法设计:对于给定的n个顾…...
使用 Flask 框架实现FTP,允许用户通过 Web 界面浏览和下载文件夹中的所有文件
Flask 文件和文件夹下载服务实现 以下是一个基于 Flask 框架的简单 Web 服务,用于开放指定文件夹(./shared_files),允许用户通过浏览器浏览和下载文件夹中的所有文件和子文件夹。ZIP 和 TAR 文件将直接下载,而文件夹将…...
【Go】从0开始学习Go
文章目录 从0开始学习Go0 与C对比1 代码框架1.1 helloworld式代码示例1.2 主体代码元素(核心三部分)1.3 其他 2 与C/C区别3 有用的小工具4 注意事项 从0开始学习Go 0 与C对比 特性CGo编译型语言需要编译为机器码直接编译为二进制可执行文件静态类型类型…...