こんにちは、
モデレーターの皆さん、もしこれが Freescale フォーラムの適切な場所でない場合は、ご指摘いただければご指定の場所へ移動します。
私は今後のプロジェクトに上記のアクセルを使用しています。部品は(ちょうど)十分に小さくて、目的を達成でき、デジタル インターフェースが気に入っています。
しかし、今のところデバイスとの通信に問題があります。私はドキュメントを読んだが、そこには曖昧な点がある(例えばセクション 5.11.1 シングル バイト読み取り - タイミング図には NAK が示されていますが、テキストでは NAK がないことが示されています ("…マスターは送信されたデータに対して確認応答 (NAK) を送信しません…")。
私が求めているのは、1 バイトの読み取りと 1 バイトの書き込みのタイミング図です。理想的には、読み取り用の reg アドレスが 0x0D (Who-Am-I reg) で、書き込み用の reg アドレスが 0x2A (Control Reg 1) です。
これはスコープからのスクリーンショット、または遷移と遷移の発信者を示すその他のもの(つまりマスター、スレーブ)。
よろしくお願いいたします。
トニー・バリー
こんにちは、トニー。
うまく動作したと聞いて嬉しく思います。また、フィードバックをいただきありがとうございます。
データシートにタイミング図を含めることを検討します。
はい、ここにコードを投稿したり、リンクを提供したりできます。Atmel AVR MCU と組み合わせて当社の I2C 加速度センサを使用している他のお客様にとっても役立つ可能性があります。
よろしくお願いいたします。
トーマス
こんにちは、トーマス。
あなたの洞察力に富んだメールのおかげで、私はアクセルを使って「Who-Am-I」バイトを正しく読み取ることができました。
タイミング図は非常に役立ちました。データシートに組み込めれば非常に良いでしょう。
しかし、最も役に立ったのは、アクセラレータが SPI ではなく I2C デバイスであることを丁寧に指摘していただいたことです
- このプロトコルを反映するように週末にコードを書き直したところ、正常に動作するようになりました。
私のこのような失敗は、おそらく金曜の夕方のデバッグ セッションでビールを 1 杯か 2 杯飲む価値があるでしょう。
質問者様の質問を「回答済み」に設定しました。お役に立てれば幸いです。
あなたのサイトがこのように動作するなら、コードを投稿することもできます。それ以外の場合は、ホストしてリンクバックすることができます。
よろしくお願いいたします。
トニー・バリー
こんにちは、トーマス。
SPI について言及しているのであれば、多少の誤解があると思います。
はい、もちろんその通りです。私はスコープに SPI デコードを使用しています - アクセル バスは I2C です。スコープが簡単にデコードできるようにチップセレクト (CS) を合成していますが、この信号は加速信号の一部ではありません。
MMA8652FC には I2C インターフェイスのみが搭載されているため、SDA (データ) ラインと SCL (クロック) ラインの両方をプルアップ抵抗を介して電源電圧に接続する必要があります。推奨値は1kΩ~4.7kΩです。
ああ、わかりました。データ転送セグメント中のクロックストレッチ。
続けます。
よろしくお願いいたします。
トニー・バリー
こんにちは、トニー。
SPI について言及しているのであれば、多少の誤解があると思います。
MMA8652FC には I2C インターフェイスのみが搭載されているため、SDA (データ) ラインと SCL (クロック) ラインの両方をプルアップ抵抗を介して電源電圧に接続する必要があります。推奨値は1kΩ~4.7kΩです。
MMA8652FC に似た加速度計を SPI インターフェース付きで使用したい場合は、 FXLS8471Q を検討することをお勧めします。SPI トランザクションを示すスクリーンショットを含む私のサンプル コードは、ここから入手できます。
よろしくお願いいたします。
トーマス
こんにちは、トーマス。
ご返信、そしてご協力のお申し出を誠にありがとうございます。アドレス 0x0D の 1 バイト読み取りのタイミング図を添付します。
4 つのトレースは次のとおりです。
CLK - マイクロコントローラから駆動される SPI クロック。
DAT - マイクロコントローラまたはアクセラレータによって駆動される SPI データ ライン。
CS - アクセルでは使用されませんが、マイクロコントローラによって出力され、Rigol スコープによってデータのデコードに使用されます。
IND - アクセルでは使用されませんが、アクセルによって ACK 信号が送信されたときにマイクロコントローラによってブラケットに出力されます。マイクロコントローラによってサンプリングされます。
データシートに記載されている標準回路を使用しました。DAT ラインは 1K 抵抗でプルアップされます。アクセルは、チップに近い BYPASS および Vdd (トレース長 5cm 以内) の 100nF キャップによってバッファリングされます。Vdd も 1uF キャップによってバッファリングされます。
データシートの表 12 に示されているように、PL_BF_ZCOMP レジスタや P_L_THS_REG レジスタなど、デフォルト値が 0x00 と異なるレジスタがいくつかあるため、これらのレジスタからも 0x00 を読み取れば、WHO_AM_I レジスタの ID が間違っていても問題にはなりません。
ありがとうございます。P_L_THS_REG と PL_BF_ZCOMP の読み取りを試みましたが、やはり 0x00 が返されました。
0x01をアドレス0x2Aに書き込むと(つまりACTIVE を 1 に設定すると、その後のすべてのアドレスの読み取りが 0x00 から 0xFF に変わります。ACTIVE を 0 に設定しても、この動作は元に戻りません (電源の投入と再投入が必要です)。このことから、コードとタイミングをもっと注意深く検討する必要があると考えるようになりました。
続けます。
これまでのご協力に心より感謝申し上げます。
よろしくお願いいたします。
トニー・バリー
こんにちは、トニー。
回路図だけでなくタイミング図もここに投稿していただければ、調査のお手伝いができるかもしれません。
データシートの表 12 に示されているように、PL_BF_ZCOMP レジスタや P_L_THS_REG レジスタなど、デフォルト値が 0x00 と異なるレジスタがいくつかあるため、これらのレジスタからも 0x00 を読み取れば、WHO_AM_I レジスタの ID が間違っていても問題にはなりません。
デバイス アドレスの変更に関しては、2 番目のバイトは実際には読み取り元のレジスタのアドレスなので、この場合は 0x3A ではなく 0x0D になります。
上記のように、WHO_AM_I レジスターを読み取るには、次の手順を実行します。
1. 開始シーケンスを送信する
2. 0x3A // MMA8652FCスレーブアドレスをR/Wビットが低い値または0x1D<<1で送信する
3. 0x0D // WHO_AM_Iレジスタアドレスを送信
4. スタートシーケンスを再度送信する(繰り返しスタート)
5. 0x3B // MMA8652FCスレーブアドレスをR/Wビットがハイまたは(0x1D << 1) | 0x01で送信する
6. WHO_AM_Iレジスタからデータバイトを読み取る
7. NAKと停止シーケンスを送信する
お役に立てれば幸いです。
よろしくお願いいたします。
トーマス
こんにちは、トーマス。
私はあなたのタイミング図をファームウェアに実装し、2 番目の MMA8652 を使用してインターフェース コードをテストしました。
最初のデバイスと同様に、WhoAmI バイト (loc: 0x0D value: 0x4A) を要求すると、このアドレスには 0x00 が格納されていると認識されます。
0x00 から 0x30 までのすべてのアドレスは 0x00 として読み取られます。
デバイス アドレス (1 バイト読み取りシーケンスのバイト 2) を 0x3A から他の値に変更すると、デバイスは確認応答しません。
whoAmI バイトがデバイス内で 0x00 としてプログラムされている可能性はありますか?
調査を続けます。
よろしくお願いいたします。
トニー・バリー
どういたしまして、トニー。
このマターの進捗状況についてご連絡いただければ幸いです。
よろしくお願いいたします。
トーマス
こんにちは、トーマス。
まさにこれこそが私が必要としているものです。どうもありがとう。
あなたのメッセージを役に立ったと評価し、翌日にその情報を適用します。それが本当に解決策であれば、私も「正解」としてマークします。
また、これをスーパープロンプトとしてマークしたいのですが、そのボタンが表示されません。
よろしくお願いいたします。
トニー・バリー
こんにちは、トニー。
以下は、WHO_AM_I レジスタ 0x0D から読み取られた 1 バイトを示すロジック アナライザーの画像です。ご覧のとおり、正しい値 0x4A が返されます。
読み取り操作でよくある問題は、 2番目のバイト(この場合は0x0D)の後にストップコンディション(SCLがHighの状態でSDAがLowからHighに遷移すること)を送信することです。正しい方法は、SCLラインがHighになる前にSDAラインを解放(Highに遷移させる)することです。
以下は、値 0x3D を CTRL_REG1 レジスタ 0x2A に書き込む 1 バイトの書き込み操作です。
お役に立てれば幸いです。
よろしくお願いいたします。
トーマス
追伸: 私の回答がご質問の解決に役立った場合は、「正解」または「役に立った」と評価してください。ありがとうございます。