参考:基于STM32-Oled(IIC)的使用
作者:奋斗的小殷
发布时间: 2021-05-07 13:09:26
网址:https://blog.csdn.net/boybs/article/details/116465668

目录

  • IIC总线简介
    • IIC协议简介
    • IIC总线系统结构
    • IIC总线物理层特点
    • 硬件IIC、软件IIC区别
  • IIC总线协议
    • 主机(单片机)写数据到从机(外设)
    • 从机(外设)写数据到主机(单片机)
    • 复合格式(发送两次起始信号,常用)
  • IIC总线时序
    • ① 空闲状态
    • ②开始信号
    • ③停止信号
    • ④应答信号
    • ⑤数据的有效性
    • ⑥数据传输
  • STM32硬件IIC外设
    • 通讯引脚
    • 时钟控制寄存器(配置通讯速率)
    • 数据控制寄存器(控制IIC通讯过程)
  • STM32的IIC结构体和库函数
    • STM32的IIC结构体
    • STM32的IIC库函数
  • OLED屏幕介绍
  • OLED显示字符串
  • OLED显示汉字和图片(取模软件的使用)

IIC总线简介

IIC协议简介

IIC通讯协议(Inter----Integrted Circuit)是由Phiips飞利浦公司开发的,由于他引脚少,硬件实现简单,可拓展性强,不需要UASRT(串口还可以需要ch340进行电平转换)、CAN通讯协议的外部收发设备(就是外设,软件IIC自己写时序不用外设),现在被广泛使用在系统内多个集成电路IC(芯片)间的通讯(芯片级的通讯一般都是使用IIC通讯)。

IIC是半双工的通讯方式(SPI是全双工,速度更快,不过线要多)

SDA:数据线
SCL:时钟线

IIC总线系统结构

  • 是一个支持多设备的总线。”总线”指多个设备共用的信号线,在一个IIC通讯总线中,可连接多个IIC通讯设备(最多同时连接127个),支持多个通讯主机及多个通讯从机。

  • 一个IIC总线只使用两条总线线路,一条双向串行数据线(SDA),一条串行时钟线(SCL)。数据线即用来表示数据,时钟线用于数据收发同步。

  • 每个连接到总线的设备都有一个独立的地址,主机可以利用这个地址进行不同设备直接的访问。

IIC总线物理层特点

  • 总线通过上拉电阻接到电源。当IIC设备空闲时,会输出高阻态(电阻很大,等效于断开,前面在讲GPIO四种输出模式里有提过),而当所有设备都空闲,都输出高阻态,由上拉电阻把总线拉成高电平。

  • 多个主机同时使用总线时,为了防止数据冲突,会利用仲裁方式(CAN总线就是,类似单片机中断优先级)决定哪个设备占用总线。

  • 具有三种传输模式:标准模式传输速率为100kbit/s,快速模式为400kbit/s,高速模式下可达3.4M/s,但目前大多IIC设备尚不支持高速模式。

硬件IIC、软件IIC区别

硬件IIC:

对应芯片上的IIC外设,有相对应的IIC驱动电路,其所使用的IIC管脚也是专用的(类似的PA9和PA10专门用于串口的收和发)

软件IIC:

一般是用普通的GPIO管脚,用软件控制管脚状态以及模拟IIC通信波形实现IIC的功能

区别:

硬件IIC的效率要远高于软件的(专门的硬件驱动电路都集成好了的),而软件IIC不受引脚限制(想要用哪个引脚作为IIC通讯都可以),接口比较灵活。

软件IIC是通过GPIO,软件模拟寄存器的工作方式,而硬件IIC是直接调用内部寄存器进行配置。如果要从具体硬件上来看,可以去看下芯片手册。因为固件IIC的端口是固定的,所以会有所区别。

如何区分:

1.硬件IIC用法复杂,模拟IIC流程更加清楚
2.硬件IIC速度比模拟快,并且可以用DMA(DMA是一种通道,目前不用了解太多)
3.模拟IIC可以在任何管脚上,硬件IIC在固定管脚上

IIC总线协议

IIC的协议定义了通讯的起始和停止信号、数据有效性、响应、仲裁、时钟同步和地址广播等环节。

主机(单片机)写数据到从机(外设)


阴影部分代表主机给从机发送信号
白色部分代表从机给主机发送信号

  • S:数据由主机传输至从机(是个起始信号)
  • SLAVE ADDRESS(从机地址): 起始信号产生后,所有从机就开始紧接下来广播的从机地址信号。IIC总线,每个设备的地址都是唯一的,当主机广播的地址与某个设备的地址相同时,这个设备就被选中了,没被选中的设备讲会忽略之后的数据信号。根据IIC协议,这个从机地址可以是7位或10位。
  • R/W(读/写):传输方向选择位,为0:表示主机向从机写数据。为1:则相反。
  • ACK:从机接收传输方向选择位后,主机或从机会返回一个应答(ACK 上图A)或非应答(NACK 上图A/A)信号,只有接收到应答信号后,主机才能继续发送或接收数据。
  • P:数据传输结束

从机(外设)写数据到主机(单片机)


阴影部分代表主机给从机发送信号
白色部分代表从机给主机发送信号

主机读从机数据:

配置方向传输位为”读数据”方向,广播完地址后,接收到应答信号后,从机开始向主机返回数据(DATA),数据包大小也为8位,从机每发送完一个数,都会等待主机的应答信号(ACK),重复这个过程,可以返回N个数据,N没有限制大小。当主机希望停止接收数据时,就向从机返回一个非应答信号(NACK),则从机自动停止数据传输。

复合格式(发送两次起始信号,常用)


阴影部分代表主机给从机发送信号
白色部分代表从机给主机发送信号

复合格式,该传输过程有两次起始信号(S)

第一次传输过程中,主机通过SLAVE_ADDRESS寻找到从设备后,发送一段”数据”,这段数据通常用于表示从设备内部的寄存器或存储器地址;第二次传输中,对该地址的内容进行读或写。也就是说,第一次通讯是告诉从机读写地址,第二次则是读写的实际内容。

IIC总线时序

① 空闲状态

IIC总线的SDA和SCL两条信号线同时处于高电平时,规定位总线的空闲状态。此时各个器件的输出级场效应管均处在截止状态,即释放总线,由两条信号线各自的上拉电阻把电平拉高。

②开始信号

起始信号:当SCL为高电平期间,SDA有高到低的跳变;启动信号是一种电平跳变时序信号,而不是一个电平信号。

③停止信号

停止信号:当SCL为高电平期间,SDA由低到高的跳变;停止信号也是一种高电平跳变时序信号,而不是一个电平信号。

串口也有起始信号和停止信号,只不过串口是没有同步的,起始信号和停止信号一般由主机产生。

④应答信号

发送器每发送一个字节(一个字节是8位),就在时钟脉冲9期间(下图所示)释放数据线,由接收器反馈一个应答信号。

  • 应答信号为低电平时,规定为有效应答位(ACK简称应答位)表示接收器已经成功地接收了该字节;
  • 应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功。

对于反馈有效应答位ACK的要求是,接收器在第九个时钟脉冲之前的低电平期间将SDA线拉低,并且确保在该时钟的高电平期间为稳定的低电平。

如果接收器是主控器,则在它收到最后一个字节后,发送一个NACK信号,以通知被控发送器数据发送,并释放SDA线,以便主控接收器发送一个停止信号P。

⑤数据的有效性

IIC总线进行数据传输时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。SDA数据线在SCL的每个时钟周期传输一位数据。

即:数据在SCL的上升沿到来之前就需准备好。并在下降沿到来之前必须稳定

⑥数据传输

在IIC总线上传送的每一位数据都有一个时钟脉冲相对应(或同步控制),即在SCL串行时钟的配合下,在SDA上逐位地串行传送每一位数据。数据位的传输是边沿触发。

STM32硬件IIC外设

①软件模拟协议: 使用CPU直接控制通讯引脚的电平,产生出符合通讯协议标准的逻辑。可移植性强,用的最多。

②硬件实现协议: 由STM32的IIC片上外设专门负责实现IIC通讯协议,只要配置好该外设,它就会自动根据协议要求产生通讯信号,收发数据并缓存起来,CPU只要检测该外设的状态和访问数据寄存器,就能完成数据收发。这种由硬件外设处理IIC协议的方式减轻了CPU的工作,且使软件设计更加简单(感觉和定时器/计数器很像)。

无论如何,芯片总还是会需要外接一些设备实现某种系统,为了与那些外设相区别,就将集成在芯片内,但是又不属于芯片本身(比如DSP,是一种微处理器,因此芯片中不属于微处理器的部分都是外设)的称为“片上外设”

STM32的IIC外设可用作通讯的主机及从机,支持100Kbit/s和400Kbits/s的速率,支持7位、10位设备地址,支持DMA数据传输,并具有数据校验功能。

通讯引脚

STM32芯片有多个IIC外设,它们的IIC通讯信号引出到不同的GPIO引脚上,使用时必须配置这些指定的引脚(硬件IIC)。下图中有三组外设IIC引脚,如果我们使用软件方式的话,任何一个IO口都可以作为IIC通讯接口。

时钟控制寄存器(配置通讯速率)

底下的2就是时钟控制部分


其中SMBA:数据传输方式,是从高位开始传还是从低位开始传。

SCL线的时钟信号,由IIC接口根据时钟控制寄存器(CCR)控制,控制的参数主要为时钟频率。

  • 可选择IIC通讯的“标准/快速”模式,这两个模式分别对应100/400Kbits/s的通讯速率

  • 在快速模式下可选择SCL时钟的占空比,可选T(low)/T(high) = 2或T(low)/T(high)=16/9模式(如下图所示),T(low)+T(high)是一个周期,T(low)/T(high)可以计算出占空比。

  • CCR寄存器中12位的配置因子CCR,它与IIC外设的输入时钟源共用作用,产生SCL时钟。STM32的IIC外设输入时钟源位PCKL1(PCLK1 = 36MHz,AHB1总线的频率是个二分频)。

配置通讯速率——计算时钟控制CCR寄存器的值

  • 标准模式
    T high = CCR* Tpckl1
    T low= CCR* Tpclk1

  • 快速模式中 Tlow/Thigh =2时:
    Thigh = CCR* Tpckl1
    Tlow = 2* low* Tpckl1

  • 快速模式中 Tlow/Thigh =16/9时:
    Thigh = 9* CCR* Tpckl1
    Tlow = 16* low* Tpckl1

例如(快速模式中 Tlow/Thigh =2时):PCLK1 = 36MHz(AHB1总线的频率 是个二分频),想要配置400Kbits/s 方法:

PCLK时钟周期: TPCLK1 = 1/36 000 000
目标SCL时钟周期: TSCL = 1/400 000
SCL时钟周期内的高电平时间: Thigh = TSCL/3
SCL时钟周期内的低电平时间: Tlow = 2*TSCL/3
计算CCR的值 : CCR = THIGH/TPCLK1 = 30
计算出来的值写入到寄存器即可

数据控制寄存器(控制IIC通讯过程)

底下的3就是数据控制部分


其中SMBA:数据传输方式,是从高位开始传还是从低位开始传。

IIC的SDA信号主要连接到数据移位寄存器上,数据移位寄存器的数据来源及目标是数据寄存器(DR)、地址寄存器(OAR)、PEC寄存器以及SDA数据线。

  • 当向外发送数据的时候,数据移位寄存器以“数据寄存器”为数据源,把数据一位一位地通过SDA信号线发送出去(上面讲到的SMBA来控制传输顺序,是从高位开始传的)。
  • 当从外部接收数据的时候,数据移位寄存器把SDA信号线采样到的数据一位一位地存储到”数据寄存器”中。

使用IIC外设通讯时,在通讯的不同阶段它会对”状态寄存器(SR1和SR2)”的不同数据位写入参数,通过读取这些寄存器标志来了解通讯状态。

主发送器

  • 控制产生起始信号(S),当发生起始信号后,它产生事件”EV5”(Event5),并会对SR1寄存器的 SB 位置1(如下图所示),表示起始信号已经发生。

  • 发送设备地址并等待应答信号,若有从机应答,则产生时间 EV6 及 EV8 ,这时SR1寄存器的ADDR位及TXE位被置1(如下图所示),ADDR位1表示地址已经发送,TEX表示数据寄存器为空。

  • 往IIC的数据寄存器DR写入要发送的数据,这时TXE位会被重置为0,表示数据寄存器非空,IIC外设通过SDA信号线一位位把数据发送出去后,又会产生EV8事件,即TXE被置1,重复这个过程,可发送多个字节。

  • 发送数据完成后,控制IIC设备产生一个停止信号P,这个时候产生EV2事件,SR1的TEX位及BTF位被置1(如下图所示),表示通讯结束。

STM32的IIC结构体和库函数

STM32的IIC结构体

在固件包i2c.h里面

typedef struct
{uint32_t I2C_ClockSpeed;     //设置SCL时钟频率,此值要低于400 000                                              uint16_t I2C_Mode;           //指定工作模式,可选IIC模式及SMBUS模式uint16_t I2C_DutyCycle;      //时钟占空比,可选low/high = 2:0或16:9uint16_t I2C_OwnAddress1;  //自身的IIC设备地址   uint16_t I2C_Ack;           //使能或者关闭响应,一般是使能uint16_t I2C_AcknowledgedAddress; //指定地址长度,可为7或10
}I2C_InitTypeDef;
  • I2C_ClockSpeed
    设置IIC的传输速率,在调用初始化函数时,函数会根据我们输入的数值经过运算后把时钟因子写入到IIC的时钟控制寄存器CCR。而我们写入的这个参数值不得高于400Khz(如下图所示)。
    实际上由于CCR寄存器不能写入小数类型的时钟因子,影响到SCL的实际频率可能会低于本成员设置的参数值,这时除了通讯会稍微慢点以外,不会对IIC的标准通讯造成其他影响。

  • I2C_Mode
    选择IIC的使用方式,有IIC模式(IIC_Mode_IIC)和SMBus主、从模式(IIC_Mode_SMBusHost、IIC_Mode_SMBusDevice)
    IIC不需要在此处区分主从模式,直接设置IIC_Mode_IICj即可

  • I2C_DutyCycle
    设置IIC的SCL线时钟的占空比。该配置有两个选择,分别为低电平时间比高电平时间为2:1(IIC_DutyCycle_2)和16:9(IIC_DutyCycle_16_9).
    其实这两个模式的比例差别并不大,一般要求都不会如此严格,这里随便选就可以了。

  • I2C_OwnAddress1
    配置STM32的IIC设备自己的地址,每个连接到IIC总线上的设备都有一个自己的地址,作为主机也不例外。地址可以设置为7位或10位(受下面IIC_AcknowledgeAddress成员决定),只要该地址是IIC总线上唯一的即可。
    STM32的IIC外设可同时使用两个地址(如下图所示),即同时对两个地址作出响应(使用非常的灵活),这个结构体成员I2C_OwnAddress1配置的是默认的,OAR1寄存器存储的地址,若需要设置第二个地址寄存器OAR2,可使用I2C_OwnAddress2Config函数来配置,OAR2不支持10位地址。

  • I2C_Ack
    配置IIC应答是否使能,设置位使能则可以发送响应信号,一般配置位允许应答(IIC_Ack_Enable),这是绝大多数遵循IIC标准的设备的通讯要求,改为禁止应答(IIC_Ack_Disable)往往会导致通讯错误。

  • I2C_AcknowledgedAddress
    选择IIC的寻址模式是7位或者是10位地址,这需要根据实际连接到IIC总线上设备的地址进行选择,这个成员的配置也影响到IIC_OwnAddress成员,只有这里设置成10位模式时,IIC_OwnAddress1才支持10位地址

配置完这些结构体成员的值,调用库函数IIC_Init就可以把结构体的配置写入到对应的寄存器中了。

STM32的IIC库函数

固件包.h文件里都给出了,仅列出了部分。

//配置自身设备地址2
void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint8_t Address);  //发送设备地址
void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction);  //接收数据
uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx);//停止接收
void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState); //IIC外设开始正常工作
void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState);

OLED屏幕介绍

OLED即有机发光管(Organic Light-Emitting Diode,OLED)。OLED显示技术具有自发光、广视角、几乎无穷高的对比度、较低功耗、极高反应速度、可用于绕曲性面板、使用温度范围广、构造及制程简单等有点,被认为是下一代的平面显示屏新兴应用技术。

OLED显示和传统的LCD显示不同,其可以自发光,所以不需要背光灯,这使得OLED显示屏相对于LCD显示屏尺寸更薄,同时显示效果更优。

常用的OLED屏幕有蓝色、黄色、白色等几种。屏的大小为0.96寸,像素点为
128*64,所以我们称为0.96oled屏或者12864屏。

OLED屏幕特点

1.模块尺寸:23.7 *23.8mm
2.电源电压:3.3-5.5V
3.驱动芯片:SSD1306
4.测试平台:提供 k60/k10,9s12XS128,51,stm32,stm8等单片机

OLED屏幕接线说明


OLED屏幕显存

OLED本身是没有显存的,他的显存是依赖SSD1306(驱动芯片)提供的,而SSD1306提供一块显存。
SSD1306显存总共为128*64bit大小,SSD1306将这些显存分成了8页(上图8行),每页包含了128个字节(每列8个像素点,共128列)。

OLED屏幕原理

STM32没有显存,它在内部建立一个缓存(共128*8个字节),每次修改的时候,只是修改STM32上的缓存(实际上就是SRAM),修改完后一次性把STM32上的缓存数据写入到OLED的GRAM显存上 。

这个方法也有坏处,对于SRAM很小的单片机(51系列)就比较麻烦。

OLED屏幕常用指令表

指令的使用说明(上图第二列)

  • 指令0X81: 设置对比度。包含两个字节,第一个0X81为命令,随后方法是的一个字节要设置这个对比度,值越大屏幕越亮。
  • 指令0XAE/0XAF: 0XAE为关闭显示命令,0XAF为开启显示命令
  • 指令0X8D: 包含两个字节,第一个为命令字,第二个为设置值,第二个字节的A2位表示电荷泵的开关状态,该位为1开启电荷泵,为0则关闭。模块初始化的时候,这个必须要开启,否则看不到屏幕显示。
  • 指令0XB0~B7:用于设置页地址(前面讲到了,一共分成了8页),其低三位的值对应GRAM页地址(很好理解,二进制三位可表示0–8)。
  • 指令0X00~0X0F:用于设置显示时的起始列地址低四位。
  • 指令0X10~0X1F: 用于设置显示时的起始列地址高四位。

OLED屏幕字模软件的使用

OLED打点方式(64行*128列的点阵)
OLED点阵的点亮方式,举个显示”P”的例子,最左边位最高位P7。

  • 1.可以看出,要想显示”P”,首先写入0x1f,则显示一个竖杠,之后控制器自动水平移动到下一列。

  • 2.再写入0X05,则出现两个小横杆,这个两个横杆就是0X05中0000 0101中两个1所处的位置,写完第二列后,控制器自动跳到第三列.

  • 3.再写入0X07,第四列写入0X00后,P就显示出来了。这也说明,即使你只想再一列的最上端显示一个小点,即写入0X01.

  • 4.不能一次性控制一个点阵,只能一次性控制八位点阵(8个像素),即一列点阵。这也决定了字模选择的取模方式为“列行式“。

OLED显示字符串

显示效果:

OLED_ShowStr(0,3,"Hello world",1);//F6*8的格式
OLED_ShowStr(0,4,"Hello world",2);//F8*16格式 同样的字符 显示更大了

oled.c

#include "stm32f10x.h"
#include "oled.h"
#include "delay.h"
#include "OLED_Codetab.h"//字库文件 下面给出了//OLED存放格式  分成了8页 每页都是8*128
//[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//IIC结构体配置
void I2C_Configuration(void)
{I2C_InitTypeDef   I2C_InitStructure;   //I2C结构体配置            i2c.h里面GPIO_InitTypeDef  GPIO_InitStructure;  //GPIO结构体配置 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //时钟使能  rcc.h里面RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);//PB6——>SCL  PB7——>SDA  接线方式GPIO_InitStructure.GPIO_Mode   =  GPIO_Mode_AF_OD;//IIC空闲时高阻态 复用开漏GPIO_InitStructure.GPIO_Pin    =  GPIO_Pin_7 | GPIO_Pin_6;GPIO_InitStructure.GPIO_Speed  =  GPIO_Speed_50MHz;GPIO_Init(GPIOB,&GPIO_InitStructure);//I2CI2C_DeInit(I2C1);//初始化使用它I2C_InitStructure.I2C_Ack                   =  I2C_Ack_Enable;//应答 使能I2C_InitStructure.I2C_AcknowledgedAddress   =  I2C_AcknowledgedAddress_7bit;//地址选7位I2C_InitStructure.I2C_ClockSpeed            =  400000;//时钟速度400KI2C_InitStructure.I2C_DutyCycle             =  I2C_DutyCycle_2;//2:1 16:9都可以I2C_InitStructure.I2C_Mode                  =  I2C_Mode_I2C;//I2C模式I2C_InitStructure.I2C_OwnAddress1           =  0X10;//主机地址 随便写I2C_Init( I2C1, &I2C_InitStructure);//初始化I2C1I2C_Cmd( I2C1,  ENABLE); //使能I2C1
}//硬件IIC写一个字节
void I2C_WriteByte(uint8_t addr , uint8_t data)
{while(I2C_GetFlagStatus(I2C1,  I2C_FLAG_BUSY));  //检测I2C总线是否繁忙 等待繁忙结束I2C_GenerateSTART(I2C1,  ENABLE);               //开启IIC1while(!I2C_CheckEvent(I2C1,  I2C_EVENT_MASTER_MODE_SELECT)); //EV5 主模式 检查是否应答 I2C_Send7bitAddress(I2C1, OLED_ADDRESS,  I2C_Direction_Transmitter);  //发生器地址(7位)  OLED_ADDRESS的值在oled.h中定义了 方向:发送器件地址(找到从机)while(!I2C_CheckEvent(I2C1 ,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); //EV6(宏定义)I2C_SendData( I2C1,  addr); //寄存器地址(复合格式 发送两次起始信号)  while(!I2C_CheckEvent(I2C1,  I2C_EVENT_MASTER_BYTE_TRANSMITTING)); //EV8 主模式    每次发送完都要有应答的 需要检测应答I2C_SendData( I2C1 , data);  //发送数据(复合格式 发送两次起始信号)   上面形参while(!I2C_CheckEvent(I2C1,  I2C_EVENT_MASTER_BYTE_TRANSMITTING)); //EV8 Ö÷ģʽI2C_GenerateSTOP(I2C1,ENABLE  );  //关闭I2C总线
}
//给OLED 写命令
void WriteCmd(unsigned char I2C_Cmd)
{   I2C_WriteByte(0X00,I2C_Cmd);//在0X00地址(ROM里)写  51单片机LCD1602讲的
}//给OLED 写数据
void  WriteData(unsigned char I2C_Data)
{   I2C_WriteByte(0X40 , I2C_Data);                 //51单片机LCD1602讲的
}//OELD屏幕初始化  这部分代码是厂家提供的 复制过来不用太关注原理
void OLED_Init(void)
{delay_ms(100);WriteCmd(0xAE); //display offWriteCmd(0x20); //Set Memory Addressing Mode    WriteCmd(0x10); //00,Horizontal Addressing Mode;01,Vertical Addressing Mode;10,Page Addressing Mode (RESET);11,InvalidWriteCmd(0xb0);   //Set Page Start Address for Page Addressing Mode,0-7WriteCmd(0xc8);    //Set COM Output Scan DirectionWriteCmd(0x00); //---set low column addressWriteCmd(0x10); //---set high column addressWriteCmd(0x40); //--set start line addressWriteCmd(0x81); //--set contrast control registerWriteCmd(0xff); //亮度调节 0x00~0xffWriteCmd(0xa1); //--set segment re-map 0 to 127WriteCmd(0xa6); //--set normal displayWriteCmd(0xa8); //--set multiplex ratio(1 to 64)WriteCmd(0x3F); //WriteCmd(0xa4); //0xa4,Output follows RAM content;0xa5,Output ignores RAM contentWriteCmd(0xd3); //-set display offsetWriteCmd(0x00); //-not offsetWriteCmd(0xd5); //--set display clock divide ratio/oscillator frequencyWriteCmd(0xf0); //--set divide ratioWriteCmd(0xd9); //--set pre-charge periodWriteCmd(0x22); //WriteCmd(0xda); //--set com pins hardware configurationWriteCmd(0x12);WriteCmd(0xdb); //--set vcomhWriteCmd(0x20); //0x20,0.77xVccWriteCmd(0x8d); //--set DC-DC enableWriteCmd(0x14); //WriteCmd(0xaf); //--turn on oled panel
}//设置起点坐标
void OLED_SetPos(unsigned char x, unsigned char y)
{WriteCmd(0xb0 + y);    //这些都是固定的      看上面的指令表WriteCmd((x & 0xf0) >> 4 | 0x10); //取高4位 指令表最后两行WriteCmd((x & 0x0f ) | 0x01);     //取低4位
}//全屏填充(一列一列地填充,每列8个像素)
void OLED_Full(unsigned char Full_Data)
{unsigned char n, m ;for( m = 0 ; m < 8 ; m++)//屏幕分成了8页 每页都要处理{WriteCmd(0xb0 + m);//0xb0 列的起点坐标 上面有WriteCmd(0x00);WriteCmd(0x10);            for( n = 0 ; n < 128 ; n++)//128列 每列8个像素地写{WriteData(Full_Data);}}
}//清屏函数 让屏幕什么都不显示
void OLED_Clear(void)
{OLED_Full(0x00);
}//oled打开(电荷泵)
void OLED_Open(void)
{WriteCmd(0x8D); //设置电荷泵指令(指令表上有) WriteCmd(0x14);  //开启电荷泵WriteCmd(0xaf);  //OLED唤醒  指令大小写都可以 最好和指令表上一致
}//oled关闭(电荷泵)
void OLED_Close(void)
{WriteCmd(0x8D);  //设置电荷泵指令(指令表上有) WriteCmd(0x10);  //关闭电荷泵WriteCmd(0xAE);  //oled关闭
}//OLED显示字符串函数      坐标                      要显示的内容(数组放到RAM里)         格式有6*8  8*16(OLED_Codetab.h文件里)
void OLED_ShowStr(unsigned char x, unsigned char y , unsigned char ch[] , unsigned TestSize)
{unsigned char c = 0 , i = 0, j = 0;switch(TestSize){case 1://6*8{while(ch[j] != '\0')//字符串结束标记{c = ch[j] - 32;//大小写的转化if(x > 126)//X越界了 放到第一个位置 难道不应该是Y? Y代表页 X代表列{x = 0 ; y ++;//回到第一行,下一列}OLED_SetPos(x , y);for( i = 0 ; i< 6 ; i++)//6列为一组显示一个字符WriteData(F6X8[c][i]);//显示到屏幕上x+= 6;//格式:6*8  跳转到下一个字符 难道不应该是Y?j++; }}break;case 2://8*16{while(ch[j] != '\0'){c = ch[j] - 32;if( x > 120)//8*16  120越界 没懂{x = 0;y++;//回到第一行,下一列}OLED_SetPos(x , y);for( i = 0 ; i < 8 ; i++)//把16分成两个部分, 屏幕是分成了8页 上下显示(目前还不太懂)WriteData(F8X16[c*16 + i]);OLED_SetPos(x , y+1);for( i = 0 ; i < 8 ; i++)WriteData(F8X16[c*16+8+i]);x+=8;//转到下一个字符j++;}}break;}
}//显示文字   字模软件生成的 F16X16数组                                            汉字个数
void OLED_ShowCn(unsigned char x, unsigned char y , unsigned char N)
{unsigned char wn = 0;unsigned  int addr = 32*N;//一个字是由32个16进制表示的(.h文件两行)OLED_SetPos(x , y);for( wn = 0 ; wn < 16 ; wn++)//一个字是由32个16进制表示的 分成两个部分{WriteData(F16X16[addr]);addr+= 1;}OLED_SetPos(x , y+1);//y+1 在下一页写for( wn = 0 ; wn < 16 ; wn++){WriteData(F16X16[addr]);addr+= 1;}
}//显示图像               图片的起点坐标和结尾坐标(对角线)
void OLED_ShowBMP(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++)//y相当于页数 一页一页的  每一页有8行{OLED_SetPos(x0 ,y);for( x= x0 ; x < x1 ; x++){WriteData(BMP[j++]);}}
}

oled.h

#ifndef _OLED_H_
#define _OLED_H_//#ifndef #define #endif 条件编译 执行下面的操作#include "stm32f10x.h"
#define  OLED_ADDRESS 0x78 //这个地址厂家设置好的?
void I2C_Configuration(void);
void I2C_WriteByte(uint8_t addr , uint8_t data);
void WriteCmd(unsigned char I2C_Cmd);
void WriteData(unsigned char I2C_Data);
void OLED_Init(void);
void OLED_SetPos(unsigned char x, unsigned char y);
void OLED_Full(unsigned char Full_Data);
void OLED_Clear(void);
void OLED_Open(void);
void OLED_Close(void);
void OLED_ShowStr(unsigned char x, unsigned char y , unsigned char ch[] , unsigned TestSize);
void OLED_ShowCn(unsigned char x, unsigned char y , unsigned char N);#endif

OLED_Codetab.h

const unsigned char F6X8[][6] =//F6X8一列是8个像素点  F8X16一列是16个像素点,同样的字符显示的更大了。
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00,// sp0x00, 0x00, 0x00, 0x2f, 0x00, 0x00,// !0x00, 0x00, 0x07, 0x00, 0x07, 0x00,// "0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14,// #0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12,// $0x00, 0x62, 0x64, 0x08, 0x13, 0x23,// %0x00, 0x36, 0x49, 0x55, 0x22, 0x50,// &0x00, 0x00, 0x05, 0x03, 0x00, 0x00,// '0x00, 0x00, 0x1c, 0x22, 0x41, 0x00,// (0x00, 0x00, 0x41, 0x22, 0x1c, 0x00,// )0x00, 0x14, 0x08, 0x3E, 0x08, 0x14,// *0x00, 0x08, 0x08, 0x3E, 0x08, 0x08,// +0x00, 0x00, 0x00, 0xA0, 0x60, 0x00,// ,0x00, 0x08, 0x08, 0x08, 0x08, 0x08,// -0x00, 0x00, 0x60, 0x60, 0x00, 0x00,// .0x00, 0x20, 0x10, 0x08, 0x04, 0x02,// /0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E,// 00x00, 0x00, 0x42, 0x7F, 0x40, 0x00,// 10x00, 0x42, 0x61, 0x51, 0x49, 0x46,// 20x00, 0x21, 0x41, 0x45, 0x4B, 0x31,// 30x00, 0x18, 0x14, 0x12, 0x7F, 0x10,// 40x00, 0x27, 0x45, 0x45, 0x45, 0x39,// 50x00, 0x3C, 0x4A, 0x49, 0x49, 0x30,// 60x00, 0x01, 0x71, 0x09, 0x05, 0x03,// 70x00, 0x36, 0x49, 0x49, 0x49, 0x36,// 80x00, 0x06, 0x49, 0x49, 0x29, 0x1E,// 90x00, 0x00, 0x36, 0x36, 0x00, 0x00,// :0x00, 0x00, 0x56, 0x36, 0x00, 0x00,// ;0x00, 0x08, 0x14, 0x22, 0x41, 0x00,// <0x00, 0x14, 0x14, 0x14, 0x14, 0x14,// =0x00, 0x00, 0x41, 0x22, 0x14, 0x08,// >0x00, 0x02, 0x01, 0x51, 0x09, 0x06,// ?0x00, 0x32, 0x49, 0x59, 0x51, 0x3E,// @0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C,// A0x00, 0x7F, 0x49, 0x49, 0x49, 0x36,// B0x00, 0x3E, 0x41, 0x41, 0x41, 0x22,// C0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C,// D0x00, 0x7F, 0x49, 0x49, 0x49, 0x41,// E0x00, 0x7F, 0x09, 0x09, 0x09, 0x01,// F0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A,// G0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F,// H0x00, 0x00, 0x41, 0x7F, 0x41, 0x00,// I0x00, 0x20, 0x40, 0x41, 0x3F, 0x01,// J0x00, 0x7F, 0x08, 0x14, 0x22, 0x41,// K0x00, 0x7F, 0x40, 0x40, 0x40, 0x40,// L0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F,// M0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F,// N0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E,// O0x00, 0x7F, 0x09, 0x09, 0x09, 0x06,// P0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E,// Q0x00, 0x7F, 0x09, 0x19, 0x29, 0x46,// R0x00, 0x46, 0x49, 0x49, 0x49, 0x31,// S0x00, 0x01, 0x01, 0x7F, 0x01, 0x01,// T0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F,// U0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F,// V0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F,// W0x00, 0x63, 0x14, 0x08, 0x14, 0x63,// X0x00, 0x07, 0x08, 0x70, 0x08, 0x07,// Y0x00, 0x61, 0x51, 0x49, 0x45, 0x43,// Z0x00, 0x00, 0x7F, 0x41, 0x41, 0x00,// [0x00, 0x55, 0x2A, 0x55, 0x2A, 0x55,// 550x00, 0x00, 0x41, 0x41, 0x7F, 0x00,// ]0x00, 0x04, 0x02, 0x01, 0x02, 0x04,// ^0x00, 0x40, 0x40, 0x40, 0x40, 0x40,// _0x00, 0x00, 0x01, 0x02, 0x04, 0x00,// '0x00, 0x20, 0x54, 0x54, 0x54, 0x78,// a0x00, 0x7F, 0x48, 0x44, 0x44, 0x38,// b0x00, 0x38, 0x44, 0x44, 0x44, 0x20,// c0x00, 0x38, 0x44, 0x44, 0x48, 0x7F,// d0x00, 0x38, 0x54, 0x54, 0x54, 0x18,// e0x00, 0x08, 0x7E, 0x09, 0x01, 0x02,// f0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C,// g0x00, 0x7F, 0x08, 0x04, 0x04, 0x78,// h0x00, 0x00, 0x44, 0x7D, 0x40, 0x00,// i0x00, 0x40, 0x80, 0x84, 0x7D, 0x00,// j0x00, 0x7F, 0x10, 0x28, 0x44, 0x00,// k0x00, 0x00, 0x41, 0x7F, 0x40, 0x00,// l0x00, 0x7C, 0x04, 0x18, 0x04, 0x78,// m0x00, 0x7C, 0x08, 0x04, 0x04, 0x78,// n0x00, 0x38, 0x44, 0x44, 0x44, 0x38,// o0x00, 0xFC, 0x24, 0x24, 0x24, 0x18,// p0x00, 0x18, 0x24, 0x24, 0x18, 0xFC,// q0x00, 0x7C, 0x08, 0x04, 0x04, 0x08,// r0x00, 0x48, 0x54, 0x54, 0x54, 0x20,// s0x00, 0x04, 0x3F, 0x44, 0x40, 0x20,// t0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C,// u0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C,// v0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C,// w0x00, 0x44, 0x28, 0x10, 0x28, 0x44,// x0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C,// y0x00, 0x44, 0x64, 0x54, 0x4C, 0x44,// z0x14, 0x14, 0x14, 0x14, 0x14, 0x14,// horiz lines
};
const unsigned char F8X16[]=
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,// 00x00,0x00,0x00,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x30,0x00,0x00,0x00,//! 10x00,0x10,0x0C,0x06,0x10,0x0C,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//" 20x40,0xC0,0x78,0x40,0xC0,0x78,0x40,0x00,0x04,0x3F,0x04,0x04,0x3F,0x04,0x04,0x00,//# 30x00,0x70,0x88,0xFC,0x08,0x30,0x00,0x00,0x00,0x18,0x20,0xFF,0x21,0x1E,0x00,0x00,//$ 40xF0,0x08,0xF0,0x00,0xE0,0x18,0x00,0x00,0x00,0x21,0x1C,0x03,0x1E,0x21,0x1E,0x00,//% 50x00,0xF0,0x08,0x88,0x70,0x00,0x00,0x00,0x1E,0x21,0x23,0x24,0x19,0x27,0x21,0x10,//& 60x10,0x16,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//' 70x00,0x00,0x00,0xE0,0x18,0x04,0x02,0x00,0x00,0x00,0x00,0x07,0x18,0x20,0x40,0x00,//( 80x00,0x02,0x04,0x18,0xE0,0x00,0x00,0x00,0x00,0x40,0x20,0x18,0x07,0x00,0x00,0x00,//) 90x40,0x40,0x80,0xF0,0x80,0x40,0x40,0x00,0x02,0x02,0x01,0x0F,0x01,0x02,0x02,0x00,//* 100x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x1F,0x01,0x01,0x01,0x00,//+ 110x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0xB0,0x70,0x00,0x00,0x00,0x00,0x00,//, 120x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,//- 130x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x00,//. 140x00,0x00,0x00,0x00,0x80,0x60,0x18,0x04,0x00,0x60,0x18,0x06,0x01,0x00,0x00,0x00,/// 150x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x0F,0x10,0x20,0x20,0x10,0x0F,0x00,//0 160x00,0x10,0x10,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//1 170x00,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00,0x30,0x28,0x24,0x22,0x21,0x30,0x00,//2 180x00,0x30,0x08,0x88,0x88,0x48,0x30,0x00,0x00,0x18,0x20,0x20,0x20,0x11,0x0E,0x00,//3 190x00,0x00,0xC0,0x20,0x10,0xF8,0x00,0x00,0x00,0x07,0x04,0x24,0x24,0x3F,0x24,0x00,//4 200x00,0xF8,0x08,0x88,0x88,0x08,0x08,0x00,0x00,0x19,0x21,0x20,0x20,0x11,0x0E,0x00,//5 210x00,0xE0,0x10,0x88,0x88,0x18,0x00,0x00,0x00,0x0F,0x11,0x20,0x20,0x11,0x0E,0x00,//6 220x00,0x38,0x08,0x08,0xC8,0x38,0x08,0x00,0x00,0x00,0x00,0x3F,0x00,0x00,0x00,0x00,//7 230x00,0x70,0x88,0x08,0x08,0x88,0x70,0x00,0x00,0x1C,0x22,0x21,0x21,0x22,0x1C,0x00,//8 240x00,0xE0,0x10,0x08,0x08,0x10,0xE0,0x00,0x00,0x00,0x31,0x22,0x22,0x11,0x0F,0x00,//9 250x00,0x00,0x00,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,//: 260x00,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x60,0x00,0x00,0x00,0x00,//; 270x00,0x00,0x80,0x40,0x20,0x10,0x08,0x00,0x00,0x01,0x02,0x04,0x08,0x10,0x20,0x00,//< 280x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x00,//= 290x00,0x08,0x10,0x20,0x40,0x80,0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x01,0x00,//> 300x00,0x70,0x48,0x08,0x08,0x08,0xF0,0x00,0x00,0x00,0x00,0x30,0x36,0x01,0x00,0x00,//? 310xC0,0x30,0xC8,0x28,0xE8,0x10,0xE0,0x00,0x07,0x18,0x27,0x24,0x23,0x14,0x0B,0x00,//@ 320x00,0x00,0xC0,0x38,0xE0,0x00,0x00,0x00,0x20,0x3C,0x23,0x02,0x02,0x27,0x38,0x20,//A 330x08,0xF8,0x88,0x88,0x88,0x70,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x11,0x0E,0x00,//B 340xC0,0x30,0x08,0x08,0x08,0x08,0x38,0x00,0x07,0x18,0x20,0x20,0x20,0x10,0x08,0x00,//C 350x08,0xF8,0x08,0x08,0x08,0x10,0xE0,0x00,0x20,0x3F,0x20,0x20,0x20,0x10,0x0F,0x00,//D 360x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x20,0x23,0x20,0x18,0x00,//E 370x08,0xF8,0x88,0x88,0xE8,0x08,0x10,0x00,0x20,0x3F,0x20,0x00,0x03,0x00,0x00,0x00,//F 380xC0,0x30,0x08,0x08,0x08,0x38,0x00,0x00,0x07,0x18,0x20,0x20,0x22,0x1E,0x02,0x00,//G 390x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x20,0x3F,0x21,0x01,0x01,0x21,0x3F,0x20,//H 400x00,0x08,0x08,0xF8,0x08,0x08,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//I 410x00,0x00,0x08,0x08,0xF8,0x08,0x08,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,0x00,//J 420x08,0xF8,0x88,0xC0,0x28,0x18,0x08,0x00,0x20,0x3F,0x20,0x01,0x26,0x38,0x20,0x00,//K 430x08,0xF8,0x08,0x00,0x00,0x00,0x00,0x00,0x20,0x3F,0x20,0x20,0x20,0x20,0x30,0x00,//L 440x08,0xF8,0xF8,0x00,0xF8,0xF8,0x08,0x00,0x20,0x3F,0x00,0x3F,0x00,0x3F,0x20,0x00,//M 450x08,0xF8,0x30,0xC0,0x00,0x08,0xF8,0x08,0x20,0x3F,0x20,0x00,0x07,0x18,0x3F,0x00,//N 460xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x10,0x20,0x20,0x20,0x10,0x0F,0x00,//O 470x08,0xF8,0x08,0x08,0x08,0x08,0xF0,0x00,0x20,0x3F,0x21,0x01,0x01,0x01,0x00,0x00,//P 480xE0,0x10,0x08,0x08,0x08,0x10,0xE0,0x00,0x0F,0x18,0x24,0x24,0x38,0x50,0x4F,0x00,//Q 490x08,0xF8,0x88,0x88,0x88,0x88,0x70,0x00,0x20,0x3F,0x20,0x00,0x03,0x0C,0x30,0x20,//R 500x00,0x70,0x88,0x08,0x08,0x08,0x38,0x00,0x00,0x38,0x20,0x21,0x21,0x22,0x1C,0x00,//S 510x18,0x08,0x08,0xF8,0x08,0x08,0x18,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//T 520x08,0xF8,0x08,0x00,0x00,0x08,0xF8,0x08,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//U 530x08,0x78,0x88,0x00,0x00,0xC8,0x38,0x08,0x00,0x00,0x07,0x38,0x0E,0x01,0x00,0x00,//V 540xF8,0x08,0x00,0xF8,0x00,0x08,0xF8,0x00,0x03,0x3C,0x07,0x00,0x07,0x3C,0x03,0x00,//W 550x08,0x18,0x68,0x80,0x80,0x68,0x18,0x08,0x20,0x30,0x2C,0x03,0x03,0x2C,0x30,0x20,//X 560x08,0x38,0xC8,0x00,0xC8,0x38,0x08,0x00,0x00,0x00,0x20,0x3F,0x20,0x00,0x00,0x00,//Y 570x10,0x08,0x08,0x08,0xC8,0x38,0x08,0x00,0x20,0x38,0x26,0x21,0x20,0x20,0x18,0x00,//Z 580x00,0x00,0x00,0xFE,0x02,0x02,0x02,0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x00,//[ 590x00,0x0C,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x06,0x38,0xC0,0x00,//\ 600x00,0x02,0x02,0x02,0xFE,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x7F,0x00,0x00,0x00,//] 610x00,0x00,0x04,0x02,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//^ 620x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,//_ 630x00,0x02,0x02,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//` 640x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x19,0x24,0x22,0x22,0x22,0x3F,0x20,//a 650x08,0xF8,0x00,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x11,0x20,0x20,0x11,0x0E,0x00,//b 660x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x0E,0x11,0x20,0x20,0x20,0x11,0x00,//c 670x00,0x00,0x00,0x80,0x80,0x88,0xF8,0x00,0x00,0x0E,0x11,0x20,0x20,0x10,0x3F,0x20,//d 680x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x22,0x22,0x22,0x22,0x13,0x00,//e 690x00,0x80,0x80,0xF0,0x88,0x88,0x88,0x18,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//f 700x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x6B,0x94,0x94,0x94,0x93,0x60,0x00,//g 710x08,0xF8,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//h 720x00,0x80,0x98,0x98,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//i 730x00,0x00,0x00,0x80,0x98,0x98,0x00,0x00,0x00,0xC0,0x80,0x80,0x80,0x7F,0x00,0x00,//j 740x08,0xF8,0x00,0x00,0x80,0x80,0x80,0x00,0x20,0x3F,0x24,0x02,0x2D,0x30,0x20,0x00,//k 750x00,0x08,0x08,0xF8,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x3F,0x20,0x20,0x00,0x00,//l 760x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x20,0x3F,0x20,0x00,0x3F,0x20,0x00,0x3F,//m 770x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x3F,0x21,0x00,0x00,0x20,0x3F,0x20,//n 780x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x1F,0x20,0x20,0x20,0x20,0x1F,0x00,//o 790x80,0x80,0x00,0x80,0x80,0x00,0x00,0x00,0x80,0xFF,0xA1,0x20,0x20,0x11,0x0E,0x00,//p 800x00,0x00,0x00,0x80,0x80,0x80,0x80,0x00,0x00,0x0E,0x11,0x20,0x20,0xA0,0xFF,0x80,//q 810x80,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x20,0x20,0x3F,0x21,0x20,0x00,0x01,0x00,//r 820x00,0x00,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x33,0x24,0x24,0x24,0x24,0x19,0x00,//s 830x00,0x80,0x80,0xE0,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x1F,0x20,0x20,0x00,0x00,//t 840x80,0x80,0x00,0x00,0x00,0x80,0x80,0x00,0x00,0x1F,0x20,0x20,0x20,0x10,0x3F,0x20,//u 850x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x00,0x01,0x0E,0x30,0x08,0x06,0x01,0x00,//v 860x80,0x80,0x00,0x80,0x00,0x80,0x80,0x80,0x0F,0x30,0x0C,0x03,0x0C,0x30,0x0F,0x00,//w 870x00,0x80,0x80,0x00,0x80,0x80,0x80,0x00,0x00,0x20,0x31,0x2E,0x0E,0x31,0x20,0x00,//x 880x80,0x80,0x80,0x00,0x00,0x80,0x80,0x80,0x80,0x81,0x8E,0x70,0x18,0x06,0x01,0x00,//y 890x00,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x21,0x30,0x2C,0x22,0x21,0x30,0x00,//z 900x00,0x00,0x00,0x00,0x80,0x7C,0x02,0x02,0x00,0x00,0x00,0x00,0x00,0x3F,0x40,0x40,//{ 910x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,//| 920x00,0x02,0x02,0x7C,0x80,0x00,0x00,0x00,0x00,0x40,0x40,0x3F,0x00,0x00,0x00,0x00,//} 930x00,0x06,0x01,0x01,0x02,0x02,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//~ 94
};const unsigned char F16X16[] =//这是根据字模软件生成的  取模软件选择16*16格式
{0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x20,0x40,0x80,0x00,0x00,0x08,0x04,0x03,0x00,0x00,0x40,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x01,0x0E,0x00,/*小",0*/0x00,0x00,0xFE,0xAA,0xAA,0xA9,0xF9,0x00,0xA0,0x9E,0x82,0x82,0x9E,0xA0,0x20,0x00,0x40,0x30,0x0F,0x02,0x22,0x42,0x3E,0x80,0x80,0x43,0x2C,0x10,0x2C,0x43,0x80,0x00,/*殷",1*/0x00,0x00,0xFE,0x02,0x12,0x92,0x92,0x92,0x92,0x92,0x92,0x12,0x02,0xFE,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x1F,0x08,0x08,0x08,0x08,0x1F,0x40,0x80,0x7F,0x00,0x00,/*"同",2*/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,/*"学",3*/};//还可以放置图像字模

main.c

#include "stm32f10x.h"
#include "SysTick.h"
#include "oled.h"//添加文件路径extern  const unsigned char BMP1[];//调用外部变量地声明 包含头文件了,不写也是可以的int main(void)
{unsigned char i = 0;initSysTick();//初始化系统时钟I2C_Configuration();OLED_Init();  //屏幕初始化  厂家给的ms_delay(2000);//2sOLED_Full(0XFF);//全屏填充 (全屏亮)1111 1111ms_delay(2000);OLED_Full(0X00);//全屏填充 (全屏灭)0000 0000ms_delay(2000);//写字符OLED_ShowStr(0,3,"  Hello world",1);//F6*8的格式OLED_ShowStr(0,4,"Hello world",2);//F8*16格式 同样的字符 显示更大了//写汉字    while(1){   OLED_ShowCn(22+i*16, 0, i);//视频里取模 ‘哞哞’二字//    覆盖整个对角线 8页  OLED_DrawBMP(0,0,128,8,(unsigned char*) BMP1);}
}

OLED显示汉字和图片(取模软件的使用)

关于取模软件使用说明:
取模主要有三种,图片、字符、汉字三种,取的原理是一样的
图片取模打开 PCtoLCD2002.exe 软件





STM32使用IIC总线通讯协议在OLED屏幕上显示字符串、汉字、图像(硬件IIC)相关推荐

  1. STM32使用IIC总线通讯协议在OLED屏幕上显示字符串、汉字、单总线获取DHT11模块温湿度并通过IIC显示到屏幕(软件IIC)

    参考:基于stm32软件IIC的oled显示温湿度 作者:ZPZ DayUp 发布时间: 2021-07-25 20:52:43 网址:https://blog.csdn.net/m0_5619768 ...

  2. # 浅谈IIC总线通讯协议

    浅谈IIC总线通讯协议 相关概念 IIC总线是PHLIPS公司在八十年代初推出的一种同步串行的半双工总线,支持多主机多从机,具备总线裁决功能,用于连接整体电路. 整体电路:同一块板子上,两个芯片之间的 ...

  3. stm32f103利用HC06进行蓝牙通信,在7针的OLED屏幕上显示,带数据更新功能(带超详细讲解)

    stm32f103利用HC06进行蓝牙通信,在7针的OLED屏幕上显示,带数据更新功能(带超详细讲解) 首先看看效果吧 手机端发送一个数据在OLED屏幕上显示 其实蓝牙通信就是个蓝牙转串口的过程,手机 ...

  4. 公有iot私有iot架构_玩洋葱Omega IoT设备在OLED屏幕上显示实时血糖

    公有iot私有iot架构 I've been playing with IoT stuff on my vacation. Today I'm looking at an Onion Omega. T ...

  5. 使用U8G2在oled屏幕上显示胡桃摇动画

    使用U8G2在oled屏幕上显示胡桃摇动画 目录 使用U8G2在oled屏幕上显示胡桃摇动画 概述 图像处理 为什么要处理? 导入opencv 分解gif 灰度化 裁剪大小和缩放 裁剪 缩放 二值化前 ...

  6. 将十进制数转化为二进制并在OLED屏幕上显示

    将十进制数转化为二进制并在OLED屏幕上显示 直接上代码: //显示二进制小数 //x,y为坐标 Num为想要转换的数(可以是十进制,也可以是十六进制) //len为想要转换的二进制的位数 size为 ...

  7. IIC总线通讯协议、EEPROM芯片

    EEPROM芯片: 掉电不会丢失数据,可以保存数据. IIC串行总线的组成及工作原理: IIC总线传输协议 IIC产生起始与终止信号: IIC字节的传送与应答: 应答位作用: 数据帧格式: 总线寻址 ...

  8. OLED模块以及OLED屏幕上显示

    一.OLED简介 OLED(Organic Light Emitting Diode):有机发光二极管 OLED显示屏:性能优异的新型显示屏,具有功耗低.相应速度快.宽视角.轻薄柔韧等特点 0.96寸 ...

  9. STM32F103C8T6学习02 将中文、英文、数字、带符号数、字符串显示到0.96寸IIC协议的OLED屏幕上

    一.结果展示 二.接线方式 SCL接B8 SDA接B9 VCC接3.3V GND接G 三.原代码 链接: https://pan.baidu.com/s/1ncVh2c9YLdK8Gdgsc1-QoA ...

最新文章

  1. 股市币市:数据分析与交易所公告(20190226)
  2. 【9.22校内测试】【可持久化并查集(主席树实现)】【DP】【点双联通分量/割点】...
  3. C中strcpy函数实现
  4. 【收藏】win10利用WSL2安装docker的2种方式
  5. 使用JUnitParams简化Parameterized tests
  6. python输出字典的前十项,从字典列表中获取前5个值?
  7. C++中? : 运算符的使用
  8. 安装过程中又一个问题出现了。
  9. 无缝对接Spark与R:Sparklyr系列—探讨属于数据科学家的Spark
  10. Atitit.常用的gc算法
  11. gcc警告: warning: dereferencing type-punned pointer will break strict-aliasing rules
  12. 【软件工程】 详细设计
  13. tbschedule 前后置处理器、定期执行任务
  14. 【OpenCV】基于Qt的“破产版”全能扫描王
  15. python将网页保存为图片_「保存网页为图片」如何将整个网页保存为图片? - seo实验室...
  16. 累积你的All Blue-使用集成库-PCB系列教程1-4
  17. excel打开很慢_从海量Excel文件中快速高效地提取数据
  18. 机器视觉怎么和plc通讯
  19. 有关java的演讲稿_有关超级演说家励志的演讲稿
  20. 网易教育论坛:“状元”在美读大学:中国孩子都被教傻了

热门文章

  1. javascript库之Mustache库使用说明
  2. 将团队迁移到可视化项目管理软件
  3. Android ListView避免多线程加载一个同一资源
  4. SQL server中DateTime类型字段如何赋值零?
  5. nand flash坏块管理OOB,BBT,ECC
  6. 使用Busybox构造cramfs根文件系统
  7. ANSYS——常见梁的后处理方法(弯曲应力、弯矩、轴力等的显示)
  8. python矩阵相关操作
  9. orb-slam2 代码逻辑梳理
  10. 图片向上滚动字幕代码html,如何通过制作滚动字幕的软件实现这种片尾的向上滚动字幕效果...