/*ForProgram*/
#defineI2C_Stop()I2CStop()
#defineI2C_SendAck()I2CSendAck()
#defineI2C_SendNoAck()I2CSendNoAck()
#defineI2C_WaitAck()I2CWaitAck()
/*I2CConfig*/
#defineI2C_ERR0
#defineI2C_CRR1
//chardata1;//为观察读取的数据的临时观察变量
#ifndefWR_DADR
#defineWR_DADR0xa0//writedevice-address
#endif
#ifndefRD_DADR
#defineRD_DADR0xa1//readdevice-address
#endif
//#defineAT24CXX_ERR0
//#defineAT24CXX_CRR1
//******************************twi初始化*************************************
//TWCR:
控制寄存器,用来控制TWI操作,说明如下:
//Bit7-TWINT:
中断标志位,Bit6-TWEA:
使能应答位,Bit5-TWSTA:
START状态位
//Bit4-TWSTO:
STOP状态位,Bit3-TWWC:
写冲突标志,Bit2-TWEN:
TWI使能位
//Bit1-RES:
保留,Bit0-TWIE:
中断使能
//TWSR:
状态寄存器,Bits7..3:
表示了TWI总线的当前状态,读取时需屏蔽低三位的值,Bits1..0-TWPS:
TWI预分频位
//TWBR:
比特率寄存器,用来设置TWI的工作频率,计算公式为:
SCL=CPU频率/(16+2*(TWBR)*4TWPS),TWPS在4的指数位置
//TWAR:
从机地址寄存器,Bits7..1:
存放从机地址,Bit0:
最低位为广播识别使能位
//TWDR:
数据寄存器,用来存放接收或要发送的地址和数据
//******************************************************************************
voidtwi_init(void)
{
TWBR=1;
TWSR=0;
TWCR=0x44;
}
/*--------------------------------------------------------------------
程序名称:
I2CStart
程序功能:
注意事项:
提示说明:
输入:
返回:
--------------------------------------------------------------------*/
INT8UI2C_Start()
{
I2CStart();
I2CWaitAck();//202页第二步等待
if(I2CChkAck()!
=I2C_START)//202页第三步开始启动传输
returnI2C_ERR;
returnI2C_CRR;
}
/*--------------------------------------------------------------------
程序名称:
I2CReStart
程序功能:
注意事项:
提示说明:
输入:
返回:
--------------------------------------------------------------------*/
INT8UI2C_Restart()
{
I2CStart();
I2CWaitAck();
if(I2CChkAck()!
=0x10)
returnI2C_ERR;
returnI2C_CRR;
}
/*--------------------------------------------------------------------
程序名称:
I2C(TWI)发送7位器件写地址:
XXXXXXX0
程序功能:
注意事项:
提示说明:
输入:
返回:
--------------------------------------------------------------------*/
INT8UI2C_SendWrDAdr(INT8UwrDAdr)//wrDAdr相当于202页表中提到的sla_w
{
I2CSendByte(wrDAdr);//202页第四步1.将SLA_W载入到TWDR寄存器,TWINT位清零,启动发送地址设置器件写地址
I2CWaitAck();//202页第四步2等待TWINT置位,TWINT置位表示总线命令SLA+W已发出,及收到应答信号ACK/NACK
if((TWSR&0xf8)!
=0x18)//202页表中第5步检验TWI状态寄存器,屏蔽预分频位,如果状态字不是MT_SLA_ACK转出错处理
returnI2C_ERR;
returnI2C_CRR;
}
/*--------------------------------------------------------------------
程序名称:
I2C(TWI)发送10位器件写地址:
11110XX0,XXXXXXXX
程序功能:
注意事项:
提示说明:
兼容发送7位器件写地址:
XXXXXXX0
输入:
返回:
--------------------------------------------------------------------*/
INT8UI2C_SendWrDAdr_(INT16UwrDAdr)
{
if((wrDAdr&0xf000)==0xF000)//判断是否为10位器件地址
if(I2C_SendWrDAdr((INT8U)wrDAdr>>8)==I2C_ERR)//设置(高位)器件写地址
returnI2C_ERR;
if(I2C_SendWrDAdr((INT8U)wrDAdr)==I2C_ERR)//设置(低位)器件写地址
returnI2C_ERR;
returnI2C_CRR;
}
/*--------------------------------------------------------------------
程序名称:
I2C(TWI)发送7位器件读地址:
XXXXXXX1
程序功能:
注意事项:
提示说明:
输入:
返回:
--------------------------------------------------------------------*/
INT8UI2C_SendRdDAdr(INT8UrdDAdr)
{
I2CSendByte(rdDAdr);//设置器件读地址
I2CWaitAck();
if(I2CChkAck()!
=I2C_MR_SLA_ACK)//I2C_MR_SLA_ACK=0x40
returnI2C_ERR;
returnI2C_CRR;
}
/*--------------------------------------------------------------------
程序名称:
I2C(TWI)发送10位器件读地址:
11110XX0,XXXXXXXX
程序功能:
注意事项:
提示说明:
输入:
返回:
--------------------------------------------------------------------*/
INT8UI2C_SendRdDAdr_(INT8UrdDAdr)
{
if(rdDAdr&0xf000==0xf000)//判断是否为10位器件地址
if(I2C_SendWrDAdr((INT8U)rdDAdr>>8)==I2C_ERR)//设置(高位)器件读地址
returnI2C_ERR;
if(I2C_SendWrDAdr((INT8U)rdDAdr)==I2C_ERR)//设置(低位)器件读地址
returnI2C_ERR;
returnI2C_CRR;
}
/*--------------------------------------------------------------------
程序名称:
I2C(TWI)发送数据
程序功能:
注意事项:
提示说明:
输入:
返回:
--------------------------------------------------------------------*/
INT8UI2C_SendDat(INT8UconfigDat)//原先位16位
{
I2CSendByte(configDat);
I2CWaitAck();
if(I2CChkAck()!
=I2C_MT_DATA_ACK)
returnI2C_ERR;
returnI2C_CRR;
}
/*--------------------------------------------------------------------
程序名称:
I2C(TWI)接收数据且不产生应答
程序功能:
只读一个字节,然后停止读取
注意事项:
提示说明:
读取一个字节后,发送不响应,用于读取1个字节
输入:
返回:
--------------------------------------------------------------------*/
INT8UI2C_RcvNAckDat(INT8U*pRdDat)
{
I2CRcvNckByte();
I2CWaitAck();
if(I2CChkAck()!
=I2C_MR_DATA_NACK)//接收到数据0x58
returnI2C_ERR;
*pRdDat=TWDR;
returnI2C_CRR;
}
/*--------------------------------------------------------------------
程序名称:
I2C(TWI)接收数据且产生应答
程序功能:
用于连续读取,读取单个字节后,在读下一个字节.最后读取n个字节后,再停止.
注意事项:
提示说明:
读取一个字节后,发送响应,用于读取多个字节
输入:
返回:
--------------------------------------------------------------------*/
INT8UI2C_RcvAckDat(INT8U*pRdDat)
{
I2CRcvAckByte();
I2CWaitAck();
if(I2CChkAck()!
=0x50)
returnI2C_ERR;
*pRdDat=TWDR;
returnI2C_CRR;
}
/*--------------------------------------------------------------------
程序名称:
I2C(TWI)写器件,写一个数据
程序功能:
注意事项:
提示说明:
输入:
wrDAdr:
writedevice-address写器件地址
wordAdr:
wordaddress字地址
dat:
data数据
返回:
--------------------------------------------------------------------*/
INT8UI2CWriteByte(INT8UwrDAdr,INT16UwordAdr,INT8Udat)
{
if(I2C_Start()==I2C_ERR)
returnI2C_ERR;
if(I2C_SendWrDAdr_(wrDAdr)==0)
returnI2C_ERR;
if(I2C_SendDat((wordAdr&0xff00)>>8)==I2C_ERR)
returnI2C_ERR;
if(I2C_SendDat(wordAdr&0x00ff)==I2C_ERR)
returnI2C_ERR;
if(I2C_SendDat(dat)==0)
returnI2C_ERR;
I2C_Stop();
returnI2C_CRR;
}
/*--------------------------------------------------------------------
程序名称:
I2C(TWI)写器件,写N个数据
程序功能:
注意事项:
提示说明:
输入:
wrDAdr:
writedevice-address写器件地址
wordAdr:
wordaddress存储数据的起始地址
*pWrDat:
p->writedata写入数据指针
num:
number写入数据个数
返回:
--------------------------------------------------------------------*/
INT8UI2CWriteStr(INT8UwrDAdr,INT16UwordAdr,INT8U*pWrDat,INT8Unum)
{
INT16Ui;
if(I2C_Start()==I2C_ERR)
returnI2C_ERR;
if(I2C_SendWrDAdr_(wrDAdr)==0)
returnI2C_ERR;
if(I2C_SendDat((wordAdr&0xff00)>>8)==I2C_ERR)
returnI2C_ERR;
if(I2C_SendDat(wordAdr&0x00ff)==I2C_ERR)
returnI2C_ERR;
for(i=0;iif(I2C_SendDat(*(pWrDat+i))==0)
returnI2C_ERR;
I2C_Stop();
returnI2C_CRR;
}
/*--------------------------------------------------------------------
程序名称:
I2C(TWI)读器件,读一个数据
程序功能:
注意事项:
提示说明:
输入:
wrDAdr:
writedevice-address写器件地址
wordAdr:
wordaddress字地址
rdDAdr:
readdevice-address读器件地址
*pRdDat:
p->readdata读取数据指针
返回:
--------------------------------------------------------------------*/
INT8UI2CReadByte(INT8UwrDAdr,INT16UwordAdr,INT8UrdDAdr,INT8U*pRdDat)
{
if(I2C_Start()==I2C_ERR)
returnI2C_ERR;
if(I2C_SendWrDAdr_(wrDAdr)==I2C_ERR)
returnI2C_ERR;
////16位地址拆分
if(I2C_SendDat((wordAdr&0xff00)>>8)==I2C_ERR)
returnI2C_ERR;
if(I2C_SendDat(wordAdr&0x00ff)==I2C_ERR)
returnI2C_ERR;
if(I2C_Restart()==I2C_ERR)
returnI2C_ERR;
if(I2C_SendRdDAdr(rdDAdr)==I2C_ERR)
returnI2C_ERR;
if(I2C_RcvNAckDat(pRdDat)==I2C_ERR)
returnI2C_ERR;
I2C_Stop();
returnI2C_CRR;
}
/*--------------------------------------------------------------------
程序名称:
I2C(TWI)读器件,读N个数据
程序功能:
注意事项:
提示说明:
输入:
wrDAdr:
writedevice-address写器件地址
wordAdr:
wordaddress存储数据的起始地址
rdDAdr:
readdevice-address读器件地址
*pRdDat:
p->readdata读取数据指针
num:
number读取数据个数
返回:
--------------------------------------------------------------------*/
INT8UI2CReadStr(INT8UwrDAdr,INT16UwordAdr,INT8UrdDAdr,INT8U*pRdDat,INT8Unum)
{
INT8Ui;
if(I2C_Start()==I2C_ERR)
returnI2C_ERR;
if(I2C_SendWrDAdr_(wrDAdr)==I2C_ERR)
returnI2C_ERR;
//16位24c256存储空间地址拆分
if(I2C_Se