こんにちは。FXOS8700 で A_VECM 機能を使用しようとすると、奇妙な応答が発生します。
次のコードがあります:
MMA865x_スタンバイ();
IIC_RegWrite(CTRL_REG4,0x02); //データレディ割り込みを無効にし、A_VECM割り込みを有効にする
IIC_RegWrite(A_VECM_THS_MSB,0x80); //MSB THSを更新し、条件が満たされない場合はリセットする
print_string("A_VECM_THS_MSB= ",16); print_hex(IIC_RegRead(A_VECM_THS_MSB)); WaitPrintBuffer();
IIC_RegWrite(A_VECM_THS_LSB,Acc_THS); // LSB THSを更新
print_string("A_VECM_THS_LSB= ",16); print_hex(IIC_RegRead(A_VECM_THS_LSB)); WaitPrintBuffer();
IIC_RegWrite(A_VECM_CNT,Acc_COUNT); //カウンターを更新
print_string("A_VECM_CNT= ",13); print_hex(IIC_RegRead(A_VECM_CNT)); printENTER; WaitPrintBuffer();
IIC_RegWrite(A_VECM_CFG,0x78); //0111 1000 ラッチ有効、A_VECM_INIT、イベント発生時に参照を更新しない
IIC_RegWrite(M_CTRL_REG1,((IIC_RegRead(M_CTRL_REG1))&(~0x03))); //Accelerometer_Onlyを有効にする
Data_Mode= Accelerometer_Only; //EX0割り込みを通知して加速度センサデータを読み取る
IIC_RegWrite(M_CTRL_REG2,((IIC_RegRead(M_CTRL_REG2))&(~0x20))); //自動インクリメントモードを無効にする
// IntSource=IIC_RegRead(TRANSIENT_SRC); // 割り込みをクリアするために0x1E TRANSIENT_SRCレジスタを読み出す
MMA865x_Active(); //センサをアクティブにする
このコードを使用すると、プログラムは正常に動作し、デバイスを移動するたびに A_VECM がアサートされます。
この段階で、print_string() 行を削除することにしました。
それを実行した後、A_VECM は一度アサートされ、それ以降はアサートされなくなります。
print_string() 行を単純な遅延に置き換えてみました: for(i=0; i<60000; i++);
この行では、A_VECM が問題なく再びアサートされます。
CNTR_REG4 を読み取ることができ、0x02 に設定されています。ただし、A_VECM はアサートされません。
その理由は何でしょうか?
よろしくお願いします。
こんにちは、トーマス
正しいリンクをありがとうございます。
問題はまだ存在します。
私のプロジェクトの詳細(コード)は以下をご覧ください
センサー初期化:
MMA865x_スタンバイ();
IIC_RegWrite(CTRL_REG4,0x02);
IIC_RegWrite(A_VECM_THS_MSB、0x80);
IIC_RegWrite(A_VECM_THS_LSB、Acc_THS);
IIC_RegWrite(A_VECM_CNT、Acc_COUNT);
IIC_RegWrite(A_VECM_INITX_MSB、0x00);
IIC_RegWrite(A_VECM_INITX_LSB、0x00);
IIC_RegWrite(A_VECM_INITY_MSB、0x00);
IIC_RegWrite(A_VECM_INITY_LSB、0x00);
IIC_RegWrite(A_VECM_INITZ_MSB、0x00);
IIC_RegWrite(A_VECM_INITZ_LSB、0x00);
IIC_RegWrite(A_VECM_CFG,0x78);
IIC_RegWrite(M_CTRL_REG1,((IIC_RegRead(M_CTRL_REG1))&(~0x03)));
IIC_RegWrite(M_CTRL_REG2,((IIC_RegRead(M_CTRL_REG2))&(~0x20)));
MMA865x_アクティブ();
IntSource=IIC_RegRead(INT_SOURCE);
今、 A_VECMイベントをポーリングしています
General_IntSource = IIC_RegRead(INT_SOURCE);
General_IntSource&0x02の場合、readdata();
そして最後に関数readdata()
void readdata (void) //
{
IntSource=IIC_RegRead(INT_SOURCE);
MMA865x_スタンバイ();
IIC_RegWrite(M_CTRL_REG1,((IIC_RegRead(M_CTRL_REG1))|0x03)); //ハイブリッドモード
IIC_RegWrite(M_CTRL_REG2,((IIC_RegRead(M_CTRL_REG2))|0x20)); //磁気自動インクリメントを有効にする
IIC_RegWrite(CTRL_REG4,0x01); //データ準備割り込みを有効にし、A_VECM割り込みを無効にする
MMA865x_アクティブ(); //センサをアクティブにする
ここで、データ準備割り込みを使用して加速度センサと磁気データを数回読み取り、新しいデータを取得します。
データの読み取りが完了したら、 A_VECM割り込みを再度受け入れるようにパラメータを設定します。
MMA865x_スタンバイ();
IIC_RegWrite(CTRL_REG4,0x02); //データレディ割り込みを無効にし、A_VECM割り込みを有効にする
for (i=0; i<60000; i++); - この行を削除すると、システムを再起動しない限り、A_VECM割り込みはアサートされなくなります。
IIC_RegWrite(M_CTRL_REG1,((IIC_RegRead(M_CTRL_REG1))&(~0x03))); //加速度計のみを有効にする
IIC_RegWrite(M_CTRL_REG2,((IIC_RegRead(M_CTRL_REG2))&(~0x20))); //自動インクリメントモードを無効にする
MMA865x_アクティブ(); //センサをアクティブにする
IntSource=IIC_RegRead(INT_SOURCE); //割り込みをクリアするために0x0C INT_SOURCEレジスタを読み出す
}
最初の割り込みは常にアサートされ、システムは期待どおりに動作します。すべてのデータの読み取り値を取得します。
遅延線を配置してもシステムは正常に動作します。問題は、それがなぜ必要なのかということです。
デバッグのために数行印刷していたので、遅延が必要だというアイデアを得ました。これらの行を削除すると、最初の A_VECM の後の割り込みが発生しなくなりました。
調査の結果、連続した割り込みを取得するには、CTRL_ REG4 の設定後に遅延が必要であることがわかりました。
デバッグ モードでGeneral_IntSource変数の値が 0x00 になっているのを確認できるため、割り込みがアサートされていないことは確かです。
このCASEについて調査してご意見を頂ければ幸いです。
よろしくお願いします。
メイア
MMA865x_スタンバイ(); IIC_RegWrite(CTRL_REG4,0x02); IIC_RegWrite(A_VECM_THS_MSB、0x80); IIC_RegWrite(A_VECM_THS_LSB、Acc_THS); IIC_RegWrite(A_VECM_CNT、Acc_COUNT); IIC_RegWrite(A_VECM_INITX_MSB, 0x00); IIC_RegWrite(A_VECM_INITX_LSB, 0x00); IIC_RegWrite(A_VECM_INITY_MSB, 0x00); IIC_RegWrite(A_VECM_INITY_LSB, 0x00); IIC_RegWrite(A_VECM_INITZ_MSB, 0x00); IIC_RegWrite(A_VECM_INITZ_LSB, 0x00); IIC_RegWrite(A_VECM_CFG,0x78);
IIC_RegWrite(M_CTRL_REG1,((IIC_RegRead(M_CTRL_REG1))&(~0x03))); IIC_RegWrite(M_CTRL_REG2,((IIC_RegRead(M_CTRL_REG2))&(~0x20))); MMA865x_アクティブ(); IntSource=IIC_RegRead(INT_SOURCE);
こんにちは、メイアさん。
申し訳ございませんが、正しいリンクは次のとおりです: https://community.freescale.com/docs/DOC-106050
私の設定を再現してみて、問題が解決しない場合はお知らせください。
よろしくお願いいたします。
トーマス
こんにちは、トーマス
迅速なご対応ありがとうございます。
残念ながら、サンプルコードとして送信されたリンクを開くことができません。
実際、私は一時割り込みを扱うプログラムから以前のコード部分をコピーして貼り付けたSO、INT_Source ではなく一時ソースを読み取りました。
質問に添付したコードは、A_VECM 割り込みを処理する最後の部分です。
割り込みがアサートされた直後に、INT_SOURCE レジスタを読み取ります。
最後に、あなたの提案に従って行を変更しました
// IntSource=IIC_RegRead(TRANSIENT_SRC); // 割り込みをクリアするために0x1E TRANSIENT_SRCレジスタを読み出す
そしてそれを
IntSource=IIC_RegRead(INT_SOURCE); //割り込みをクリアするために0x0C INT_SOURCEレジスタを読み出す
問題はまだ存在しています。
私のCASEのポイントは、一拍違うことです。
行の後に遅延がある場合のように見えます:
IIC_RegWrite(CTRL_REG4,0x02); //データレディ割り込みを無効にし、A_VECM割り込みを有効にする
中断されることはあります。
遅延は、いくつかのレジスタを設定して印刷することによって行われます(質問で送信したコードを参照してください)。
あるいは単純に for(i=0; i<60000; i++); とすることで遅延を実装することもできます。
このようなCASE、最初の割り込みの後に A_VECM 割り込みが発生しますが、これは常に予想どおりにアサートされます。
遅延が実装されていない場合、最初にアサートされた後の割り込みは発生しません。
よろしくお願いします。
メイア・サドリー
こんにちは、メイアさん。
私のサンプルコードを見てください。SRC_A_VECM ステータス ビットをクリアし、INTx ピンをデアサートするには、INT_SOURCE レジスタ (0x0C) を読み取る必要があります。
お役に立てれば幸いです。
よろしくお願いいたします。
トーマス
追伸: 私の回答が質問の解決に役立った場合は、「正解」とマークしてください。ありがとう。