IIC简介

IIC简介基于 STM32F407ZGT 的 IIC 通信协议在 OLED 上显示汉字和爱心 iic 地址怎么确定的

大家好,欢迎来到IT知识分享网。

IIC(Inter-Integrated Circuit,又称为I2C或I²C)是一种简单而灵活的串行通信协议,用于连接微控制器和外部设备,例如传感器、存储器、显示器等。

基本原理

  • 双线制: I2C使用两根线来进行通信:串行数据线(SDA)和串行时钟线(SCL)。SDA线上的数据在SCL线的时钟信号下进行同步传输。
  • 主从结构: I2C通信中,设备分为主设备(通常是微控制器)和从设备(例如传感器或存储器)。主设备负责发起通信和控制通信的时序,而从设备响应主设备的指令。
  • 地址寻址: 每个I2C设备都有一个唯一的7位或10位地址,主设备通过发送目标设备的地址来选择通信对象。

通信过程

  1. 启动条件(Start): 主设备发出一个启动信号,即SDA线从高电平转为低电平,而SCL线保持高电平状态
  2. 发送地址和读写位: 主设备发送目标设备的地址,并指定是读取数据还是写入数据。
  3. 地址确认(ACK): 从设备接收到地址后会发送应答信号(ACK),表示准备好与主设备通信。
  4. 数据传输: 主设备或从设备在SCL时钟信号的边缘上发送或接收数据位。
  5. 停止条件(Stop): 主设备发送一个停止信号,即SDA线从低电平转为高电平,而SCL线保持高电平状态。

优点

  • 双向通信(半双工): I2C支持主设备向从设备发送数据,并且支持从设备向主设备发送数据,具有双向通信能力。
  • 多设备连接: I2C总线支持多个设备连接到同一条总线上,可以通过设备地址进行选择通信对象。

应用领域

  • 传感器接口: 许多传感器(如温度传感器、湿度传感器、加速度传感器等)使用I2C接口与微控制器进行通信。
  • 存储器接口: EEPROM、实时时钟(RTC)等存储器设备也常使用I2C接口。
  • 显示器接口: 一些OLED和LCD显示器使用I2C接口来传输图像数据和控制命令。

IIC简介

IIC物理层

IIC简介

双线制: I2C通信协议使用两根线进行通信,分别是串行数据线(SDA)和串行时钟线(SCL)。这两根线构成了I2C总线,在总线上连接了所有的I2C设备。(数据线即用来表示数据,时钟线用于数据收发同步)

开漏输出: I2C总线上的信号是开漏输出的,这意味着每个I2C设备的输出引脚都是一个开漏输出,可以通过外部上拉电阻拉高。这种设计允许多个设备共享同一根总线,而不会出现信号冲突和短路。(当I2C 设备空闲时,会输出高阻态,而当所有设备都空闲,都输出高阻态时,由上拉电阻把总线拉成高电平。)

数据传输: 数据传输是以字节为单位进行的,每个字节都包括8个数据位和1个ACK位。传输的起始和停止由特定的序列来定义,包括起始条件(Start)和停止条件(Stop)。

时钟同步: I2C通信是通过主设备发送的时钟信号来同步的。主设备负责产生时钟信号,并且所有的数据传输都是在时钟信号的边沿上进行的。

地址寻址: 每个I2C设备都有一个唯一的7位或10位地址,主设备通过发送目标设备的地址来选择通信对象。地址的长度取决于设备的规格和协议版本。

数据速率: I2C总线的数据传输速率通常可以选择为100kHz、400kHz或1MHz等不同的速率。速率的选择取决于系统要求和设备的兼容性。

总线仲裁: 多个主机同时使用总线时,为了防止数据冲突,会利用仲裁方式决定由哪个设备占用总线。

IIC协议层

I2C总线在传送数据过程中共有三种类型信号, 它们分别是:起始信号、停止信号和应答信号。其基本读写过程如图:

IIC简介

IIC简介

IIC简介

代码编写

/*

  1. GPIO口软件模拟IIC时序,实现IIC通讯
  2. 跟OLED屏幕通讯

*/

//iic.h #ifndef __IIC_H #define __IIC_H #include "public.h" //选择PE3和PE4 做为通讯引脚 PE3:SCL PE4:SDA #define RCC_IIC_SCL RCC_AHB1Periph_GPIOE //端口时钟 #define IIC_SCL_PORT GPIOE //端口号 #define IIC_SCL GPIO_Pin_3 //引脚 #define RCC_IIC_SDA RCC_AHB1Periph_GPIOE #define IIC_SDA_PORT GPIOE #define IIC_SDA GPIO_Pin_4 //io操作 #define IIC_SCL_H GPIO_SetBits(IIC_SCL_PORT,IIC_SCL); //SCL置1 #define IIC_SCL_L GPIO_ResetBits(IIC_SCL_PORT,IIC_SCL);//SCL置0 #define IIC_SDA_H GPIO_SetBits(IIC_SDA_PORT,IIC_SDA); //SDA置1 #define IIC_SDA_L GPIO_ResetBits(IIC_SDA_PORT,IIC_SDA);//SDA置0 #define READ_SDA GPIO_ReadInputDataBit(IIC_SDA_PORT,IIC_SDA)//读取SDA输入引脚电平 void IICx_GPIO_Init(void); void IIC_SDA_OUT(void); void IIC_SDA_IN(void); void IIC_Start(void); void IIC_Stop(void); void IIC_ACK(void); void IIC_NACK(void); void IIC_SendByte(uint8_t data); uint8_t IIC_ReadByte(uint8_t ack); uint8_t IIC_WaitACK(void); uint16_t BH1750_ReadData(void); #endif //iic.c #include "public.h" void GPIO_IIC(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE); GPIO_InitStructure.GPIO_Pin=GPIO_Pin_4 | GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode= GPIO_Mode_OUT; GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP; GPIO_InitStructure.GPIO_OType=GPIO_OType_OD; GPIO_InitStructure.GPIO_Speed=GPIO_High_Speed; GPIO_Init(GPIOA, &GPIO_InitStructure); } //flag = 1 读 flag = 0 写 void change_GPIO_mode(flag) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_5; GPIO_InitStructure.GPIO_Speed=GPIO_High_Speed; //引脚响应速度 if(flag == 1) { GPIO_InitStructure.GPIO_Mode= GPIO_Mode_IN; //读 GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP; } if else(flag == 0) { GPIO_InitStructure.GPIO_Mode= GPIO_Mode_OUT; //写 GPIO_InitStructure.GPIO_Otype=GPIO_OType_OD; // 开漏模式 } GPIO_Init(GPIOA, &GPIO_InitStructure); } //SCL保持高电平,SDA先出现下降沿,SCL后出现下降沿 void IIC_start(void) { change_GPIO_mode(WRITE); SCL_H; SDA_H; Delay_us(4); SDA_L; Delay_us(4); SCL_L; //SCL,SDA都为低电平,钳住电路等待数据传输 } //SCL保持高电平,SDA出现上升沿 void IIC_stop(void) { change_GPIO_mode(WRITE); SCL_H; SDA_L; Delay_us(4); SDA_H; } //主机应答 void IIC_ack(void) { change_GPIO_mode(WRITE); SCL_L;//先把时钟电平值拉低,处于空闲状态时才能切换SDA。否则产生起始终止信号 SDA_L;//主机SDA始终为低电平,产生应答 Delay_us(1); SCL_H; Delay_us(1); SCL_L; } //主机非应答 void IIC_nack(void) { change_GPIO_mode(WRITE); SCL_L;//先把时钟电平值拉低,处于空闲状态时才能切换SDA。否则产生起始终止信号 SDA_H;//主机SDA始终为高电平,非应答 Delay_us(1); SCL_H; Delay_us(1); SCL_L; } //IIC发送一个字节 void IIC_send_byte(uint8_t data) { change_GPIO_mode(WRITE); SCL_L; int i; for(i = 0;i < 8;i++) { if((data&0x80) > 0) //判断最高位是否为1 { SDA_H; } else { SDA_L; } //Delay_us(1); SCL_H: Delay_us(1); SCL_L; Delay_us(1); data <<= 1; } } //IIC读取一个字节 uint8_t IIC_receive_byte(uint8_t ack) { change_GPIO_mode(READ); int i; uint8_t receive = 0; for(i = 0;i < 8;i++) { SCL_L; Delay_us(1); SCL_H; receive <<= 1; if(SDA_READ == 1) { receive++; } Delay_us(1); } //确认帧 if(ack) IIC_ack(); elde IIC_nack(); return receive; } //7位设备地址+1位读写位 void IIC_send_ADDR_WR(uint8_t addr,uint8_t flag) { uint8_t data; data = addr<<1; data += flag; IIC_send_byte(data); } //等待应答信号,返回0表示应答,返回1表示非应答 uint8_t wait_receive_ack(void) { int time = 0; change_GPIO_mode(READ); SDA_H; Delay_us(1); SCL_H; Delay_us(1); while(SDA_READ) { time++; if(time>1000) { return ACK_FALLED; // 1 表示非应答 } } SCL_L; return ACK_SUCCESS;// 0 表示应答 } 

可以使用取模软件取字模

oled_font.h (字模库)

#ifndef __OLED_FONT_H #define __OLED_FONT_H #include <stdint.h> static unsigned char Love_Heart0[8]={0x1C,0x22,0x42,0x84,0x84,0x42,0x22,0x1C};/*"空心图形",0*/ static unsigned char Love_Heart1[8]={0x1C,0x3E,0x7E,0xFC,0xFC,0x7E,0x3E,0x1C};/*"实心图形",1*/ /*OLED字模库,宽8像素,高16像素*/ const uint8_t OLED_F8x16[][16]= { 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 }; const uint8_t OLED_F10x16[][40]= { 0x00,0x00,0x10,0x10,0x12,0xFE,0x90,0x10,0x10,0x7E,0x50,0x50,0x50,0x48,0x48,0x44, 0x44,0x70,0x40,0x00,0x00,0x02,0x02,0x42,0x41,0x3F,0x00,0x00,0x00,0x41,0x7E,0x2A, 0x2A,0x2A,0x2A,0x2A,0x7F,0x00,0x00,0x00,/*"指",0*/ 0x00,0x40,0x60,0x50,0x48,0xC6,0x60,0x20,0x10,0x10,0xF0,0x12,0x1C,0x10,0x90,0x70, 0x10,0x18,0x10,0x00,0x00,0x20,0x24,0x26,0x15,0x94,0x52,0x52,0x40,0x20,0x20,0x13, 0x0C,0x1C,0x33,0x20,0x60,0x40,0x00,0x00,/*"纹",1*/ 0x00,0x40,0x40,0x40,0x44,0x54,0x54,0x54,0x54,0xD4,0xD4,0x54,0x54,0x54,0x7C,0xC0, 0x40,0x40,0x40,0x00,0x00,0x20,0x20,0x10,0x10,0x13,0x0E,0x48,0x44,0x7F,0x3F,0x02, 0x04,0x0A,0x12,0x31,0x21,0x20,0x20,0x00,/*"录",2*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x04,0xC4,0x78,0x70,0x80,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x40,0x20,0x20,0x10,0x08,0x04,0x03,0x01,0x00,0x00,0x01, 0x03,0x0C,0x18,0x10,0x30,0x20,0x20,0x00,/*"入",3*/ 0x00,0x80,0x80,0xFC,0x84,0xFC,0x84,0x80,0xFC,0x84,0x84,0xFC,0x80,0x80,0xF8,0x08, 0x00,0xFE,0x02,0x00,0x00,0x40,0x38,0x27,0x20,0x3F,0x40,0x38,0x47,0x40,0x40,0x3F, 0x00,0x00,0x0F,0x40,0x40,0x7F,0x00,0x00,/*"删",4*/ 0x00,0x00,0xFC,0x04,0x64,0x94,0x8C,0x44,0x20,0x60,0x58,0x4C,0xC2,0x4C,0x50,0x70, 0x20,0x60,0x00,0x00,0x00,0x00,0x7F,0x04,0x08,0x08,0x47,0x20,0x12,0x0E,0x42,0xC2, 0x7F,0x02,0x02,0x0A,0x12,0x22,0x00,0x00,/*"除",5*/ }; #endif 

oled.c

/OLED屏幕操作函数*/ #include "public.h" #include "oled_font.h" void OLED_WriteCommand(uint8_t Command) { IIC_Start(); IIC_SendByte(0x78); //从机地址,并且写数据 IIC_WaitACK(); IIC_SendByte(0x00); // IIC_WaitACK(); IIC_SendByte(Command); // 写入命令 IIC_WaitACK(); IIC_Stop(); } void OLED_WriteData(uint8_t Data) { IIC_Start(); IIC_SendByte(0x78); //从机地址 IIC_WaitACK(); IIC_SendByte(0x40); IIC_WaitACK(); IIC_SendByte(Data); // 写入命令 IIC_WaitACK(); IIC_Stop(); } / * @brief OLED设置光标位置 * @param Y 以左上角为原点,向下方向的坐a'a'a'a'a'a'a'a'a'a'a'a'a'a'a'a'a'a'a标,范围:0~7 * @param X 以左上角为原点,向右方向的坐标,范围:0~127 * @retval 无 */ void OLED_SetCursor(uint8_t Y, uint8_t X) { //协议规定 OLED_WriteCommand(0xB0 | Y); // 设置Y位置 OLED_WriteCommand(0x10 | ((X & 0xF0) >> 4)); // 设置X位置高4位 OLED_WriteCommand(0x00 | (X & 0x0F)); // 设置X位置低4位 } / * @brief OLED清屏 * @param 无 * @retval 无 */ void OLED_Clear(void) { uint8_t i, j; for (j = 0; j < 8; j++) { OLED_SetCursor(j, 0); for (i = 0; i < 128; i++) { OLED_WriteData(0x00); } } } / * @brief OLED显示一个字符 * @param Line 行位置,范围:1~4 * @param Column 列位置,范围:1~16 * @param Char 要显示的一个字符,范围:ASCII可见字符 * @retval 无 */ void OLED_ShowCN(uint8_t Line, uint8_t Column, uint8_t Num) { uint8_t i; uint8_t wide=20;//字宽 OLED_SetCursor((Line-1)*2, (Column-1)*wide); //参数1:把光标设置在第几页. 参数2:把光标设置在第几列 for (i = 0; i < wide; i++) { OLED_WriteData(OLED_F10x16[Num][i]); //显示上半部分内容 } OLED_SetCursor((Line-1)*2+1,(Column-1)*wide); for (i = 0; i < wide; i++) { OLED_WriteData(OLED_F10x16[Num][i+wide]); //显示下半部分内容 } } void OLED_ShowLove(uint8_t Line, uint8_t Column) { uint8_t i; uint8_t wide=8;//字宽 OLED_SetCursor((Line-1)*2, (Column-1)*wide); //参数1:把光标设置在第几页. 参数2:把光标设置在第几列 for (i = 0; i < wide; i++) { OLED_WriteData(Love_Heart0[i]); //显示内容 } OLED_SetCursor((Line-1)*2 + 1, (Column-1)*wide); for (i = 0; i < wide; i++) { OLED_WriteData(Love_Heart1[i]); //显示两行 } } void OLED_ShowChar(uint8_t Line, uint8_t Column, char Char) { uint8_t i; OLED_SetCursor((Line - 1) * 2, (Column - 1) * 8); // 设置光标位置在上半部分 for (i = 0; i < 8; i++) { OLED_WriteData(OLED_F8x16[Char - ' '][i]); // 显示上半部分内容 } OLED_SetCursor((Line - 1) * 2 + 1, (Column - 1) * 8); // 设置光标位置在下半部分 for (i = 0; i < 8; i++) { OLED_WriteData(OLED_F8x16[Char - ' '][i + 8]); // 显示下半部分内容 } } / * @brief OLED显示字符串 * @param Line 起始行位置,范围:1~4 * @param Column 起始列位置,范围:1~16 * @param String 要显示的字符串,范围:ASCII可见字符 * @retval 无 */ void OLED_ShowString(uint8_t Line, uint8_t Column, char *String) { uint8_t i; for (i = 0; String[i] != '\0'; i++) { OLED_ShowChar(Line, Column + i, String[i]); } } / * @brief OLED次方函数 * @retval 返回值等于X的Y次方 */ uint32_t OLED_Pow(uint32_t X, uint32_t Y) { uint32_t Result = 1; while (Y--) { Result *= X; } return Result; } / * @brief OLED显示数字(十进制,正数) * @param Line 起始行位置,范围:1~4 * @param Column 起始列位置,范围:1~16 * @param Number 要显示的数字,范围:0~ * @param Length 要显示数字的长度,范围:1~10 * @retval 无 */ void OLED_ShowNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length) { uint8_t i; for (i = 0; i < Length; i++) { OLED_ShowChar(Line, Column + i, Number / OLED_Pow(10, Length - i - 1) % 10 + '0'); } } / * @brief OLED显示数字(十进制,带符号数) * @param Line 起始行位置,范围:1~4 * @param Column 起始列位置,范围:1~16 * @param Number 要显示的数字,范围:-~ * @param Length 要显示数字的长度,范围:1~10 * @retval 无 */ void OLED_ShowSignedNum(uint8_t Line, uint8_t Column, int32_t Number, uint8_t Length) { uint8_t i; uint32_t Number1; if (Number >= 0) { OLED_ShowChar(Line, Column, '+'); Number1 = Number; } else { OLED_ShowChar(Line, Column, '-'); Number1 = -Number; } for (i = 0; i < Length; i++) { OLED_ShowChar(Line, Column + i + 1, Number1 / OLED_Pow(10, Length - i - 1) % 10 + '0'); } } / * @brief OLED显示数字(十六进制,正数) * @param Line 起始行位置,范围:1~4 * @param Column 起始列位置,范围:1~16 * @param Number 要显示的数字,范围:0~0xFFFFFFFF * @param Length 要显示数字的长度,范围:1~8 * @retval 无 */ void OLED_ShowHexNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length) { uint8_t i, SingleNumber; for (i = 0; i < Length; i++) { SingleNumber = Number / OLED_Pow(16, Length - i - 1) % 16; if (SingleNumber < 10) { OLED_ShowChar(Line, Column + i, SingleNumber + '0'); } else { OLED_ShowChar(Line, Column + i, SingleNumber - 10 + 'A'); } } } / * @brief OLED显示数字(二进制,正数) * @param Line 起始行位置,范围:1~4 * @param Column 起始列位置,范围:1~16 * @param Number 要显示的数字,范围:0~1111 1111 1111 1111 * @param Length 要显示数字的长度,范围:1~16 * @retval 无 */ void OLED_ShowBinNum(uint8_t Line, uint8_t Column, uint32_t Number, uint8_t Length) { uint8_t i; for (i = 0; i < Length; i++) { OLED_ShowChar(Line, Column + i, Number / OLED_Pow(2, Length - i - 1) % 2 + '0'); } } / * @brief OLED初始化 * @param 无 * @retval 无 */ void OLED_Init(void) { Delay_ms(100); OLED_WriteCommand(0xAE); // 关闭显示 OLED_WriteCommand(0xD5); // 设置显示时钟分频比/振荡器频率 OLED_WriteCommand(0x80); OLED_WriteCommand(0xA8); // 设置多路复用率 OLED_WriteCommand(0x3F); OLED_WriteCommand(0xD3); // 设置显示偏移 OLED_WriteCommand(0x00); OLED_WriteCommand(0x40); // 设置显示开始行 OLED_WriteCommand(0xA1); // 设置左右方向,0xA1正常 0xA0左右反置 OLED_WriteCommand(0xC8); // 设置上下方向,0xC8正常 0xC0上下反置 OLED_WriteCommand(0xDA); // 设置COM引脚硬件配置 OLED_WriteCommand(0x12); OLED_WriteCommand(0x81); // 设置对比度控制 OLED_WriteCommand(0xCF); OLED_WriteCommand(0xD9); // 设置预充电周期 OLED_WriteCommand(0xF1); OLED_WriteCommand(0xDB); // 设置VCOMH取消选择级别 OLED_WriteCommand(0x30); OLED_WriteCommand(0xA4); // 设置整个显示打开/关闭 OLED_WriteCommand(0xA6); // 设置正常/倒转显示 OLED_WriteCommand(0x8D); // 设置充电泵 OLED_WriteCommand(0x14); OLED_WriteCommand(0xAF); // 开启显示 OLED_Clear(); // OLED清屏 } 

main.c

#include "public.h" /* 1. GPIO口软件模拟IIC时序,实现IIC通讯 2. 跟OLED屏幕通讯(OLED驱动代码不需要我们写,直接复制过来) 3. 跟BH1750光照模块通讯,获取光照信息并打印输出 */ int main(void) { //2号分组:2bit给抢占 2bit给响应 0-3 0-3 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); SysTick_Init(); USART_Init_Config(); IICx_GPIO_Init(); OLED_Init(); OLED_ShowCN(1,1,0); OLED_ShowCN(1,2,1); OLED_ShowCN(1,3,2); OLED_ShowCN(1,4,3); OLED_ShowCN(1,5,4); OLED_ShowCN(1,6,5); OLED_ShowString(1,16,":"); int i,j; OLED_ShowLove(2,7); OLED_ShowLove(2,8); OLED_ShowLove(2,15); OLED_ShowLove(2,16); OLED_ShowNum(3,1,1,1); while(1) { } } 

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/152400.html

(0)
上一篇 2024-11-26 19:45
下一篇 2024-11-26 20:00

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信