找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1997|回复: 1
打印 上一主题 下一主题
收起左侧

IIC通信协议笔记

[复制链接]
跳转到指定楼层
楼主
ID:204624 发表于 2018-5-17 16:04 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
1.IIC总线是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据。它在传输数据过程中有三种特殊类型信号,分别是:开始信号、结束信号和应答信号。
区分UART通信:同样使用两根线进行数据传输,但UART通信中一根用于接收数据,一根用于发送数据,每次通信的时候只用到一根线。且其传输数据与时钟无关,因此称为异步串行通信,随时进行数据的接收和发送,SBUF寄存器存满时,则说明完成数据接收;想要进行数据发送时,只需把数据写入SBUF寄存器。
IIC通信:IIC通信无论发送还是接收,都需要结合时钟SCL来进行数据SDA的传输,因此一次要使用两条线。传输数据与时钟有关,因此称为同步串行通信。
2.IIC通信的起始信号和停止信号
时钟线SCL为高电平期间,数据线SDA由高电平向低电平变化——起始信号
时钟线SCL为高电平期间,数据线SDA由低电平向高电平变化——停止信号
3.IIC通信的数据传输
时钟线SCL为高电平期间,数据线SDA上的数据必须保持稳定。
只有时钟线SCL信号为低电平期间,数据线SDA状态才允许变化。 4.数据线SDA上的数据一般先于时钟SCL发生变化
原因:发生变化说明信号需要翻转,分两种情况(数据线SDA随你怎么翻)。情况1-1:当数据线SDA先发生变化,时钟线SCL再从1变为0,与上述第3点相违背,在时钟SCL为高电平时,数据线SDA并没有保持稳定,而发生翻转,这样的信号只会被当做是起始信号或停止信号;
情况1-2:数据线SDA还是先发生变化,时钟线SCL从0变1,在时钟线SCL为0时,数据线SDA早已经完成了翻转,也就是说,在时钟线SCL为0时,数据线没有发生变化,那么在后来时钟线SCL为1时,所传输的数据则是数据线SDA上刚完成翻转后的数据。情况2-1:时钟线SCL由0变1,先于数据线SDA发生变化,时钟线SCL低电平时的状态内,数据线SDA没有发生任何变化,所以只在最后维持高电平有效,而在高电平后,再改变数据线SDA的数据,违反了上述第3点;
情况2-2:时钟线SCL由1变0,先于数据线SDA发生变化,在变0之后,数据线SDA会完成信号的翻转。在之后得等时钟线SCL重新置1,才能确认数据线SDA的传输数据----那如果这样的话,不就又变成了数据线SDA先变化,时钟线SCL后变化的情况了??
综上所述,去除掉违反IIC数据传输的规则的两则情况后,剩下的红色两种情况,则是现在第4点的最好说明...
5.IIC的数据读写和应答
区分UART数据传输:UART数据传输先传低位,后传高位
IIC数据传输:先传高位,后传低位
主机写数据时,每发送一个字节,接收机需要回复一个应答位“0”,通过应答位来判断从机是否接收成功
主机读数据时,接收一个字节结束后,主机也需要发一个应答位“0”,但是当接收最后一个字节结束后,需要发送一个非应答位“1”,发完这个非应答位“1”后,再发一个停止信号,最终结束通信。
如果需要检测应答信号“0”,得先置高数据线SDA,如果数据线后来检测到应答信号“0”,则是应答信号存在的最好说明!
如果需要检测非应答信号“1”,得先拉低数据线SDA,如果数据线后来检测到非应答信号“1”,也是非应答信号存在的最好说明!
6.IIC协议传输一位数据程序分析
void Delay(void) //在使用IIC进行通信的时候,需要控制传输数据的速度,这里的使用了4个机器周期的延时,而具体的延时由于包括了函
{ //数调用时的压栈和出栈,而且受编译环境的影响,因此实际延时并不止4个机器周期
_nop_() ;_nop_() ;_nop_() ;_nop_() ;
}
void IIC_Send_Byte(unsigned char byte) //有数据传入,类型为八位无符号字节型——传入数据 / 命令 / 地址
{
unsigned char mask, i; //定义两个八位无符号字节型变量,一个用以for循环,另一个用以把传入的十六进制数,以二进制方式提取各个位
mask = 0x80;//再结合时钟线SCL时序变化,控制数据线SDA进行信号传输
for(i = 0; i < 8; i++)
{
SCL = 0; //先把时钟线SCL置“0”,为了使数据线SDA数据能变化
Delay(); //数据传输的延时
if((mask & byte) == 0) //用mask十六进制数(以二进制的方式)与传入的数据byte取“与”,把传入的十六进制byte以二进制的方式提取位
{
SDA = 0;//如果该位取“与”为0,则控制数据线SDA数据变为0
}
else
{
SDA = 1; //否则如果该位取“与”为1,则控制数据线SDA数据变为1
}
mask >>= 1; //mask变量右移一位,假如第一次mask值为1000 0000,完成数据线SDA的一次输出后,mask的值为0100 0000,方便
Delay(); //继续提取第二位数据,数据传输的延时
SCL= 1; //在时钟线SCL为1的时候维持数据SDA的稳定,便能确认传入的数据
Delay(); //数据传输的延时
}
SCL = 0; //先置低时钟线SCL,才能拉高数据线SDA,用以检测后面的应答信号
SDA= 1;
Delay();
SCL= 1; //下面对时钟线SCL的操纵则是用以检测应答信号的
Delay();
SCL= 0;
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:242300 发表于 2018-10-5 23:58 | 只看该作者
学习学习。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表