はじめに
旧Atmel社(現在はPICを擁するMicrochip社に買収)のアーキテクチャ、AVRの中でもATmega328系列はArduino Unoで採用されているなど特によく使われるマイコンと言えます。
DigikeyではATmega328PBは無印やP付きよりも安価に販売されており(2018年5月16日現在で32TQFPが161円程度)入手性が高いのですが、mega328Pとmega328PBは若干機能が異なる型番であり、当然Signature(後述)も異なるため、avrdude
においては互換性がありません。
さらにいうとHomebrewでインストールされる最新版のCrossPack for AVR(2013-12-16)ではデバイス自体が定義されておらず、-F
オプションで識別子を無視することでしか書き込みできません。
今回は安心してavrdude
でmega328PBを扱える方法をまとめました。
mega8系のマイコンまとめ
ATmegaシリーズの32ピンの型番(mega8,48,88,168,328)はフラッシュ容量や一部機能などが異なりますが、基本的にはピン配置などの互換性があります。
mega328PBはmega328Pの機能に加えてMicrochipのQTouch(静電容量タッチセンサ)機能の他一部I/Oの増強が行われています。
詳細についてはこのドキュメント にまとめられれています。
型番 | Signature | PORTE | QTouchコントローラ | 消費電流@1MHz,1.8V,25°C |
---|---|---|---|---|
ATmega328P | 1E 95 0F | - | - | 0.2 mA |
ATmega328PB | 1E 95 16 | ✓ | ✓ | 0.24 mA |
mega328Pのレジスタアドレス等はそのままmega328PBに引き継がれているため、ファームウェア自体については完全に後方互換性があります(コンパイル済みのプログラムをそのまま書き込める)。
ただし、mega328Pで電源/ADCに割り当てられていたピン(VccとGND1組とADC6,7)がPORTEに拡張されているため、mega328P用に設計した回路にmega328PBを実装する場合は、PORTEの出力設定を誤って短絡させないように注意が必要です。
avrdude
の新規デバイス追加方法
avrdude
では付属しているavrdude.conf
内で定義されているデバイスのみを使用できます。
これに以下を追記してmega328PBを追加します。
(普通にHomebrewでインストールすると/usr/local/CrossPack-AVR/etc/avrdude.conf
に配置されますが、直接編集せずに適当な場所にコピーして編集するほうが無難です)
(省略)
part parent "m328"
id = "m328p";
desc = "ATmega328P";
signature = 0x1e 0x95 0x0F;
ocdrev = 1;
;
# 以下を追加
part parent "m328"
id = "m328pb";
desc = "ATmega328PB";
signature = 0x1e 0x95 0x16;
ocdrev = 1;
;
# 以上を追加
(省略)
ocdrev
はAtmelのツール内で使用される何からしいですが、詳細は不明なのでとりあえずATmega328Pと同じ値に設定します。
オリジナルのavrdude.conf
を編集した場合はこれでatmega328pb
が使用できます。
コピーしたファイルを編集した場合は以下のように-C
オプションでパスを指定することが必要です。
$ avrdude -P usb -c your-favorite-writer -p atmega328pb -C /path/to/avrdude.conf -U flash:w:program.hex # 書き込み
おまけ: Makefile
結果的に、avrdude
ではatmega328pb
を指定して書き込みを行いますが、コンパイルは引き続きatmega328p
を指定することなります。
私は以下のようなMakefileを使用しています。
DEVICE = atmega328p
DEVICE_WR = atmega328pb
CLOCK = 8000000
MAIN = main
OBJECT = $(MAIN).o
WRITER = avrispmkii
CONFIG = avrdude.conf
COMPILE = avr-g++ -std=c++11 -Wall -Os -DF_CPU=$(CLOCK) -mmcu=$(DEVICE)
AVRDUDE = avrdude -P usb -c $(WRITER) -p $(DEVICE_WR) -C $(CONFIG)
all: $(MAIN).hex
.cpp.o:
$(COMPILE) -c $< -o $@
clean:
rm -f $(MAIN).hex $(MAIN).elf $(OBJECT)
$(MAIN).elf: $(OBJECT)
$(COMPILE) -o $(MAIN).elf $(OBJECT)
$(MAIN).hex: $(MAIN).elf
avr-objcopy -j .text -j .data -O ihex $(MAIN).elf $(MAIN).hex
avr-size --format=avr --mcu=$(DEVICE) $(MAIN).elf
flash:
$(AVRDUDE) -U flash:w:$(MAIN).hex