• 締切済み

ATtiny2313でsleep_mode()関数でパワーダウンモード機能はステートマシンでは使えない?

C言語プログラミングでアトメル社製ATtiny2313マイコンでプログラミングをやってます。 ATtiny2313のパワーダウンモード機能を使って割り込み入力端子、INT0、INT1端子を使って、入力の組み合わせでLEDを数パターンの点滅させるステートを作り、入力がない場合は、パワーダウンモードのステートで消費電流を節約するようにし、次の割り込みを待つようなプログラムを作っています。 ただ、パワーダウンモードのステートに入って、きっかけである”sleep_mode();”関数を使うと、割り込み入力でウェイクアップさせようとしてもLEDの点灯ステートに行っていないようで、完全にマイコンが動作停止してしまいます。 この時の状態をyoutubeに動画投稿しましたので参照をお願いします。 現在このプログラムは https://sourceforge.jp/projects/midicv/svn/view/trunk/LED_FLASHER/?root=midicv このサイトで”Download GNU tarball”をクリックでダウンロードできるようになっております。 この問題の原因がわかるかたいらっしゃいましたら是非ご教授よろしくお願い致します。 ちなみに、このプログラムファイル”LED_FLASHER.c”の224行目のsleep_mode();関数をコメントアウトすると、このステートマシンはちゃんと動作できていることを確認しております。こちらも動画で掲載しております。

みんなの回答

  • goosyu
  • ベストアンサー率58% (36/62)
回答No.1

・原因はsleep_mode()関数がコールされる直前に割り込みが発生する為です。  sleep_mode()関数がコールされる前にGIMSKの操作により割り込み許可にしていますが,その直後にINT0/INT1の割り込みが発生して,GIMSKによる割り込み禁止の状態でsleepになる為,割り込みが発生せずsleepしたままになります。(複合要因の可能性もありますが1つの原因です。)  この問題の改善案・・・(すいません実機が無いので実際に動作するか未確認です。) ■修正点その1  case MODESW_LOWPOWER ://ここからINT0/1が発生しても割り込み処理内で処理を行わない。   GIMSK |= (1<<INT0);   GIMSK |= (1<<INT1);   sleep_mode();   MODESWState = MODESW_IDLE;//ここからINT0/1が発生したら既存どおり   break; ■修正点その2  SIGNAL(SIG_INTERRUPT0)  {   if (MODESWState != MODESW_LOWPOWER) { // LOWPOWER以外は既存処理どおり。    GIMSK &= ~(1<<INT0);    GIMSK &= ~(1<<INT1);    MODESWState = MODESW_INPUT_CHK;   }  }  SIGNAL(SIG_INTERRUPT1)  {   if (MODESWState != MODESW_LOWPOWER) {    GIMSK &= ~(1<<INT0);    GIMSK &= ~(1<<INT1);    MODESWState = MODESW_INPUT_CHK;   }  }

関連するQ&A

専門家に質問してみよう