历史上的今天
今天是:2024年10月26日(星期六)
2021年10月26日 | #51单片机# I2C时序初步认识和寻址模式
2021-10-26 来源:eefocus
I2C,由PHILIIPS公司开发的两线式串行总线(SCL和SDA),是一种常用的通信协议,多用于连接微处理器及其外围芯片。
I2C的特点:1.接口方式简单。2.两条线可挂多个参与通信的器件,即多机模式。且任一器件都可作为主机(同一时刻只能有一个主机)。
相比与UART通信,I2C属于同步通信。SCL时钟线负责收发双方的时钟节拍,SDA数据线负责传输数据。 I2C的发送方和接收方都以SCL的时钟节拍为基准进行数据发送与接收。
从应用上来说,UART通信多用于板间通信,如:单片机和计算机。I2C多用于板内通信,如:单片机和E2PROM。
I2C时序初步认识
硬件上,I2C总线由SCL时钟总线和SDA数据总线两条线构成。连接到I2C总线的所有器件,SCL相连,SDA相连。
I2C上的任一设备都可做主机(绝大多数情况下是单片机做主机)。
I2C总线是开漏引脚并联的结构其外部有上拉电阻,此时,线与线之间有着‘与’的逻辑关系。也就是说所有接入器件保持高电平,总线才会是高电平。一旦有设备输出低电平,总线就会变成低电平。这也是为什么任一设备都可为主机,因为任一设备都可输出低电平。
开漏引脚图:

总线上的每一个器件都有唯一属于自己的地址。信息传输中,识别地址可分辨出属于自己的信息。
I2C通信原则:高位在前,低位在后。
I2C中有起始信号、数据传输和停止信号。
I2C时序流程图:

I2C数据传输可一次传输任意数量的字节。每个字节末会跟着一位数据,该数据位叫应答位,通常用ACK表示,类似于UART的停止位。
起始信号:SCL为高电平期间,SDA由高电平向低电平转变,产生的下坡沿(上图中的start部分)。
数据传输:只有当SCL为低电平时,SDA可变化。当SCL为高电平时,SDA不可变化,因为此时接收方要读取当前SDA的电平信号,以此来保证SDA的稳定。
停止信号:SCL为高电平期间,SDA由低电平向高电平变化,产生的上升沿(上图中的Stop部分)。
I2C寻址模式
经历起始信号(Start)后,主机要发送一个从机的地址,地址一共7位,第8位是数据方向位(R/W),‘0’表示接下来要发送数据(写),‘1’表示接下来是请求数据(读)。发送完这8位后,若发送的这个地址存在,主机应收到为’0’的ACK回应(即拉低SDA)。若地址不存在,主机应收到为’1’的ACK回应(即SDA保持高电平)。
下面有一段关于I2C寻址的演示代码
#include #include #define I2CDelay(){_nop();_nop();_nop();_nop();} //_nop()函数包含在intrins.h文件中,可进行精准延时,一个_nop()就是一个机器周期。 sbit I2C_SCL = P0^0; sbit I2C_SDA = P0^1; sbit LED = P1^0; bit I2CAddressing(unsigned char addr);//I2C寻址函数,即检查地址位addr的器件是否存在,返回值为从器件应答值 void main() { bit ack; ack = I2CAddressing(0X50); //判断0X50地址是否存在 if(ack == 1) //存在 LED = 0; //LED灯亮起 while(1); } //产生总线起始信号 void I2CStart() { I2C_SDA = 1; //首先确保SDA,SCL都是高电平 I2C_SCL = 1; I2CDelay(); I2C_SDA = 0; //先拉低SDA I2CDelay(); I2C_SCL = 0; //再拉低SCL } //产生总线停止信号 void I2CStop() { I2C_SCL = 0; //首先确保SDA,SCL都是低电平 I2C_SDA = 0; I2CDelay(); I2C_SCL = 1; //先拉高SCL I2CDelay(); I2C_SCA = 1; //再拉高SDA I2CDelay(); } bit I2CWrite(unsigned char dat) { bit ack; //用于暂存应答位的值 unsigned char mask; //用于探测字节内某一位值的掩码变量 for (mask = 0X80; mask!=0; mask>>=1) //从高位到低位依次进行 { if((mask&dat) == 0) //该位的值输出到SDA上 I2C_SDA = 0; else I2C_SDA = 1; I2CDelay(); I2C_SCL = 1; //拉高SCL I2CDelay(); I2C_SCL = 0; //再拉低SCL,完成一个位周期 } I2C_SDA = 1; //8位数据发送完后,主机释放SDA,以检测从机应答 I2CDelay(); I2C_SCL = 1; //拉高SCL ack = I2C_SDA; //读取此时的SDA值即从机应答值 I2CDelay(); I2C_SCL = 0; //再拉低SCL完成应答位,并保持住总线 return ack; //返回从机应答位 } bit I2CAddressing(unsigned char addr) { bit ack; I2CStart(); //产生起始位,即启动一次总线操作 ack = I2CWrite(addr<<1); //器件地址需左移一位,因为寻址命令的最低位为读写为,用于表示之后的操作是读是写 I2CStop(); //不需进行后续读写,直接停止本次总线操作 return ack; }
上一篇:#51单片机#SPI时序初步认识
下一篇:#51单片机#PWM
史海拾趣
|
本帖最后由 paulhyde 于 2014-9-15 09:07 编辑 专为今年9月全国电子电路设计大赛,为大家能够更充足的备战本次大赛,也为解决有些朋友因找不到资料而痛苦的情况。 所以希望大家 : 都晒晒自己的作品,分享出自己整理 ...… 查看全部问答> |
|
我写了一个窗体(默认启动)上面有一个进度条,想实现这样的效果,当窗体完全显示出来后,再执行后台的程序update.目前我把update写在了窗体的load事件里,每次都是把update执行完了,才会显示出窗体,要怎么实现呢?高手帮忙了.… 查看全部问答> |
|
如题,全屏是指系统的任务栏也被程序覆盖掉,m_pMainWnd->ShowWindow(SW_SHOWMAXIMIZED);不能覆盖任务栏,不算全屏。… 查看全部问答> |
|
Embedded Systems Design: Steve Heath 《Embedded Systems Design》: Steve Heath 请问各位这本书有中文版的吗? Paperback: 430 pages Publisher: Newnes; 2 edition (June 15, 2002) Language: English ISBN-10: 0750655461 ISBN-13: 978-0750655460 … 查看全部问答> |
|
有IC或POS开发经验,或无经验但喜欢钻研,善于沟通,做事认真。熟悉C语言,会VS更好,熟悉串口编程、TCP通信编程、ActiveX,DLL编程。 有意者请将您在eeworld的注册号或发表的帖子,您的应对简历发至ordercjl@163.com… 查看全部问答> |
|
本帖最后由 dontium 于 2015-1-23 13:28 编辑 我使用cap测量脉冲的频率。从10hz到50k,使用一个计数器的话会溢出,有什么方法自动换挡或者知道溢出了多少次呢, … 查看全部问答> |
|
这个例程演示了使用以太网控制器和lwIP TCP/IP 协议栈的基于web的I/O控制。DHCP被用来获取一个以太网地址。如果DHCP获取超时,AutoIP将会被选择来获取一个静态的IP地址。IP地址将被显示在OLED屏幕上,通过该地址使用普通的浏览器进入到此例程 ...… 查看全部问答> |
|
还以为MSP430中Flash最小的是1KBytes呢,哎 ~~~~ 好想得满分啊,不知道铁电的板子有木有希望呢,求赐啊~~~~~~~~~~~~… 查看全部问答> |




