• 締切済み

PIC I2C について

8ビットのデータを送り、そのままスレーブのLEDに反映させるプログラムを組んでいます。 マスターからはリピートして何度もデータを送ります。 このとき、なぜか一瞬アドレスのビットデータをLEDに反映させてから本来のデータを表示します。 つまり、アドレスとデータを交互にLEDに表示する状況です。 たとえば、アドレスが 0b1111111 データが 0b00000000 だとします。 本来LEDは消灯状態にならなくてはいけないのですが、なぜか一瞬アドレスデータの内容で光ります 原因がお分かりの方はいらっしゃいますか? 使用PIC PIC16F873A //master #use i2c(MASTER, SDA=PIN_C4, SCL=PIN_C3, SLOW, RESTART_WDT, FORCE_HW) output_float(PIN_C3); output_float(PIN_C4); while (1) { i2c_start(); i2c_write(AddData << 1); i2c_write(sBitData); i2c_stop(); delay_ms(50); } //slave #use i2c(SLAVE, SDA=PIN_C4, SCL=PIN_C3, ADDRESS=0x00, SLOW, RESTART_WDT, FORCE_HW) output_float(PIN_C3); output_float(PIN_C4); while (1) { if (i2c_poll()) { indata = i2c_read(); output_b(indata); } }

みんなの回答

  • inara1
  • ベストアンサー率78% (652/834)
回答No.3

zero-spicaさんは締め切るのが早すぎます。 「オペアンプ通過後の波形のゆがみについて」の回答です。 > NJM4580DD もしくは LM386N が利用でき LM386はオペアンプでなくパワーアンプですが、LM358Nの間違いでしょうか。 >波の一番下は 2V 程度に見えます。上はおそらく 5V 程度です。 その電圧だと反転現象は起きないはずですが・・・ NJM4580を5Vの単一電源で使ったとき、入力電圧範囲は +1.6V~+3.4V なので、振幅が1.8Vpp未満信号しか扱えません。LM358の場合、入力電圧範囲は 0V~+3.5V なので、振幅が3.5Vppまでの信号を入力できます。入力信号が 2V~5Vの範囲で振れるのなら、NJM4580はダメです。LM358を使うべきです。 添付回路では、入力信号に重畳されたDC電圧がコンデンサC1でカットされます。DC成分がカットされた入力信号には1.667VのDC電圧が重畳されます。1.667Vの電圧というのは、抵抗R1とR2を使って電源電圧(5V)を1/3倍して作ったものです。1.667Vを中心にした信号に変換すると、LM385の入力電圧範囲を有効に使えるようになります(入力信号が3.333Vppの信号のとき、LM358の入力電圧は0V~3.333V)。その信号をLM358のバッファで1倍し、バッファの出力信号はコンデンサC2で再びDC成分がカットされ、AC信号だけが出力されます。途中でいじっているのはDC成分だけで、振幅は入出力とも同じです。入力信号にDC成分が重畳していても構いませんが、振幅は最大3.3Vpp程度が限度です。この回路の周波数帯域は1Hz~1MHzです。

  • inara1
  • ベストアンサー率78% (652/834)
回答No.2

「オペアンプからプラスマイナスで出力変換」でお答えしようとしたら既に締め切られていました。質問が違いますがここでお答えします。 添付図のような回路でできます。この回路はDC信号も扱えるので入力信号がどんな波形でも、±5Vを0Vから12Vの信号に変換できます。 +側電源を12Vとしたとき、+12Vの出力電圧を出すために、出力電圧が電源電圧いっぱいに振れるCMOSオペアンプのLMC662 [1] を使いました。LMC662の最大電源電圧(±電源電圧の差)は+16Vなので、-側の電源電圧は-3Vとしています(-側を-12Vとすると壊れる)。 入力信号の±5V を R1 と R2 で3/5倍し、±3Vに変換してLMC662に加えています。そうするとLMC662の入力電圧は電源電圧範囲内(-3V~+12V)に収まります。この±3Vの入力信号を2倍し、オフセット電圧を加えることで、±6Vにオフセット電圧が加わった信号が出力されます。オフセット電圧は可変抵抗VRを変えることで、0Vから12Vの範囲で変えることができます。図の回路では可変抵抗の位置が半分程度のところで6Vのオフセット(出力電圧が0V~12V)になるようになっています。 LMC663の-側の電源電圧はダイオード(1S4148) [2] で作っていますが、ダイオードの順方向電圧(Vf)のバラツキのために、LMC663の-側の電源電圧が-3Vより高くなる(-2.9Vなど)ことがあるかもしれません。そのときはダイオードをもう1本追加して5個直列としてください。LMC662の最大電源電圧は16Vなので、+側電源電圧(12V)と-側電源電圧(-3V)の差が16Vを越えないように注意してください。 [1] LMC662(2個150円) http://akizukidenshi.com/catalog/g/gI-00067/ [2] 1N4148(50本100円) http://akizukidenshi.com/catalog/g/gI-00941/

  • Yorisin
  • ベストアンサー率54% (364/663)
回答No.1

I2CのデータバスにLEDを直結して(もしくはトランジスタか何かを用いて)、データバスの状態に応じてLEDを点灯・消灯させようとしていますか? I2CのSDAはInput/Output共用のため、アドレス:11111111からデータ:000000000をリードしたらSDAから直接制御している場合、 バスに流れるデータとしては111111110000000000 となりますので、LEDは点灯×9回、消灯×9となります。 (ACKを含む) 時間は非常に短いでしょうから、一瞬の点灯と消灯のように見えるのではないでしょうか?

zero-spica
質問者

補足

I2C の通信内容を視覚的に表示する意図では LED は接続してません I2C のネットワークバスはあくまで I2C 通信のためだけに存在しています LED は RB の足にひとつずつ、計8個付いています たとえば 01001001 というデータを送ると ●○●●○●●○ という風に発光します。 ACK や スタートコンディションなどを省いた例ですが、アドレスが 0b0111001 データが 0b00001111 だとします I2C の通信フォーマットでは以下のように送信されています  01110010 00001111 これを受信した場合、本来以下のように LED が発光します  ●●●●○○○○ ですが、実際には以下のようになります  ●○○○●●○○ (一瞬発光)      ↓  ●●●●○○○○ 書き方が悪かったようで、申し訳ありません

関連するQ&A