“OLED屏幕,色彩绚丽,画面清晰,让每一帧都生动无比。“#IIC协议【上】
"OLED屏幕,色彩绚丽,画面清晰,让每一帧都生动无比。"#IIC协议【上】
- 前言
- 预备知识
- 1.IIC协议初识
- 1.1 IIC协议概述
- 1.2 IIC协议的特点
- 1.3 IIC协议的构成
- 2. IIC起始信号和终止信号
- 2.1起始型号和终止信号时序图分析
- 2.2起始信号函数和终止信号函数代码
- 2.3完整程序代码
- 3. IIC协议ACK函数封装
- 3.1应答信号简介
- 3.2应答信号时序图分析
- 3.3应答信号函数代码
- 3.4完成程序代码
- 4. IIC协议发送一个字节的函数封装
- 4.1 IIC协议发送时序图分析
- 4.2 IIC协议发送一个字节的算法思想。
- 4.3函数代码
- 4.4完整程序代码
- 5.OLED写入指令和数据
- 5.1 OLED写入指令和数据手册详解
- 5.2根据手册内容得OLED写指令和数据函数
- 6. OLED显示一个点的思路
- 6.1 OLED屏幕的组成
- 6.2 OLDE屏幕地址结构图
- 6.3 OLED单页地址结构体
- 6.4 OLED的三种地址寻址模式
- 6.5 OLED页地址模式选择
- 6.6写入 0000 1000
- 结束语
前言
本篇博文介绍的是用51单片机的 IIC 协议【上】(OLED屏幕),包含IIC协议初识,IIC起始信号和终止信号,IIC协议ACK函数封装,IIC协议发送一个字节的函数封装,OLED写入指令和数据,OLED显示一个点的思路。看到这篇博文的朋友,可以先赞再看吗?
预备知识
一、基本电路标识识别和接线,例如VCC,GND。
二、电脑基本操作复制粘贴
三、准备软件FastStone Capture,会简单操作(此软件需要的评论区评论)
四、数字电子时序图的识别
五、一点点专业英语积累
六、C变量
七、基本输入输出
八、流程控制
九、函数
十、指针
十一、字符串
如果以上知识不清楚,请自行学习后再来浏览。如果我有没例出的,请在评论区写一下。谢谢啦!
1.IIC协议初识
1.1 IIC协议概述
IIC全称Inter-Integrated Circuit (集成电路总线)
是由PHILIPS公司在80年代开发的两线式串行总线,用于连接微控制器及其外围设备。IIC属于半双工同步通信方式
1.2 IIC协议的特点
- 简单性和有效性。
由于接口直接在组件之上
,因此IIC总线占用的空间非常小
,减少了电路板的空间和芯片管脚的数量,降低了互联成本。总线的长度可高达25英尺
,并且能够以10Kbps
的最大传输速率支持40个
组件
- 多主控
其中任何能够进行发送和接收的设备都可以成为主总线
。一个主控能够控制信号的传输和时钟频率
。当然,在任何时间点上只能有一个主控。
1.3 IIC协议的构成
IIC串行总线一般有两根信号线
,一根是双向的数据线SDA
,另一根是时钟线SC
L,其时钟信号
是由主控器件产生
。所有接到IIC总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上。对于并联在一条总线上的每个IC都有唯一的地址
。
2. IIC起始信号和终止信号
2.1起始型号和终止信号时序图分析
2.2起始信号函数和终止信号函数代码
void IICStart() //IIC起始信号函数
{
SCL = 1; //根据起始信号时序图,SCL一直为高电平
SDA = 1; //根据起始信号时序图阴影部分,SDA先是高电平
_nop_(); //_nop_()寒素执行时间为5微秒,并不是1微秒,原因是调用函数时有进出栈操作
//此时在这里,根据起始信号时序图可知需要延时》4.7微秒
SDA = 0; //根据起始信号时序图阴影部分,SDA此时为低电平
_nop_(); //延时5微秒
}
void IICStop() //IIC终止信号函数
{
SCL = 1; //根据起始信号时序图,SCL一直为高电平
SDA = 0; //根据起始信号时序图阴影部分,SDA先是低电平
_nop_(); //延时5微秒
SDA = 1; //根据起始信号时序图阴影部分,SDA此时为高电平
_nop_(); //延时5微秒
}
2.3完整程序代码
#include "reg52.h"
#include "intrins.h"
sbit SCL = P0^1; //把SCL接单片机P0.1口
sbit SDA = P0^3; //把SDA接单片机P0.3口
void IICStart() //IIC起始信号函数
{
SCL = 1; //根据起始信号时序图,SCL一直为高电平
SDA = 1; //根据起始信号时序图阴影部分,SDA先是高电平
_nop_(); //_nop_()寒素执行时间为5微秒,并不是1微秒,原因是调用函数时有进出栈操作
//此时在这里,根据起始信号时序图可知需要延时》4.7微秒
SDA = 0; //根据起始信号时序图阴影部分,SDA此时为低电平
_nop_(); //延时5微秒
}
void IICStop() //IIC终止信号函数
{
SCL = 1; //根据起始信号时序图,SCL一直为高电平
SDA = 0; //根据起始信号时序图阴影部分,SDA先是低电平
_nop_(); //延时5微秒
SDA = 1; //根据起始信号时序图阴影部分,SDA此时为高电平
_nop_(); //延时5微秒
}
void main()
{
IICStart();
IICStop();
}
3. IIC协议ACK函数封装
3.1应答信号简介
发送器每发送一个字节(8个bit)
,就在时钟脉冲9
期间释放数据线,由接收器反馈
一个应答信号
。应答信号为低电平时
,规定为有效应答位
(ACK,简称应答位
),表示接收器已经成功地接收了该字节
;
应答信号为高电平时
,规定为非应答位
(NACK
),一般表示接收器接收该字节没有成功
。
3.2应答信号时序图分析
3.3应答信号函数代码
char IIC_ACK()
{
char flag;
SDA = 1; //释放数据线
_nop_();
SCL = 1;
_nop_();
flag = SDA;
_nop_();
SCL = 0;
_nop_();
return flag;
}
3.4完成程序代码
#include "reg52.h"
#include "intrins.h"
sbit SCL = P0^1; //把SCL接单片机P0.1口
sbit SDA = P0^3; //把SDA接单片机P0.3口
char IIC_ACK()
{
char flag;
SDA = 1; //释放数据线
_nop_();
SCL = 1;
_nop_();
flag = SDA;
_nop_();
SCL = 0;
return flag;
}
void main()
{
char i;
i = IIC_ACK();
}
4. IIC协议发送一个字节的函数封装
4.1 IIC协议发送时序图分析
4.2 IIC协议发送一个字节的算法思想。
从上面的时序图分析中可知是发送一个位的
数据,那么发送一个字节
也就是8位数据
就需要发送8次
一个位的数据。从高位开始发,每次发送的数据必须是当前数据的最高位
。可以用与上0x80
解决,但这又衍生出一个问题,0x80只能发送8位数据的最高位
,那怎么办才能将数据往左边移动呢?这可以用移位运算解决。
这样的算法思想便可以使通过IIC协议发送一个字节的数据。
4.3函数代码
void IICSendByte(char cdata)
{
char i;
for(i=0; i<8; i++ )
{
SCL = 0; //scl拉低,让sda做好数据准备
SDA = cdata & 0x80; //0x80 = 1000 0000获得cdata的最高位,给sda
_nop_(); //发送建立数据时间
SCL = 1; //SCL被拉高开始发送数据
_nop_(); //数据发送时间
SCL = 0; //发送完数据被拉低
_nop_();
cdata = cdata << 1;
}
}
4.4完整程序代码
#include "reg52.h"
#include "intrins.h"
sbit SCL = P0^1; //把SCL接单片机P0.1口
sbit SDA = P0^3; //把SDA接单片机P0.3口
void IICSendByte(char cdata)
{
char i;
for(i=0; i<8; i++ )
{
SCL = 0; //scl拉低,让sda做好数据准备
SDA = cdata & 0x80; //0x80 = 1000 0000获得cdata的最高位,给sda
_nop_(); //发送建立数据时间
SCL = 1; //SCL被拉高开始发送数据
_nop_(); //数据发送时间
SCL = 0; //发送完数据被拉低
_nop_();
cdata = cdata << 1;
}
}
void main()
{
char i;
IICSendByte(i);
}
5.OLED写入指令和数据
5.1 OLED写入指令和数据手册详解
5.2根据手册内容得OLED写指令和数据函数
void OledWriteCmd(char Cmd)
{
//1.start
IICStart();
//2.写入从机地址 b0111 1000 0x78
IICSendByte(0x78);
//3.ACK
IIC_ACK();
//4.cotrol byte: (0)(0)000000 写入命令 (0)(1)000000写入数据
IICSendByte(0x00);
//5.ACK
IIC_ACK();
//6. 写入指令/数据
IICSendByte(Cmd);
//7.ACK
IIC_ACK();
//8.STOP
IICStop();
}
void OledWriteData(char Data)
{
//1.start
IICStart();
//2.写入从机地址 b0111 1000 0x78
IICSendByte(0x78);
//3.ACK
IIC_ACK();
//4.cotrol byte: (0)(0)000000 写入命令 (0)(1)000000写入数据
IICSendByte(0x40);
//5.ACK
IIC_ACK();
//6. 写入指令/数据
IICSendByte(Data);
//7.ACK
IIC_ACK();
//8.STOP
IICStop();
}
6. OLED显示一个点的思路
6.1 OLED屏幕的组成
OLED屏幕是由128×64像素
点构成,也就是128×64个小灯珠
构成。
6.2 OLDE屏幕地址结构图
从地址结构图可知,OLED将128×64像素点分成了7个大组,每组为128×8个像素点。每组的名字被命名为*页。
6.3 OLED单页地址结构体
6.4 OLED的三种地址寻址模式
- 页地址模式
- 水平地址模式
- 垂直地址模式(少用)
6.5 OLED页地址模式选择
配置指令如下:
图中有红框处前面的地址有两行。
第一行命令为:0x20
第二行命令为:0x02 (可不用配,默认就为页地址)
6.6写入 0000 1000
- 一个字节负责一个Page的列显示
64 | 0 列 | 1 列 | 2 列 | 3 列 | … | 124 列 | 125 列 | 126 列 | 127 列 |
---|---|---|---|---|---|---|---|---|---|
Page0 | bit0 | 0行 | 0 | ||||||
bit1 | 1行 | 0 | |||||||
bit2 | 2行 | 0 | |||||||
bit3 | 3行 | 1 | |||||||
bit4 | 4行 | 0 | |||||||
bit5 | 5行 | 0 | |||||||
bit6 | 6行 | 0 | |||||||
bit7 | 7行 | 0 | |||||||
Page1 | 8到 15行 | ||||||||
Page2 | 16到 23行 | ||||||||
Page3 | … | ||||||||
Page4 | … | ||||||||
Page5 | … | ||||||||
Page6 | … |
结束语
很高兴您能看到这里,点个赞再走呗。谢谢您啦!!!