Make: AVR Programming pt.01

 買ってから優に一年間放置していた“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をいちいち手で接続したり外したりするのがめんどうなので使う、とのこと。

 正直肉眼で見ても全然わからなかったので写真に撮る。

f:id:squeuei:20160815001430j:plain

 Analog Discovery2のロジアナで見るとこんな感じ。ありがとうAD2。

f:id:squeuei:20160815001520j:plain

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でUART、シリアル通信

Raspberry PIのGPIO上シリアルとArduinoの通信 - Qiita

RPi2 Model B IO Pins – Raspberry Pi Projects

 意外なところで意外なものが役に立つものだなあと、感心することしきりである。