I2C スレーブとしての PIC 24F には、複数のデータ バイトをマスターに送信する (MASTER READ) ロックアップの問題があります。
データを受信する I2C スレーブとしての PIC (具体的には 24FJ128GB202) (MASTER WRITE) は完全に機能し、すべての単体テストに合格しています。(アドレスのみ、アドレスとレジスタ、アドレスレジスタのシングルデータとマルチデータ自動インクリメント)
私のスレーブコードは、アドレスのみを処理し、1 バイトを読み取ることができます。マスターからの複数の読み取りでハングします (自動インクリメント)。
コードのベースとして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 クロック後に発生するはずですが、その時点を示すビットがありません。任意のガイダンスをいただければ幸いです。