STM32硬件I2C驱动OLED屏幕
本文基于STM32硬件I2C驱动SSD1306 OLED屏幕,提供完整的代码实现及关键注意事项,适用于128x32或128x64分辨率屏幕。代码通过模块化设计,支持显示字符、数字、汉字及位图,并优化了显存刷新机制。
零、完整代码
完整代码:
1)oled.c
/*** @file oled.c* @brief OLED显示驱动层,支持SSD1306控制器* @details 提供OLED初始化、基本绘图、字符显示、显存刷新等功能* @note 本驱动针对128x32分辨率和128x64OLED屏适配,需要修改106-110行的启动参数*/#include "oledfont.h"
#include "string.h"
#include "oled.h"
#include "stdlib.h"
#include "main.h"extern I2C_HandleTypeDef hi2c1; ///< I2C外设句柄/*** @brief OLED绘制位图* @param x0 起始列坐标(0~127)* @param y0 起始页号(0~3)* @param x1 结束列坐标(需大于x0)* @param y1 结束页号(需大于y0)* @param BMP 位图数据数组指针* @note 页号与屏幕行的对应关系:每页8行,128x32屏共4页*/
void OLED_DrawBMP(unsigned char x0, unsigned char y0, unsigned char x1, unsigned char y1, unsigned char BMP[])
{unsigned int j = 0;unsigned char x, y;if (y1 % 8 == 0)y = y1 / 8;elsey = y1 / 8 + 1;for (y = y0; y < y1; y++){OLED_Set_Pos(x0, y);for (x = x0; x < x1; x++){OLED_WR_Byte(BMP[j++], OLED_DATA);}}
}// OLED的显存
// 存放格式如下.
//[0]0 1 2 3 ... 127
//[1]0 1 2 3 ... 127
//[2]0 1 2 3 ... 127
//[3]0 1 2 3 ... 127
//[4]0 1 2 3 ... 127
//[5]0 1 2 3 ... 127
//[6]0 1 2 3 ... 127
//[7]0 1 2 3 ... 127
// (128x64显存,8页)
uint8_t OLED_GRAM[128][8];/*** @brief 刷新显存到OLED物理屏幕* @details 将GRAM数组内容通过I2C写入OLED的GDDRAM*/
void OLED_Refresh_Gram(void)
{uint8_t i, n;for (i = 0; i < 4; i++){ // 仅刷新前4页(原为8)OLED_WR_Byte(0xb0 + i, OLED_CMD);OLED_WR_Byte(0x00, OLED_CMD);OLED_WR_Byte(0x10, OLED_CMD);for (n = 0; n < 128; n++)OLED_WR_Byte(OLED_GRAM[n][i], OLED_DATA);}
}/*** @brief 初始化SSD1306控制器* @details 配置显示参数、硬件选项,执行上电序列*/
void OLED_Init(void)
{OLED_WR_Byte(0xAE,OLED_CMD);//关闭显示屏OLED_WR_Byte(0x40,OLED_CMD);//设置起始行地址OLED_WR_Byte(0xB0,OLED_CMD);//设置页面起始地址为页面寻址模式,0-7OLED_WR_Byte(0xC8,OLED_CMD);//上下反置关(行重映射),C8,从COM[N-1]扫描到COM0;C0,设置 从COM0扫描到COM[N-1],N为复用率OLED_WR_Byte(0x81,OLED_CMD);// 设置对比度OLED_WR_Byte(0xff,OLED_CMD);// 选择0xff对比度,选择范围0x00-0xffOLED_WR_Byte(0xa1,OLED_CMD);// 左右反置关(段重映射),A0H 设置GDDRAM的COL0映射到驱动器输出SEG0,A1H 设置COL127映射到SEG0OLED_WR_Byte(0xa6,OLED_CMD);// 正常显示(1亮0灭)OLED_WR_Byte(0xa8,OLED_CMD);// 设置多路传输比率,显示行数OLED_WR_Byte(0x1f,OLED_CMD);// MUX=31 (显示31行)OLED_WR_Byte(0xd3,OLED_CMD);// 设置垂直显示偏移(向上)OLED_WR_Byte(0x00,OLED_CMD);// 偏移0行OLED_WR_Byte(0xd5,OLED_CMD);// 设置DCLK分频和OSC频率OLED_WR_Byte(0xf0,OLED_CMD);// 频率最高OLED_WR_Byte(0xd9,OLED_CMD);// 设置预充电的持续时间OLED_WR_Byte(0x22,OLED_CMD);OLED_WR_Byte(0xda,OLED_CMD);// 设置COM引脚配置// 128*32OLED_WR_Byte(0x02,OLED_CMD);// 序列COM配置,禁用左右反置// 128*64// OLED_WR_Byte(0x12, OLED_CMD); // 交替COM,左右不反置OLED_WR_Byte(0xdb,OLED_CMD);//调整Vcomh调节器的输出OLED_WR_Byte(0x49,OLED_CMD);OLED_WR_Byte(0x8d,OLED_CMD);// 启用电荷泵OLED_WR_Byte(0x14,OLED_CMD);// 启用电荷泵OLED_WR_Byte(0xaf,OLED_CMD);// 开OLED显示OLED_Clear();
}/*** @brief 显示单个ASCII字符* @param x 列坐标(0-127)* @param y 页号(0-3)* @param chr 要显示的字符* @param Char_Size 字体大小:8或16* @note 8像素字体使用6x8点阵,16像素使用8x16点阵*/
void OLED_ShowChar(uint8_t x, uint8_t y, uint8_t chr, uint8_t Char_Size)
{unsigned char c = 0, i = 0;c = chr - ' '; // 得到偏移后的值if (x > Max_Column - 1){x = 0;// 原代码:y += 2(适用于8页,改为y += 1适应4页)y = y + 1; // 每页高度为8像素,32行共4页}if (Char_Size == 16){// 16像素字体占2页(原为两行,需确保不超过4页)OLED_Set_Pos(x, y);for (i = 0; i < 8; i++)OLED_WR_Byte(F8X16[c * 16 + i], OLED_DATA);OLED_Set_Pos(x, y + 1);for (i = 0; i < 8; i++)OLED_WR_Byte(F8X16[c * 16 + i + 8], OLED_DATA);}else if (Char_Size == 8){OLED_Set_Pos(x, y);for (i = 0; i < 6; i++)OLED_WR_Byte(F6x8[c][i], OLED_DATA);}
}/*** @brief 显示无符号整数* @param x,y 起始坐标* @param num 要显示的数字(0~4294967295)* @param len 显示位数(自动截断高位)* @param size2 字体大小(需为8或16)*/
void OLED_ShowNum(uint8_t x, uint8_t y, uint32_t num, uint8_t len, uint8_t size2) // OLED_ShowNum(103,6,t,3,16);//显示ASCII字符的码值
{uint8_t t, temp;uint8_t enshow = 0;for (t = 0; t < len; t++){temp = (num / oled_pow(10, len - t - 1)) % 10;if (enshow == 0 && t < (len - 1)){if (temp == 0){OLED_ShowChar(x + (size2 / 2) * t, y, ' ', size2);continue;}elseenshow = 1;}OLED_ShowChar(x + (size2 / 2) * t, y, temp + '0', size2);}
}/*** @brief 计算m的n次方* @param m 底数* @param n 指数* @return m^n的值*/
uint32_t oled_pow(uint8_t m, uint8_t n)
{uint32_t result = 1;while (n--)result *= m;return result;
}/*** @brief 显示字符串* @param x,y 起始坐标* @param chr 字符串数组指针* @param Char_Size 字体大小(8或16)* @note 字符串以'\0'结尾,自动计算长度*/
void OLED_ShowString(uint8_t x, uint8_t y, uint8_t chr[], uint8_t Char_Size)
{unsigned char j = 0;while (chr[j] != '\0'){OLED_ShowChar(x, y, chr[j], Char_Size);x += 8;if (x > Max_Column - 8){x = 0;y += 2;}j++;}
}/*** @brief 显示汉字* @param x,y 起始坐标* @param no 汉字索引(0~7)* @note 汉字数据存储在ZH数组中,索引范围为0~7*/
void OLED_ShowCHinese(uint8_t x, uint8_t y, uint8_t no)
{uint8_t t, adder = 0;OLED_Set_Pos(x, y);for (t = 0; t < 16; t++){OLED_WR_Byte(ZH[2 * no][t], OLED_DATA);adder += 1;}OLED_Set_Pos(x, y + 1);for (t = 0; t < 16; t++){OLED_WR_Byte(ZH[2 * no + 1][t], OLED_DATA);adder += 1;}
}/*** @brief 设置OLED显示位置* @param x 列坐标(0~127)* @param y 页号(0~3)* @note 页号与屏幕行的对应关系:每页8行,128x32屏共4页*/
void OLED_Set_Pos(unsigned char x, unsigned char y)
{OLED_WR_Byte(0xb0 + y, OLED_CMD);OLED_WR_Byte(((x & 0xf0) >> 4) | 0x10, OLED_CMD);OLED_WR_Byte((x & 0x0f), OLED_CMD);
}// 打开OLED显示
void OLED_Display_On(void)
{OLED_WR_Byte(0X8D, OLED_CMD); // SET DCDC命令OLED_WR_Byte(0X14, OLED_CMD); // DCDC ONOLED_WR_Byte(0XAF, OLED_CMD); // DISPLAY ON
}// 关闭OLED显示
void OLED_Display_Off(void)
{OLED_WR_Byte(0X8D, OLED_CMD); // SET DCDC命令OLED_WR_Byte(0X10, OLED_CMD); // DCDC OFFOLED_WR_Byte(0XAE, OLED_CMD); // DISPLAY OFF
}/*** @brief 清空OLED显示* @note 将所有像素设置为0(黑色)*/
void OLED_Clear(void)
{uint8_t i, n;for (i = 0; i < 8; i++){OLED_WR_Byte(0xb0 + i, OLED_CMD); // 设置页地址(0~7)OLED_WR_Byte(0x00, OLED_CMD); // 设置显示位置—列低地址OLED_WR_Byte(0x10, OLED_CMD); // 设置显示位置—列高地址for (n = 0; n < 128; n++)OLED_WR_Byte(0, OLED_DATA);} // 更新显示
}/*** @brief 打开OLED显示* @note 将所有像素设置为1(白色)*/
void OLED_On(void)
{uint8_t i, n;for (i = 0; i < 8; i++){OLED_WR_Byte(0xb0 + i, OLED_CMD); // 设置页地址(0~7)OLED_WR_Byte(0x00, OLED_CMD); // 设置显示位置—列低地址OLED_WR_Byte(0x10, OLED_CMD); // 设置显示位置—列高地址for (n = 0; n < 128; n++)OLED_WR_Byte(1, OLED_DATA);} // 更新显示
}/*** @brief 填充OLED显示* @param fill_Data 填充数据(0x00或0xFF)* @note 0x00填充黑色,0xFF填充白色*/
void fill_picture(unsigned char fill_Data)
{unsigned char m, n;for (m = 0; m < 8; m++){OLED_WR_Byte(0xb0 + m, 0); // page0-page1OLED_WR_Byte(0x00, 0); // low column start addressOLED_WR_Byte(0x10, 0); // high column start addressfor (n = 0; n < 128; n++){OLED_WR_Byte(fill_Data, 1);}}
}/*** @brief 写入数据或命令到OLED* @param dat 要写入的数据* @param cmd 0表示命令,1表示数据* @note 通过I2C将数据发送到OLED控制器*/
void OLED_WR_Byte(uint8_t dat, uint8_t cmd)
{static uint8_t cmd_data[2];if (cmd == OLED_CMD){cmd_data[0] = 0x00;}else{cmd_data[0] = 0x40;}cmd_data[1] = dat;HAL_I2C_Master_Transmit(&hi2c1, 0X78, cmd_data, 2, 10);
}/*** @brief 写入I2C命令或数据* @param I2C_Command 要写入的命令或数据* @note 通过I2C将数据发送到OLED控制器*/
void Write_IIC_Command(unsigned char I2C_Command) // 写命令
{uint8_t *pData;pData = &I2C_Command;HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x00, I2C_MEMADD_SIZE_8BIT, pData, 1, 100);
}/*** @brief 写入I2C数据* @param IIC_Data 要写入的数据* @note 通过I2C将数据发送到OLED控制器*/
void Write_IIC_Data(unsigned char IIC_Data) // 写数据
{uint8_t *pData;pData = &IIC_Data;HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x40, I2C_MEMADD_SIZE_8BIT, pData, 1, 100);
}
2)oled.h
#ifndef __OLED_H
#define __OLED_H
// #include "sys.h"#include "main.h"
// OLED模式设置
// 0: 4线串行模式 (模块的BS1,BS2均接GND)
#define OLED_MODE 0
#define X_WIDTH 128
#define Y_WIDTH 32
#define Max_Column 128 // 列
#define Max_Row 32 // 行#define SIZE 8
#define XLevelL 0x00
#define XLevelH 0x10#define Brightness 0xFF#define OLED_CMD 0 // 写命令
#define OLED_DATA 1 // 写数据void Write_IIC_Data(unsigned char IIC_Data);
void Write_IIC_Command(unsigned char I2C_Command);
void OLED_WR_Byte(uint8_t dat, uint8_t cmd);
void fill_picture(unsigned char fill_Data);
void OLED_On(void);
void OLED_Clear(void);
void OLED_Display_Off(void);
void OLED_Display_On(void);void OLED_Set_Pos(unsigned char x, unsigned char y);
void OLED_ShowCHinese(uint8_t x, uint8_t y, uint8_t no);
void OLED_ShowString(uint8_t x, uint8_t y, uint8_t chr[], uint8_t Char_Size); // OLED_ShowString(0,0,a,sizeof(a));
void OLED_ShowNum(uint8_t x, uint8_t y, uint32_t num, uint8_t len, uint8_t size2); // OLED_ShowNum(103,6,t,3,16);//显示ASCII字符的码值uint32_t oled_pow(uint8_t m, uint8_t n);
void OLED_ShowChar(uint8_t x, uint8_t y, uint8_t chr, uint8_t Char_Size);
void OLED_Init(void);
void OLED_Refresh_Gram(void);
void OLED_DrawBMP(unsigned char x0, unsigned char y0, unsigned char x1, unsigned char y1, unsigned char BMP[]);/*
x x x x x x x x x x x x x x x x ==16个字符列 y=0行
x x x x x x x x x x x x x x x x ==16个字符列 y=1行
x x x x x x x x x x x x x x x x ==16个字符列 y=2行
x x x x x x x x x x x x x x x x ==16个字符列 y=3行
x x x x x x x x x x x x x x x x ==16个字符列 y=4行
x x x x x x x x x x x x x x x x ==16个字符列 y=5行
x x x x x x x x x x x x x x x x ==16个字符列 y=6行
x x x x x x x x x x x x x x x x ==16个字符列 y=7行
*/#endif
3) oledfont.h
#ifndef __OLEDFONT_H
#define __OLEDFONT_H
//常用ASCII表
//偏移量32
//ASCII字符集: !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
//PC2LCD2002取模方式设置:阴码+逐列式+顺向+C51格式
//总共:3个字符集(12*12、16*16和24*24),用户可以自行新增其他分辨率的字符集。
//每个字符所占用的字节数为:(size/8+((size%8)?1:0))*(size/2),其中size:是字库生成时的点阵大小(12/16/24...)//12*12 ASCII字符集点阵
const unsigned char F6x8[][6] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// sp
0x00, 0x00, 0x00, 0x2f, 0x00, 0x00,// !
0x00, 0x00, 0x07, 0x00, 0x07, 0x00,// "
0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14,// #
0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12,// $
0x00, 0x62, 0x64, 0x08, 0x13, 0x23,// %
0x00, 0x36, 0x49, 0x55, 0x22, 0x50,// &
0x00, 0x00, 0x05, 0x03, 0x00, 0x00,// '
0x00, 0x00, 0x1c, 0x22, 0x41, 0x00,// (
0x00, 0x00, 0x41, 0x22, 0x1c, 0x00,// )
0x00, 0x14, 0x08, 0x3E, 0x08, 0x14,// *
0x00, 0x08, 0x08, 0x3E, 0x08, 0x08,// +
0x00, 0x00, 0x00, 0xA0, 0x60, 0x00,// ,
0x00, 0x08, 0x08, 0x08, 0x08, 0x08,// -
0x00, 0x00, 0x60, 0x60, 0x00, 0x00,// .
0x00, 0x20, 0x10, 0x08, 0x04, 0x02,// /
0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E,// 0
0x00, 0x00, 0x42, 0x7F, 0x40, 0x00,// 1
0x00, 0x42, 0x61, 0x51, 0x49, 0x46,// 2
0x00, 0x21, 0x41, 0x45, 0x4B, 0x31,// 3
0x00, 0x18, 0x14, 0x12, 0x7F, 0x10,// 4
0x00, 0x27, 0x45, 0x45, 0x45, 0x39,// 5
0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30,// 6
0x00, 0x01, 0x71, 0x09, 0x05, 0x03,// 7
0x00, 0x36, 0x49, 0x49, 0x49, 0x36,// 8
0x00, 0x06, 0x49, 0x49, 0x29, 0x1E,// 9
0x00, 0x00, 0x36, 0x36, 0x00, 0x00,// :
0x00, 0x00, 0x56, 0x36, 0x00, 0x00,// ;
0x00, 0x08, 0x14, 0x22, 0x41, 0x00,// <
0x00, 0x14, 0x14, 0x14, 0x14, 0x14,// =
0x00, 0x00, 0x41, 0x22, 0x14, 0x08,// >
0x00, 0x02, 0x01, 0x51, 0x09, 0x06,// ?
0x00, 0x32, 0x49, 0x59, 0x51, 0x3E,// @
0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C,// A
0x00, 0x7F, 0x49, 0x49, 0x49, 0x36,// B
0x00, 0x3E, 0x41, 0x41, 0x41, 0x22,// C
0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C,// D
0x00, 0x7F, 0x49, 0x49, 0x49, 0x41,// E
0x00, 0x7F, 0x09, 0x09, 0x09, 0x01,// F
0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A,// G
0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F,// H
0x00, 0x00, 0x41, 0x7F, 0x41, 0x00,// I
0x00, 0x20, 0x40, 0x41, 0x3F, 0x01,// J
0x00, 0x7F, 0x08, 0x14, 0x22, 0x41,// K
0x00, 0x7F, 0x40, 0x40, 0x40, 0x40,// L
0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F,// M
0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F,// N
0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E,// O
0x00, 0x7F, 0x09, 0x09, 0x09, 0x06,// P
0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E,// Q
0x00, 0x7F, 0x09, 0x19, 0x29, 0x46,// R
0x00, 0x46, 0x49, 0x49, 0x49, 0x31,// S
0x00, 0x01, 0x01, 0x7F, 0x01, 0x01,// T
0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F,// U
0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F,// V
0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F,// W
0x00, 0x63, 0x14, 0x08, 0x14, 0x63,// X
0x00, 0x07, 0x08, 0x70, 0x08, 0x07,// Y
0x00, 0x61, 0x51, 0x49, 0x45, 0x43,// Z
0x00, 0x00, 0x7F, 0x41, 0x41, 0x00,// [
0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55,// 55
0x00, 0x00, 0x41, 0x41, 0x7F, 0x00,// ]
0x00, 0x04, 0x02, 0x01, 0x02, 0x04,// ^
0x00, 0x40, 0x40, 0x40, 0x40, 0x40,// _
0x00, 0x00, 0x01, 0x02, 0x04, 0x00,// '
0x00, 0x20, 0x54, 0x54, 0x54, 0x78,// a
0x00, 0x7F, 0x48, 0x44, 0x44, 0x38,// b
0x00, 0x38, 0x44, 0x44, 0x44, 0x20,// c
0x00, 0x38, 0x44, 0x44, 0x48, 0x7F,// d
0x00, 0x38, 0x54, 0x54, 0x54, 0x18,// e
0x00, 0x08, 0x7E, 0x09, 0x01, 0x02,// f
0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C,// g
0x00, 0x7F, 0x08, 0x04, 0x04, 0x78,// h
0x00, 0x00, 0x44, 0x7D, 0x40, 0x00,// i
0x00, 0x40, 0x80, 0x84, 0x7D, 0x00,// j
0x00, 0x7F, 0x10, 0x28, 0x44, 0x00,// k
0x00, 0x00, 0x41, 0x7F, 0x40, 0x00,// l
0x00, 0x7C, 0x04, 0x18, 0x04, 0x78,// m
0x00, 0x7C, 0x08, 0x04, 0x04, 0x78,// n
0x00, 0x38, 0x44, 0x44, 0x44, 0x38,// o
0x00, 0xFC, 0x24, 0x24, 0x24, 0x18,// p
0x00, 0x18, 0x24, 0x24, 0x18, 0xFC,// q
0x00, 0x7C, 0x08, 0x04, 0x04, 0x08,// r
0x00, 0x48, 0x54, 0x54, 0x54, 0x20,// s
0x00, 0x04, 0x3F, 0x44, 0x40, 0x20,// t
0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C,// u
0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C,// v
0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C,// w
0x00, 0x44, 0x28, 0x10, 0x28, 0x44,// x
0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C,// y
0x00, 0x44, 0x64, 0x54, 0x4C, 0x44,// z
0x14, 0x14, 0x14, 0x14, 0x14, 0x14,// horiz lines
};/****************************************8*16的点阵************************************/
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
};char ZH[][32]={ {0x40,0x44,0x54,0x65,0xC6,0x64,0x54,0x44,0x00,0xFC,0x44,0x44,0xC4,0x42,0x40,0x00},
{0x20,0x12,0x4A,0x82,0x7F,0x02,0x0A,0x92,0x60,0x1F,0x00,0x00,0xFF,0x00,0x00,0x00},/*"新",0*/
{0x00,0x20,0x18,0xC7,0x44,0x44,0x44,0x44,0xFC,0x44,0x44,0x44,0x44,0x04,0x00,0x00},
{0x04,0x04,0x04,0x07,0x04,0x04,0x04,0x04,0xFF,0x04,0x04,0x04,0x04,0x04,0x04,0x00},/*"年",1*/
{0x00,0xE0,0x00,0xFF,0x10,0x20,0x08,0x08,0x08,0xFF,0x08,0x08,0xF8,0x00,0x00,0x00},
{0x01,0x00,0x00,0xFF,0x00,0x81,0x41,0x31,0x0D,0x03,0x0D,0x31,0x41,0x81,0x81,0x00},/*"快",2*/
{0x00,0x00,0xE0,0x9C,0x84,0x84,0x84,0xF4,0x82,0x82,0x83,0x82,0x80,0x80,0x00,0x00},
{0x00,0x20,0x10,0x08,0x06,0x40,0x80,0x7F,0x00,0x00,0x02,0x04,0x08,0x30,0x00,0x00},/*"乐",3*/
{0x40,0x30,0x11,0x96,0x90,0x90,0x91,0x96,0x90,0x90,0x98,0x14,0x13,0x50,0x30,0x00},
{0x04,0x04,0x04,0x04,0x04,0x44,0x84,0x7E,0x06,0x05,0x04,0x04,0x04,0x04,0x04,0x00},/*"学",4*/
{0x80,0x80,0x80,0x80,0xFF,0x80,0x80,0xA0,0x90,0x88,0x84,0x82,0x80,0x80,0x80,0x00},
{0x00,0x00,0x00,0x00,0xFF,0x40,0x21,0x12,0x04,0x08,0x10,0x20,0x20,0x40,0x40,0x00},/*"长",5*/
{0x20,0x24,0x24,0x24,0xFE,0x23,0x22,0x20,0x20,0xFF,0x20,0x22,0x2C,0xA0,0x20,0x00},
{0x00,0x08,0x48,0x84,0x7F,0x02,0x41,0x40,0x20,0x13,0x0C,0x14,0x22,0x41,0xF8,0x00},/*"我",6*/
{0x10,0x0C,0x04,0x24,0x24,0x24,0x25,0x26,0x24,0x24,0x24,0x24,0x04,0x14,0x0C,0x00},
{0x00,0x81,0x81,0x41,0x31,0x0F,0x01,0x01,0x01,0x7F,0x81,0x81,0x81,0xF1,0x00,0x00},/*"完",7*/
{0x00,0x00,0xF8,0x88,0x88,0x88,0x88,0x08,0x08,0xFF,0x08,0x09,0x0A,0xC8,0x08,0x00},
{0x80,0x60,0x1F,0x00,0x10,0x20,0x1F,0x80,0x40,0x21,0x16,0x18,0x26,0x41,0xF8,0x00},/*"成",8*/
{0x00,0xFC,0x04,0xFC,0x00,0x10,0x10,0xFF,0x90,0xC8,0x09,0x0E,0x08,0xE8,0x08,0x00},
{0x00,0x0F,0x04,0x0F,0x00,0x44,0x82,0x7F,0x00,0x40,0x4F,0x60,0x5C,0x43,0x40,0x00},/*"啦",9*/{0x10,0x88,0xC4,0x33,0x00,0x20,0x10,0x28,0x24,0xE3,0x24,0x28,0x10,0x20,0x20,0x00},
{0x01,0x00,0xFF,0x00,0x20,0x11,0x0D,0x41,0x81,0x7F,0x01,0x05,0x09,0x31,0x00,0x00},/*"徐",10*/
/* (16 X 16 , 宋体 )*/{0x00,0xFE,0x22,0xFE,0x00,0xFE,0x22,0xFE,0x00,0xFC,0x16,0x25,0x84,0xFC,0x00,0x00},
{0x60,0x1F,0x22,0xBF,0x40,0x3F,0x82,0xFF,0x00,0x13,0x12,0x12,0x52,0x82,0x7E,0x00},/*"鹏",11*/
/* (16 X 16 , 宋体 )*/{0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0x02,0xFE,0x40,0xA0,0x10,0x08,0x00,0x00},
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0C,0x10,0x21,0x42,0xF0,0x00},/*"飞",12*/
/* (16 X 16 , 宋体 )*///每个字必须带大括号否则显示效果不好
};#endif
(注:需根据具体硬件调整I2C引脚和屏幕参数)
一、硬件连接
- OLED屏幕:SSD1306控制器,支持I2C通信。
- STM32引脚配置:
- SCL:I2C时钟线(如PB6)
- SDA:I2C数据线(如PB7)
- I2C地址:0x78(若屏幕带RESET引脚,需额外配置)
二、代码结构
1. 核心文件说明
- oled.c:驱动层实现,包含初始化、显存管理、字符显示等功能。
- oled.h:定义宏、函数原型及屏幕参数。
- oledfont.h:存储ASCII和汉字点阵数据(6x8、8x16字体)。
2. 关键函数解析
- OLED_Init():初始化SSD1306控制器,配置显示参数。
void OLED_Init(void) {OLED_WR_Byte(0xAE, OLED_CMD); // 关闭显示OLED_WR_Byte(0xD5, OLED_CMD); // 设置时钟分频OLED_WR_Byte(0xA8, OLED_CMD); // 设置复用率// ... 其他配置命令OLED_Clear(); // 清屏
}
- OLED_Refresh_Gram():将显存数据刷新到物理屏幕,通过I2C逐页写入。
- OLED_ShowChar():显示单个字符,支持8/16像素字体,自动换行。
三、关键实现细节
1. 显存管理
- 显存数组:OLED_GRAM[128][8],每页8行,共4页(128x32)或8页(128x64)。
- 刷新逻辑:仅刷新有效页,减少I2C传输量。
void OLED_Refresh_Gram(void) {for (uint8_t i = 0; i < 4; i++) { // 仅刷新前4页OLED_Set_Pos(0, i);HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x40, I2C_MEMADD_SIZE_8BIT, OLED_GRAM[i], 128, 100);}
}
2. 字体显示优化
- ASCII字符:使用F6x8和F8X16点阵数据,通过偏移量快速定位。
- 汉字显示:预存储常用汉字点阵(如“新年快乐”),通过索引调用。
void OLED_ShowCHinese(uint8_t x, uint8_t y, uint8_t no) {OLED_Set_Pos(x, y);for (uint8_t t = 0; t < 16; t++)OLED_WR_Byte(ZH[2*no][t], OLED_DATA); // 写入上半部分OLED_Set_Pos(x, y+1);for (uint8_t t = 0; t < 16; t++)OLED_WR_Byte(ZH[2*no+1][t], OLED_DATA); // 写入下半部分
}
四、注意事项(重点!)
-
头文件包含问题
- main.c中禁止包含oledfont.h,否则报错:工程\工程名.axf: Error: L6200E: Symbol F6x8 multiply defined (by gpio.o and main.o).等。
- 正确做法:仅在oled.c中包含oledfont.h,其他文件通过extern引用。
-
屏幕参数调整
- 修改初始化参数(oled.c第106-110行),否则字符高度异常。
// 128x32屏配置
OLED_WR_Byte(0xDA, OLED_CMD);
OLED_WR_Byte(0x02, OLED_CMD); // COM引脚配置
// 128x64屏需改为:OLED_WR_Byte(0x12, OLED_CMD);
-
I2C地址与速率
- 确认OLED的I2C地址(通常为0x78或0x7A)。
- 调整I2C时钟频率(STM32默认100kHz,SSD1306支持400kHz)。
- extern I2C_HandleTypeDef hi2c1; ///< I2C外设句柄,根据实际情况改
五、使用示例
显示字符串和数字
OLED_ShowString(0, 0, "Hello World!", 16); // 16像素字体
OLED_ShowNum(0, 2, 2023, 4, 16); // 显示数字2023
显示自定义位图
const uint8_t BMP[] = {0xFF, 0x81, 0xBD, ...}; // 位图数据
OLED_DrawBMP(0, 0, 128, 4, BMP); // 全屏显示位图
六、常见问题
- 屏幕不显示:检查I2C地址、引脚配置及初始化序列。
- 字符错位:确认OLED_Set_Pos()的页号与显存对应关系。
- 刷新闪烁:提高刷新频率(建议200Hz以上),或使用双缓冲机制。
感谢婷婷后援团的小徐同学❤❤❤
相关文章:
STM32硬件I2C驱动OLED屏幕
本文基于STM32硬件I2C驱动SSD1306 OLED屏幕,提供完整的代码实现及关键注意事项,适用于128x32或128x64分辨率屏幕。代码通过模块化设计,支持显示字符、数字、汉字及位图,并优化了显存刷新机制。 零、完整代码 完整代码: 1&#x…...
2021-11-16 C++歌手去掉2最高2最低均分
缘由大学一年级c编程题目-编程语言-CSDN问答 void 歌手去掉2最高2最低均分() {//缘由https://ask.csdn.net/questions/7551893?spm1005.2025.3001.5141int n 0, h 0, j 0, qd[6]{0}, fs[50]{0};scanf_s("%d", &n); j n; qd[2] qd[3] INT_MAX; qd[0] qd[…...
Vue插槽(Slots)详解
文章目录 1. 插槽简介1.1 什么是插槽?1.2 为什么需要插槽?1.3 插槽的基本语法 2. 默认插槽2.1 什么是默认插槽?2.2 默认插槽语法2.3 插槽默认内容2.4 默认插槽实例:创建一个卡片组件2.5 Vue 3中的默认插槽2.6 默认插槽的应用场景 …...
[虚幻官方教程学习笔记]深入理解实时渲染(An In-Depth Look at Real-Time Rendering)
原英文教程地址深入理解实时渲染(An In-Depth Look at Real-Time Rendering) 文章目录 1.Intro to An In-Depth Look at Real-Time RenderingCPU VS GPUDeferred VS Forward 2. Before Rendering and OcclusionCulling计算的步骤使用console command:fre…...
【bibtex4word】在Word中高效转换bib参考文献,Texlive环境安装bibtex4word插件
前言 现已退出科研界,本人水货一个。希望帮到有缘人 本篇关于如何将latex环境中的参考文献bib文件转化为word,和一些踩坑记录。 可以看下面的资料进行配置,后面的文字是这些资料的补充说明。 参考文章:https://blog.csdn.net/g…...
torch.nn 下的常用深度学习函数
1. 层(Layers) 这些函数用于定义神经网络中的各种层,是构建模型的基础模块。 torch.nn.Linear 用途:全连接层(也称为线性层)。用于将输入数据从一个维度映射到另一个维度,常用于神经网络的隐藏…...
(2025)图文解锁RAG从原理到实操
什么是RAG RAG(检索增强生成)是一种将语言模型与可搜索知识库结合的方法,主要包含以下关键步骤: 数据预处理 加载:从不同格式(PDF、Markdown等)中提取文本分块:将长文本分割成短序列(通常100-500个标记),作为检索单元…...
PXE_Kickstart_无人值守自动化安装系统
文章目录 1. PXE2. 配置服务参数2.1 tftp服务配置2.2 dhcp服务配置2.3 http服务配置 3. 配置PXE环境3.1 网络引导文件pxelinux.03.2 挂载镜像文件3.3 创建配置文件default3.4 复制镜像文件和驱动文件3.5 修改default文件3.6 配置ks.cfg文件 4. PXE客户端4.1 创建虚拟机…...
Redis经典面试题
本篇文章简单介绍一些 Redis 常见的面试题。 Redis 是什么? Redis,英文全称是Remote Dictionary Server(远程字典服务),是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库&…...
Vite Proxy配置详解:从入门到实战应用
Vite Proxy配置详解:从入门到实战应用 一、什么是Proxy代理? Proxy(代理)是开发中常用的解决跨域问题的方案。Vite内置了基于http-proxy的代理功能,可以轻松配置API请求转发。 二、基础配置 在vite.config.js中配置…...
用AI写简历是否可行?
让AI批量写简历然后投简历是绝对不行的!!! 为什么不行,按照 "招聘经理" 工作经历举例: ai提示词:请帮我写一份招聘经理的工作经历内容: 招聘经理 | XXX科技有限公司 | 2020年…...
投影显示技术全解析:主流方案对比与雷克赛恩 CyberPro1 的核心优势
目录 一、主流投影显示技术深度解析 (一)LCD 投影技术 (二)DP 投影技术 (三)3LCD 技术 (四)FSHD 技术 FSHD 技术优势 二、雷克赛恩 CyberPro1 核心优势对比分析 (…...
Skyvern:用 AI+视觉驱动浏览器自动化
Skyvern:用 AI视觉驱动浏览器自动化 一、前言二、项目概览2.1 Skyvern 项目简介2.2 代码结构与模块划分 三、环境搭建与快速上手3.1 环境准备3.1.1 系统与依赖3.1.2 克隆项目3.1.3 安装 Python 依赖3.1.4 配置环境变量3.1.5 启动服务 3.2 验证安装 四、核心功能与实…...
101alpha第九
alpha ((rank(ts_arg_max((vwap - close), 3)) * rank(ts_delta(volume, 3))) 今天我们来学下这个 这个是两个rank操作符相加,然后和另外一个操作符相乘,我们来看实现了什么 vwap - close:这部分先计算成交量加权平均价(vwap&am…...
蓝牙身份证阅读器使用Uniapp调用二次开发demo
<template> <view class"content"> <view class"search" :loading"searchingstatus" click"searchbluetooth"> {{searchingstatus?"搜索中":"搜索蓝牙阅读器"}} </view> …...
好用的shell终端工具
FinalShell SSH工具,服务器管理 FinalShell SSH工具,服务器管理,远程桌面加速软件,支持Windows,macOS,Linux,版本4.5.12,更新日期2024.10.30 - FinalShell官网...
OSPF不规则区域划分
1、建立一条虚链路 vlink 可以被视为是⻣⼲区域的⼀段延伸。 这⼀条虚拟的链路,只能够跨域⼀个⾮⻣⼲区域。 [r2-ospf-1-area-0.0.0.1]vlink-peer 3.3.3.3 [r3-ospf-1-area-0.0.0.1]vlink-peer 2.2.2.2 在没有建立虚链路之前,r1是不能ping r4的。vlink建⽴的邻居关…...
复习javascript
1.修改元素内的内容 <div>zsgh</div> <script> const box1document.querySelector("div") box1.innerText"ppp" box1.innerHtml<h1>修改</h1> </script> 2.随机点名练习 <!DOCTYPE html> <html lang…...
海盗王64位服务端+32位客户端3.0版本
经过多天的尝试,终于把海盗王3.0的服务端改成了64位的,包括AccountServer GroupServer GameServer GateServer。 客户端则保留了32位。 服务端改成64位的好处是GameServer可以只启动一个就开全部地图,大概6G内存左右,直接将跳…...
【从零实现JsonRpc框架#2】Muduo库介绍
1.基本概念 Muduo 由陈硕大佬开发,是一个基于非阻塞IO和事件驱动的C高并发TCP网络编程库。它是一款基于主从Reactor模型的网络库,其使用的线程模型是 one loop per thread。 1.1 主从 Reactor 模型 主 Reactor(MainReactor,通常…...
如何创建伪服务器,伪接口
创建伪接口一般是用于模拟真实接口的行为,以便在开发和测试过程中进行使用,以下是一些常见的创建伪接口的方法: 使用 Web 框架搭建: Python 和 Flask:Flask 是一个轻量级的 Python Web 框架。示例代码如下:…...
NX949NX952美光科技闪存NX961NX964
NX949NX952美光科技闪存NX961NX964 在半导体存储领域,美光科技始终扮演着技术引领者的角色。其NX系列闪存产品线凭借卓越的性能与创新设计,成为数据中心、人工智能、高端消费电子等场景的核心组件。本文将围绕NX949、NX952、NX961及NX964四款代表性产品…...
vue配置代理解决前端跨域的问题
文章目录 一、概述二、报错现象三、通过配置代理来解决修改request.js中的baseURL为/api在vite.config.js中增加代理配置 四、参考资料 一、概述 跨域是指由于浏览器的同源策略限制,向不同源(不同协议、不同域名、不同端口)发送ajax请求会失败 二、报错现象 三、…...
深入解析Vue3中ref与reactive的区别及源码实现
深入解析Vue3中ref与reactive的区别及源码实现 前言 Vue3带来了全新的响应式系统,其中ref和reactive是最常用的两个API。本文将从基础使用、核心区别到源码实现,由浅入深地分析这两个API。 一、基础使用 1. ref import { ref } from vueconst count…...
Java Bean容器详解:核心功能与最佳使用实践
在Java企业级开发中,Bean容器是框架的核心组件之一,它通过管理对象(Bean)的生命周期、依赖关系等,显著提升了代码的可维护性和扩展性。主流的框架如Spring、Jakarta EE(原Java EE)均提供了成熟的…...
Xilinx Kintex-7 XC7K325T-2FFG676I 赛灵思 FPGA
XC7K325T-2FFG676I 属于 Kintex-7 FPGA ,低功耗与合理成本的应用市场,可提供比前代产品两倍的性价比提升和卓越的系统集成能力。该器件于 28 nm 工艺节点制造,速度等级为 -2,适合对时序要求严格但预算有限的系统设计。 产品架构与…...
AI实战笔记(1)AI 的 6 大核心方向 + 学习阶段路径
一、机器学习(ML) 目标:用数据“训练”模型,完成分类、回归、聚类等任务。 学习阶段: (1)基础数学:线性代数、概率统计、微积分(适度) (2…...
Ceph集群故障处理 - PG不一致修复
Ceph集群故障处理 - PG不一致修复 目录故障现象故障分析故障定位修复过程磁盘状态检查OSD存储结构检查修复分析故障总结问题原因修复方法后续建议经验教训最佳实践 参考资料 # ceph -v ceph version 14.2.22目录 故障现象故障分析故障定位修复过程磁盘状态检查OSD存储结构检查…...
【前端】每日一道面试题3:如何实现一个基于CSS Grid的12列自适应布局?
要实现一个基于CSS Grid的12列自适应布局,关键在于利用网格系统的灵活性和响应式设计能力。以下是具体实现步骤及核心代码示例: 一、基础网格容器定义 创建网格容器 使用display: grid将父元素定义为网格容器: .container {display: grid;gr…...
leetcode 349. Intersection of Two Arrays
题目描述 题目限制0 < nums1[i], nums2[i] < 1000,所以可以开辟一个1001个元素的数组来做哈希表。 class Solution { public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {vector<int> table(1001,0…...
机器学习 day01
文章目录 前言一、机器学习的基本概念二、数据集的加载1.玩具数据集2.联网数据集3.本地数据集 三、数据集的划分四、特征提取1.稀疏矩阵与稠密矩阵2.字典列表特征提取3.文本特征提取 前言 目前我开始学习机器学习部分的相关知识,通过今天的学习,我掌握了…...
C++STL——priority_queue
优先队列 前言优先队列仿函数头文件 前言 本篇主要讲解优先队列及其底层实现。 优先队列 优先队列的本质就是个堆,其与queue一样,都是容器适配器,不过优先队列是默认为vector实现的。priority_queue的接口优先队列默认为大根堆。 仿函数 …...
DS18B20温度传感器
1.基本信息 测温范围为一55~ 125℃;3.3/5V的供电电压;-10~85内精度较高; 典型的温度转换时间为 750ms(12 位分辨率); 输出最小分辨率:0.0625; 采用单总线数据格式&am…...
《Python星球日记》 第50天:深度学习概述与环境搭建
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、什么是深度学习?它与传统机器学习的区别1. 深度学习的定义2. 深…...
BUUCTF——Cookie is so stable
BUUCTF——Cookie is so stable 进入靶场 页面有点熟悉 跟之前做过的靶场有点像 先简单看一看靶场信息 有几个功能点 flag.php 随便输了个admin 根据题目提示 应该与cookie有关 抓包看看 构造payload Cookie: PHPSESSIDef0623af2c1a6d2012d57f3529427d52; user{{7*7}}有…...
Java 基础面试题
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/literature?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,…...
bcm5482 phy 场景总结
1,BCM5482是一款双端口10/100/1000BASE-T以太网PHY芯片,支持多种速率和双工模式。其配置主要通过MDIO(Management Data Input/Output)接口进行,MDIO接口用于访问PHY芯片内部的寄存器,从而配置网络速率、双工模式以及其他相关参数。 a,具体以下面两种场景举例 2. 寄存器和…...
小程序多线程实战
在小程序开发中,由于微信小程序的运行环境限制,原生并不支持传统意义上的多线程编程,但可以通过以下两种核心方案实现类似多线程的并发处理效果,尤其在处理复杂计算、避免主线程阻塞时非常关键: 一、官方方案ÿ…...
PPT图表怎么制作?说5款自己使用过的PPT图表制作工具
PPT图表怎么制作?准备一份吸引人的PPT演示文稿时,图表往往能起到画龙点睛的作用。但是,对于很多人来说,制作既美观又专业的图表却不是一件容易的事情。今天,我们就来聊聊如何利用一些优秀的工具制作PPT图表。 1、亿图图…...
渠道销售简历模板范文
模板信息 简历范文名称:渠道销售简历模板范文,所属行业:其他 | 职位,模板编号:KRZ3J3 专业的个人简历模板,逻辑清晰,排版简洁美观,让你的个人简历显得更专业,找到好工作…...
数据库实验10
设计性实验 1.实验要求 1.编写函数FsumXXX,1~n(参数)求和; GO CREATE FUNCTION Fsum065 (n INT) RETURNS INT AS BEGIN DECLARE sum INT 0 WHILE n > 0 BEGIN SET sum sum n SET n n - 1 END RETURN sum END …...
C#异步Task,await,async和Unity同步协程
标题 TaskawaitasyncUnity协程 Task Task是声明异步任务的必要关键字,也可以使用Task<>泛型来定义Task的返回值。 await await是用于等待一个Task结束,否则让出该线程控制权,让步给其他线程,直到该Task结束才往下运行。 …...
【ML-Agents】ML-Agents示例项目导入unity报错解决
最近在跑ML-Agents的示例代码,无奈往unity中导入项目后,就出现报错。本文简要描述了各个报错的解决方法。 文章目录 一、error CS0234: The type or namespace name InputSystem does not exist in the namespace UnityEngine (are you missing an assem…...
【Web前端开发】HTML基础
Web前端开发是用来直接给用户呈现一个一个的网页,主要包含实现用户的结构(HTML)、样式(CSS)、交互(JavaScript)。然而一个软件通常是由后端和前端完成的。可以查阅文档:HTML 教程 (w…...
spark-哈希join介绍
目录 1. Shuffle Join 和 Hash Join 的复杂度1.1 Shuffle Join1.2 Hash Join 2. 哈希算法的原理2.1 什么是哈希算法?2.2 哈希算法的工作原理2.3 常见哈希函数 3. 哈希算法的弊端3.1 哈希碰撞3.2 哈希分布不均匀3.3 哈希值不可逆 4. 哈希碰撞的处理方法4.1 链地址法4…...
计算机网络与多线程同步机制详解
一、IP地址与子网划分 在互联网世界中,IP地址就像是每个设备的"门牌号",它使得数据包能够准确送达目的地。IP地址的划分与管理就像城市的规划,通过合理的子网划分,能够高效地管理网络资源。 子网掩码的工作原理 子网…...
栈溢出攻击最基本原理
函数在调用的过程中,函数在调用之前呢,会将调用完这个函数之后的下一条命令的地址保存到LR中。 void func() {int a[4];a[6] 100; } 这个函数在用gcc编译的时候是不会报错的,所以我们可以在尝试之后,修改LR的值,让代…...
ChemDraw、InDraw、KingDraw有什么差别?
在化学相关的科研与教学领域,一款好用的结构式编辑器至关重要,ChemDraw因此闻名;但近年来,ChemDraw代理商频繁发送律师函,给学校和企业带来诸多困扰,促使大家纷纷寻找替代软件。InDraw和KingDraw这两款软件…...
NVMe控制器IP设计之接口模块
这是NVMe控制器IP设计系列博客之一,其他的见本博客或csdn搜用户名:tiantianuser。相关视频见B站用户名:专注与守望。 接口转换模块负责完成AXI4接口与控制器内部的自定义接口之间的转换工作。接口转换模块的框图如图1所示。 图1 接口转换示…...
从0开始学linux韦东山教程第三章问题小结(2)
本人从0开始学习linux,使用的是韦东山的教程,在跟着课程学习的情况下的所遇到的问题的总结,理论虽枯燥但是是基础。 摘要关键词:PC远程访问ubuntu配置,ubuntu配置uboot环境,串口控制开发板 本文详细介绍以下问题&…...