申明,下面的关于真值和假值的定义跟一般软件中的值相反,一般TRUE为1:
#define TRUE 0 //
#define WRONG -1 //
U8 dtv_i2c_read( void ) //带应答的读字节,用于读多个数据时的中间字节
{
U8 bReadData = 0x00; //默认值
U8 RoopCt;
BusWait( _45us );
pvSDA2= OFF; //置SDA为输入
for( RoopCt=0; RoopCt<8; RoopCt++ )
{
IntDisableWithPush;
poSCL2 = OFF;
pvSCL2 = ON;
IntEnableByPop;
BusWait( 4 + CNT_DATA );
pvSCL2 = OFF;
BusWait( 1 + CNT_DATA );
if( poSDA2 == ON )
{
bReadData |= BitOn[RoopCt]; //读的是1就保存相应位,否则以0移位
}
BusWait( 1 + CNT_DATA );
}
IntDisableWithPush;
poSCL2 = OFF;
pvSCL2 = ON;
IntEnableByPop;
BusWait( 4 + CNT_DATA );
IntDisableWithPush;
poSDA2 = OFF;
pvSDA2 = ON; //ack ,读完一个字节数据要发应答信号
IntEnableByPop;
BusWait( 1 + CNT_DATA );
pvSCL2 = OFF;
BusWait( 4 + CNT_DATA );
IntDisableWithPush;
poSCL2 = OFF;
pvSCL2 = ON;
IntEnableByPop;
BusWait( 1 + CNT_DATA );
return bReadData;
}
U8 dtv_i2c_readnc( void ) //不带应答的读数据,用来读取最后一个字节,同时停止I2C通讯
{
U8 bReadData = 0x00;
U8 RoopCt;
BusWait( _45us );
pvSDA2= OFF;
for( RoopCt=0; RoopCt<8; RoopCt++ )
{
IntDisableWithPush;
poSCL2 = OFF;
pvSCL2 = ON;
IntEnableByPop;
BusWait( 4 + CNT_DATA );
pvSCL2 = OFF;
BusWait( 1 + CNT_DATA );
if( poSDA2 == ON )
{
bReadData |= BitOn[RoopCt]; //读取数据位并保存
}
BusWait( 1 + CNT_DATA );
}
IntDisableWithPush;
poSCL2 = OFF;
pvSCL2 = ON;
IntEnableByPop;
BusWait( 4 + CNT_DATA );
pvSDA2 = OFF; //no ack 读完后不发应答,终止I2C通讯
BusWait( 4 + CNT_DATA );
pvSCL2 = OFF;
BusWait( 4 + CNT_DATA );
IntDisableWithPush;
poSCL2 = OFF;
pvSCL2 = ON;
IntEnableByPop;
BusWait( 4 + CNT_DATA );
return bReadData;
}
以下是I2C传输基础函数
SI dtv_i2c_send( U8 bDataLength, U8* bDatBuffer ) //写数据,bDataLength数据长度,bDatBuffer 数据组指针
{
SI RoopCt = 1;
if( !dtv_i2c_start(*bDatBuffer) ) //I2C开始,并写一个数据
{
while(1)
{
if(RoopCt>=bDataLength) //如果RoopCt计数大于等于数据长度,说明I2C传输完整成功
{
dtv_i2c_end();
return TRUE;
}
if(dtv_i2c_data(*(bDatBuffer+RoopCt))) //如果没有传输完毕,继续剩下的数据
{
break;
}
RoopCt++;
}
}
dtv_i2c_end();
return WRONG;
}
SI dtv_i2c_recv( U8 bDataLength, U8 bInputPos, U8* bDatBuffer ) //bInputPos表示开始接受输入的数组元素位置
{ //bDataLength是总共的写入参数跟读出参数共享一个数组bDatBuffer 的长度
SI IICErr;
SI OutputCount = 1;
U8 SlaveRead = 0;
if(dtv_i2c_start(*bDatBuffer)==TRUE) //开始I2C传输并传输一个数据
{
if(bInputPos!=1) //如果bInputPos不为1,说明还要写入几个数据后,才能开始读
{
for(IICErr=TRUE; OutputCount<bInputPos; OutputCount++)
{
if(dtv_i2c_data(*(bDatBuffer+OutputCount))) //继续写入要传入的几个数据
{
IICErr=WRONG;
break;
}
}
SlaveRead = (*bDatBuffer | 0x01); //之后,开始配置读命令。*bDatBuffer 始终存地址
dtv_i2c_end(); //写完要读的地址之后,发个STOP。
if((IICErr==WRONG)||(dtv_i2c_start(SlaveRead)==WRONG)) //开始真正的读命令
{
dtv_i2c_end();
return WRONG;
}
}
for( ; OutputCount<bDataLength; OutputCount++ )
{
*(bDatBuffer+OutputCount)=dtv_i2c_read(); //持续的读数据,用带应答的读命令
}
*(bDatBuffer+OutputCount)=dtv_i2c_readnc(); //读最后一个数据时,采用不发应答的读命令
dtv_i2c_end();
return TRUE;
}
dtv_i2c_end();
return WRONG;
}