51单片机——I2C总线
2016-03-16 09:03
337 查看
单片机——I2C
宗旨:技术的学习是有限的,分享的精神是无限的。
UART 属于异步通信,比如电脑发送给单片机,电脑只负责把数据通过TXD 发送出来即可,接收数据是单片机自己的事情。而 I2C 属于同步通信, SCL 时钟线负责收发双方的时钟节拍, SDA 数据线负责传输数据。 I2C 的发送方和接收方都以 SCL 这个时钟节拍为基准进行数据的发送和接收。
I2C总线包括SCL,SDA 两根信号线,其中SCL是时钟线,SDA是数据线。
1、起始信号
UART 通信是从一直持续的高电平出现一个低电平标志起始位;而 I2C 通信的起始信号的定义是 SCL 为高电平期间, SDA 由高电平向低电平变化产生一个下降沿,表示起始信号。
2、数据传输
UART 是低位在前,高位在后;而 I2C 通信是高位在前,低位在后。UART 通信数据位是固定长度,波特率分之一,一位一位固定时间发送完毕就可以了。而 I2C 没有固定波特率,但是有时序的要求,要求当 SCL 在低电平的时候, SDA 允许变化。
3、停止信号
UART 通信的停止位是一位固定的高电平信号; 而 I2C 通信停止信号的定义是 SCL 为高电平期间, SDA 由低电平向高电平变化产生一个上升沿,表示结束信号。
4、写完从器件之后等待从器件的应答
在主器件完成对从器件的写操作时候(每次会有一个字节的数据),主器件会等待从器件发送指示信号,这个指示信号是说从器件已经接受到了主器件的数据,这是由从器件的硬件来完成的,不需要主器件来软件操作,只需要等待;
5、主器件读完数据后向从器件发送应答信号
这其实包括两种情况,一种是主器件读完后还要继续读就要发送一个继续读的信号(其实就是发送0),另一种就是不再继续读了,就要发送停止读信号(其实就是发送1)。
6、I2C寻址模式
I2C 通信的起始信号(Start)后,首先要发送一个从机的地址,这个地址一共有 7位,紧跟着的第 8 位是数据方向位(R/W),“ 0”表示接下来要发送数据(写),‘“ 1”表示接下来是请求数据(读)。第九位 ACK应答。
宗旨:技术的学习是有限的,分享的精神是无限的。
UART 属于异步通信,比如电脑发送给单片机,电脑只负责把数据通过TXD 发送出来即可,接收数据是单片机自己的事情。而 I2C 属于同步通信, SCL 时钟线负责收发双方的时钟节拍, SDA 数据线负责传输数据。 I2C 的发送方和接收方都以 SCL 这个时钟节拍为基准进行数据的发送和接收。
I2C总线包括SCL,SDA 两根信号线,其中SCL是时钟线,SDA是数据线。
1、起始信号
UART 通信是从一直持续的高电平出现一个低电平标志起始位;而 I2C 通信的起始信号的定义是 SCL 为高电平期间, SDA 由高电平向低电平变化产生一个下降沿,表示起始信号。
2、数据传输
UART 是低位在前,高位在后;而 I2C 通信是高位在前,低位在后。UART 通信数据位是固定长度,波特率分之一,一位一位固定时间发送完毕就可以了。而 I2C 没有固定波特率,但是有时序的要求,要求当 SCL 在低电平的时候, SDA 允许变化。
3、停止信号
UART 通信的停止位是一位固定的高电平信号; 而 I2C 通信停止信号的定义是 SCL 为高电平期间, SDA 由低电平向高电平变化产生一个上升沿,表示结束信号。
4、写完从器件之后等待从器件的应答
在主器件完成对从器件的写操作时候(每次会有一个字节的数据),主器件会等待从器件发送指示信号,这个指示信号是说从器件已经接受到了主器件的数据,这是由从器件的硬件来完成的,不需要主器件来软件操作,只需要等待;
5、主器件读完数据后向从器件发送应答信号
这其实包括两种情况,一种是主器件读完后还要继续读就要发送一个继续读的信号(其实就是发送0),另一种就是不再继续读了,就要发送停止读信号(其实就是发送1)。
6、I2C寻址模式
I2C 通信的起始信号(Start)后,首先要发送一个从机的地址,这个地址一共有 7位,紧跟着的第 8 位是数据方向位(R/W),“ 0”表示接下来要发送数据(写),‘“ 1”表示接下来是请求数据(读)。第九位 ACK应答。
#include<reg52.h> #include<intrins.h> #define I2CDelay() {_nop_();_nop_();_nop_();_nop_();} sbit I2C_SCL = P3 ^ 7; sbit I2C_SDA = P3 ^ 6; /* 产生总线起始信号 */ 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_SDA = 1; //再拉高SDA I2CDelay(); } /* I2C总线写操作,dat-待写入字节,返回值-从机应答位的值 */ 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); //应答值取反以符合通常的逻辑: //0=不存在或忙或写入失败,1=存在且空闲或写入成功 } /* I2C总线读操作,并发送非应答信号,返回值-读到的字节 */ unsigned char I2CReadNAK() { unsigned char mask; unsigned char dat; I2C_SDA = 1; //首先确保主机释放SDA for (mask = 0x80; mask != 0; mask >>= 1) //从高位到低位依次进行 { I2CDelay(); I2C_SCL = 1; //拉高SCL if(I2C_SDA == 0) //读取SDA的值 { dat &= ~mask; //为0时,dat中对应位清零 } else { dat |= mask; //为1时,dat中对应位置1 } I2CDelay(); I2C_SCL = 0; //再拉低SCL,以使从机发送出下一位 } I2C_SDA = 1; //8位数据发送完后,拉高SDA,发送非应答信号 I2CDelay(); I2C_SCL = 1; //拉高SCL I2CDelay(); I2C_SCL = 0; //再拉低SCL完成非应答位,并保持住总线 return dat; } /* I2C总线读操作,并发送应答信号,返回值-读到的字节 */ unsigned char I2CReadACK() { unsigned char mask; unsigned char dat; I2C_SDA = 1; //首先确保主机释放SDA for (mask = 0x80; mask != 0; mask >>= 1) //从高位到低位依次进行 { I2CDelay(); I2C_SCL = 1; //拉高SCL if(I2C_SDA == 0) //读取SDA的值 { dat &= ~mask; //为0时,dat中对应位清零 } else { dat |= mask; //为1时,dat中对应位置1 } I2CDelay(); I2C_SCL = 0; //再拉低SCL,以使从机发送出下一位 } I2C_SDA = 0; //8位数据发送完后,拉低SDA,发送应答信号 I2CDelay(); I2C_SCL = 1; //拉高SCL I2CDelay(); I2C_SCL = 0; //再拉低SCL完成应答位,并保持住总线 return dat; }
相关文章推荐
- 如何组织构建多文件 C 语言程序(二)
- 如何写好 C main 函数
- C#实现子窗体与父窗体通信方法实例总结
- ruby实现的一个异步文件下载HttpServer实例
- C#异步绑定数据实现方法
- Lua和C语言的交互详解
- 科学知识:同步、异步、阻塞和非阻塞区别
- 探讨Ajax中同步与异步之间的区别
- C#中异步回调函数用法实例
- 关于C语言中参数的传值问题
- 简要对比C语言中三个用于退出进程的函数
- 深入C++中API的问题详解
- 基于C语言string函数的详解
- C语言中fchdir()函数和rewinddir()函数的使用详解
- C语言内存对齐实例详解
- java和c#使用hessian通信的方法
- C语言编程中统计输入的行数以及单词个数的方法
- C语言自动生成enum值和名字映射代码
- 使用C语言判断英文字符大小写的方法
- c语言实现的带通配符匹配算法