ATmega328Pに1 MHz版ブートローダを書き込み

Arduino Unoを書き込み装置として、ATmega328Pに1 MHz版ブートローダを書き込む。

以前、『ArduinoのWatchdog timerを使用』でArduinoの低電力稼働を試みた。ウォッチドッグタイマのリファレンスとしてはある程度まとまったものの、残念ながら思ったほどの効果は得られなかった。これは、周辺部品の存在(LEDもそれなりに消費する)に加え、動作電圧と動作周波数の高さも原因のようだ。ATmega328Pのデータシートによると、5 V、16 MHzで稼働させた場合のアイドル電流は約2.4 mAである(Fig. 34-7)。一方、3.3 V、1 MHzの場合は約0.08 mA(Fig. 34-6)と、消費電力は約1/45程度で済む。そこで、ATmega328Pに1 MHz版ブートローダを書き込む方法を調査したので、以下にまとめる。出来の悪い卒論の出だしのようである。

ブートローダの作成

8 MHzのブートローダに比べ、1 MHzのブートローダに関する情報はそれほど多くはなかった。
MakerSpace
に記載されている方法で自分でコンパイルするのが安心のようである。まず、公式の“From Arduino to a Microcontroller on a Breadboard”からリンクされているbreadboard-1-6-x.zipをダウンロードした。当方で使用したArduino IDEは本記事記載時点で最新の1.8.5であるが、問題なかった。以後、ファイルをダウンロードしたフォルダを(DOWNLOAD_HOME)、Arduino IDEインストールフォルダを(ARDUINO_HOME)とする。ダウンロードしたファイルは(ARDUINO_HOME)\hardware以下に展開した。

展開すると、(ARDUINO_HOME)\hardware\breadboard\avr\boards.txtファイルが作成されている。これを退避させた後、boards.txtで置き換えた。ヒューズビットについては、よくまとまっている“Arduino / ATmega 328P fuse settings”を参考にした。次に、(ARDUINO_HOME)\hardware\arduino\avr\bootloaders\atmega\ATmegaBOOT_168.c(ARDUINO_HOME)\hardware\breadboard\avr\bootloaders\atmega下にコピーした。また、同フォルダにMakefileを作成した(雛形は(ARDUINO_HOME)\hardware\arduino\avr\bootloaders\atmega\Makefileである)。

最後に、MSYS2環境下でコンパイルした。ここまでの過程を以下に記す。当方で作成したATmegaBOOT_168_atmega328_1MHz.hexATmegaBOOT_168_atmega328_8MHz.hexは自己責任でお使いください。

$ cd (ARDUINO_HOME)/hardware/
$ unzip (DOWNLOAD_HOME)/breadboard-1-6-x.zip
Archive:  (DOWNLOAD_HOME)/breadboard-1-6-x.zip
   creating: breadboard/
   creating: breadboard/avr/
  inflating: breadboard/avr/boards.txt
   creating: breadboard/avr/bootloaders/
   creating: breadboard/avr/bootloaders/atmega/
  inflating: breadboard/avr/bootloaders/atmega/ATmegaBOOT_168_atmega328_pro_8MHz.hex
   creating: breadboard/avr/variants/
$ mv breadboard/avr/boards.txt breadboard/avr/boards.txt.orig
$ cp (DOWNLOAD_HOME)/boards.txt breadboard/avr/
$ cd breadboard/avr/bootloaders/atmega/
$ cp (ARDUINO_HOME)/hardware/arduino/avr/bootloaders/atmega/ATmegaBOOT_168.c .
$ cp (DOWNLOAD_HOME)/Makefile .
$ export PATH="(ARDUINO_HOME)/hardware/tools/avr/bin:$PATH"
$ export CC="avr-gcc -I(ARDUINO_HOME)/hardware/tools/avr/include"
$ make atmega328_8MHz
avr-gcc -g -Wall -Os -mmcu=atmega328p -DF_CPU=8000000L  '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' -DBAUD_RATE=57600 -DDOUBLE_SPEED   -c -o ATmegaBOOT_168.o ATmegaBOOT_168.c
avr-gcc -g -Wall -Os -mmcu=atmega328p -DF_CPU=8000000L  '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' -DBAUD_RATE=57600 -DDOUBLE_SPEED -Wl,--section-start=.text=0x7800 -o ATmegaBOOT_168_atmega328_8MHz.elf ATmegaBOOT_168.o
avr-objcopy -j .text -j .data -O ihex ATmegaBOOT_168_atmega328_8MHz.elf ATmegaBOOT_168_atmega328_8MHz.hex
rm ATmegaBOOT_168_atmega328_8MHz.elf ATmegaBOOT_168.o
$ make atmega328_1MHz
avr-gcc -g -Wall -Os -mmcu=atmega328p -DF_CPU=1000000L  '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' -DBAUD_RATE=9600 -DDOUBLE_SPEED   -c -o ATmegaBOOT_168.o ATmegaBOOT_168.c
avr-gcc -g -Wall -Os -mmcu=atmega328p -DF_CPU=1000000L  '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' -DBAUD_RATE=9600 -DDOUBLE_SPEED -Wl,--section-start=.text=0x7800 -o ATmegaBOOT_168_atmega328_1MHz.elf ATmegaBOOT_168.o
avr-objcopy -j .text -j .data -O ihex ATmegaBOOT_168_atmega328_1MHz.elf ATmegaBOOT_168_atmega328_1MHz.hex
rm ATmegaBOOT_168.o ATmegaBOOT_168_atmega328_1MHz.elf

ブートローダの書き込み

書き込みの方法は、ブートローダ作成の方法に比べ、ネット上に情報が潤沢にある。上述の公式サイトもその一つだ。ところが、サイトによって微妙に配線が異なる。ここでは、『ATMEGA328PをArduinoとして使う』に記載のものをベースに、『Arduino Unoを使ってATmega328Pにブートローダを書き込む』に従ってリセットピンに10 µFの電解コンデンサを接続した。また、8 MHzの水晶発振子の代わりに、“How to make an Arduino-compatible minimal board”で紹介されているD9ピンを使用した。

後は、Arduino Unoを書き込み装置に設定し、ボードを“ATmega328 on a breadboard (1 MHz internal clock)”としてブートローダを書き込めば終わりである。当初、breadboard-1-6-x.zipに含まれるATmegaBOOT_168_atmega328_pro_8MHz.hexをブートローダに用いてLow Fuse Byteの7 bit目を立てればよい、という記載に従ったが、単に動作が8倍遅くなるだけであった。つまり、&ldquot;Blink&rdquot;のdelay(1000)が8秒待ちとなる。ここまで記した方法ではクロックは合っているようである。1 MHzで動いているよね・・・。

コメントをどうぞ