1. 数据位的有效性规定

I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化



2. 起始和终止信号

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



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

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

3. 数据传送格式

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



主机向从机发送数据:

有阴影部分表示数据由主机向从机传送,无阴影部分则表示数据由从机向主机传送

A表示应答, Â非表示非应答。S表示起始信号,P表示终止信号



主机在第一个字节后,立即从从机读数据:



改变传送方向:

在传送过程中,当需要改变传送方向时,起始信号和从机地址都被重复产生一次



4. 总线的寻址



D7~D1位组成从机的地址。D0位是数据传送方向位,为“0”时表示主机向从机写数据,为“1”时表示主机由从机读数据

主机发送地址时,总线上的每个从机都将这7位地址码与自己的地址进行比较,如果相同,则认为自己正被主机寻址,根据R/T位将自己确定为发送器或接收器

一个从机的7位寻址位有4位是固定位,3位是可编程位,这时仅能寻址8个同样的器件,即可以有8个同样的器件接入到该I2C总线系统中

5. 信号模拟



起始信号:

void I2CStart(void)
{
SDA = 1;
SomeNop();
SCL = 1;
SomeNop();
SDA = 0;
SomeNop();
}

终止信号:

void I2CStop(void)
{
SDA = 0;
SomeNop();
SCL = 1;
SomeNop();
SDA = 1;
SomeNop();
}

6. 串行E2PROM

写入过程:



读出过程:



7. 引脚说明



A0、A1、A2均为0







所以从机地址的7位数据为:0xa0

8. 总线时序



9. 举例

单片机小精灵:

http://download.csdn.net/download/zhangxuechao_/9894028

void delay10us(void)   //误差 0us
{
unsigned char a,b;
for(b=1;b>0;b--)
for(a=2;a>0;a--);
} //IIC起始
void i2cStart()
{
SDA = 1;
delay10us();
SCL = 1;
delay10us();
SDA = 0;
delay10us();
SCL = 0;
delay10us(); return;
} //IIC停止
void i2cStop()
{
SDA = 0;
delay10us();
SCL = 1;
delay10us();
SDA = 1;
delay10us(); return;
} //IIC发送
u8 i2cSend(u8 d)
{
u8 i = 0, j = 0;
for(i = 0; i < 8; i++)
{
SDA = d >> 7;
d = d << 1;
delay10us();
SCL = 1;
delay10us();
SCL = 0;
} SDA = 1;
delay10us();
SCL = 1; while(SDA)
{
if(j++ > 200)
{
SCL = 0;
delay10us();
return 0;
}
} SCL = 0;
delay10us(); return 1;
} //IIC接收
u8 i2cRecv()
{
u8 i = 0, d = 0;
for(i = 0; i < 8; i++)
{
SCL = 1;
delay10us();
d <<= 1;
d |= SDA;
delay10us();
SCL = 0;
delay10us();
} return d;
} //E2PROM写
void at24c02Write(u8 addr, u8 d)
{
i2cStart();
i2cSend(0xa0);
i2cSend(addr);
i2cSend(d);
i2cStop();
} //E2PROM读
u8 at24c02Read(u8 addr)
{
u8 d = 0; i2cStart();
i2cSend(0xa0);
i2cSend(addr);
i2cStart();
i2cSend(0xa1);
d = i2cRecv();
i2cStop(); return d;
}

最新文章

  1. 读书笔记--SQL必知必会15--插入数据
  2. 转载list
  3. JavaScript 基础第四天
  4. PostgreSQL基础整理(三)
  5. JavaScript(五)——插入地图
  6. 图像特征提取:Sobel边缘检测
  7. PHP和AJAX笔记汇总
  8. Ext.Net学习笔记10:Ext.Net ComboBox用法
  9. Python的协程
  10. JODA-TIME获取本月的第一天及最后一天
  11. ES6项目构建(babel+gulp+webpack)
  12. 2018acm-icpc宁夏邀请赛后记
  13. keepalived主备节点都配置vip,vip切换异常案例分析
  14. VB6 选择文件夹路径
  15. eclipse zg项目学习
  16. 安装部署 OpenPAI Install OpenPAI on Ubuntu
  17. mysql 命令行查看数据库、创建数据库、选择数据库、删除数据库
  18. iOS开发-通过正则表达式进行各种判断银行卡,车牌号,邮箱地址,QQ,身份证,全字母,仅输入字母或数字同时包含大小写字母和数字,仅能输入中文等
  19. in操作符
  20. (转)USB协议简介

热门文章

  1. vue+七牛云 截图工具
  2. 21 Flutter仿京东商城项目 商品详情 请求接口渲染数据 商品属性数据渲染
  3. Python描述性统计numpy
  4. Cloudera Manager 概念
  5. ubuntu下virtualbox的安装、卸载
  6. js时间戳转为日期函数
  7. 【leetcode_easy】551. Student Attendance Record I
  8. golang web框架设计2:自定义路由
  9. Linux中移动,复制,删除,打包排除某个目录或文件
  10. Rocketmq-简单部署