(4)数据帧格式
在起始信号后必须传送一个从机的地址(7位),第8位是数据的传送方向位(R/W),用“0”表示主机发送数据(W),“1”表示主机接收数据(R)。数据传输一般由主机产生停止位终止。但是,如果主机仍希望在总线上通讯,它可以产生重复起始条件和寻址另一个从机,而不是首先产生一个停止条件。在这种传输中可能有不同的读/写格式组合。
单片机IO口模拟I2C总线发送与接收数据:
/****************************************************************
函数名称:Send_Byte
函数功能:发送一字节数据
入口参数:dat //要发送的8位数据
出口参数:
备 注:
*****************************************************************/
void Send_Byte(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
if((dat< )&0x80)>
sda=1;
else
sda=0;
_nop_();
scl=1; //置时钟线为高,通知从机开始接收数据位
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
scl=0;
}
_nop_();
_nop_();
sda=1; //8位发送完后释放数据线,准备接收应答位
_nop_();
_nop_();
scl=1;
_nop_();
_nop_();
_nop_();
if(sda==1)
ack=0;
else
ack=1; //判断是否接收到应答信号
scl=0;
_nop_();
_nop_();
}
/****************************************************************
函数名称:Rcv_Byte
函数功能:接收一字节数据
入口参数:无
出口参数:dat //将接收到出来的一字节数据赋给dat变量,并返回dat
备 注:
*****************************************************************/
unsigned char Rcv_Byte()
{
unsigned char dat;
unsigned char i;
sda=1; //置数据线为输入方式
for(i=0;i<8;i++)
{
_nop_();
scl=0; //置时钟线为低,准备接收数据位
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
scl=1; //置时钟线为高使数据线上数据有效
_nop_();
_nop_();
dat<<=1;
if(sda==1) //读数据位,接收的数据位放入dat中
dat++;
_nop_();
_nop_();
}
scl=0;
_nop_();
_nop_();
return(dat);
}
(5)7位总线寻址
I2c总线的寻址过程是通常在起始条件后的第一个字节决定了主机选择哪一个从机。第一个字节的头7位组成了从机地址。最低位(LSB)是第8位,它决定了报文的方向。最低位为0表示主机写数据到被选中从机,1表示主机向从机读数据。
当发送了一个地址后,系统中的每个器件都在起始条件后将头7位与它自己的地址比较。如果一样,器件会认为它被主机寻址,至于是从机-接收器还是从机-发送器由第8位决定。
从机地址由一个固定和一个可编程的部分组成。可编程地址位的数量由它可使用的管脚决定。固定部分通常决定了所连接器件的类型。
用户347025 2012-8-27 11:46