DSC08745

Crystal-less Arduino (8MHz)


ブレッドボードにATmega168さして、自作のArduinoアダプタさして実験中



問題なく動いてるのでアダプタ外して、ブレボにリセット回路とクロック回路組んでブレッドボードArduino

だがしかし、この回路、スピードもクロック精度も全然いらないんで外付けXtal使わないで内蔵RCクロックで動かしたい!
つうことでブートローダーを書き換える事にした


まずはヒューズの設定をどうするのかデータシートとにらめっこ
Calibrated internal RC oscillatorってことでCKSEL3..0は0010になります。


内蔵クロックに変更したので、スタートアップタイムも見直します。
14CK+65msということに



という訳で、ヒューズの設定は
Extended = 0xF8
High = 0xDD
Low = 0xE2
となりました。



ロックビットは変わらず 0xCF



さてさて、それではブートローダーを内蔵8MHz用にMakeしてやります。
"C:\Program Files\arduino-0022\hardware\arduino\bootloaders\atmega"のMakefileに以下追加します。


diecimila_8mhz: TARGET = diecimila_8mhz
diecimila_8mhz: CFLAGS += '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1'
diecimila_8mhz: AVR_FREQ = 8000000L
diecimila_8mhz: $(PROGRAM)_diecimila_8mhz.hex

そしてコマンドラインからMake diecimila_8mhzを実行


C:\Program Files\arduino-0022\hardware\arduino\bootloaders\atmega>make diecimila_8mhz
avr-gcc -g -Wall -O2 -mmcu=atmega168 -DF_CPU=8000000L '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' -c -o ATmegaBOOT_168.o ATmegaBOOT_168.c
ATmegaBOOT_168.c: In function 'main':
ATmegaBOOT_168.c:586: error: 'EEWE' undeclared (first use in this function)
ATmegaBOOT_168.c:586: error: (Each undeclared identifier is reported only once
ATmegaBOOT_168.c:586: error: for each function it appears in.)
make: *** [ATmegaBOOT_168.o] Error 1

げげっ!!エラってしまいました。。。
なんじゃい???

該当箇所、ATmegaBOOT_168.cの586行付近を見ると、


#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega1281__)
while(bit_is_set(EECR,EEPE)); //Wait for previous EEPROM writes to complete
#else
while(bit_is_set(EECR,EEWE)); //Wait for previous EEPROM writes to complete
#endif

となってました。どうやらレジスタ名称がチップによって違うみたいです。ATMega128ではEEPEでそれ以外はEEWEなの??
EEPROM関係なのでeeprom.hを見てみると。。。EEWEって定義ありませんでした。
そりゃそうだ、そうエラーが言ってるもん。

なんでだ??
Arduinoフォーラム内を検索してみたらまさしく同じ問題に困ってた人が居ました。

どうやら、AVR Libcをバージョンアップしちゃった事による弊害だそうです。
ArduinoのブートローダーはAVRLibc1.6.7を使えって言ってるよ。

ですが、バージョンダウンさせるのも気が引けるので強引にいきます。

EEWEもEEPEも同じレジスタ、名前が違うだけです。
という訳でブートローダーのソースを修正!
eeprom.hをインクルードした直後に以下コードを追加しました。


/* Check for aliases. */
#if !defined(EEWE) && defined(EEPE)
# define EEWE EEPE
#endif

#if !defined(EEMWE) && defined(EEMPE)
# define EEMWE EEMPE
#endif

そして再びMake


C:\Program Files\arduino-0022\hardware\arduino\bootloaders\atmega>make diecimila_8mhz
avr-gcc -g -Wall -O2 -mmcu=atmega168 -DF_CPU=8000000L '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' -c -o ATmegaBOOT_168.o ATmegaBOOT_168.c
avr-gcc -g -Wall -O2 -mmcu=atmega168 -DF_CPU=8000000L '-DMAX_TIME_COUNT=F_CPU>>4' '-DNUM_LED_FLASHES=1' -Wl,--section-start=.text=0x3800 -o ATmegaBOOT_168_die
cimila_8mhz.elf ATmegaBOOT_168.o
avr-objcopy -j .text -j .data -O ihex ATmegaBOOT_168_diecimila_8mhz.elf ATmegaBOOT_168_diecimila_8mhz.hex
rm ATmegaBOOT_168_diecimila_8mhz.elf ATmegaBOOT_168.o

これで内蔵8MHz用のブートローダが出来ました。
あとはこれをライタで書き込んで完成

Arduino IDEのボード定義ファイル、board.txtに内蔵8MHz、ATMega168用の定義を追加しました。


##############################################################
diecimila.name=Arduino Diecimila, Duemilanove, or Nano w/ ATmega168 8MHz

diecimila.upload.protocol=stk500
diecimila.upload.maximum_size=14336
diecimila.upload.speed=19200

diecimila.bootloader.low_fuses=0xf8
diecimila.bootloader.high_fuses=0xdd
diecimila.bootloader.extended_fuses=0xE2
diecimila.bootloader.path=atmega
diecimila.bootloader.file=ATmegaBOOT_168_diecimila_8mhz.hex
diecimila.bootloader.unlock_bits=0x3F
diecimila.bootloader.lock_bits=0x0F

diecimila.build.mcu=atmega168
diecimila.build.f_cpu=8000000L
diecimila.build.core=arduino

これでボード一覧に追加されました。

外付けのXtal無しでもちゃんと動きました。
ただ、Arduinoライブラリのdelay()等が16MHz基準で作られているので時間が2倍になっちゃいました。。通信とかも気を付けないと。。



おまけ

ブレッドボード上にArduinoつくった時のAVRライタ接続用のアダプタを作りました。


AVRライタとこうつないで、


該当するピン位置に差し込んで使います。
ブートローダーさえ書いちゃえばあとはArduino IDEから書き込めるから不要だしね。もっと早く作っておけば良かった。

以上内蔵RCオシレータでブレッドボードArduinoを動かす覚書でした。