本文へ移動
サポートシェアリングソリューション
OKWAVE Plus

このQ&Aは役に立ちましたか?

締切済み
※ ChatGPTを利用し、要約された質問です(原文:PIC18F15Q40のI2Cスレーブ動作について)

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

2023/10/21 05:39

このQ&Aのポイント
  • PIC18F15Q40を使用したI2Cスレーブ動作において、割り込み処理から復帰せずにWDTによるリセットが発生してしまう問題が発生しています。
  • 以前PIC16F18877で同様の処理を行っていた際には問題が発生しなかったため、MCCの設定に問題がある可能性があります。
  • 現在のMCCの設定は、スレーブアドレスとクロックストレッチ有効、Interrupt Driven有効のみに設定されています。
※ 以下は、質問の原文です

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

2023/05/23 11:48

現在、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有効以外に変更していません。
どなたか解決策お持ちの方はいらっしゃいますでしょうか。

回答 (2件中 1~2件目)

2023/05/23 12:27
回答No.2

>やはり割り込み処理内でハングアップしている気がしてなりません……
正直私もそれ疑ってます。
関数の戻りは、retですが、
割り込み関数からの戻りは、iretなので、
しかし、C言語だと、インタラプトリターンとの区別ができるのか?
ってな、気持ちもありまして。
後は、多重割り込み(割り込み中にさらに次のが入ってくる)
通常は、起こらない物の、この関数が普通の関数に見えるので、
誰がDI/EI制御をしてるのかが、全く分からないので、
正直、割り込み制御を私ならCに任せたくないな~
ってな、印象はありますね。
あと、PICってCに向いてない気もしなくもないのでね~
(これはこの件に無関係ですが)

あまりお力になれずすいません。

とりあえず、インタラプト入り口で何かを+1
出る時-1して、暴走した後も、メモリって保持されてるので、
そこをダンプしてみると、ネスト(再入=割り込みの多段発生)
などをチェックできるので、そこからかな~。
割り込みってデバッグしにくいですからね~。

補足

2023/05/23 13:56

ありがとうございます。
MCCの自動生成コードが妙に複雑なのと実はウラでタイマ割り込みも動いてたりするので、一旦WDTを切って色々なところに変数仕込んで根気よくチェックしてみます。

質問者

このQ&Aは役に立ちましたか?

2023/05/23 11:56
回答No.1

私がPIC使ってた頃は、フルアセンブラだったので。
C表記では書いたことはなかったのですが。

>固定長データを送り返す
これが、
>WDTによるリセットが掛かってしまいます。

ウォッチドッグタイマーに食われるのであれば、
ウォッチドッグ周期を広げるか、
時間がかかりそうな処理前にクリアしてみるか。
そもそも、ウォッチドッグを止めてしまうか?
(インタラプト中だけ、割り込みRETURN前に
 WDTクリアが一番よさげ)
を私なら選択しそうだな~と感じました。
(なんせ、フルアセ時代の人なので^^今風の書き方は
 あまりわかってないので、あくまでチップ単位での
 テクニックとして)

補足

2023/05/23 12:17

ご回答ありがとうございます。
再度WDT設定見直してみたのですが、約2秒で設定されていたのでやはり割り込み処理内でハングアップしている気がしてなりません……

自動生成コードは以前PIC16で試したときとほぼ一緒の動きをしているようなのですが、やはりMSSPモジュールとI2Cモジュールで勝手が違いすぎて困惑中です

レジスタ直接操作で作ってしまえば楽だと思うのですがどうにもMCCを捨てきれず……

質問者

お礼をおくりました

さらに、この回答をベストアンサーに選びますか?

ベストアンサーを選ぶと質問が締切られます。
なおベストアンサーを選びなおすことはできません。