• 締切済み

PIC18FとADXL345間のI2C通信

現在PIC18F26K22のI2C機能を用いて、ADXL345(秋月電子の加速度センサモジュール)の値を読み込むプログラムを作成しています。コンパイラはXC8です。 http://www.geocities.jp/zattouka/GarageHouse/micon/MPLAB/16F1827/Acceleration/Acceleration.htmのサイトのプログラムをほぼそのまま使用して(ピンの定義などは変更)動作させたところ、DEVID(0Xe5)が返ってきた後に、センサーの値らしきものが返ってきたため、正常に動作しているものと思われました。 しかし、動作確認していくとどうも値が安定しないため、I2Cの波形を確認してみましたところ、添付画像のようにCLKの波形(CH D)が等間隔ではないことがわかりました。いつも同じ波形であればいいのですが、通信するたびに波形も変化してしまいます。 I2Cでの通信は初めて行ったため、異常なのか正常なのかもわかりません。 異常であれば、どなたか解決方法をお分かりになられる方はいらっしゃいませんでしょうか? 何卒、ご教授よろしくお願いいたします。

みんなの回答

  • tadys
  • ベストアンサー率40% (856/2135)
回答No.1

I2Cでクロックの周波数が変化するのはごく普通のことです。 SCLやSDAの変化のタイミングはソフトウエアで制御される場合が多いのです。 この場合、割り込みなどが発生するとその処理のためにI2Cの制御に遅れが出ます。 I2Cにおいて、SCLの最低周波数はゼロです。 また、tLOW、tHIGHの最大パルス幅は無限大です。 下記資料の50~52ページ辺りを参照してください。 http://www.nxp.com/documents/user_manual/UM10204_JA.pdf

関連するQ&A

  • I2C通信について

    マイコンにI2C通信対応ICを5個接続して使用しようとしています. 基板上で5個のICのI2Cバスを接続して通信したところ,1個だけ(型番 : INA231)データが正常に返ってきませんでした. オシロで波形を確認すると,INA231と通信する時のみ,SDA/SCLともに波形の電圧が正常時の半分程度でした.他の4個のICとの通信時は正常な電圧(highが電源電圧)でした. 試しに,マイコンとINA231を1:1で接続してI2C通信すると問題なくデータを取得できたため,プログラムは問題ないことが確認できました. 上記のような現象の発生原因と,対策など,お分かりになられる方がいらっしゃいましたら何卒ご教授よろしくお願い致します.

  • マイコンPIC16F84Aについて質問です

    MPLAB(秋月)のライターを使用して PIC16F84Aにプログラムを製作したいのですがプログラムの組み方がわかりません 内容は、センサー5v~24vがオンしたらLEDが点灯する回路です。 動作確認をしたところ、センサーはオンオフしているのですが、LEDが点灯しません。 プログラムを組む時に、RB0がオンしたらRA0がオンする為の繋がりがイマイチわかりません。 c言語はわからないので、アセンブル命令で教えていただけないでしょうか? 初心者なので全くわかりませんがお願いします。

  • PICでのI2C通信でのマスタ、スレーブの切り替え

    現在PIC18F2550同士で、I2C通信を行いたくアセンブラでプログラミングをしておりますが、教えていただきたい点があります。 ・マスターとスレーブは動作中に入れ替えることはできないのでしょうか? RS等から任意の信号を与えると、マスタとスレーブが切り替わるようなことがしたいのですが、どの書籍をみてもそのような事ができるとは書いてなく困っております。 ・PICだけでなくI2C通信を行うことのできるマイコンorCPU(プログラミングが簡単で高速動作できる)はあるのでしょうか?あればお教えいただきたいです。 以上よろしくお願いいたします。

  • PIC24FでI2C

    PIC24FでRTCを制御するためのI2C通信がうまくいかず困っています。 そこでSDA/SCLから信号が出ているかのみを確認するため 下記のようなプログラムをPICに書込みました。 (STARTの出力のみ) 当方オシロを持っていませんので汎用のテスタでSDA/SCL電圧の一時的な変化を読み取ろうと試みましたが全く電圧の変化はありません。 #include "p24FJ64GA002.h" _CONFIG1( JTAGEN_OFF & GCP_OFF & GWRP_OFF & BKBUG_OFF & COE_OFF & ICS_PGx1& FWDTEN_OFF ) _CONFIG2( IESO_ON & FNOSC_FRC & FCKSM_CSDCMD & OSCIOFNC_OFF & IOL1WAY_ON & I2C1SEL_SEC & POSCMOD_NONE) int main(void) { AD1PCFG = 0xffff; CLKDIV = 0; TRISA = 0xFFE3; TRISB = 0x006F; LATB = 0x0010; CNPU1 = 0x003C; /// I2Cの初期設定 I2C1BRG = 0x27; I2C1CON = 0x8000; I2C1RCV = 0x00; I2C1TRN = 0x00; while(1){ I2C1CONbits.SEN = 1; while(I2C1CONbits.SEN); } } 心ある方、どなたかご教示お願いいたします。

  • PIC12F629の発振

    PIC12F629を外部に某社のセラロックを使って XTモードで4MHzで発振しています。 (今回は内部発振は精度上使えません。) しかしCLKOUTの出力スィングは01.7V しかありません。 ただしプログラムは正常に動作しています。 同様のことをPIC16F84Aでやると CLKOUTの出力スィングは04Vあります。 CLKOUTの出力スィングが小さいことは 問題ないのでしょうか。 ただPIC12F629をHSモードにするとスィングは 05VありますがCLKOUTの波形の 歪は大きくなります。 プログラムは正常に動作しているといっても試作の 3セットだけなので量産したときのことを かんがえるとやや不安です。 どう考えたらよいかアドバイスください。

  • PICのI2C通信のプログラムについて

    I2Cの同報機能を使いたいのですが、プログラムの書き方がよく分かりません。 後閑さんの電子工作の実験室も見たんですが、そこに書いてあったのは多分アセンブラのプログラムで、CCSを使っている自分には理解できませんでした。 CCSで同報機能は使えるのでしょうか?もし使えるのなら、プログラム例などをいただけると助かります。 ちなみに、使っているPICはマスターが16F873でスレーブが16F819です。 よろしくお願いいたします。

  • PICのI2C通信を行っているときにタイマ割り込みはできますか?

    私はC言語(CCS-Cコンパイラを使用)でPICのプログラミングをしています。使用しているPICは16F877Aです。 いま学習リモコンを製作中なのですが、赤外線信号の学習方法としてベタ読みを(1kByte分)行うつもりです。その際、16F877AではデータメモリがEEPROMを合わせても1kByteには足りません。ということは、赤外線信号を39kHz毎にチェックしながら、1ページ分(64byte)信号データがたまったらI2C通信で外部EEPROMにページ書き込みをしなくてはいけない、と考えています。 そこで、「I2C用組み込み関数を使用して外部EEPROM(24LC256)にページ書き込みを行っている最中に、タイマ割り込みは使用できるのか?」また、「タイマ割り込みが使える場合、正確にI2C通信が行えるのか(データが欠けたりしないか)?」を教えてほしいんです。 もちろん、18F452を使用すればデータメモリだけで1kByteを超えるので、この問題は解決できます。しかし、できれば現在手元にあるものを使って作りたいので、どなたか分かる方がみえましたら、教えてください!

  • C18(PIC18)でのシフト演算など

    PIC18で、加速度センサからの値を読み取るプログラムを作成しています。 加速度センサからのパルスを読み取るのに、 以下のようなプログラムを作成しました。 しかし、どうしてもif文がうまく動いてくれません。 (条件が「1100」、「0b1100」、「0xc」、「12」のいずれの場合も引っかかりませんでした。) その他、プログラムをいろいろ見たのですが、 原因を発見することができませんでした。 皆様の、アドバイス、ご指摘お願いします。 ------------------------------------------------------------------- (メインループ)  ↓  リセット命令(コマンド 0000)  ↓  測定開始コマンド(コマンド 1000)  ↓  READコマンド(終了のみ)(コマンド 1100)   flag1 = 0;      「1100」を送る命令の次に    PORTBbits.RB2 = 1; //CLK = 1    Delay10TCYx(10); //待ち時間    PORTBbits.RB2 = 0; //CLK = 0    Delay10TCYx(5); //待ち時間    if(PORTBbits.RB4 == 1) flag1 |= (1 << (3 - 0));    Delay10TCYx(5); //待ち時間    PORTBbits.RB2 = 1; //CLK = 1    Delay10TCYx(10); //待ち時間    PORTBbits.RB2 = 0; //CLK = 0    Delay10TCYx(5); //待ち時間    if(PORTBbits.RB4 == 1) flag1 |= (1 << (3 - 1));    Delay10TCYx(5); //待ち時間    PORTBbits.RB2 = 1; //CLK = 1    Delay10TCYx(10); //待ち時間    PORTBbits.RB2 = 0; //CLK = 0    Delay10TCYx(5); //待ち時間    if(PORTBbits.RB4 == 1) flag1 |= (1 << (3 - 2));    Delay10TCYx(5); //待ち時間    PORTBbits.RB2 = 1; //CLK = 1    Delay10TCYx(10); //待ち時間    PORTBbits.RB2 = 0; //CLK = 0    Delay10TCYx(5); //待ち時間    if(PORTBbits.RB4 == 1) flag1 |= 1;    Delay10TCYx(5); //待ち時間    return flag1;  ↓  メインループ   if(flag1 == 1100){ //「1100」では動きません    11bit分読む命令    11bit分読む命令   } ------------------------------------------------------------------- 加速度センサ(HM55B) http://www.hitachi-metals.co.jp/prod/prod01/p01_13_a.html

  • 自動車のECUの電圧をPICに取り込みたいのですが

    自動車のスロットルセンサーの電圧をECUからPIC16F873Aに取り込みたいのですが、 A/Dコンバータのポートへ直接入れるとなぜか電圧が下がって正常な値が出ません。 抵抗を入れてみたのですが、同じような結果になってしまいました。 温度センサーやGセンサーなどの電圧は正常に取り込めているのでプログラムでは無いと思っています。 ECUから電圧を取るには特別な方法が必要なのでしょうか? よろしくお願いします。 詳しい説明をしていただきありがとうございます。 電圧が下がるというのはECUより0.5~3.8Vが出ているはずなのですが、 実際測ると200mV程度しか出ていません。(直接GNDに落とすとちゃんと出ています) 本日、別のポートにつないでみたところ問題なく動作しました。 ECU --- 10KΩ --- PICとつなぎました。 AN0のポートは問題なく動作してAN1のポートでは動作しないので、AN1のポートが開いていないようです。 プログラムの問題のようなのでもう少し調べてみます。 プログラムに問題は無いと言っておきながら、プログラムが間違っているという 結果で大変申し訳ございません。

  • PIC18F15Q40のI2Cスレーブ動作について

    現在、PIC18F15Q40をMicrochip MPLAB X v5.50とMCC v5.0.3で開発しています。 MCCの自動生成コードによってI2Cスレーブ動作(割り込み駆動)をさせ、 マスタからREAD要求 -> 固定長データを送り返すというようなプログラムを書きたいのですが、 データを送信し終わった後に割り込み処理から復帰せず、WDTによるリセットが掛かってしまいます。 以下、割り込み関数内の処理です。単純にデータカウンタをインクリメントし、それに応じたデータをI2C1_Writeしているだけになります。 void I2C_WriteInterrupt(void) { volatile static uint8_t tx_buf; switch(I2C_TxCounter) { case REV: tx_buf = Revision; break; case STAT: tx_buf = Status; break; case VOL_MSB: tx_buf = (uint8_t)((ADC_Result >> 8) & 0x00FF); break; case VOL_LSB: tx_buf = (uint8_t)(ADC_Result & 0x00FF); break; case CYL_MSB: tx_buf = (uint8_t)((CycleCount >> 8) & 0x00FF); break; case CYL_LSB: tx_buf = (uint8_t)(CycleCount & 0x00FF); break; default: tx_buf = 0xFF; } I2C1_Write(tx_buf); // カウンタ操作とタイマ再開 if(I2C_TxCounter < CYL_LSB) I2C_TxCounter++; } 以前PIC16F18877で同様の処理を行わせた際には特に問題は発生しなかったのですが…… MCCの設定はスレーブアドレスとクロックストレッチ有効、Interrupt Driven有効以外に変更していません。 どなたか解決策お持ちの方はいらっしゃいますでしょうか。