ページ移動

エントリー

2014年09月の記事は以下のとおりです。

AVRのフューズビット

AVRのフューズビットについて調査してみようと思いAtmelのデータシートを参照した

  • ATmega168Pと328Pのみ
  • フューズビットとされているがデータシートではフューズバイトと記載されている
  • 負論理なのでビットの意味に対する肯定・否定は、0:肯定、1:否定となる
  • クロック選択関係はややこしかったので未稿
328P
上位バイト(HIGH FUSE)
名称 ビット 意味 備考
RSTDISBL 7

PC6がI/Oピンかリセットピンかを選択

0:I/Oピン

1:リセットピン

 
DWEN 6 デバッグWIRE機能許可  
SPIEN 5

プログラム許可

0:許可

1:非許可

フラッシュメモリとEEPROMへの書込みを制御
WDTON 4

ウォッチドックタイマを常時有効

0:有効

1:無効(プログラムモード)

0:有効ではリセット後から開始される

1:無効の場合WDTCSRで有効にできる

EESAVE 3

ChipErase(初期化)時EEPROMの内容を保護

0:初期化しない

1:初期化する

0なら内蔵されているEEPROMを初期化しない
BOOTSZ1 2

ブートローダの容量選択

00:2048bytes($3800~$3fff)

01:1024bytes($3c00~$3fff)

10:512bytes($3e00~$3fff)

11:256bytes($3f00~$3fff)

()内はブートローダアドレス範囲(開始~終了)

開始アドレスがブートローダ実行時のリセットアドレス

プログラム領域は$0000~ブートローダ開始アドレス-1となる

BOOTSZ0 1
BOOTRST 0

リセット時に実行される領域の選択

0:ブートローダ領域

1:プログラム領域

 
下位バイト(LOW FUSE)
名称 ビット 意味 備考
CKDIV8 7

システムクロック8分周

0:8分周する

1:8分周しない

 
CKOUT 6

システムクロック出力

0:出力する

1:出力しない

PB0に出力
SUT1 5

起動時間選択(最低14×CK)

00:+0

01:+4.1ms

10:+65ms

11:予約

00でリセット時RSTDISBLが0の場合は+4.1ms

SUT0 4
CKSEL3 3 クロック種別選択        
CKSEL2 2
CKSEL1 1
CKSEL0 0
拡張バイト(Extended FUSE)
名称 ビット 意味 備考
 - 7 未使用      
 - 6
 - 5
 - 4
 - 3
BODLEVEL2 2 低電圧検出リセットの検出電圧選択    
BODLEVEL1 1
BODLEVEL0 0
168P
上位バイト(HIGH FUSE)
 名称 ビット 意味 備考
RSTDISBL 7

PC6がI/Oピンかリセットピンかを選択

0:I/Oピン

1:リセットピン

 
DWEN 6 デバッグWIRE機能許可  
SPIEN 5

プログラム許可

0:許可

1:非許可

フラッシュメモリとEEPROMへの書込みを制御
WDTON 4

ウォッチドックタイマを常時有効

0:有効

1:無効(プログラムモード)

0:有効ではリセット後から開始される

1:無効の場合WDTCSRで有効にできる

EESAVE 3

ChipErase(初期化)時EEPROMの内容を保護

0:初期化しない

1:初期化する

0なら内蔵されているEEPROMを初期化しない
BODLEVEL2 2  低電圧検出リセットの検出電圧選択    
BODLEVEL1 1
BODLEVEL0 0
下位バイト(LOW FUSE)
名称 ビット 意味 備考
CKDIV8 7

システムクロック8分周

0:8分周する

1:8分周しない

 
CKOUT 6

システムクロック出力

0:出力する

1:出力しない

PB0に出力
SUT1 5

起動時間選択(最低14×CK)

00:+0

01:+4.1ms

10:+65ms

11:予約

00でリセット時RSTDISBLが0の場合は+4.1ms
SUT0 4
CKSEL3 3 クロック種別選択  
CKSEL2 2
CKSEL1 1
CKSEL0 0
拡張バイト(Extended FUSE)
名称 ビット 意味 備考
 - 7 未使用      
 - 6
 - 5
 - 4
 - 3
BOOTSZ1 2

ブートローダの容量選択

00:1024bytes($1c00~$1fff)

01:512bytes($1e00~$1fff)

10:256bytes($1f00~$1fff)

11:128bytes($1f80~$1fff)

()内はブートローダアドレス範囲(開始~終了)

開始アドレスがブートローダ実行時のリセットアドレス

プログラム領域は$0000~ブートローダ開始アドレス-1となる

BOOTSZ0 1
BOOTRST 0

リセット時に実行される領域の選択

0:ブートローダ領域

1:プログラム領域

 

 

 

秋月オシロスコープキットの波形イメージ転送(3)

先日Arduino上で確認したものを実際に使用する回路にするためブレッドボードで実装した

ブレッドボードでの実装は消費電力を確認する目的もある

回路は3.3V供給とArduinoの簡易互換で済むので楽勝

(回路図は未稿)

通信状態時の電流は6.77mA、LEDが点灯している割には省電力である

01

パワーダウンスリープ時は0.19mA(こちらの情報では0.13mAとありほぼ同じなので問題ないだろう)

02

PC(Tera Term)と実際に通信してみた(USB経由だがUSBへのレベル変換はPCから電力供給しているので以下の測定値には含まれない)

実際の通信では7.11mAで、一瞬なのではっきりとした数値は不明だが偶に10mA位になる

おそらくSDカードに書き込みする際に3mA位消費するのだろう

最大でも約10mAと考えて良さそうだ

03

電源部の三端子レギュレータはNJU7223F33(500mA)を使ったが余裕過ぎるので、XC6202P332TB(150mA)に変更

同じ低損失CMOSなので消費電力はほとんど同じであった

まだ余裕だし50mAタイプの物(秋月ならS-812C33AY-B-G)でも良さそうなので今度購入しておこう

04

とりあえず問題なさそうで後はユニバーサル基板に実装してケースに入れるのだがSDカードスロットやボタンがあるため配置で悩んでいる

急ぐこともないのでじっくりと考えてからにする

(追記)

ユニバーサル基板への実装(ケースに付けた写真は撮影してなかった)

秋月オシロスコープキットの波形イメージ転送(2)

プログラムはできTera Termとのテストは完了したので実際にUSART(UARTかな)接続による実機確認を行うことにする

先ずはオシロキットの転送機能の確認を行っていないのでUSBで接続で確認してみた(動作しなかったら確認にもならないので・・・)

電源ON時にそれなりの文字が表示されると、どこかのサイトで見たことがあるが文字化けで最初の文字は確認できなかった(USB変換の性能の問題か?)

term

Tera Term側からXmodem受信したところ正常終了したのでオシロキットの転送機能は正常動作している

転送前後で何らかの文字が送られてないか期待したが何もなかった(転送後も上のTera Term画面から変化なし)

次は作成した(Arduino上)プログラムで確認し正常終了

実機

これまでテストで使ったSDカードの中身、タイムスタンプが同じになるのは残念なところ

SD

今回転送した波形イメージ

今日はここまでで終了

秋月オシロスコープキットの波形イメージ転送

秋月オシロスコープキットの波形イメージをPCに取り込みできるようにする

元々PCへ波形イメージをシリアルで転送する機能があるがI/FがUSARTなのでPCと通信するにはRS232CかUSBレベルに変換する必要がある

いずれにしても転送する際にPCと接続しないとならないのと受信ソフトの操作が必要で面倒だなってことで、いっそSDカードに格納してしまおうかってことを考えていた(SDにしてもPCにもっていく作業はあるが・・・)

といっても、オシロスコープにSDカードスロットを追加することはハード、ソフト的にも困難なのでUSARTの出力をAVRで受けてSDカードに格納することにした

ざーと思い立った仕様は

  • 3.3V版のATmega328Pを使用しArduinoで開発後ユニバーサル基盤に実装して組み込む
  • SDカードスロットとの接続は先日確認した物を使う
  • イメージの転送が行われてない時はスリープ状態で省電力化(自動的に転送を開始したいが可能かどうか現状は不明)
  • SDカードに格納される波形イメージファイルは連番のファイル名で被らないようにする

当初、作成しないとならないと思っていたXmodemプロトコルはArduino用のxmodemライブラリがあったので利用させてもらった

しかもXmodemで受けてSDカードに保存してくれる仕様だったのでありがたい

ライブラリはダウンロードし、IDEの libraries\xmodem 配下(xmodem フォルダー作成)に展開して、xmodem.h はそのまま、xmodem.c は xmodem.cpp と変更して置いた

さくっと以下(コメントなどは適当な部分があるので注意)を作成してTera Termを相手にテスト

/*    Oscilloscope kit for micro SD card
 *
 *      SD card attached to SPI bus as follows:
 *        MOSI - pin 11
 *        MISO - pin 12
 *        CLK - pin 13
 *        CS - pin 4
 */
 
#include <avr/sleep.h>        // スリープモード
#include <EEPROM.h>
#include <SD.h>
#include <xmodem.h>

#define PROM_CPUID_ADDR        (0)        //byte data address
#define PROM_FILENUM_ADDR    (2)        //short data address

#define CABLESELECTPIN    (4)
#define STATLEDPIN        (8)

char cpuID;
int fileNum;

void setup()
{
    // Open serial communications and wait for port to open:
    //Serial.begin(38400);
    Serial.begin(9600);
    // wait for serial port to connect. Needed for Leonardo only
    while (!Serial);

    Serial.print("Initializing SD card...");
    // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
    // Note that even if it's not used as the CS pin, the hardware SS pin
    // (10 on most Arduino boards, 53 on the Mega) must be left as an output
    // or the SD library functions will not work.
    pinMode(10, OUTPUT);

    if(!SD.begin(CABLESELECTPIN)) {
        Serial.println("initialization failed!");
        return;
    }
    Serial.println("initialization done.");

    //LEDステータス
    pinMode(STATLEDPIN, OUTPUT);

    //スリープモード設定(アイドル)
    set_sleep_mode(SLEEP_MODE_IDLE);

    //格納ファイル名データ(EEPROM保持)
    cpuID = EEPROM.read(PROM_CPUID_ADDR);
    fileNum = (EEPROM.read(PROM_FILENUM_ADDR)<<8) + EEPROM.read(PROM_FILENUM_ADDR + 1);
}

void loop()
{
    char fileName[13];

    //シリアル入出力バッファ初期化
    Serial.flush();

    //アイドルモードで転送待ち(シリアルデータ受信でウェイクアップ)
    while(!Serial.available()) {
        cli();                //割り込み禁止
        sleep_enable();        //スリープ許可
        sei();              //割り込み許可
        sleep_cpu();        //割り込みで抜ける
        sleep_disable();    //スリープ禁止
    }

    //receive file to SD write
    digitalWrite(STATLEDPIN, HIGH);
    sprintf(fileName, "OSK%c%04d.BMP", cpuID, fileNum);

    Serial.println(fileName);

    short res = XReceive(&SD, &Serial, fileName);

    Serial.print("XReceive result : ");
    Serial.println(res);

    if(res < 0) {
        //error
        for(;;) {
          digitalWrite(STATLEDPIN, HIGH);
          delay(500);
          digitalWrite(STATLEDPIN, LOW);
          delay(500);
        }
    }
    //complite
    fileNum++;

    EEPROM.write(PROM_FILENUM_ADDR, (fileNum>>8)&0xff);
    EEPROM.write(PROM_FILENUM_ADDR + 1, fileNum&0xff);

    digitalWrite(STATLEDPIN, LOW);
}

(処理概要)リセット後アイドルモードでスリープしシリアルの割り込みでウェイクアップしたらXmodemでデータ受信してSDカードに記録する

ところが、このプログラムは失敗

なぜかというと、Xmodemは受信側が転送プロトコルのトリガーになっており(つまり受信側が受信しますというデータを送信しないと送信側は待ち状態で送信しない)このプログラムでは送信側のTera Termで送信手順を行っても動作しない

とりあえずはTera Termで1文字入力したらXmodemによる通信が開始されSDカードに記録されたのでXmodemライブラリの動作確認はとれた

仕様変更で以下を追加

・SDカード格納時リセットボタンを押す

起動ボタン操作でも可能なのだがハングアップやエラー状態からの復帰方法を考慮した結果リセットボタンにすることにした
(オシロキットから転送開始が受けれれば自動にもできるが信号があるかどうか不明)

改良仕様版は以下のとおり(同じくコメントなどいいかげんな部分もあるので注意)

/*    Oscilloscope kit for micro SD card
 *
 *      SD card attached to SPI bus as follows:
 *        MOSI - pin 11
 *        MISO - pin 12
 *        CLK - pin 13
 *        CS - pin 4
 */
 
#include <avr/sleep.h>        // スリープモード
#include <EEPROM.h>
#include <SD.h>
#include <xmodem.h>

#define PROM_CPUID_ADDR        (0)        //byte data address
#define PROM_FILENUM_ADDR    (2)        //short data address

#define CABLESELECTPIN        (4)
#define STATLEDPIN            (8)

void setup()
{
    char fileName[13];

    //パワーON・外部リセット判定
    char regMCUSR = (MCUSR&0x0f);
    MCUSR = 0;

    //LEDステータス
    pinMode(STATLEDPIN, OUTPUT);

    //パワーオン・リセットとブラウン・アウト・リセットの場合はスリープする
    if(regMCUSR&(0x01|0x04)) {
        sleep();
        return;
    }

    //外部リセットとウォッチドッグ・システム・リセットの場合はデータ受信後スリープ
    // Open serial communications and wait for port to open:
    Serial.begin(38400);
    //Serial.begin(9600);
    // wait for serial port to connect. Needed for Leonardo only
    while (!Serial);

//    Serial.print("Initializing SD card...");
    // On the Ethernet Shield, CS is pin 4. It's set as an output by default.
    // Note that even if it's not used as the CS pin, the hardware SS pin
    // (10 on most Arduino boards, 53 on the Mega) must be left as an output
    // or the SD library functions will not work.
    pinMode(10, OUTPUT);

    if(!SD.begin(CABLESELECTPIN)) {
//        Serial.println("initialization failed!");
        return;
    }
//    Serial.println("initialization done.");

    //格納ファイル名データ(EEPROM保持)
    char cpuID = EEPROM.read(PROM_CPUID_ADDR);
    int fileNum = (EEPROM.read(PROM_FILENUM_ADDR)<<8) + EEPROM.read(PROM_FILENUM_ADDR + 1);

    //シリアル入出力バッファ初期化
    Serial.flush();

    //receive file to SD write
    digitalWrite(STATLEDPIN, HIGH);
    sprintf(fileName, "OSK%c%04d.BMP", cpuID, fileNum);

//    Serial.println(fileName);

    short xresult = XReceive(&SD, &Serial, fileName);

//    Serial.print("XReceive result : ");
//    Serial.println(xresult);

    //エラーの場合はloop()へ
    if(xresult < 0) return;

    //正常終了でファイルNoをカウントアップして格納
    fileNum++;
    EEPROM.write(PROM_FILENUM_ADDR, (fileNum>>8)&0xff);
    EEPROM.write(PROM_FILENUM_ADDR + 1, fileNum&0xff);

    digitalWrite(STATLEDPIN, LOW);

    sleep();
}

void sleep()
{
    set_sleep_mode(SLEEP_MODE_PWR_DOWN);
    cli();                //割り込み禁止
    sleep_enable();        //スリープ許可
    sei();              //割り込み許可
    sleep_cpu();
}

void loop()
{
    //エラー時の点滅処理
    digitalWrite(STATLEDPIN, HIGH);
    delay(500);
    digitalWrite(STATLEDPIN, LOW);
    delay(500);
}

(処理概要)電源ON時は何もしないでパワーダウンスリープ、リセットボタンでXmodeによる通信を行いSDカードに記録し正常終了でパワーダウンスリープする

アイドルスリープからパワーダウンスリープになったので未処理中は更に省電力になった

ボタンを押すという操作が増えてしまったのは残念(改良したい課題となった)

尚、プログラムサイズは以下のとおり

(追加)

状態を知るためLEDを使っている

消灯:スリープ中

点灯:通信処理中(通信しているとは限らない)

点滅:エラー時(SDカード無し、書込みエラーなど)

ページ移動

  • ページ
  • 1
  • 2

ユーティリティ

検索

エントリー検索フォーム
キーワード

過去ログ

Feed