我们可以把数据保存在EEPROM中,这样断电数据也不会丢失。

常用的串行总线协议:

目前常用的微机与外设之间进行数据传输的串行总线主要有I2C总线、SPI总线和SCI总线。

I2C总线:以同步串行2线方式进行通信(一条时钟线,一条数据线)。

SPI总线:则以同步串行3线方式进行通信(一条时钟线,一条数据输入线,一条数据输出线)。

SCI总线:是以异步方式进行通信(一条数据输入线,一条数据输出线)。

1-wire  即单线总线,又叫单总线。

例子:

1-wire ——数字温度传感器DS18B20

IIC——oled屏幕


I2C串行总线的组成及工作原理

I2C总线是PHLIPS公司推出的一种串行总线,它只有两根双向信号线。一根是数据线SDA(serial data I/O),另一根是时钟线SCL(serial clock)。

如下图所示,IIC总线上可以挂多个器件,而每个器件都有唯一的地址,这样可以标识通信目标。数据的通信的方式采用主从方式,主机负责主动联系从机,而从机则被动回应数据。

在多主机系统中,可能同时有几个主机企图启动总线传送数据。为了避免混乱,I2C总线要通过总线仲裁来决定由哪一台主机控制总线。

但是我们现在学习的单片机一般都是单主机情况。

I2C总线通过上拉电阻接正电源。当总线空闲时,两根线均为高电平。连到总线上的任一器件输出的低电平,都将使总线的信号变低,即各器件的SDA及SCL都是线“与”关系。


函数

要掌握IIC的通信协议,需要掌握以下几个函数的写法:
1.起始信号 i2c_Start()
2.终止信号 i2c_Stop()
3.写数据 i2c_SendByte()
4.读数据 i2c_ReadByte()
5.发送应答信号 i2c_Ack()
6.发送非应答信号 i2c_Nack()
7.等待应答 i2c_WaitAck()
8.检测I2C总线设备 i2c_CheckDevice


I2C总线传输协议

I2C的起始和终止信号

SCL线为高电平期间,SDA线由高电平向低电平的变化表示起始信号;SCL线为高电平期间,SDA线由低电平向高电平的变化表示终止信号。

起始和终止信号都是由主机发出的,在起始信号产生后,总线就处于被占用的状态;在终止信号产生后,总线就处于空闲状态。

连接到I2C总线上的器件,若具有I2C总线的硬件接口,则很容易检测到起始和终止信号。

接受期间收到一个完整的数据字节后,有可能需要完成一些其他工作,例如处理内部中断服务等,可能无法立刻接收下一个字节,这时接收器件可以将SCL线拉成低电平,从而使主机处于等待状态。直到接受器件准备好接收下一个字节时,再释放SCL线使之为高电平,从而使数据传送可以继续进行。

数据位的有效性规定

SCL为高电平期间,数据线上的数据必须保持稳定,只有SCL信号为低电平期间,SDA状态才允许变化。

I2C字节的传送与应答

每一个字节必须保证是8位长度。数据传送时,先传送最高位(MSB),每一个被传送的字节后面都必须跟随一位应答位(即一帧共有9位)。

应答位的作用

主机在发送数据时,每次发送一字节数据,都需要读取从机应答位,当从机空闲可以接收该字节数据时,从机会发出应答(一帧数据的第9位为“0”)当从机正忙于其他工作的处理来不及接收主机发送的数据时,从机会发出非应答(一帧数据的第9位为“1”)主机则应发出终止信号以结束数据的继续传送,主机通过从机发出的应答位来判断从机是否成功接收数据。

当主机接收数据时,它收到最后一个数据字节后,必须向从机发出一个结束传送的信号。这个信号是由对从机的“非应答”来实现的。然后,从机释放SDA线,以允许主机产生终止信号。


注意:阴影部分是主机的数据,白色部分是从机的数据

I2C写数据流程

起始信号后必须传送一个从机的地址(7位)我们开发板上的AT24C02地址为0xa0,第8位是数据的传送方向位(R/T),用“0”表示主机发送数据(T)——写,“1”表示主机接收数据(R)——读。

I2C读数据流程

在读数据时也要先发送器件地址,读写方向为写,因为我们下一帧需要发送从AT24C02内那个单元开始读,之后需在发一次器件地址这个时候读写方向就为读了,接着我们就可以从总线上读取数据。


从机地址例子(AT24C02的1k),这里不同内存版本的芯片不同可编程位数量。

A0 - A2是可编程位,可以通过控制引脚电平来控制内容


软件模拟I2C通信时序

I2C总线的数据传送有严格的时序要求。I2C总线的起始信号、终止信号、发送“0”及发送“1”的模拟时序 :

代码思路:

/*
*********************************************************************************************************
*   函 数 名: i2c_Start
*   功能说明: CPU发起I2C总线开启信号
*   形    参:  无
*   返 回 值: 无
*********************************************************************************************************
*/
void i2c_Start(void)
{/* 当SCL高电平时,SDA出现一个下跳沿表示I2C总线启动信号 */SDA = 1;SCL = 1;i2c_Delay();SDA = 0;i2c_Delay();SCL = 0;i2c_Delay();
}/*
*********************************************************************************************************
*   函 数 名: i2c_Stop
*   功能说明: CPU发起I2C总线停止信号
*   形    参:  无
*   返 回 值: 无
*********************************************************************************************************
*/
void i2c_Stop(void)
{/* 当SCL高电平时,SDA出现一个上跳沿表示I2C总线停止信号 */SDA = 0;SCL = 1;i2c_Delay();SDA = 1;i2c_Delay();
}/*
*********************************************************************************************************
*   函 数 名: i2c_WaitAck
*   功能说明: CPU产生一个时钟,并读取器件的ACK应答信号
*   形    参:  无
*   返 回 值: 返回0表示正确应答,1表示无器件响应
*********************************************************************************************************
*/
unsigned char i2c_WaitAck(void)
{unsigned char re; //应答信号等于0则应答正确,等于1则没有应答SDA = 1;          //释放总线,能让对方拉低i2c_Delay();SCL = 1;          //此时刻开始,数据保持应答状态稳定i2c_Delay();if(SDA == 1){re = 1;        //没有应答}else{re = 0;        //应答正确                                                                                                                                                                            }SCL = 0;i2c_Delay();return re;
}/*
*********************************************************************************************************
*   函 数 名: i2c_SendByte
*   功能说明: CPU向I2C总线设备发送8bit数据
*   形    参:  _ucByte : 等待发送的字节
*   返 回 值: 无
*********************************************************************************************************
*/
void i2c_SendByte(unsigned char _ucByte)
{unsigned char i;     //其实信号开始后SCL是被拉低的for(i = 0; i < 8; i++){if(_ucByte & 0x80)SDA = 1;elseSDA = 0;SCL = 1; i2c_Delay();SCL = 0;      //SCL等于0的时候写数据if(i == 7)    //最后一次时释放总线{SDA = 1;}_ucByte<<=1;  //左移一位i2c_Delay();}
}/*
*********************************************************************************************************
*   函 数 名: i2c_ReadByte
*   功能说明: CPU从I2C总线设备读取8bit数据
*   形    参:  无
*   返 回 值: 读到的数据
*********************************************************************************************************
*/
unsigned char i2c_ReadByte(void)
{unsigned char i;unsigned char value = 0;for(i = 0; i < 8; i++){value<<=1;SCL = 1;  //稳定状态的时候读数据if(SDA == 1)value++;SCL = 0;  //允许数据变化i2c_Delay();}return value;
}/*
*********************************************************************************************************
*   函 数 名: i2c_Ack
*   功能说明: CPU产生一个ACK信号
*   形    参:  无
*   返 回 值: 无
*********************************************************************************************************
*/
void i2c_Ack(void)
{SDA = 0;//响应i2c_Delay();SCL = 1;i2c_Delay();SCL = 0;i2c_Delay();   //在SCL为高电平期间SDA都为0即产生一个应答信号SDA = 1;       //释放总线i2c_Delay();
}/*
*********************************************************************************************************
*   函 数 名: i2c_NAck
*   功能说明: CPU产生1个NACK信号
*   形    参:  无
*   返 回 值: 无
*********************************************************************************************************
*/
void i2c_NAck(void)
{SDA = 1;i2c_Delay();SCL = 1;i2c_Delay();SCL = 0;i2c_Delay();   //在SCL为高电平期间SDA都为1即产生一个非应答信号
}/*
*********************************************************************************************************
*   函 数 名: i2c_Delay
*   功能说明: I2C总线位延迟,最快400KHz
*   形    参:  无
*   返 回 值: 无
*********************************************************************************************************
*/
static void i2c_Delay(void)
{unsigned char i;/* IIC 延时时间根据具体情况自行决定for循环延迟时间的大小实际应用选择小于400KHz左右的速率即可*/for (i = 0; i < 10; i++);
}

51单片机——I2C总线EEPROM相关推荐

  1. 51单片机——I2C总线

    目录 1.概述 2.I2C总线通信协议 3.I2C总线的数据传送格式 3.1 单字节数据传送格式 3.2 多字节数据传送格式 4.I2C总线存储器24C02(E2PROM) 4.1  外形与引脚功能说 ...

  2. 单片机I2C总线AT24C02读写、扩展keil工程多个实例及Proteus仿真

    1.对I2C总线上挂接多个AT24C02的读写操作源代码如下: //对I2C总线上的2个AT24C02(U2和U3)的读写/*I2C总线系统中器件地址包括固定部分和可编程部分. 可编程部分必须根据A0 ...

  3. 51单片机读写内部EEPROM详解

    文档共包含三个程序. 第一个程序最简单易懂,看懂了基本就会读写51单片机内部EEPROM了. 第二个程序和第一个读写EEPROM原理差不多,包含有LCD1602操作方法,有写字符串的方法. 第三个程序 ...

  4. 51单片机IIC总线编程

    #include<reg52.h> #define uchar unsigned char sbit sda=P2^0; sbit scl=P2^1;//用单片机的两个I/O口模拟I2C接 ...

  5. 学习51单片机外部总线扩展并口芯片8255

    1.8255A 8255A是一可编程的并行IO接口扩展芯片,可以使单片机扩展出三个8位并行IO口. 扩展IO口有多种模式,可以实现方向控制.询问.应答控制多种功能. 3个可编程的并行I/O口:PA口. ...

  6. linux i2c 多字节读写,基于51单片机i2c多字节的读写

    描述 使用Keil的编译环境下载,确实能够下载,但是入口的地址是如下黄色的那行显示所示,如果单步执行(F11)或全速运行(F5),程序始终在原位置不动(0x1FFF4252),如果强制的将PC指针的值 ...

  7. 最简单DIY基于C#和51单片机上下位机一体化的PCA9685舵机控制程序

    51单片机物联网智能小车系列文章目录 第一篇:最简单DIY的51蓝牙遥控小车设计方案 第二篇:最简单DIY串口蓝牙硬件实现方案 第三篇:最简单DIY蓝牙PS2遥控器控制蓝牙智能小车 第四篇:最简单DI ...

  8. 最简单DIY基于51单片机、PCA9685、IIC、云台的舵机集群控制程序

    51单片机物联网智能小车系列文章目录 第一篇:最简单DIY的51蓝牙遥控小车设计方案 第二篇:最简单DIY串口蓝牙硬件实现方案 第三篇:最简单DIY蓝牙PS2遥控器控制蓝牙智能小车 第四篇:最简单DI ...

  9. 【51单片机快速入门指南】4.1: I2C 与 AT24C02 (EEPROM) 的跨页连续读写

    目录 硬知识 AT24Cxx 介绍 引脚排列 引脚说明 存储结构 器件寻址 器件操作 待机模式 存储复位 写操作 字节写 页写 应答查询 读操作 当前地址读 随机读 顺序读 示例程序 24C02.c ...

最新文章

  1. Learn OpenGL (二):三角形
  2. 7 个显著提升编码效率的IntelliJ IDEA必备插件
  3. WDS使用捕获映像制作企业自定义映像
  4. 3YAdmin-专注通用权限控制与表单的后台管理系统模板
  5. html页面跳转_HTTP响应协议状态码以及跳转问题
  6. php 嵌套 mysql_PHP中实现MySQL嵌套事务的两种解决方案,mysql嵌套_PHP教程
  7. poj 2985(并查集+线段树求K大数)
  8. 监督学习和无监督学习_让半监督学习再次伟大!谷歌最新无监督数据增强研究,全面超越现有半监督学习方法...
  9. sklearn模型的训练(上)
  10. Texture Inspection 纹理检验halcon算子,持续更新
  11. 谷歌、CMU发文:别压榨单模型了!集成+级联上分效率更高!
  12. win10安装应用商店版word(ump版word)
  13. 大神级ppt作品欣赏_【重磅源文件来了】课程更新2019苹果宣传片PPT福利来袭
  14. Zotero如何更改字体大小
  15. bug-猎豹wifi提示无线网卡未打开(微星笔记本)
  16. PS 色调——颜色运算
  17. 技术科普:虚拟现实系统
  18. 什么是真正的架构设计?某厂十年Java经验让我总结出了这些,不愧是我
  19. 标准模式和怪异模式指的是什么?
  20. 75道程序员面试逻辑题和答案

热门文章

  1. 19_ue4进阶末日生存游戏开发[关联UI和数据]
  2. 微信小程序15---将组件设置为圆形
  3. iview添加自定义表头
  4. 游戏里面的人物是怎么做的
  5. Web服务器软件,severlet
  6. python turtle 画老鼠,Python Turtle绘图讲解,画一只属于双十一的单身狗
  7. ABB机器人系统输入输出信号System Input和Output详解(二)
  8. android canvas drawrect画图,为什么在android中调用canvas.drawRect时只绘制一个矩形?
  9. 产品经理必读的九步法(转)
  10. R语言dplyr包group_by函数、summarise函数和across函数计算dataframe数据中指定范围数值数据列的均值、across函数对多个列执行相同的操作