USBasp 2.0 + avrdudeでATmega328PにArduinoプログラムを書き込む

Pocket

Arduinoで開発したプログラムを素のATmega328pに書き込んで自作回路で動かしたい……という場合にどうするかについてのメモ。外部クリスタルなども含めてArduinoの青いボードと同じ構成にするならArduino IDE上で完結することも可能だが、実際にはヒューズビットなどを若干変える必要があったりする。そんな場合は

  • とりあえずArduino IDEから書き込んでみて
  • 書き込み時に実際に実行しているコマンドを把握して
  • avrdudeのオプションを追加したものをコマンドラインから実行

という流れで大体うまくいく。

Arduino自体を書き込み装置として使うという手もあるが、よりお手軽でコンパクトなUSBasp 2.0を使ってみた。
まずUSBasp V2.0とICを接続。たくさん書きたい場合にはゼロプレッシャーソケットをつけておくと便利。

配線はこんな感じ。GND / VCC / RST / MISO / MOSI / SCLKの6本を繋げばOK。

USBasp ATmega
VCC 2 7
GND 10 8
RST 5 1
MOSI 1 17
MISO 9 18
SCK 7 19

Windowsの場合はドライバを入れる必要がある。ドライバの入れ方についてはUSBaspの公式サイト参照。

自作基板にArduinoボードと同じような外部クリスタルを乗っけて……といった構成でなければ、Arduino IDEで書き込んでいるのと全く同じことをやればそのまま動くというわけではない。内部クロックを使いたいなどの事情がある場合は、ヒューズビット (fuse bits) を指定する必要がある。

詳しくはATmegaのデータシートの中を “fuse” で検索。たとえば、クロックの選択はFuse Low Byteの3〜0ビットで、内部クロックを使用したい場合はここを0010にする。

ATmega328Pの8MHzの内部クロックを使う場合、Arduino IDEで以下のような設定でコンパイルする。

  • Board : Arduino Pro or Pro Mini
  • Processor : Atmega328P (3.3V, 8MHz)
  • Port : 選ばなくていい
  • Programmer : USBasp

Arduino IDEのPreferencesを開いて、”Show verbose output during:” のところの “upload” のところにチェックを入れる。すると、実際にどんなコマンドを叩いているのかがわかる。
(ちなみに、”compilation” のところにチェックを入れると、コンパイル時に何をやっているのかがわかる。ビルドがうまくいかない場合はこの出力を見るとたいてい解決する。)

普段のUploadボタンを押すのではなく、”Upload using programmer” を実行すると、書き込みが始まる。さて、実際に実行してみる。サンプルスケッチのBlinkを書いてみたらこんなふうになった。

/Users/maripo/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino14/bin/avrdude -C/Users/maripo/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino14/etc/avrdude.conf -v -patmega328p -cusbasp -Pusb -Uflash:w:/var/folders/2p/s0l5t1z16gd3h1m5j5jlzp500000gq/T/arduino_build_619280/Blink.ino.hex:i

これがArduino IDEがウラで実行しているコマンドである。
ここで実行しているavrdudeというのは、AVRマイコンに書き込むための外部機器のお世話などをやってくれるソフトウェアである。オプションとして、使用するツール (今回はUSBasp)、書き込みたいファイル等などを指定することになるが、それに追加してfuseなどを指定することができる。

たとえば、次のような設定で書き込みたい場合

  • Extended = 0xFD
  • High = 0xDA
  • Low = 0xE2

-Uオプションでfuse値を指定することができる。以下のようなオプションをくっつける。

-Uefuse:w:0xFD:m -Uhfuse:w:0xDA:m -Ulfuse:w:0xE2:m

オプションの中身をもうちょっと詳しく説明すると、たとえば “-Uefuse:w:0xFD:m” の場合は

  • efuse : 値の種別 (Extended=efuse, High=hfuse, Low=lfuse)
  • w : 読み/書き (書き込み=w)
  • 0xFD : 書き込む値
  • m : 値のフォーマット(値を16進数でそのまま指定するならm)

コマンド全体はこんな感じになる。最後の部分が新たに足した部分。

/Users/maripo/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino14/bin/avrdude -C/Users/maripo/Library/Arduino15/packages/arduino/tools/avrdude/6.3.0-arduino14/etc/avrdude.conf -v -patmega328p -cusbasp -Pusb -Uflash:w:/var/folders/2p/s0l5t1z16gd3h1m5j5jlzp500000gq/T/arduino_build_619280/Blink.ino.hex:i \
-Uefuse:w:0xFD:m -Uhfuse:w:0xDA:m -Ulfuse:w:0xE2:m

これをコマンドラインから実行すると書き込める。同じ要領で、ブートローダもオプション付きで書き込める。

Pocket