大家好 ,我正在使用TMS320F2.8069万上的I2C来写入和读取多个器件,例如I2C到一个线桥,I2C到IO扩展器等。我想按以下方式写入和读取。
S AD,WR [A] WCFG [A] CF [A] SR AD,RD,[A][CF] A\ P
//[]表示从机
//WCFG -写入配置寄存器地址
// cf -要写入的配置字节
// AD -地址
// SR -重复开始
当我用out Rd单独书写时,即
S AD,WR [A] WCFG [A] CF [A] A] A\ P
通过SDA发送的数据是完美的
但当我这样做时
S AD,WR [A] WCFG [A] CF [A] SR AD,RD,[A][CF] A\ P
写后读写将写入 I2caRegs.I2CDXR寄存器。 我尝试在写和读之间设置延迟。 它只是被忽略了,而过度的权利继续存在。 请就要检查的内容给出一些想法或建议。
代码为
void I2CAInit (void){
//初始化I2C
I2caRegs.I2CSAR = 0x0050;
I2caRegs.I2CPsc.all = 10;//预分频器-需要7-12 MHz的模块clk,此处= 30M/(6+1)= 4.28 MHz
I2caRegs.I2CCLKL = 10;//指定空间,必须为非零
I2caRegs.I2CCLKH = 10;//指定标记,必须为非零
I2caRegs.I2CIER = 0x24;//启用SCD和ARDY中断
I2caRegs.I2CMDR.ALL = 0x0020;//从重置中取出I2C
//暂停时停止I2C
I2caRegs.I2CFFTX.ALL = 0x6021;//启用FIFO模式和TXFIFO
I2caRegs.I2CFFTX.bit.TXFFIENA = 1;
I2caRegs.I2CFFRX.ALL = 0x2040;//启用RXFIFO,清除RXFFINT
//I2caRegs.I2CFFTX.ALL = 0x0000;//禁用FIFO模式和TXFIFO
//I2caRegs.I2CFFRX.ALL = 0x0000;//禁用RXFIFO,清除RXFFINT,
返回;
}
Int16 B1WWrConfig (UINT16配置){
//写入配置(案例A)
// S AD,0 [A] WCFG [A] CF [A] SR AD,1 [A][CF] A\ P
//[]表示从机
//要写入的CF配置字节
I2C.MsgBuffer[0]=B1W_WCFG;
I2C.MsgBuffer[1]=配置;
I2C.NumOfBytes=2;//数据字节的数目,不包括地址
I2CAWrite (&I2C);
毫秒(100);
I2C.MsgStatus = I2C_MSGSTAT_RESTART;
I2C.NumOfBytes=1;
I2CARead (&I2C);
毫秒(5);
IF(I2C.MsgBufferRX[0]==(Config&0x0F)))return(0);
else返回(-1);
}
UINT16 I2CAWrite(I2CMSG *msg){
UINT16 I;
//等待STP位从以前的任何主通信中清除。
//模块清除此位的时间延迟到SCD位之后
//设置。 如果在启动新消息之前未检查此位,则
// I2C可能会混淆。
//IF (I2caRegs.I2CMDR.bit.STP == 1)
//返回I2C_STP_NOT_READY_ERROR;
while (I2caRegs.I2CMDR.bit.stp);
MSG->WrDone = 1;
I2caRegs.I2CSAR = msg->SlaveAddress;
//检查总线是否繁忙
如果(I2caRegs.I2CSTR.bit.BB == 1)返回I2C_BUS_BUSY_ERROR;
I2caRegs.I2CCNT = msg->NumOfBytes;
I2caRegs.I2CFFTX.Bit.TXFFIL = msg->NumOfBytes;
用于(i=0; i<msg->NumOfBytes; i++){
I2caRegs.I2CDXR =*(msg->MsgBuffer+I);
}
//作为主发送器发送启动
IF (msg->MsgStatus == I2C_MSGSTAT_SEND_NOSTOP){
}
//I2caRegs.I2CMDR.ALL = 0x6E20;//运行空闲,发送开始,停止,主模式,传输模式,模块已启用
I2caRegs.I2CMDR.All = 0x6E20;//运行空闲,发送开始,停止,主模式,传输模式,模块已启用
//I2caRegs.I2CMDR.bit.rm=1;//重复模式
//I2caRegs.I2CMDR.bit.stp = 1;
//while (I2caRegs.I2CSTR.bit.XRDY == 1){}
//while (I2caRegs.I2CSTR.bit.BB == 1){}
//while (msg->WrDone);
返回I2C_SUCCESS;
}
UINT16 I2CARead (I2CMSG *消息){
//等待STP位从以前的任何主通信中清除。
//模块清除此位的时间延迟到SCD位之后
//设置。 如果在启动新消息之前未检查此位,则
// I2C可能会混淆。
//IF (I2caRegs.I2CMDR.bit.STP == 1)
//返回I2C_STP_NOT_READY_ERROR;
while (I2caRegs.I2CMDR.bit.stp);
I2caRegs.I2CSAR = msg->SlaveAddress;
MSG->RdDone = 1;
IF (msg->MsgStatus == I2C_MSGSTAT_SEND_NOSTOP){
//检查总线是否繁忙
如果(I2caRegs.I2CSTR.bit.BB == 1)返回I2C_BUS_BUSY_ERROR;
I2caRegs.I2CCNT = msg->NumOfBytes;
I2caRegs.I2CDXR = 0;
I2caRegs.I2CMDR.All = 0x2620;//发送数据至设置EEPROM地址
}
否则,如果(msg->MsgStatus == I2C_MSGSTAT_RESTART){
I2caRegs.I2CCNT = msg->NumOfBytes;//设置预期的字节数
I2caRegs.I2CDXR = 0;
I2caRegs.I2CMDR.All = 0x2C20;//作为主接收器发送重启
}
//while (I2caRegs.I2CSTR.Bit.BB == 1 || I2caRegs.I2CSTR.Bit.XRDY ==0)
//while (I2caRegs.I2CSTR.bit.BB == 1);
//while (I2caRegs.I2CSTR.bit.RRDY == 1);
//while (msg->RdDone);
返回I2C_SUCCESS;
}
中断void i2c_int1a_isr(void){
UINT16 IntSource,I;
//读取中断源
IntSource = I2caRegs.I2CISRC.ALL;
//中断源=检测到停止条件
IF (I2caRegs.I2CFFTX.Bit.TXFFINT){
I2caRegs.I2CFFTX.bit.TXFFINTCLR = 1;
I2C.WrDone = 0;
}
IF (IntSource == I2C_SCD_ISRC){
//如果已完成的消息正在写入数据,请将消息重置为非活动状态
IF (I2C.MsgStatus == I2C_MSGSTAT_WRITE _BUSY){
I2C.MsgStatus = I2C_MSGSTAT_INACTIVE;
}
否则{
//如果消息在的地址设置部分收到nack
// EEPROM读取,以下代码包含在寄存器访问就绪中
//中断源代码将生成停止条件。 停止后
//条件已接收(此处),请将消息状态设置为重试。
//用户可能希望在生成错误之前限制重试次数。
IF (I2C.MsgStatus == I2C_MSGSTAT_SEND_NOSTOP_BUSY){
I2C.MsgStatus = I2C_MSGSTAT_SEND_NOSTOP;
}
//如果已完成消息正在读取EEPROM数据,请将消息重置为非活动状态
//并从FIFO读取数据。
否则,如果(I2C.MsgStatus == I2C_MSGSTAT_READ_BUSY){
I2C.MsgStatus = I2C_MSGSTAT_INACTIVE;
对于(i=0;i < I2C.NumOfBytes;i++){
I2C.MsgBufferRX[i]= I2caRegs.I2CDRR;
}
}
//检查收到的数据
对于(i=0;i < I2C.NumOfBytes;i++){
I2C.MsgBufferRX[i]= I2caRegs.I2CDRR;
}
I2C.RdDone = 0;
}
}
//中断源=寄存器访问就绪
//此中断用于确定的EEPROM地址设置部分的时间
//读取数据通信已完成。 由于没有命令停止位,所以此标志
//告诉我们邮件已发送,而不是SCD标志。 如果是一个nack
//已收到,请清除nack位并命令停止。 否则,继续阅读
//通信的数据部分。
否则IF (IntSource == I2C_ARDY_ISRC){
IF (I2caRegs.I2CSTR.bit.nack == 1){
I2caRegs.I2CMDR.bit.stp = 1;
I2caRegs.I2CSTR.All = I2C_CLR_nack_bit;
}
否则IF (I2C.MsgStatus == I2C_MSGSTAT_send_NOSTOP_BUSY){
I2C.MsgStatus = I2C_MSGSTAT_RESTART;
}
}//注册访问结束就绪
//启用未来的I2C (PIE组8)中断
PieCtrlRegs.PIEACK.ALL = PIEACK_group8;
}