買ってから優に一年間放置していた“Make: AVR Programming”を夏休みに読んでしまおう計画。
http://squeuei.hatenablog.com/entry/2015/08/11/212000squeuei.hatenablog.com
Chapter 1
AVRISPmk2を入手しておいたのだけど、こいつは自分で+5Vを供給してくれないので、ACアダプタでブレッドボードに5Vを給電するとかしないといけない。かつ、私の環境ではavrdudeでうまくmake flash
してくれないので、Arduino ISPを活用することにする。ISP買った意味がない。
システムやユーザの環境変数を通すのが嫌だったので、PATHを通すバッチファイルを書いて、そこから操作することにする。
PATH=%PATH%;foo\bar\avr8-gnu-toolchain\bin;hoge\fuga\avrdude_utilities;
cd mado\homu\AVR-Programming
といった内容の.batファイル(ここでは安易にavr.batとした)を作成した後、エクスプローラから
C:\Windows\System32\cmd.exe /k "yui\azu\avr"
というショートカットを作る。フォルダやファイルの場所は各自修正のこと。ショートカットがリンクする先の最後にあるavr
は.batファイルのファイル名にする。拡張子を付けないのが個人的にポイントだった。
このショートカットを開けば、コンパイラとユーティリティへのPATHが通ったコマンドプロンプトが開く。
サンプルコードを書き込む際には、Makefileで
PROGRAMMER_TYPE = avrisp
PROGRAMMER_ARGS = -b 19200 -P com3
などとして、PATHが通ったコマンドプロンプトからmake flash
する。
Chapter 2
RAMに変数をつくることと、ピンへの書き込みやピンの入出力設定は同じインタフェース(代入)で行われるけど、これは実際に同じ事をレジスタに対して行っているから。そのレジスタの情報はio.h
に格納されてる。
重要なハードウェアレジスタ
DDRx : data-direction registers port x
インプットかアウトプットかを決める。
PORTx port x data registers
- アウトプットに設定したとき:high or lowを設定
- インプットに設定したとき:pull-upするかどうか(chapter 6参照)を設定
PINx port x input pins address
- インプットに設定したピンのhigh or lowを読んだ結果が格納される。
デフォルトで全部のピンはインプット。
DDRの設定をせずにPORTを設定してしまうパティーンが多いので気をつけよう。
Chapter 3
MOSFETはLEDのGNDとプログラマのGNDをいちいち手で接続したり外したりするのがめんどうなので使う、とのこと。
正直肉眼で見ても全然わからなかったので写真に撮る。
Analog Discovery2のロジアナで見るとこんな感じ。ありがとうAD2。
Chapter 4
サイロン (Cylon) は、SFテレビドラマ『宇宙空母ギャラクティカ』に登場する架空のキャラクター。
サイロン - Wikipedia
さすがにわからん。
プリアンプルの#defineは大文字をアンダースコアで区切って書くのが慣例。
- ビットの設定:OR
- ビットの消去:AND
- ビットの反転:XOR
Chapter 5
UARTのRT/TXの関係はSPIとは違って送り手と受け手で逆になるから気をつけよう。
以下はこの本の著者が用意した便利関数の数々。
initUSARTは、ボードレートの設定、2Xモードの設定、RXTXの有効化、データ長とストップビットの設定を行う。
void initUSART(void) {
UBRR0H = UBRRH_VALUE;
UBRR0L = UBRRL_VALUE;
#if USE_2X
UCSR0A |= (1 << U2X0);
#else
UCSR0A &= ~(1 << U2X0);
#endif
UCSR0B = (1 << TXEN0) | (1 << RXEN0);
UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
}
送信時はUCSR0A(USART Control and Status Register 0 A)レジスタのUDRE0(USART Data Register Empty)が1になるまで待って、それからUDR0(USART Data Register)に送信したいデータを格納する。
void transmitByte(uint8_t data) {
loop_until_bit_is_set(UCSR0A, UDRE0);
UDR0 = data;
}
受信時はUCSR0AレジスタのRCX0(receive-complete bit)が1になるまで待って、それからUDR0の値を読みに行く。
uint8_t receiveByte(void) {
loop_until_bit_is_set(UCSR0A, RXC0);
return UDR0;
}
私が持っていたUSB-RS232C変換ケーブルだと、PCで入力した文字と送信された文字が食い違う現象が発生した。
これもAnalog Discovery 2のロジアナが無ければ、何が起きているのかわからないままだった。ありがとうAD2(2回目)。
そういえばRaspberry Pi2Bを買ったまま死蔵していたなという事を思い出したので、下記サイトを参考に、シリアルコンソールによるログインを無効に設定してから
- RPi2B Pin 5 <-> AVR GND
- RPi2B Pin 7 <-> AVR Pin 2
- RPi2B Pin 9 <-> AVR Pin 3
で接続し、cu -s 9600 -l /dev/ttyAMA0
すると、ちゃんと動作した。
Raspberry PIのGPIO上シリアルとArduinoの通信 - Qiita
RPi2 Model B IO Pins – Raspberry Pi Projects
意外なところで意外なものが役に立つものだなあと、感心することしきりである。