往期内容
STM32F1基于HAL库的学习记录实用使用教程分享(一、GPIO_Output)
STM32F1基于HAL库的学习记录实用使用教程分享(二、GPIO_Input 按键)
STM32F1基于HAL库的学习记录实用使用教程分享(三、外部中断 按键)
文章目录
前言
本文记录了通过使用STM32F103ZET6单片机进行OLED_IIC的学习
随着嵌入式行业的兴起,于此记录个人的一些学习过程并进行分享,本次是单片机控制里很重要的一个通信协议:IIC
声明:本文章在编写过程中,我始终致力于尊重并保护所有原创内容及其知识产权。然而,由于信息来源的多样性和复杂性,可能存在个别内容未明确标注出处、存在事实性错误或无意中侵犯了他人的知识产权的情况。对于任何可能存在的上述问题,我深感歉意,并在此提前向受影响的作者表示最诚挚的歉意。我始终秉持着尊重原创、维护知识产权的原则,绝无意侵犯任何人的合法权益。一旦收到您的反馈,我将立即核实并在第一时间内对文章进行修改。这包括但不限于补充相关引用信息、更正错误内容或删除涉嫌侵权的内容。再次感谢您的关注与支持,期待与您共同营造一个更加美好的知识共享空间。新手文章诸多不足,还望海涵。
一、IIC
IIC(Inter-Integrated Circuit,集成电路间总线)是一种同步的多主机通信总线,广泛用于连接微控制器与其他设备,如传感器、存储器等。IIC总线支持多个主设备和从设备之间的通信,可以在软件和硬件层面上进行。这两者之间的主要区别在于实现方式和控制机制。
硬件IIC
专用硬件支持:硬件 IIC 由微控制器或其他设备内部的专用硬件模块实现,包括 IIC 总线控制器和物理层接口。这种设计使得 IIC 通信更为高效,能够直接处理信号的发送和接收。
自动控制:硬件 IIC 模块能够自动管理 IIC 协议的所有细节,包括起始条件、地址传输、数据传输和应答信号等。这种自动化处理减少了微控制器的负担,使其能将更多的资源用于其他任务。
高效性:由于硬件 IIC 模块在独立的硬件层面上运作,因此其数据传输效率通常高于软件 IIC。硬件 IIC 能在执行通信时,同时并行处理其他操作,从而提高系统整体性能。
资源占用:虽然硬件 IIC 提高了通信效率,但也可能会占用更多的硬件资源,如 GPIO 引脚 和 内部寄存器。这意味着在设计电路时需要考虑资源的合理配置。
灵活性:硬件 IIC 的灵活性相对较低,其功能和特性由硬件电路设计决定,调整和改动的可能性有限。相比之下,软件 IIC 更具灵活性,可以根据需要进行编程和修改。
适用场景:硬件 IIC 非常适合于对 实时性 和 性能 要求较高的应用,尤其是在需要频繁进行数据传输的情况下。而软件 IIC 则更适合于对硬件资源要求较少和灵活性较高的场合,例如在开发测试阶段或快速原型设计时。
软件IIC
软件实现:软件 IIC 不依赖于专用的硬件模块,而是通过软件编程来模拟 IIC 协议的所有操作。这使得它可以在没有专用硬件支持的系统上实现 IIC 通信。
控制信号生成:软件 IIC 通过手动控制 GPIO 引脚 来生成 IIC 总线上的时钟信号(SCL)和数据线信号(SDA)。这种方式的灵活性使得用户能够准确调整信号的启动和传输过程。
效率:由于软件 IIC 需要 CPU 时间来生成和处理 IIC 信号,其效率通常低于硬件 IIC。在高频次传输的应用中,软件 IIC 可能成为性能瓶颈。
资源占用:相较于硬件 IIC,软件 IIC 占用的硬件资源更少,仅需几个 GPIO 引脚 来支持基本的通信。这使得软件 IIC 成为资源受限环境中的良好选择。
灵活性:软件 IIC 具有高度的灵活性,能够根据需要调整时序和协议细节,特别适合在没有硬件 IIC 模块的设备上或需要特定定制的应用场景。开发者可以轻松地修改代码来满足特定需求。
适用场景:软件 IIC 特别适用于快速原型开发、测试或小规模系统,并在实施定制通信协议或实验性功能时表现出色。它为灵活的设计和修改提供了便利,尤其在开发过程中需要频繁调整的情况下尤为有效。
1.概念
IIC(Inter-Integrated Circuit)总线是一种由 NXP(原 PHILIPS)公司开发的两线式串行通信协议。这种总线主要用于连接微控制器与其外围设备,广泛应用于主控制器与从器件之间的主从通信。
其特征包括:
两线制设计:IIC 总线仅使用两根信号线——数据线(SDA)和时钟线(SCL),简化了连接和布线。
主从通信:在 IIC 总线上,通信是以主从架构进行的,任意时刻只能有一个主机向多个从器件发送命令。因此,主机负责控制通信过程,而从器件执行接收和响应。
短距离传输:IIC 总线主要适用于小数据量的场合,传输距离相对较短,通常不超过几米。这使得它特别适合于PCB(印刷电路板)内的设备互联。
最高速度:高速 IIC 总线的传输速率可达 400 kbps,适合于需要快速数据传输的应用。在某些情况下,IIC 的速率甚至可以提升至 1 Mbps,满足更高性能的需求。
双向通信:IIC 总线支持在 CPU 与被控 IC 之间、IC 与 IC 之间的双向数据传输。这种双向能力使得设备之间可以轻松地交换信息。
应用场景
IIC 总线被广泛应用于各种项目和产品,包括但不限于:
传感器:用于与各种传感器或执行器的连接,如温度传感器、气体传感器、显示器等。
嵌入式系统:在微控制器与外围设备之间建立有效的通信链路。
消费电子:如智能家居、便携式设备等领域,提供高效的数据传输解决方案。
2.IIC作用
一般来讲,中断有三个作用:
实时控制:当温度较高时,自动开启空调功能。
故障处理:出现错误时及时修正。
数据传输:串口或其他通信方式进行数据的传输
3.IIC的特点
IIC初始化与信号
-
初始化
在 IIC 总线的初始化阶段,SCL(时钟线)和 SDA(数据线)均应保持在高电平状态。这一状态表示总线处于空闲等待状态,准备进行后续的通信。 -
开始信号
开始信号的生成步骤如下:保持 SCL 高电平:在发送开始信号前,确保时钟线 SCL 维持在高电平状态。
SDA 由高变低:在 SCL 处于高电平时,数据线 SDA 必须从高电平转为低电平。
拉低 SCL:最后,将 SCL 线拉低,完成开始信号的发送。此时,设备进入数据传输状态。 -
停止信号
停止信号的生成步骤如下:拉高 SCL:首先将 SCL 线拉高,确保与总线通信的同步。
SDA 由低变高:在 SCL 高电平时,数据线 SDA 从低电平变为高电平。
这一过程标志着数据传输的结束,设备重新回到空闲状态。
IIC 总线的优缺点
优点
硬件资源节约:由于只使用两条线,IIC 总线在连接和电路设计上显著降低了硬件资源的占用。
协议设计精巧:IIC 协议结构简单,易于理解和实现,使其成为开发者的优先选择。
易用性强:由于其简单的架构和广泛的应用场景,IIC 总线具有较高的易用性。
适用性广泛:广泛应用于传输命令、数据采集等场景,具有良好的互操作性,便于移植到不同的平台和设备。
缺点
传输速率较慢:相比于其他总线协议(如 SPI 和 UART)而言,IIC 总线的最大传输速率相对较低,这在需要高带宽数据传输的场合可能成为瓶颈。
二、配置
在选择好芯片并进入配置界面后的操作如下进行
1.RCC
2.SYS
3.时钟树
以上三个部分再前三期文章中都已赘述过,而且也很基础,故在从今以后的文章中都会省略,有需要的同学可翻阅往期文章查阅。
STM32F1基于HAL库的学习记录实用使用教程分享(一、GPIO_Output)
4.引脚配置
软件IIC
(1).选择引脚和模式
本文是基于第一篇文章的LED后进行的操作,有不了解的同学可以移步STM32F1基于HAL库的学习记录实用使用教程分享(一、GPIO_Output)进行配置。
根据硬件点击所需要使用的引脚,之后在弹窗里选择GPIO_Output,如图2-1 :
(2).进行细节配置
在此
硬件IIC
(1).选择引脚和模式
本文是基于第一篇文章的LED后进行的操作,有不了解的同学可以移步STM32F1基于HAL库的学习记录实用使用教程分享(一、GPIO_Output)进行配置。
根据硬件点击所需要使用的引脚,之后在弹窗里选择IIC1_SCL IIC1_SDA,如图2-3 :
(2).进行细节配置
在此
5.工程项目生成
该部分在前面的文章中也多次提及,在此不再赘述。
三、程序
sys.h、led.h、stm32f1xx_it.c和stm32f10x_it.h在我的第一篇博客STM32F1基于HAL库的学习记录实用使用教程分享(一、GPIO_Output)里。
软件IIC
GPIOX代表目标引脚的端口号,例如GPIOG。
GPIO_Pin代表目标引脚的引脚号,例如GPIO_Pin_2。
在main.h中可找到宏定义:
/* Private defines -----------------------------------------------------------*/
#define OLED_SCL_Pin GPIO_PIN_2
#define OLED_SCL_GPIO_Port GPIOG
#define OLED_SDA_Pin GPIO_PIN_3
#define OLED_SDA_GPIO_Port GPIOG
定义数组
uint8_t OledString[50]; //OLED显示使用的字符串数组
初始化并且在主函数循环内检测
/* USER CODE BEGIN 2 */
OLED_Init();
OLED_Clear();
OLED_Display_On();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
OLED_ShowNum(1,1,5,1,1);//显示数字
float temp = 0;
for(temp=0;temp<10;temp++)
{
sprintf((char *)OledString,"temp:%.2f",temp);//显示温度
OLED_ShowString(1,2,OledString,12); //显示在OLED上
HAL_Delay(200);
}
OLED_ShowCHinese(1,6,0); //嵌
OLED_ShowCHinese(17,6,1); //入
OLED_ShowCHinese(33,6,2); //式
}
/* USER CODE END 3 */
以此实现OLED显示的功能。
下面是OLED的驱动函数
//
// oled.c
// 作者 : ZTY
// 创建日期 : 2024-05-16
// 说明 : 0.96寸 OLED 显示屏驱动程序 (STM32F103ZE,通过 IIC 接口)
// 接线说明 :
// ----------------------------------------------------------------
// GND 接地
// VCC 供电 5V 或 3.3V
// SCL 时钟线连接 PG2 (SCL)
// SDA 数据线连接 PG3 (SDA)
// ----------------------------------------------------------------
//
#include "oled.h"
#include "stdlib.h"
#include "oledfont.h"
// OLED 显示的操作函数定义
// 启动 IIC 通信
void IIC_Start() {
OLED_SCLK_Set(); // 设置时钟线为高
OLED_SDIN_Set(); // 设置数据线为高
OLED_SDIN_Clr(); // 将数据线拉低
OLED_SCLK_Clr(); // 将时钟线拉低以准备发送数据
}
// 停止 IIC 通信
void IIC_Stop() {
OLED_SCLK_Set(); // 设置时钟线为高
OLED_SDIN_Clr(); // 将数据线拉低
OLED_SDIN_Set(); // 将数据线拉高以结束通信
}
// 等待 IIC 回应
void IIC_Wait_Ack() {
OLED_SCLK_Set(); // 设置时钟线为高
OLED_SCLK_Clr(); // 将时钟线拉低
}
// 写入一个字节到 IIC
void Write_IIC_Byte(unsigned char IIC_Byte) {
unsigned char i;
unsigned char m, da;
da = IIC_Byte;
OLED_SCLK_Clr(); // 开始时将时钟线拉低
for (i = 0; i < 8; i++) { // 逐位输出字节
m = da;
m = m & 0x80; // 取出最高位
if (m == 0x80) {
OLED_SDIN_Set(); // 发送 1
} else {
OLED_SDIN_Clr(); // 发送 0
}
da = da << 1; // 左移数据
OLED_SCLK_Set(); // 发送时钟信号
OLED_SCLK_Clr(); // 拉低以准备下一位
}
}
// 发送命令到 OLED
void Write_IIC_Command(unsigned char IIC_Command) {
IIC_Start(); // 启动 IIC
Write_IIC_Byte(0x78); // 从设备地址
IIC_Wait_Ack(); // 等待设备应答
Write_IIC_Byte(0x00); // 写入命令
IIC_Wait_Ack(); // 等待应答
Write_IIC_Byte(IIC_Command); // 发送命令字节
IIC_Wait_Ack(); // 等待应答
IIC_Stop(); // 停止 IIC
}
// 发送数据到 OLED
void Write_IIC_Data(unsigned char IIC_Data) {
IIC_Start(); // 启动 IIC
Write_IIC_Byte(0x78); // 从设备地址
IIC_Wait_Ack(); // 等待设备应答
Write_IIC_Byte(0x40); // 写入数据
IIC_Wait_Ack(); // 等待应答
Write_IIC_Byte(IIC_Data); // 发送数据字节
IIC_Wait_Ack(); // 等待应答
IIC_Stop(); // 停止 IIC
}
// 根据数据和命令标识写入数据
void OLED_WR_Byte(unsigned dat, unsigned cmd) {
if (cmd) {
Write_IIC_Data(dat); // 如果是数据
} else {
Write_IIC_Command(dat); // 如果是命令
}
}
// 填充整个画面
void fill_picture(unsigned char fill_Data) {
unsigned char m, n;
for (m = 0; m < 8; m++) { // OLED 有 8 页
OLED_WR_Byte(0xb0 + m, 0); // 设置页地址
OLED_WR_Byte(0x00, 0); // 设置低列地址
OLED_WR_Byte(0x10, 0); // 设置高列地址
for (n = 0; n < 128; n++) { // 每页有 128 列
OLED_WR_Byte(fill_Data, 1); // 填充数据
}
}
}
// 延时 50 毫秒
void Delay_50ms(unsigned int Del_50ms) {
unsigned int m;
for (; Del_50ms > 0; Del_50ms--) {
for (m = 6245; m > 0; m--); // 根据系统时钟调整
}
}
// 延时 1 毫秒
void Delay_1ms(unsigned int Del_1ms) {
unsigned char j;
while (Del_1ms--) {
for (j = 0; j < 123; j++); // 根据系统时钟调整
}
}
// 设置 OLED 的显示位置
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); // 设置低 4 位列地址
}
// OLED 开启显示
void OLED_Display_On(void) {
OLED_WR_Byte(0X8D, OLED_CMD); // 设置充电泵
OLED_WR_Byte(0X14, OLED_CMD); // 启动充电泵
OLED_WR_Byte(0XAF, OLED_CMD); // 开启显示
}
// OLED 关闭显示
void OLED_Display_Off(void) {
OLED_WR_Byte(0X8D, OLED_CMD); // 设置充电泵
OLED_WR_Byte(0X10, OLED_CMD); // 关闭充电泵
OLED_WR_Byte(0XAE, OLED_CMD); // 关闭显示
}
// 清空显示内容
void OLED_Clear(void) {
uint8_t i, n;
for (i = 0; i < 8; i++) { // 遍历每一页
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(0, OLED_DATA); // 填充空白数据
}
}
}
// OLED 开启所有像素
void OLED_On(void) {
uint8_t i, n;
for (i = 0; i < 8; i++) {
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(1, OLED_DATA); // 显示为全白
}
}
}
// 在指定位置显示字符
void OLED_ShowChar(uint8_t x, uint8_t y, uint8_t chr, uint8_t Char_Size) {
unsigned char c = chr - ' '; // 获取 ASCII 码索引
if (x > Max_Column - 1) {
x = 0; // 超过最大列数,回到第一列
y += 2; // 换行
}
if (Char_Size == 16) { // 大字符
OLED_Set_Pos(x, y);
for (unsigned char i = 0; i < 8; i++)
OLED_WR_Byte(F8X16[c * 16 + i], OLED_DATA);
OLED_Set_Pos(x, y + 1);
for (unsigned char i = 0; i < 8; i++)
OLED_WR_Byte(F8X16[c * 16 + i + 8], OLED_DATA);
} else { // 小字符
OLED_Set_Pos(x, y);
for (unsigned char i = 0; i < 6; i++)
OLED_WR_Byte(F6x8[c][i], OLED_DATA);
}
}
// 指数函数
uint32_t oled_pow(uint8_t m, uint8_t n) {
uint32_t result = 1;
while (n--) result *= m;
return result;
}
// 在指定位置显示数字
void OLED_ShowNum(uint8_t x, uint8_t y, uint32_t num, uint8_t len, uint8_t size2) {
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); // 不显示 0
continue;
} else {
enshow = 1; // 一旦显示数字,不再显示空格
}
}
OLED_ShowChar(x + (size2 / 2) * t, y, temp + '0', size2); // 显示数字
}
}
// 在指定位置显示字符串
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 > 120) { // 如果超出一行长度,换行
x = 0;
y += 2;
}
j++;
}
}
// 显示中文字符
void OLED_ShowCHinese(uint8_t x, uint8_t y, uint8_t no) {
uint8_t t;
OLED_Set_Pos(x, y);
for (t = 0; t < 16; t++) {
OLED_WR_Byte(Hzk[2 * no][t], OLED_DATA); // 显示上半部分
}
OLED_Set_Pos(x, y + 1);
for (t = 0; t < 16; t++) {
OLED_WR_Byte(Hzk[2 * no + 1][t], OLED_DATA); // 显示下半部分
}
}
// 绘制 BMP 位图
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;
else y = 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); // 绘制 BMP 数据
}
}
}
// 初始化 OLED 显示屏
void OLED_Init(void) {
HAL_Delay(800); // 等待 OLED 准备
OLED_WR_Byte(0xAE, OLED_CMD); // 关闭显示
OLED_WR_Byte(0x00, OLED_CMD); // 设置低列地址
OLED_WR_Byte(0x10, OLED_CMD); // 设置高列地址
OLED_WR_Byte(0x40, OLED_CMD); // 设置起始行
OLED_WR_Byte(0xB0, OLED_CMD); // 设置页地址
OLED_WR_Byte(0x81, OLED_CMD); // 对比度控制
OLED_WR_Byte(0xFF, OLED_CMD); // 128
OLED_WR_Byte(0xA1, OLED_CMD); // 设置段重映射
OLED_WR_Byte(0xA6, OLED_CMD); // 正常显示
OLED_WR_Byte(0xA8, OLED_CMD); // 设置多路复用比率
OLED_WR_Byte(0x3F, OLED_CMD); // 1/64 duty
OLED_WR_Byte(0xC8, OLED_CMD); // 器件扫描方向
OLED_WR_Byte(0xD3, OLED_CMD); // 设置偏移
OLED_WR_Byte(0x00, OLED_CMD); // none
OLED_WR_Byte(0xD5, OLED_CMD); // 设置时钟分频
OLED_WR_Byte(0x80, OLED_CMD); // none
OLED_WR_Byte(0xD8, OLED_CMD); // 设置区域色彩模式
OLED_WR_Byte(0x05, OLED_CMD); // none
OLED_WR_Byte(0xD9, OLED_CMD); // 设定预充电周期
OLED_WR_Byte(0xF1, OLED_CMD); // none
OLED_WR_Byte(0xDA, OLED_CMD); // 设置 COM 引脚配置
OLED_WR_Byte(0x12, OLED_CMD); // none
OLED_WR_Byte(0xDB, OLED_CMD); // 设置 Vcomh 电压
OLED_WR_Byte(0x30, OLED_CMD); // none
OLED_WR_Byte(0x8D, OLED_CMD); // 设置充电泵使能
OLED_WR_Byte(0x14, OLED_CMD); // 启用充电泵
OLED_WR_Byte(0xAF, OLED_CMD); // 开启显示
}
其对应的头文件为
//
// oled.h
// 作者 : ZTY
// 创建日期 : 2024-05-16
// 说明 : 0.96寸 OLED 显示屏驱动程序 (STM32F103ZE,通过 IIC 接口)
// 接线说明 :
// ----------------------------------------------------------------
// GND 接地
// VCC 供电 5V 或 3.3V
// SCL 时钟线连接 PG2 (SCL)
// SDA 数据线连接 PG3 (SDA)
// ----------------------------------------------------------------
//
#ifndef __OLED_H
#define __OLED_H
#include "stdlib.h"
#include "main.h"
#define OLED_MODE 0
#define SIZE 8
#define XLevelL 0x00
#define XLevelH 0x10
#define Max_Column 128
#define Max_Row 64
#define Brightness 0xFF
#define X_WIDTH 128
#define Y_WIDTH 64
//-----------------OLED IIC端口定义----------------
#define OLED_SCLK_Clr() HAL_GPIO_WritePin(OLED_SCL_GPIO_Port, OLED_SCL_Pin, GPIO_PIN_RESET)//设置SCL低电平
#define OLED_SCLK_Set() HAL_GPIO_WritePin(OLED_SCL_GPIO_Port, OLED_SCL_Pin, GPIO_PIN_SET)//设置SCL高电平
#define OLED_SDIN_Clr() HAL_GPIO_WritePin(OLED_SDA_GPIO_Port,OLED_SDA_Pin,GPIO_PIN_RESET)//设置SDA低电平
#define OLED_SDIN_Set() HAL_GPIO_WritePin(OLED_SDA_GPIO_Port,OLED_SDA_Pin,GPIO_PIN_SET)//设置SDA高电平
#define OLED_CMD 0 //写命令
#define OLED_DATA 1 //写数据
//OLED控制用函数
void OLED_WR_Byte(unsigned dat,unsigned cmd);
void OLED_Display_On(void);
void OLED_Display_Off(void);
void OLED_Init(void);
void OLED_Clear(void);
void OLED_DrawPoint(uint8_t x,uint8_t y,uint8_t t);
void OLED_Fill(uint8_t x1,uint8_t y1,uint8_t x2,uint8_t y2,uint8_t dot);
void OLED_ShowChar(uint8_t x,uint8_t y,uint8_t chr,uint8_t Char_Size);
void OLED_ShowNum(uint8_t x,uint8_t y,uint32_t num,uint8_t len,uint8_t size);
void OLED_ShowString(uint8_t x,uint8_t y, uint8_t *p,uint8_t Char_Size);
void OLED_Set_Pos(unsigned char x, unsigned char y);
void OLED_ShowCHinese(uint8_t x,uint8_t y,uint8_t no);
void OLED_DrawBMP(unsigned char x0, unsigned char y0,unsigned char x1, unsigned char y1,unsigned char BMP[]);
void Delay_50ms(unsigned int Del_50ms);
void Delay_1ms(unsigned int Del_1ms);
void fill_picture(unsigned char fill_Data);
void Picture(void);
void IIC_Start(void);
void IIC_Stop(void);
void Write_IIC_Command(unsigned char IIC_Command);
void Write_IIC_Data(unsigned char IIC_Data);
void Write_IIC_Byte(unsigned char IIC_Byte);
void IIC_Wait_Ack(void);
#endif
将字符数据存在这个头文件
#ifndef __OLEDFONT_H
#define __OLEDFONT_H
//常用ASCII表
//偏移量32
//ASCII字符集
//偏移量32
//大小:12*6
/************************************6*8的点阵************************************/
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,// 0
0x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! 1
0x00,0x10,0x0C,0x06,0x10,0x0C,0x06,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
0x10,0x16,0x0E,0x00,0x00,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,0x80,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,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,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,0x00,0x04,0x02,0x02,0x02,0x04,0x00,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,0x02,0x04,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
0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,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,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//~ 94
};
char Hzk[][32]={
{0x80,0x80,0xEE,0x88,0x88,0x88,0xE8,0x8F,0x08,0x88,0x78,0x48,0x4E,0x40,0xC0,0x00},
{0x00,0x00,0x7F,0x24,0x24,0x24,0x7F,0x00,0x81,0x40,0x30,0x0F,0x30,0x41,0x80,0x00},/*"嵌",0*/
{0x00,0x00,0x00,0x00,0x00,0x01,0xE2,0x1C,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00},
{0x80,0x40,0x20,0x10,0x0C,0x03,0x00,0x00,0x00,0x03,0x0C,0x30,0x40,0x80,0x80,0x00},/*"入",1*/
{0x10,0x10,0x90,0x90,0x90,0x90,0x90,0x10,0x10,0xFF,0x10,0x10,0x11,0x16,0x10,0x00},
{0x00,0x20,0x60,0x20,0x3F,0x10,0x10,0x10,0x00,0x03,0x0C,0x10,0x20,0x40,0xF8,0x00},/*"式",2*/
};
#endif
硬件IIC
依旧是要先进行初始化
/* USER CODE BEGIN 2 */
OLED_Init(); //OLED初始
OLED_Clear(); //清屏
//上面的初始化以及清屏的代码在一开始处一定要写
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
OLED_ShowString(0,0,"I love you",12, 1); //反相显示8X16字符串
OLED_ShowString(0,2,"ZTY",12,0);//正相显示6X8字符串
OLED_ShowChinese(0,4,0,1); //反相显示汉字“嵌”
OLED_ShowChinese(16,4,1,1);//反相显示汉字“入”
OLED_ShowChinese(32,4,2,1);//反相显示汉字“式”
OLED_ShowNum(60,5,22,1,12, 0);//正相显示1位8X16数字“12”
OLED_ShowNum(48,7,23,2,12, 1);//反相显示2位6X8数字“23”
// OLED_DrawBMP(6,6,38,38,BMP1,0);//正相显示图片BMP1
}
OLED.c
/*
* oled.c
*
* Created on: 2024年6月13日
* Author: ZTY
*/
#include "oled.h"
/**********************************************************
* OLED 初始化命令数组,根据芯片手册编写
***********************************************************/
static const uint8_t OLED_InitCmds[] = {
0xAE, // 关闭显示
0xD5, 0x80, // 设置时钟分频
0xA8, 0x3F, // 设置MUX比率
0xD3, 0x00, // 设置显示偏移
0x40, // 设置起始行
0xA1, // 设置横向翻转
0xC8, // 设置垂直翻转
0xDA, 0x12, // 设置电源控制
0x81, 0xCF, // 设置对比度
0xD9, 0xF1, // 设置预充电周期
0xDB, 0x40, // 设置VCOMH
0xA4, // 继续显示RAM内容
0xA6, // 不反相显示
0x8D, 0x14, // 开启电源
0xAF // 打开显示
};
/**
* @brief OLED 初始化
*/
void OLED_Init(void) {
HAL_Delay(200); // 等待供电稳定
for (uint8_t i = 0; i < sizeof(OLED_InitCmds); i++) {
OLED_WriteCommand(OLED_InitCmds[i]);
}
}
/**
* @brief 向 OLED 发送控制命令
* @param cmd 芯片手册规定的命令
*/
void OLED_WriteCommand(uint8_t cmd) {
HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x00, I2C_MEMADD_SIZE_8BIT, &cmd, 1, 0x100);
}
/**
* @brief 向 OLED 发送数据
* @param data 要写入的数据
*/
void OLED_WriteData(uint8_t data) {
HAL_I2C_Mem_Write(&hi2c1, 0x78, 0x40, I2C_MEMADD_SIZE_8BIT, &data, 1, 0x100);
}
/**
* @brief 开启 OLED 显示
*/
void OLED_On(void) {
for (uint8_t page = 0; page < 8; page++) {
OLED_WriteCommand(0xb0 + page); // 设置页地址
OLED_WriteCommand(0x00); // 设置列低地址
OLED_WriteCommand(0x10); // 设置列高地址
for (uint8_t n = 0; n < 128; n++) {
OLED_WriteData(1); // 将每个数据位置为1
}
}
}
/**
* @brief 清空 OLED 屏幕
*/
void OLED_Clear(void) {
for (uint8_t page = 0; page < 8; page++) {
OLED_WriteCommand(0xb0 + page); // 设置页地址
OLED_WriteCommand(0x00); // 设置列低地址
OLED_WriteCommand(0x10); // 设置列高地址
for (uint8_t n = 0; n < 128; n++) {
OLED_WriteData(0); // 将每个数据位置为0
}
}
}
/**
* @brief 开启 OLED 显示
*/
void OLED_DisplayOn(void) {
OLED_WriteCommand(0x8D); // 设置 DCDC 命令
OLED_WriteCommand(0x14); // 开启 DCDC
OLED_WriteCommand(0xAF); // 打开显示
}
/**
* @brief 关闭 OLED 显示
*/
void OLED_DisplayOff(void) {
OLED_WriteCommand(0x8D); // 设置 DCDC 命令
OLED_WriteCommand(0x10); // 关闭 DCDC
OLED_WriteCommand(0xAE); // 关闭显示
}
/**
* @brief 设置光标的位置
* @param x X 坐标
* @param y Y 坐标(页地址)
*/
void OLED_SetPosition(uint8_t x, uint8_t y) {
OLED_WriteCommand(0xb0 + y); // 设置页地址
OLED_WriteCommand(((x & 0xF0) >> 4) | 0x10); // 设置列高地址
OLED_WriteCommand(x & 0x0F); // 设置列低地址
}
/**
* @brief 计算 m^n
* @param m 底
* @param n 指数
* @return 计算结果
*/
unsigned int OLED_Pow(uint8_t m, uint8_t n) {
unsigned int result = 1;
while (n--) {
result *= m;
}
return result;
}
/**
* @brief 在 OLED 显示字符
* @param x 起始横坐标
* @param y 起始纵坐标
* @param chr 显示的字符
* @param FontSize 字体大小 (12 或 16)
* @param ColorTurn 是否反相显示
*/
void OLED_ShowChar(uint8_t x, uint8_t y, uint8_t chr, uint8_t FontSize, uint8_t ColorTurn) {
uint8_t c = chr - ' '; // 计算字符偏移
if (x > 128 - 1) { x = 0; y += 2; }
if (FontSize == 16) {
OLED_SetPosition(x, y);
for (uint8_t i = 0; i < 8; i++) {
OLED_WriteData(ColorTurn ? ~F8X16[c * 16 + i] : F8X16[c * 16 + i]);
}
OLED_SetPosition(x, y + 1);
for (uint8_t i = 0; i < 8; i++) {
OLED_WriteData(ColorTurn ? ~F8X16[c * 16 + i + 8] : F8X16[c * 16 + i + 8]);
}
} else {
OLED_SetPosition(x, y);
for (uint8_t i = 0; i < 6; i++) {
OLED_WriteData(ColorTurn ? ~F6x8[c][i] : F6x8[c][i]);
}
}
}
/**
* @brief 在 OLED 显示字符串
* @param x 字符串起始横坐标
* @param y 字符串起始纵坐标
* @param str 字符串内容
* @param FontSize 字体大小 (12 或 16)
* @param ColorTurn 是否反相显示
*/
void OLED_ShowString(uint8_t x, uint8_t y, const char *str, uint8_t FontSize, uint8_t ColorTurn) {
uint8_t j = 0;
while (str[j] != '\0') {
OLED_ShowChar(x, y, str[j], FontSize, ColorTurn);
x += (FontSize == 12) ? 6 : 8; // 更新位置
if ((x > 122 && FontSize == 12) || (x > 120 && FontSize == 16)) {
x = 0; y++; // 换行
}
j++;
}
}
/**
* @brief 在 OLED 显示数字
* @param x 起始横坐标
* @param y 起始纵坐标
* @param num 显示的数字
* @param len 数字位数
* @param size2 字体大小
* @param ColorTurn 是否反相显示
*/
void OLED_ShowNum(uint8_t x, uint8_t y, unsigned int num, uint8_t len, uint8_t size2, uint8_t ColorTurn) {
uint8_t temp, enshow = 0;
for (uint8_t 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, ColorTurn);
continue;
} else {
enshow = 1;
}
}
OLED_ShowChar(x + (size2 / 2) * t, y, temp + '0', size2, ColorTurn);
}
}
/**
* @brief 在 OLED 显示浮点数
* @param x 起始横坐标
* @param y 起始纵坐标
* @param num 浮点数
* @param z_len 整数部分位数
* @param f_len 小数部分位数
* @param size2 字体大小
* @param ColorTurn 是否反相显示
*/
void OLED_ShowDecimal(uint8_t x, uint8_t y, float num, uint8_t z_len, uint8_t f_len, uint8_t size2, uint8_t ColorTurn) {
int z_temp = (int)num;
int f_temp = (int)((num - z_temp) * OLED_Pow(10, f_len));
if (num < 0) {
z_len += 1; // 如果是负数,整数位数 +1
OLED_ShowChar(x, y, '-', size2, ColorTurn); // 显示负号
}
for (uint8_t t = 0; t < z_len; t++) {
uint8_t temp = (z_temp / OLED_Pow(10, z_len - t - 1)) % 10;
OLED_ShowChar(x + ((size2 / 2) * t) + (num < 0 ? 6 : 0), y, temp + '0', size2, ColorTurn);
}
OLED_ShowChar(x + ((size2 / 2) * z_len) + (num < 0 ? 6 : 0), y, '.', size2, ColorTurn);
for (uint8_t t = 0; t < f_len; t++) {
uint8_t temp = (f_temp / OLED_Pow(10, f_len - t - 1)) % 10;
OLED_ShowChar(x + ((size2 / 2) * (t + z_len + 1)) + (num < 0 ? 6 : 0), y, temp + '0', size2, ColorTurn);
}
}
/**
* @brief 在 OLED 显示汉字
* @param x 起始横坐标
* @param y 起始纵坐标
* @param no 汉字编号
* @param ColorTurn 是否反相显示
*/
void OLED_ShowChinese(uint8_t x, uint8_t y, uint8_t no, uint8_t ColorTurn) {
OLED_SetPosition(x, y);
for (uint8_t t = 0; t < 16; t++) {
OLED_WriteData(ColorTurn ? ~Hzk[2 * no][t] : Hzk[2 * no][t]);
}
OLED_SetPosition(x, y + 1);
for (uint8_t t = 0; t < 16; t++) {
OLED_WriteData(ColorTurn ? ~Hzk[2 * no + 1][t] : Hzk[2 * no + 1][t]);
}
}
/**
* @brief 在指定区域绘制 BMP 图片
* @param x0 图片起始横坐标
* @param y0 图片起始纵坐标
* @param x1 图片结束横坐标
* @param y1 图片结束纵坐标
* @param BMP 图片数据
* @param ColorTurn 是否反相显示
*/
void OLED_DrawBMP(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t *BMP, uint8_t ColorTurn) {
uint32_t j = 0;
for (uint8_t y = y0; y < y1; y++) {
OLED_SetPosition(x0, y);
for (uint8_t x = x0; x < x1; x++) {
OLED_WriteData(ColorTurn ? ~BMP[j++] : BMP[j++]);
}
}
}
/**
* @brief OLED 屏幕内容水平滚动
* @param direction 滚动方向 (LEFT 或 RIGHT)
*/
void OLED_HorizontalShift(uint8_t direction) {
OLED_WriteCommand(0x2E); // 停止滚动
OLED_WriteCommand(direction); // 设置滚动方向
OLED_WriteCommand(0x00); // 虚拟字节设置
OLED_WriteCommand(0x00); // 开始页地址
OLED_WriteCommand(0x07); // 滚动间隔
OLED_WriteCommand(0x07); // 结束页地址
OLED_WriteCommand(0x00); // 虚拟字节设置
OLED_WriteCommand(0xFF); // 虚拟字节设置
OLED_WriteCommand(0x2F); // 开启滚动
}
/**
* @brief OLED 屏幕部分内容水平滚动
* @param direction 滚动方向 (LEFT 或 RIGHT)
* @param start 开始页地址
* @param end 结束页地址
*/
void OLED_Some_HorizontalShift(uint8_t direction, uint8_t start, uint8_t end) {
OLED_WriteCommand(0x2E); // 停止滚动
OLED_WriteCommand(direction); // 设置滚动方向
OLED_WriteCommand(0x00); // 虚拟字节设置
OLED_WriteCommand(start); // 开始页地址
OLED_WriteCommand(0x07); // 设置滚动步频
OLED_WriteCommand(end); // 结束页地址
OLED_WriteCommand(0x00); // 虚拟字节设置
OLED_WriteCommand(0xFF); // 虚拟字节设置
OLED_WriteCommand(0x2F); // 开启滚动
}
/**
* @brief OLED 屏幕内容垂直和水平滚动
* @param direction 滚动方向
*/
void OLED_VerticalAndHorizontalShift(uint8_t direction) {
OLED_WriteCommand(0x2E); // 停止滚动
OLED_WriteCommand(direction); // 设置滚动方向
OLED_WriteCommand(0x01); // 虚拟字节设置
OLED_WriteCommand(0x00); // 开始页地址
OLED_WriteCommand(0x07); // 帧频
OLED_WriteCommand(0x07); // 结束页地址
OLED_WriteCommand(0x01); // 垂直滚动偏移量
OLED_WriteCommand(0x00); // 虚拟字节设置
OLED_WriteCommand(0xFF); // 虚拟字节设置
OLED_WriteCommand(0x2F); // 开启滚动
}
/**
* @brief 设置 OLED 显示模式
* @param mode ON (0xA7) 或 OFF (0xA6)
*/
void OLED_DisplayMode(uint8_t mode) {
OLED_WriteCommand(mode);
}
/**
* @brief 控制 OLED 屏幕亮度
* @param intensity 亮度值 (0x00~0xFF),RESET=0x7F
*/
void OLED_IntensityControl(uint8_t intensity) {
OLED_WriteCommand(0x81); // 设置对比度命令
OLED_WriteCommand(intensity); // 设置对应的对比度值
}
其头文件为
#ifndef OLED_OLED_H_
#define OLED_OLED_H_
#include "stm32f1xx_hal.h"
#include "oledfont.h"
extern I2C_HandleTypeDef hi2c1; // 外部 I2C 句柄,允许在其他文件中使用
/**
* @brief 写入控制命令到 OLED
* @param cmd 要发送的命令
*/
void OLED_WriteCommand(uint8_t cmd);
/**
* @brief 写入数据到 OLED
* @param data 要发送的数据
*/
void OLED_WriteData(uint8_t data);
/**
* @brief 初始化 OLED 显示屏
*/
void OLED_Init(void);
/**
* @brief 清空 OLED 显示屏
*/
void OLED_Clear(void);
/**
* @brief 开启 OLED 显示
*/
void OLED_DisplayOn(void);
/**
* @brief 关闭 OLED 显示
*/
void OLED_DisplayOff(void);
/**
* @brief 设置 OLED 显示的光标位置
* @param x 横坐标
* @param y 纵坐标(页地址)
*/
void OLED_SetPosition(uint8_t x, uint8_t y);
/**
* @brief 打开 OLED 显示
*/
void OLED_On(void);
/**
* @brief 在 OLED 显示指定位置显示整数
* @param x 显示的横坐标
* @param y 显示的纵坐标
* @param num 要显示的数字
* @param len 数字位数
* @param fontSize 字体大小
* @param colorInverted 是否反相显示(1:反相,0:正常)
*/
void OLED_ShowNum(uint8_t x, uint8_t y, unsigned int num, uint8_t len, uint8_t fontSize, uint8_t colorInverted);
/**
* @brief 在 OLED 显示指定位置显示浮点数
* @param x 显示的横坐标
* @param y 显示的纵坐标
* @param num 要显示的浮点数
* @param integerLength 整数部分位数
* @param decimalLength 小数部分位数
* @param fontSize 字体大小
* @param colorInverted 是否反相显示(1:反相,0:正常)
*/
void OLED_ShowDecimal(uint8_t x, uint8_t y, float num, uint8_t integerLength, uint8_t decimalLength, uint8_t fontSize, uint8_t colorInverted);
/**
* @brief 在 OLED 显示指定位置显示字符
* @param x 显示的横坐标
* @param y 显示的纵坐标
* @param chr 要显示的字符
* @param charSize 字体大小(12 或 16)
* @param colorInverted 是否反相显示(1:反相,0:正常)
*/
void OLED_ShowChar(uint8_t x, uint8_t y, uint8_t chr, uint8_t charSize, uint8_t colorInverted);
/**
* @brief 在 OLED 显示指定位置显示字符串
* @param x 显示的起始横坐标
* @param y 显示的起始纵坐标
* @param str 要显示的字符串
* @param charSize 字体大小(12 或 16)
* @param colorInverted 是否反相显示(1:反相,0:正常)
*/
void OLED_ShowString(uint8_t x, uint8_t y, const char *str, uint8_t charSize, uint8_t colorInverted);
/**
* @brief 在 OLED 显示指定位置显示汉字
* @param x 显示的横坐标
* @param y 显示的纵坐标
* @param characterIndex 汉字编号
* @param colorInverted 是否反相显示(1:反相,0:正常)
*/
void OLED_ShowChinese(uint8_t x, uint8_t y, uint8_t characterIndex, uint8_t colorInverted);
/**
* @brief 在 OLED 指定区域显示 BMP 图片
* @param x0 图片起始横坐标
* @param y0 图片起始纵坐标
* @param x1 图片结束横坐标
* @param y1 图片结束纵坐标
* @param BMP 图片数据数组
* @param colorInverted 是否反相显示(1:反相,0:正常)
*/
void OLED_DrawBMP(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, uint8_t *BMP, uint8_t colorInverted);
/**
* @brief 屏幕内容水平滚动
* @param direction 滚动方向(LEFT 或 RIGHT)
*/
void OLED_HorizontalShift(uint8_t direction);
/**
* @brief 屏幕部分内容水平滚动
* @param direction 滚动方向(LEFT 或 RIGHT)
* @param start 开始页地址
* @param end 结束页地址
*/
void OLED_Some_HorizontalShift(uint8_t direction, uint8_t start, uint8_t end);
/**
* @brief 屏幕内容垂直和水平滚动
* @param direction 滚动方向
*/
void OLED_VerticalAndHorizontalShift(uint8_t direction);
/**
* @brief 设置 OLED 显示模式
* @param mode ON (0xA7) 或 OFF (0xA6)
*/
void OLED_DisplayMode(uint8_t mode);
/**
* @brief 控制 OLED 屏幕亮度
* @param intensity 亮度值 (0x00~0xFF),RESET=0x7F
*/
void OLED_IntensityControl(uint8_t intensity);
#endif /* OLED_OLED_H_ */
四、演示效果
<iframe allowfullscreen="true" data-mediaembed="csdn" frameborder="0" id="l6yLXNy9-1736927024556" src="https://live.csdn.net/v/embed/443392"></iframe>OLED_IIC_Simulated
<iframe allowfullscreen="true" data-mediaembed="csdn" frameborder="0" id="NpS1kUnH-1736929518054" src="https://live.csdn.net/v/embed/443398"></iframe>OLED_IIC_Hardware
总结
本篇内容略少,但这也是为后期的内容做铺垫衔接。后面的内容“干货”会更多一些,敬请期待。
又是经过一个充实而忙碌的夜晚,深知文章中仍不免有诸多省略和未及细讲之处。对于那些在阅读过程中仍感意犹未尽、存有疑问的同学,建议大家不妨拓宽视野,多阅读几篇来自不同作者、风格各异的优秀文章。相信通过多角度、多层次的学习,你们定能集百家之长从而对单片机有更加深入和全面的理解。
在此,我的初衷不仅是为初学者提供一份学习路上的指引,也是对自己学习历程的一次回顾与总结。通过分享,我希望能激发更多人对单片机技术的兴趣,共同探索这片充满挑战与机遇的领域。
为了保持内容的连贯性和避免不必要的重复,我计划在未来的博客中,对于本文中已提及但未深入展开的话题,将通过链接的方式引导大家回到本文进行查阅。同时,我也将不断优化和完善文章内容,力求为大家提供更加准确、全面、易于理解的学习资源。
感谢大家的关注与支持!
参考文献引用
4针0.96寸OLED的HAL库代码(硬件I2C/全代码/stm32f1/CubeMX配置/包含有正负浮点数/100%一次点亮)
HAL库软件IIC、硬件IIC移植江科大0.96寸OLED屏幕代码;软件I2C和硬件I2C区别
【STM32】HAL库 STM32CubeMX教程十二—IIC(读取AT24C02 )
HAL库软件IIC、硬件IIC移植江科大0.96寸OLED屏幕代码;软件I2C和硬件I2C区别
标签:HAL,0x20,0x00,uint8,OLED,0x80,IIC,0x08 From: https://blog.csdn.net/m0_72614426/article/details/145156383