第七章:IIC时序

推荐连接

https://blog.csdn.net/gogomusic/article/details/79344139

I2C(IIC,Inter-Integrated Circuit),数据线SDA(data)和时钟SCL(clock)构成的串行总线,双向传送。高速IIC总线一般可达400kbps以上,IIC是半双工通信方式。

第七章:IIC时序_第1张图片

第七章:IIC时序_第2张图片

第七章:IIC时序_第3张图片

例子是:24C02

/*********************************************************************
* 函 数 名       : I2cStart
* 函数功能		 : I2C时序中发送起始信号
* 参数列表       : 无
* 函数输出    	 : 无
*********************************************************************/
static void I2cStart(void)
{
	SDA = 1;
	delay5us();		   	// 查24C02时序图可知,各种时序中在1.8、2.5V供电
						// 时最小应为4.7us,而在4.5-5.5V时最小为1.2us
	SCL = 1;			// 本开发板为5V供电,但考虑到代码的通用性,因此
	delay5us();			// 将所有的时序延时统一定为5us。这样虽然牺牲了
						// 少许性能(读写时间),但代码写起来更简单,更
	SDA = 0;			// 健壮可移植。
	delay5us();			

	SCL = 0;			
	delay5us();		
}
/*********************************************************************
* 函 数 名       : I2cStop
* 函数功能		 : I2C时序中发送结束信号
* 参数列表       : 无
* 函数输出    	 : 无
*********************************************************************/
static void I2cStop(void)
{
	SDA = 0;
	delay5us();

	SCL = 1;
	delay5us();

	SDA = 1;
	delay5us();	
}
/*********************************************************************
* 函 数 名       : I2cSendByte
* 函数功能		 : I2C发送1字节数据的底层时序
* 参数列表       : dat - 待发送的1字节数据
* 函数输出    	 : 无
*********************************************************************/
static void I2cSendByte(u8 dat)
{
	u8 i = 0;	//最大255,一个机器周期为1us,最大延时255us。
	// 为了保证时序正确,这里应该加一句 SCL = 0;
			
	for(i=0; i<8; i++)//要发送8位,从最高位开始
	{
		SDA = dat >> 7;	 //起始信号之后I2C_SCL=0,所以可以直接改变I2C_SDA信号
		dat = dat << 1;
		delay5us();
		SCL = 1;
		delay5us();//建立时间>4.7us
		SCL = 0;
		delay5us();//时间大于4us		
	}
	SDA = 1;			// 主设备释放SDA线给从设备去操作
	delay5us();

	SCL = 1;			// 主设备开始了第9个周期
	delay5us();

	SCL = 0;
	delay5us();		
}
/*********************************************************************
* 函 数 名       : I2cReadByte
* 函数功能		 : 按照I2C时序从总线上读取1字节数据
* 参数列表       : 无
* 函数输出    	 : 返回读取的1字节数据
*********************************************************************/
static u8 I2cReadByte(void)
{
	u8 i = 0, dat = 0;

	SDA = 1;			//起始和发送一个字节之后I2C_SCL都是0
	delay5us();

	// 按道理这里应该有一个SCL = 0的
	for (i=0; i<8; i++)//接收8个字节
	{
		SCL = 1;		// 通知从设备我要开始读了,可以放1bit数据到SDA了
		delay5us();

		dat <<= 1;			// 读取的时候是高位在前的
		dat |= SDA;
		delay5us();

		SCL = 0;		// 拉低,为下一个bit的周期做准备
		delay5us();
	}

	return dat;		
}

例子:OLCD12864

第七章:IIC时序_第4张图片

// OLED的I2C接口定义
sbit OLED_SCL = P2^1;		//时钟SCL
sbit OLED_SDIN = P2^0;		//数据SDA

#define OLED_CS_Clr()  		OLED_CS=0
#define OLED_CS_Set()  		OLED_CS=1

#define OLED_RST_Clr() 		OLED_RST=0
#define OLED_RST_Set() 		OLED_RST=1

#define OLED_DC_Clr() 		OLED_DC=0
#define OLED_DC_Set() 		OLED_DC=1

#define OLED_SCLK_Clr() 	OLED_SCL=0
#define OLED_SCLK_Set() 	OLED_SCL=1

#define OLED_SDIN_Clr() 	OLED_SDIN=0
#define OLED_SDIN_Set() 	OLED_SDIN=1


/**********************************************
//IIC Start
**********************************************/
void IIC_Start()
{
	OLED_SCLK_Set();
	OLED_SDIN_Set();
	OLED_SDIN_Clr();
	OLED_SCLK_Clr();
}

/**********************************************
//IIC Stop
**********************************************/
void IIC_Stop()
{
	OLED_SCLK_Set();
//	OLED_SCLK_Clr();
	OLED_SDIN_Clr();
	OLED_SDIN_Set();
	
}
/**********************************************
// IIC Write byte
**********************************************/

void Write_IIC_Byte(unsigned char IIC_Byte)
{
	unsigned char i;
	unsigned char m,da;
	da=IIC_Byte;
	OLED_SCLK_Clr();
	for(i=0;i<8;i++)		
	{
		m=da;
		//	OLED_SCLK_Clr();
		m=m&0x80;
		if(m==0x80)
		{OLED_SDIN_Set();}
		else OLED_SDIN_Clr();
			da=da<<1;
		OLED_SCLK_Set();
		OLED_SCLK_Clr();
		}
}

 

你可能感兴趣的:(第七章:IIC时序)