“OLED屏幕,色彩绚丽,画面清晰,让每一帧都生动无比。“#IIC协议【上】

前言

  本篇博文介绍的是用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,另一根是时钟线SCL,其时钟信号是由主控器件产生。所有接到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

结束语

  很高兴您能看到这里,点个赞再走呗。谢谢您啦!!!

最近更新

  1. TCP协议是安全的吗?

    2024-02-10 14:36:03       14 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-10 14:36:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-10 14:36:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-10 14:36:03       18 阅读

热门阅读

  1. 从零开始学howtoheap:理解fastbins的double-free攻击

    2024-02-10 14:36:03       24 阅读
  2. 人工智能之数学基础【导数】

    2024-02-10 14:36:03       23 阅读
  3. Qt博客目录

    2024-02-10 14:36:03       31 阅读
  4. 视频处理学习笔记1:YUYV422、NV12和h264

    2024-02-10 14:36:03       28 阅读
  5. cool 框架 node 后端封装三方Api post请求函数

    2024-02-10 14:36:03       26 阅读
  6. ComfyUI 学习笔记

    2024-02-10 14:36:03       29 阅读
  7. Qt的几种布局样例代码

    2024-02-10 14:36:03       28 阅读
  8. GCC编译器技巧--在C语言里面使用使用内敛汇编

    2024-02-10 14:36:03       22 阅读
  9. RuoYi模块功能分析:第二章 日志

    2024-02-10 14:36:03       25 阅读
  10. C#系列-C#访问hadoop API(9)

    2024-02-10 14:36:03       32 阅读
  11. 11.1 OpenGL可编程顶点处理:顶点着色器

    2024-02-10 14:36:03       37 阅读