OELD I2C通讯

I2C总线时序,只写,有应答(oled)

I2C通讯接口由从机地址位SA0,I2C总线数据信号(SDAout/D2输出和SDAin/D1输入)和I2C总线时钟信号SCL(D0)组成。数据和时钟信号线都必须接上上拉电阻。RES#用来初始化设备。
a.从机地址位(SA0
SSD1306在发送或接受任何信息之前必须识别从机地址。设备将会响应从机地址,后面跟着从机地址位(SA0位)和读写选择位(R/W#位),格式如下:
b7 b6 b5 b4 b3 b2 b1 b0
0 1 1 1 1 0 SA0 R/W#
SA0位为从机地址提供了一个位的拓展。 0111100或0111101都可以做为SSD1306的从机地址。D/C#引脚用作SA0用于从机地址选择。
R/W#位用来决定I2C总线接口的操作模式。R/W# = 1,读模式。R/W# = 0 写模式
b.I2C总线数据信号SDA
SDA作为发送者和接受者之间的通讯通道。数据和应答都是通过SDA发送。
应该注意的是ITO轨道电阻和SDA引脚上的上拉电阻会变成一个潜在的电压分压器。结果就是SDA上的应答可能不能达到有效的逻辑0。
SDAin和SDAout绑定到了一起作为SDA。SDAin引脚必须连接到SDA。SDAout引脚可以不连接。当SDAout引脚不连接,应答信号将会被I2C总线忽略。
c.I2C总线时钟信号SCL
I2C总线上的信息传输任务追随一个时钟信号,SCL。每个数据位的传输任务发生在SCL的单个的时钟周期中。
I2C总线接口提供了写数据和命令到设备的接口。关于I2C总线的写模式的时序请参考下图:**
在这里插入图片描述
写模式
1.主机设备通过开始条件初始化数据通讯。开始条件的定义在下面的图中展示。开始条件是在SCL保持高的状态下将SDA从高拉低。
2.从机地址紧跟着开始条件。对于SSD1306,从机地址可以通过改变SA0到LOW或HIGH(D/C引脚作为SA0)设成“b0111100”或“b0111101”。
3.写模式的建立是通过设置R/W#位为逻辑0实现的。
4.应答位信号在接收到一个字节的数据后生成,包括从机地址和R/W#位组成的一个字节数据。可以参考下面的应答位信号的图示。应答位的定义是在应答位相关的时钟脉冲的高周期中把SDA线拉低。
5.传输完从机地址之后,控制字节或数据字节开始通过SDA传输。一个控制字节主要由Co和D/C#位后面再加上六个0组成的。
a)如果Co为设为逻辑0,后面传输的信息就只包含数据字节。
b)D/C为决定了下个数据字节是作为命令还是数据。如果D/C#位设为0,下一个数据就是命令。如果D/C#位设为1,下一个数据就是数据,并会被存放在GDDRAM中。GDDRAM列地址(16位最高位无效)指针将会在每次数据写入之后自动加1.
6.应答位将会在接收到每个控制字节或数据字节之后生成。
7.写模式会在用了停止条件之后结束。停止条件:将SDA从低拉高,而SCL保持高。

在这里插入图片描述

#include "reg52.h"
#include "intrins.h"
#define high 1
#define low 0 
#defing I2Cdelay() {_nop_();_nop_();_nop_();_nop_();}
/*************Pin Define***************/

sbit SCL=P1^0;
sbit SDA=P1^1;
/****************************************************/
void IIC_Start();
void IIC_Stop();
void Write_IIC_Command(unsigned char IIC_Command);
void Write_IIC_Data(unsigned char IIC_Data);
bit Write_IIC_Byte(unsigned char IIC_Byte);


/**********************************************
//IIC Start
**********************************************/
void IIC_Start()
{
   SDA = high;
   SCL = high;		
   I2Cdelay();
   SDA = low;
   I2Cdelay();
   SCL = low;

}

/**********************************************
//IIC Stop
**********************************************/
void IIC_Stop()
{
   SCL = low;
   SDA = low;  //首先确保SDA,SCL都是低电平
   I2Cdelay();
   SCL = high;  //先拉高SCL
   I2Cdelay();
   SDA = high;  //在拉高SDA
}
/**********************************************
// IIC Write byte  发送数据两种方法
第一种:
**********************************************/
bit Write_IIC_Byte(unsigned char IIC_Byte)
{
	unsigned char i;
	bit Ack_Bit;                    //应答信号
	for(i=0;i<8;i++)		
	{
		if(IIC_Byte & 0x80)		//1?0?
		SDA=high;
		else
		SDA=low;
		//Delay_us(1);
		SCL=high;
		I2Cdelay();
		SCL=low;
		//Delay_us(1);
		IIC_Byte<<=1;			//loop
	}
	 SDA = high;		                //释放IIC SDA总线为主器件接收从器件产生应答信号	
	I2Cdelay();
	SCL = high;                     //第9个时钟周期
	I2Cdelay();
	Ack_Bit = SDA;		            //读取应答信号
	SCL = low;
	return Ack_Bit;	
}  
/**********************************************
// IIC Write byte  发送数据两种方法
第二种:

bit Write_IIC_Byte(unsigned char IIC_Byte)
{
	unsigned char i;
	bit Ack_Bit;                    //应答信号
	for(i=0&0x80;i!=0;i>>=1)		//从高位到低位依次进行
	{	
	    if((i&dat)==0)             //将该位值输出到SDA上
	       SDA=low;
		else
		SDA=high;
		I2Cdelay();
		SCL=high;              //拉高SCL
		I2Cdelay();
		SCL=low;              //拉低SLC,完成一个位周期
	}	
		
	 SDA = high;		  //释放IIC SDA总线为主器件接收从器件产生应答信号	
	 I2Cdelay();
	 SCL = high;                     //第9个时钟周期
	 I2Cdelay();
	 Ack_Bit = SDA;		            //读取应答信号
	 SCL = low;              //拉低时钟,完成应答,并保持住总线
	 return Ack_Bit;	  //返回从机应答值
}  
**********************************************/
/**********************************************
// IIC Write Command
**********************************************/
void Write_IIC_Command(unsigned char IIC_Command)
{
   IIC_Start();
   Write_IIC_Byte(0x78);            //Slave address,SA0=0
   Write_IIC_Byte(0x00);			//write command
   Write_IIC_Byte(IIC_Command); 
   IIC_Stop();
}
/**********************************************
// IIC Write Data
**********************************************/
void Write_IIC_Data(unsigned char IIC_Data)
{
   IIC_Start();
   Write_IIC_Byte(0x78);			
   Write_IIC_Byte(0x40);			//write data
   Write_IIC_Byte(IIC_Data)IIC_Stop(); 
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值