I2C总线

简介

I2C(Inter-Integrated Circuit)总线是一种由PHILIPS公司开发的两线式串行总线,用于连接微控制器及其外围设备(特别是外部存储器件)。

与UART的区别

u异步通信:只负责发送
i同步通信:SCL时钟负责收发双方的时钟节拍,SDA数据线负责传输数据

u:多用于板间通信
i:板内通信

I2C通信时序

在这里插入图片描述
分为起始信号、数据传输部分和停止信号
(1)起始信号
SCL为高电平期间,SDA由高变低
(2)数据传输
UART:低位在前,高位在后。由固定的波特率
I2C:高位在前,低位在后。无波特率要求,但是要符合时序图

要求:SCL低电平,允许改变SDA。SCL为高电平的时候,SDA不可以变化
数据位最后一位为ACK,应答位。
数据传输部位对字节数没有限制,但是每一位字节后面需要跟一位应答位
(3)停止信号
UART:固定高电平信号
I2C:SCL为高电平期间,SDA由低变高

寻址模式

发送完起始信号后,发送从机地址,地址有7位,第8位为数据方向位(R/W)
1为读,0为写
如果发送地址存在,该地址器件会回应一个ACK,(拉低电平输出0),否则,SDA保持高电平回应1。

//I2C.c文件
#include <reg52.h>
#include <intrins.h>
#define I2CDelay(){_nop_();_nop_();_nop_();_nop_();} //一个_nop_()为一个机器周期
sbit I2C_SCL=P3^7;
sbit I2C_SDA=P3^6;
void I2CStart()//产生起始信号
{
	I2C_SDA=1;
	I2C_SCL=1;
	I2CDelay();
	I2C_SDA=0;
	I2CDelay();
	I2C_SCL=0;
}
void I2CStop() //产生结束信号
{
	I2C_SCL=0;
	I2C_SDA=0;
	I2CDelay();
	I2C_SCL=1;
	I2CDelay();
	I2C_SDA=1;
	I2CDelay();
}
bit I2CWrite(unsigned char dat)	//写操作,返回值为从机应答位值
{
	bit ack;
	unsigned char mask;
	for(mask=0x80;mask!=0;mask>>=1)	//从高位到低位发送数据位
	{
		if((mask&dat)==0)
			I2C_SDA=0;
		else
			I2C_SDA=1;
		I2CDelay();
		I2C_SCL=1;
		I2CDelay();
		I2C_SCL=0;
	}
	I2C_SDA=1; //发送完数据位将这个电平拉高,检测应答位
	I2CDelay();
	I2C_SCL=1;
	ack=I2C_SDA;
	I2CDelay();
	I2C_SCL=0;
	return (~ack);//进行取反以符合正常的逻辑
}
//读操作,并发送非应答信号,返回值为读到的字节
unsigned char I2CReadNAK() //从高位到低位进行读取
{
	unsigned char mask;
	unsigned char dat;
	I2C_SDA=1;
	for(mask=0x80;mask!=0;mask>>=1)
	{
		I2CDelay();
		I2C_SCL=1;//拉高SCL
		if(I2C_SDA==0)//为0对应位为0
			dat&=~mask;
		else
			dat|=mask;//为1对应位为1
		I2CDelay();
		I2C_SCL=0;
	}	
	I2C_SDA=1;
	I2CDelay();
	I2C_SCL=1;
	I2CDelay();
	I2C_SCL=0;
	return dat;
}
unsigned char I2CReadACK()//读操作,并发送应答信号,就可以继续往下读取
{
	unsigned char mask;
	unsigned char dat;
	I2C_SDA=1;
	for(mask=0x80;mask!=0;mask>>=1)
	{
		I2CDelay();
		I2C_SCL=1;//拉高SCL
		if(I2C_SDA==0)//为0对应位为0
			dat&=~mask;
		else
			dat|=mask;//为1对应位为1
		I2CDelay();
		I2C_SCL=0;
	}	
	I2C_SDA=0;
	I2CDelay();
	I2C_SCL=1;
	I2CDelay();
	I2C_SCL=0;
	return dat;
}
//检查地址为ADDR的器件是否存在,返回值为器件应答值
bit I2CAddressing(unsigned char addr)
{
	bit ack;
	I2CStart();
	ack=I2CWrite(addr<<1); //左移一位,最低位需要表示读或写
	I2CStop();
	return ack;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王蒟蒻

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值