素のAVRに何かをフラッシュする / ArduinoをAVR書き込み器として使う

ArduinoをAVR書き込み器に利用して何かをArduino IDEから素のAVR (ブートローダーを持たないAVR)に書き込んでみる。

テキストは168をターゲットにしているがここでは328を使った。発振子は外づけせずに内部発振器を使って8 MHz動作とする。

AVR書き込み器には、『作って遊べるArduino互換機』で作ったUno互換機を使った。
 
(1) サンプルファイルに用意されているArduinoISP.inoを普段どおりにコンパイルしてArduinoにフラッシュする。これでArduinoがAVR書き込み器になったはずである。
f:id:ti-nspire:20190115160656p:plain:w300

(2) ターゲットAVRのヒューズビットを切り直してクロックの8分周を無効にする。方法は色々あるが、ここでは、鈴木哲哉, 『作って遊べるArduino互換機』, pp.28-31, ソシムを参考にavrdude-GUIを使った。

これがlow Fuseのビット割り当て:
f:id:ti-nspire:20190119180518p:plain:w300

これが工場出荷時の状態(0b01100010 = 0x62) (Readボタンを押して現状を確認したところ):
f:id:ti-nspire:20190119174442p:plain:w300

low Fuseを0x62から0xE2 (= 0b11100010)に切り直す(Writeボタンを押すと書き込まれる)。
f:id:ti-nspire:20190119174639p:plain:w300

(3) 下のように配線する。LEDはLチカによる確認用。それ以外が書き込み用の配線(と電源とグラウンドと)。
f:id:ti-nspire:20190120135638p:plain:w500

(4) ターゲットAVRに書き込むスケッチを用意する。ArduinoスタイルでもCスタイルでもどちらでもよいがコンパイル後のサイズはかなり違う。

#define whichBits (1 << PB0)

void setup(){
    DDRB = whichBits; // PB0のIOをOUTにする。Data Direction Register

    while(1){
        PORTB ^= whichBits; // ループするたびにPB0のステータスを反転する。Port Output Register Thing
        delay(500);
    }
}
                   
/*
#include <avr/io.h>
#include <util/delay.h>

#define whichBits (1 << PB0)

int main(void){
    DDRB = whichBits;
    
    while(1){
        PORTB ^= whichBits;
        _delay_ms(500);
    }
    return 0;
}
*/

(5) 下のように選択してProgrammerをArduino as ISPにする。
f:id:ti-nspire:20190120084505p:plain:w300
(6) 下のように選択してBoardをArduino Pro or Pro Miniにする(Pro or Pro Miniを指定したのはターゲットプロセッサーを"328P、8 MHz"に指定したいからであってPro or Pro Mini自体に意味はない)。
f:id:ti-nspire:20190120082852p:plain:w300
(7) 下のように選択してProcessorをATmega328P (3.3V, 8 MHz)にする。"3.3V"になっているが周波数だけが問題なのであってこれでよい。
f:id:ti-nspire:20190120083003p:plain:w300
(8) Ctrl+Shift+Uを押すとスケッチがコンパイルされて素のAVRへフラッシュされる。普段の勢いで間違ってCtrl+Uを押してもエラーが出るだけであってArduinoが書き換えられるわけではないので安心してよい。
f:id:ti-nspire:20190120083259p:plain:w300
(9) 実行結果:
f:id:ti-nspire:20190120134942j:plain:w300
 
 
 
キーワード: CKDIV8, AVR, _delay_ms(), 遅い, 遅すぎる, 分周, プリスケーラー, ATmega168, ATmega328P, 8 MHz, 1 MHz, ヒューズビット, fuse, クロック