WinAVRの環境(avr-gccなら同じだと思うが)で複雑な割り込みがかかるようなプログラムを書いているとき、原因不明のリセットがかかる場合、可能性として考えられるのは1)ウォッチドッグ、2)電圧低下のBORリセット、3)割り込みベクタが変、が考えられる。このうち1と2は割とデバグしやすいのだが3がどう対応すればいいのかと思って調べてみたところ、こう書けばいいということがわかった。
ISR(BADISR_vect) { cli(); // これ以上割り込ませない // このあたりでデバグメッセージ for(;;); // ここで止めておく }
とりあえずこの中でデバッグメッセージを書いて止めてしまえば、何か起きていることまではわかる。その先はさらにデバグデバグ。
なんでこういうことになったかというと、送信可能状態になったときに飛んでくる割り込み(USART1_UDRE_vect)を書かないといけないところに、ぼんやりしていて送信完了時に飛んでくる割り込み(USART1_TX_vect)を書いてしまっていたからだった。そりゃBADISRにもなる。
同じはまり方をしないためにメモ。
追記:何も考えずにTXCIEnを有効にする場合、USARTn_UDRE_vectだけだとBADISRになる。USARTn_TX_vectも書いておくこと。
追追記:嘘書いた。TXCIEnはUSARTn_TX_vect、UDRIEnがUSARTn_UDRE_vectに対応ということのよう。もう少し調べてまとめたい。