2018年9月30日日曜日

Atmega328pにISP経由でPlatformIOからプログラムを書き込む方法


背景

Atmega328pとは、Atmel社が製造しているAVRと呼ばれる種類のマイコンの1つです。
Arduino UNOなどに使われています。

ISP(In-System Programming)とは、プロセッサが製品に実装された状態でもプログラムを書き込める仕組みのことです。
Arduinoとして売られているAtmega328pはUSBシリアル経由でプログラムを書き込むことが多いと思いますが、AVRマイコンはISPをサポートしているため、それ用の(2x3のピンとして出ていることが多い)端子からでもプログラムを書き込めます。

ISPをいつ使うかと言うと、Arduino互換機版を自分で作った時に使います。
購入直後のAVRマイコンはArduinoのファームウェアが書かれていない(Arduinoとして動いていない)ため、プログラムを書き込むためにISP形式を利用します。
(他の形式での書き込み方法もあるのかもしれませんが、自分が知っているのは今の所ISP形式だけです。)

PlatformIOとは、 組み込みやIoT関係の機器開発ができる開発環境の1つです。
Arduinoの開発環境としてはArduino IDEがありますが、PlatformIOの方が、コマンドで操作できること、開発対象のマイコンに関連するプログラムを自動的にダウンロードしてくれることなど、個人的に使いやすく感じているため、この記事ではPlatformIOを使った方法を共有します。

ISP経由でAtmega328pにプログラムを書き込むことに成功したため、備忘録を兼ねて、書き込み方法を共有します。

使ったもの

PlatformIOをインストールしたPC

PlatformIOのインストールは、本家の解説ページ自分が過去に書いた記事(PlatformIOを使うと、Arduinoのプロジェクトのライブラリの管理が楽そうだった話)が参考になると思います。

この記事は下記の環境で動作を確認しました。
OS: Ubuntu18.04
PlatformIO: version 3.6.0

書き込み用のArduinoもしくはISPライター

この記事ではArduino UNOをISPのライターとして利用しました。

スイッチサイエンスで売っているArduino ISPやAliexpressで売っているISPライターでも書き込めると思います。

atmega328pが載ったArduino

この記事ではArduino NANOを利用しました。
Arduino UNOやAtmega328pに水晶振動子を付けた独自の回路でも、この記事の内容でプログラムを書き込めると思います。

ブレッドボード、ジャンパワイヤ、LED、抵抗

ライターとAtmega328pを接続したり、Atmega328pの動作確認としてLEDを接続するのに利用しました。

回路の準備

このように接続します。
役割 Atmega328pのピン 接続する装置
LED control D2 LED + Registor
MOSI D11 D11 of Arduino as ISP
MISO D12 D12 of Arduino as ISP
SCK D13 D13 of Arduino as ISP
Reset signal Reset D10 of Arduino as ISP
5V 5V 5V of Arduino as ISP
GND GND GND of LED and Arduino as ISP

接続するとこのようになりました。


プログラムの準備

PlatformIOでAtmega328p向けのプロジェクトを作ります。
この記事では16MHzで駆動するAtmega328p向けにpio-isp-blinkというプロジェクトを作ります。
(Arduino UNOやNANOは16MHzで動作しているので、Arduinoに載っているAtmega328pを利用する場合は16MHz向けにします。)
mkdir pio-isp-blink
cd pio-isp-blink
pio init -b 328p16m

プロジェクトができたら、LEDを点滅させるプログラムをsrc/main.cppとして作成します。
pio-isp-blink/src/main.cpp
#include <Arduino.h>

#define LED_PIN 2

void setup() {
  pinMode(LED_PIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_PIN, HIGH);
  delay(500);
  digitalWrite(LED_PIN, LOW);
  delay(1500);
}

pio-isp-blinkで下記のコマンドを実行すると、コンパイルできます。
コンパイルが成功することを確認してください。
pio run

書き込み装置の準備

Arduinoを使う場合

Arduino UNOを利用する場合、PCにUNOを接続した状態で下記のコマンドを実行し、Arduino as ISPプログラムをUNOに書き込みます。
mkdir arduino-isp
cd arduino-isp
pio init -b uno
cd src
wget https://raw.githubusercontent.com/arduino/Arduino/master/build/shared/examples/11.ArduinoISP/ArduinoISP/ArduinoISP.ino
cd ../
pio run -t upload
cd ../
rm -r arduino-isp

UNO以外を利用する場合は、「pip init -b」に渡す「uno」を、利用するボードの情報に変更してください。
ボード情報は下記のコマンドを実行するか、PlatformIOのボード一覧検索で確認できます。
pio boards

ISPライタとして使うArduinoにプログラムを書き込めたら、先ほど作ったプロジェクトのplatform.iniに書き込み装置の設定を追加します。
この記述はPlatformIOで利用できるatmel avrのプログラマーのArduino as ISPの設定です。
pio-isp-blink/platformio.ini
upload_protocol = custom
upload_flags =
-C
; use "tool-avrdude-megaavr" for the atmelmegaavr platform
$PROJECT_PACKAGES_DIR/tool-avrdude/avrdude.conf
-p
$BOARD_MCU
-P
$UPLOAD_PORT
-b
$UPLOAD_SPEED
-c
stk500v1
upload_port = /dev/ttyACM0 upload_speed = 19200
upload_command = avrdude $UPLOAD_FLAGS -U flash:w:$SOURCE:i

upload_portには、使っているPCが認識しているArduinoのポート名を記述してください。
自分のPCにArduinoUNOを接続したら「/dev/ttyACM0」と認識されたので、上記の例はそのような記述になっています。

ISPライターを使う場合

例として紹介したUSBtinyISPを利用する場合は、プロジェクトのplatformio.iniに下記の記述を追加します。
pio-isp-blink/platformio.ini
upload_protocol = custom
upload_flags =
-C
; use "tool-avrdude-megaavr" for the atmelmegaavr platform
$PROJECT_PACKAGES_DIR/tool-avrdude/avrdude.conf
-p
$BOARD_MCU
-c
usbtiny
upload_command = avrdude $UPLOAD_FLAGS -U flash:w:$SOURCE:i

USBtinyISP以外のライターを使う場合は、PlatformIOで利用できるatmel avrのプログラマーで紹介されているものの中から、該当する記述を追加してください。

プログラムを書き込み・動作確認

書き込み用のArduinoもしくはISPライターをPCに接続します。

下記のコマンドを入力するとプログラムを書き込めます。
(PlatformIOの4系までは「-t program」でしたが、 5.0から他の書き込み方法と同様に「-t upload」で書き込めるようになりました。)
pio run -t uplooad

書き込みに成功すると、準備したプログラム通りにLEDが点滅すると思います。


まとめ

ISP経由でPlatformIOからAtmega328pにプログラムを書き込めました。

何かの参考になれば嬉しいです。

変更履歴

2020.11.01
PlatformIOの5.0からISP経由でプログラムを書き込む際の設定と書き込みコマンドが変わっていたので、新しい形式に変更しました。

0 件のコメント :