首页 > 其他分享 >STM32F1基于HAL库的学习记录实用使用教程分享(四、OLED IIC)

STM32F1基于HAL库的学习记录实用使用教程分享(四、OLED IIC)

时间:2025-01-15 16:29:03浏览次数:3  
标签:HAL 0x20 0x00 uint8 OLED 0x80 IIC 0x08

往期内容

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初始化与信号

  1. 初始化
    在 IIC 总线的初始化阶段,SCL(时钟线)和 SDA(数据线)均应保持在高电平状态。这一状态表示总线处于空闲等待状态,准备进行后续的通信。

  2. 开始信号
    开始信号的生成步骤如下:

    保持 SCL 高电平:在发送开始信号前,确保时钟线 SCL 维持在高电平状态。
    SDA 由高变低:在 SCL 处于高电平时,数据线 SDA 必须从高电平转为低电平。
    拉低 SCL:最后,将 SCL 线拉低,完成开始信号的发送。此时,设备进入数据传输状态。

  3. 停止信号
    停止信号的生成步骤如下:

    拉高 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-1 OLED

(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

相关文章

  • 嵌入式杂谈(问题解决一:使用HAL库时keil中代码的分区)
     如图,代码分区代码区域作用Privateincludes引入所需头文件,提供函数声明、类型定义和宏等Privatetypedef创建自定义数据类型,增强代码可读性与维护性Privatedefine定义常量和宏,方便代码修改与简化Privatemacro实现简单代码替换,简化代码逻辑Privatevariables声明和初始化......
  • Datawhale 组队学习wow-agenttask01 openai库搭建Al Agent
    Datawhale组队学习wow-agentDatawhale项目链接:https://www.datawhale.cn/learn/summary/86笔记作者:博客园-岁月月宝贝......
  • HAL库-第五章-BH1750光强传感器模块、MPU6050陀螺仪、Dht11温湿度模块使用
    目录一、实验目的二、实验原理代码1-usart模块化代码serial_port.c serial_port.h三、实验步骤,代码与结果1.添加USART串口(1)在项目文件中添加serial_port.c以及serial_port.h,位置分别为Core_Src以及Core_Inc。(2)在keil中添加.c代码(3)在Drivers/CMSIS下修改stm32f1xx_h......
  • STM32单片机芯片与内部75 USB虚拟串口 标准库 HAL库 配置实现
    目录一、标准库工程1、USB初始化2、USB中断配置3、中断服务函数与回调接收4、USB连接5、时钟配置6、数据发送二、HAL库工程1、USB初始化2、中断服务函数与回调接收4、USB连接5、时钟配置6、数据发送一、标准库工程1、USB初始化    由官方进行适配。v......
  • STM32 HAL库函数入门指南:从原理到实践
    1STM32HAL库概述STM32HAL(HardwareAbstractionLayer)库是ST公司专门为STM32系列微控制器开发的一套硬件抽象层函数库。它的核心设计理念是在应用层与硬件层之间建立一个抽象层,这个抽象层屏蔽了底层硬件的具体实现细节,为开发者提供了一套统一的、标准化的应用程序接口(API)......
  • ESP32模拟IIC,0.96英寸OLED(四针),改编自江科大/江协。
    #喜欢的宝子可以copy。#本文采用ArduinoIDE开发,用到了多文件形式。点击这里可以创建文件。下面直接分享代码和效果图。效果图0.96OLED.ino #include"OLED.h"voidsetup(){OLED_Init();OLED_ShowString(1,1,"sugkug");}intcnt=0;voidloop()......
  • half hour
    Theytakeahalfhourtocallindetectives.他们花了半个小时叫侦探。tookalmostahalfhour.花了差不多半个小时。I'mgettingcallsfromNewYorkeveryhalfhour.我每半小时就会接到纽约的电话。 Westillhavetwoandhalfhoursleftuntilourdate.离约会还......
  • Android 14.0 app调用hal层接口功能实现系列一(hal接口的创建)
    1.前言在14.0的系统rom定制化开发中,对于一些需要在app中调用hal层的一些接口来实现某些功能而言,就需要打通app到hal的接口,实现功能需求,这一节首先讲在hal层中提供接口然后通过jni来调用,首先来建立hal层的相关接口和c++文件,提供hal层供上层调用的接口2.app调用hal层接口功能实......
  • C#Halcon找线封装
        利用CreateMetrologyModel封装找线工具时,在后期实际应用调试时容易把检测极性搞混乱,造成检测偏差,基于此,此Demo增加画线后检测极性的指引,首先看一下效果加载测试图片画线确定后指引效果找线效果修改显示UI代码usingSystem;usingSystem.Collections.Ge......
  • CH5XX 软件模拟iic驱动SHT21
    本文使用CH592X软件模拟iic驱动SHT21,1.i2c.c#include"i2c.h"#include"CH59x_common.h"#defineIIC_SCL_PINGPIO_Pin_15//PB15-SCL#defineIIC_SDA_PINGPIO_Pin_14//PB14-SDA#defineIIC_SCL_H()R32_PB_DIR&=~IIC_SCL_PIN#defineIIC_SC......