作为 I2C 从机的 PIC 24F 在向主机发送多个数据字节(主读取)时存在锁定问题。
PIC(特别是 24FJ128GB202)作为 I2C 从机接收数据(MASTER WRITE)工作完美,通过了所有单元测试。(仅地址,地址和寄存器,地址寄存器单数据和多数据自动递增)
我的从代码可以只处理地址并读取单个字节。它挂在从主机进行的多次读取(自动增量)上。
我使用Microchip 应用笔记作为我的代码的基础,并查看了 Code Composer 生成的代码。
初始化:
void I2C1_Initialize(void)
{
I2C1ADD = I2C1_SLAVE_ADDRESS;
I2C1MSK = I2C1_SLAVE_MASK;
I2C1CONL = 0x8200;
I2C1CONH = 0x0000;
I2C1STAT = 0x0000;
// clear the master interrupt flag
IFS1bits.SI2C1IF = 0;
// enable the master interrupt
IEC1bits.SI2C1IE = 1;
}
中断写:
// clear the interrupt
_SI2C1IF = 0;
// Write from Master to Slave - Address
// S = 1, D_A = 0, R_W = 0, BF = 1
if ( (I2C1STATbits.S == 1) && (I2C1STATbits.D_A == 0) && (I2C1STATbits.R_W == 0) && (I2C1STATbits.RBF == 1) )
{
myI2CAd = I2C1RCV;
mySTATE = 0;
}
// Write from Master to Slave - Data
// S = 1, D_A = 1, R_W = 0, BF = 1
if ( (I2C1STATbits.S == 1) && (I2C1STATbits.D_A == 1) && (I2C1STATbits.R_W == 0) && (I2C1STATbits.RBF == 1))
{
mySTATE++;
if(mySTATE == 1)
{
myREGISTER = I2C1RCV;
// limit register to MAX
if(myREGISTER > I2CMAXREGISTER) myREGISTER = I2CMAXREGISTER;
}
if(mySTATE == 2)
{
myDATA = I2C1RCV;
shelfregister[myREGISTER] = myDATA;
}
if(mySTATE > 2)
{
myDATA = I2C1RCV;
// limit register to MAX
if(myREGISTER < I2CMAXREGISTER) myREGISTER++;
shelfregister[myREGISTER] = myDATA;
}
}
中断读取:
// Read from Slave to Master - Address
// S = 1, D_A = 0, R_W = 1, BF = 0
if ( (I2C1STATbits.S == 1) && (I2C1STATbits.D_A == 0) && (I2C1STATbits.R_W == 1) && (I2C1STATbits.TBF == 0) )
{
myI2CAd = I2C1RCV;
I2C1TRN = shelfregister[myREGISTER];
I2C1CONLbits.SCLREL = 1;
if(myREGISTER < I2CMAXREGISTER) myREGISTER++;
}
Code Composer 为从属操作生成的代码非常相似,并且具有相同的问题。
我的主要问题是如何处理来自主机的多次读取,而不仅仅是在这个读取函数中处理的单个字节。它应该涉及检查 I2CSTATbits.ACKSTAT,但我不清楚该位的时序,因为它应该在字节进入寄存器后 9 个时钟发生,但没有位指示该时间点。任何指导表示赞赏。