最終更新日: 2012年6月10日

ArduinoにATMega168P

Arduino Duemilanoveが最初に発売された時は、MCUはATMega168が使われていました。その後ATMega328Pになり、UNOへとモデルチェンジしています。しかし現在MCU単体で発売されているものはATMega168Pであり、それをそのままArduinoに装着してもIDEでブートローダーを書き込むことができません。ATMega168と168Pとでシグネチャーが違うためです。

ということで、168Pに対応できるようにしてみました。せっかくなのでoptibootです。
以下、Arduino IDEはVer1.0以上を想定しています。

ブートローダーの作成

まずはATMega168P対応のoptibootのブートローダーを作成します。このためにはいくつかのファイルを書き換える必要があります。

まずはブートローダーのソースであるoptiboot.c。ここにはATMega168P用の定義が無いので付け加えます。赤文字の部分を追加します。

optiboot.c
231行目から
…
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) 
#define RAMSTART (0x100)
#define NRWWSTART (0x3800)
…

そのファイルからインクルードされているpin_defs.hにも同様に定義を加えます。

fpin_defs.h
1行目から
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__) || defined(__AVR_ATmega88) || defined(__AVR_ATmega8__) || defined(__AVR_ATmega88__)
/* Onboard LED is connected to pin PB5 in Arduino NG, Diecimila, and Duemilanove */ 
#define LED_DDR     DDRB
#define LED_PORT    PORTB
#define LED_PIN     PINB
#define LED         PINB5
…

それをコンパイルするためのMakefileにATMega168P用の定義を追加します。
「__AVR_ATmega168P__」を定義させる方法がわからなかったので、強引に-Dパラメーターで定義させてしましました。

Makefile
atmega168: TARGET = atmega168
atmega168: MCU_TARGET = atmega168
atmega168: CFLAGS += '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
atmega168: AVR_FREQ = 16000000L 
atmega168: $(PROGRAM)_atmega168.hex
atmega168: $(PROGRAM)_atmega168.lst

atmega168_isp: atmega168
atmega168_isp: TARGET = atmega168
# 2.7V brownout
atmega168_isp: HFUSE = DD
# Low power xtal (16MHz) 16KCK/14CK+65ms
atmega168_isp: LFUSE = FF
# 512 byte boot
atmega168_isp: EFUSE = 04
atmega168_isp: isp

atmega168p: TARGET = atmega168p
atmega168p: MCU_TARGET = atmega168p
atmega168p: CFLAGS += '-D__AVR_ATmega168P__=1' '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'
atmega168p: AVR_FREQ = 16000000L 
atmega168p: $(PROGRAM)_atmega168p.hex
atmega168p: $(PROGRAM)_atmega168p.lst

atmega168p_isp: atmega168p
atmega168p_isp: TARGET = atmega168p
# 2.7V brownout
atmega168p_isp: HFUSE = DD
# Low power xtal (16MHz) 16KCK/14CK+65ms
atmega168p_isp: LFUSE = FF
# 512 byte boot
atmega168p_isp: EFUSE = 04
atmega168p_isp: isp

そしてコンパイルします。

$PATH=$PATH:/Applications/Arduino.app/Contents/Resources/Java/hardware/tools/avr/bin/
$cd /Applications/Arduino.app/Contents/Resources/Java/hardware/arduino/bootloaders/optiboot/
$make atmega168p
avr-gcc -g -Wall -Os -fno-inline-small-functions -fno-split-wide-types -mshort-calls -mmcu=atmega168p -DF_CPU=16000000L   '-D__AVR_ATmega168P__=1' '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200'   -c -o optiboot.o optiboot.c
avr-gcc -g -Wall -Os -fno-inline-small-functions -fno-split-wide-types -mshort-calls -mmcu=atmega168p -DF_CPU=16000000L   '-D__AVR_ATmega168P__=1' '-DLED_START_FLASHES=3' '-DBAUD_RATE=115200' -Wl,--section-start=.text=0x3e00 -Wl,--section-start=.version=0x3ffe -Wl,--relax -Wl,--gc-sections -nostartfiles -nostdlib -o optiboot_atmega168p.elf optiboot.o 
avr-size optiboot_atmega168p.elf
   text	   data	    bss	    dec	    hex	filename
    500	      0	      0	    500	    1f4	optiboot_atmega168p.elf
avr-objcopy -j .text -j .data -j .version --set-section-flags .version=alloc,load -O ihex optiboot_atmega168p.elf optiboot_atmega168p.hex
avr-objdump -h -S optiboot_atmega168p.elf > optiboot_atmega168p.lst
rm optiboot_atmega168p.elf optiboot.o
$

これでブートローダーができあがりました。

定義の追加

次にboard.txtにATMega168P optibootの定義を追加します。

board.txt
…
##############################################################

diecimila_optiboot.name=Arduino Diecimila or Duemilanove w/ ATmega168P optiboot

diecimila_optiboot.upload.protocol=arduino
diecimila_optiboot.upload.maximum_size=15872
diecimila_optiboot.upload.speed=115200

diecimila_optiboot.bootloader.low_fuses=0xff
diecimila_optiboot.bootloader.high_fuses=0xdd
diecimila_optiboot.bootloader.extended_fuses=0x00
diecimila_optiboot.bootloader.path=optiboot
diecimila_optiboot.bootloader.file=optiboot_atmega168p.hex
diecimila_optiboot.bootloader.unlock_bits=0x3F
diecimila_optiboot.bootloader.lock_bits=0x0F

diecimila_optiboot.build.mcu=atmega168p
diecimila_optiboot.build.f_cpu=16000000L
diecimila_optiboot.build.core=arduino
diecimila_optiboot.build.variant=standard

##############################################################

…

これで、Arduino IDEからブートローダーの書き込みにも対応できるようになりました。
ATMega168/168Pは当然328Pよりもプログラムエリアが小さいので、optibootの恩恵は大きいです。



home | Elec top

inserted by FC2 system