Archive for the 'AVR' Category

AVR割り込みメモ

Posted by ゆのじ on 11月 4th, 2009

またはまっていた。AVRのPCINT割り込みを使う場合のはまりどころ。特に頭が疲れているとやらかしかねない。

割り込みレジスタ関連:

PCMSKnにビットを立てただけでは駄目。PCICRにPCIEnを指定しよう。

割り込み内エッジ処理関連:

PCINT割り込みはINT割り込みと違ってエッジの指定が出来ないので自分でやる必要がある。ここでぼーっとしてると

ISR(PCINT3_vect)
{
	if(bit_is_set(PORTD, PD4)) {
		// rise
	} else {
		// fall
	}
}

と書いてしまいがち。正しくはこう。

ISR(PCINT3_vect)
{
	if(bit_is_set(PIND, PIND4)) {
		// rise
	} else {
		// fall
	}
}

PORTnだと生の値が拾えないので忘れずに。

 

なんというか、昔もこうだったっけ、ということだらけ。十分なリハビリが必要そうで泣ける。

AVRが予想せずリセットされる時

Posted by ゆのじ on 11月 2nd, 2009

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に対応ということのよう。もう少し調べてまとめたい。

Arduino事始め

Posted by ゆのじ on 3月 11th, 2009

IMG_0041

友人のひがさんとマイコントークをしていたら、Arduinoを持っているけれど使ってないから貸してあげようか、とのありがたいお言葉。是非是非お願いしますということで受け取ったのが先日のこと。お借りしたのはArduino Diecimila、つまりちょっと古い型のArduinoになる。

Arduinoとは、ATMEGAになってから搭載されたブートローダ+自己書き換え機能をフルに使って、シリアル経由でプログラムをダウンロードする仕組みを持ったマイコンボードで、シリアル部分にFTDIのUSB-Serialブリッジを使うことで給電を行いつつ扱いやすいケーブルでPCに繋ぐことを可能にしている。マイコンに直接ファームウェアを書くのが当たり前だったATMEGA以前のAVR時代からするとかなり常識が違うので最初とまどってしまったが、自己書き換えが出来るならそりゃー便利に使えるよなと納得。

Arduinoの偉いのは、余計なことを一切考えなくてもいい(つまり初心者にやさしい)統合開発環境を用意しているところ。表面はJavaの類で実装してあって、中身はgcc-avrでうまく自動化されている。ユーザがやることは、動かすコードを書いて「Upload to I/O Board」ボタンをクリックするだけ。コードをコンパイルするとかリンクするとか、繋がってる手段によってライタを用意するとか、そういうことを考える必要は一切無い。

そして、かなり潤沢なライブラリのおかげで、とにかく一から書くことに比べると圧倒的にコード行数が少なくて済むのが良いところ。もっともブートローダに加えて便利な(=冗長な)ライブラリで実装されているわけで、出来ることは自然少なくなるが、プロトタイプを可能な限りすぐ作りたいという目的であればかなり良いソリューションだろうと思う。

あえて駄目出しするならば、直接デバッグできない、ということがあるだろう。シリアルは書き込みに使う線をそのままデバグに使える(統合開発環境から1クリックでモニタできる)から、いわゆるprintfデバッグ的なことをシリアル経由で行えばいいが、特定箇所にブレークポイントを仕掛けてデバッグ、といったことは出来ない。ある程度以上大きい(まじめにアセンブラメインで書いてFlashがかなり埋まるとかいう)レベルのプロジェクトに適用することはオススメできない。

とはいえ、ちょっと朝飯前的なプロジェクトにはもの凄い便利であることがよくわかった。通常、1つ1つに書き込み器が付いている必要はあまりないので、USB-Serialブリッジ部分と本体部分を分離したものを作ってやると半プロダクトにも便利に使えそうに思う。色々つかってみたらまたレポートしたい。