2

Cで定義されたデータ構造をArduino Unoボードの不揮発性メモリに書き込もうとしているので、電源がオフになるかリセットされた後も構造の値が保持されます。私の理解では、(スケッチの実行中に) これを行う唯一の方法は、arduino の EEPROM に書き込むことです。個々のバイトを書き込むことはできますが (アドレス 0 に値 1 のバイトを設定します):

eeprom_write_byte(0,1);

構造体全体を書き込もうとして立ち往生しています:

typedef struct NewProject_Sequence {
    NewProject_SequenceId sequenceId;
    NewProject_SequenceLength maxRange;
    NewProject_SequenceLength minRange;
    NewProject_SequenceLength seqLength;
    NewProject_SceneId sceneList[5];
} NewProject_Sequence;

EEPROM の書き込み回数は 100,000 回に制限されているため、各バイトをループして Arduino に書き込みたくありません。EEPROMを使用するか、スケッチの実行中にPROGMEMに書き込む方法があるかどうか、これを行うより効率的な方法を知っている人はいますか? (Arduino ライブラリを使用せずに、C のみ)。

解決済み eepromWrite と eepromRead という 2 つのカスタム関数を作成することになりました。以下にそれらを示します。

void eepromRead(uint16_t addr, void* output, uint16_t length) {
    uint8_t* src; 
    uint8_t* dst;
    src = (uint8_t*)addr;
    dst = (uint8_t*)output;
    for (uint16_t i = 0; i < length; i++) {
        *dst++ = eeprom_read_byte(src++);
    }
}

void eepromWrite(uint16_t addr, void* input, uint16_t length) {
    uint8_t* src; 
    uint8_t* dst;
    src = (uint8_t*)input;
    dst = (uint8_t*)addr;
    for (uint16_t i = 0; i < length; i++) {
        eeprom_write_byte(dst++, *src++);
    }
}

は次のように実装されます。

uint16_t currentAddress;
struct {
    uint16_t x;
    uint16_t y;
} data;

struct {

} output;
uint16_t input

eepromWrite(currentAddress, data, sizeof(data);
eepromRead(currentAddress, output, sizeof(data));
4

2 に答える 2

2

いくつかのソリューションや組み合わせ。

  1. 連続してではなく定期的に値を保存するようにタイマーイベントを設定します。
  2. チェックサムを使用し、書き込み時に初期オフセットをインクリメントします。読み取り時に、有効なチェックサムが得られるまで各インクリメントを試みます。これにより、データが範囲全体に広がり、寿命が延びます。最新のフラッシュドライブはこれを行います。
  3. 外部ブラウンアウト検出器を使用して INT をトリガーし、EEPROM にすばやく書き込むことにより、ユニットの電源オフを検出します。安全な書き込み電圧を下回る前に、内部 BOD を使用して破損を防ぐこともできます。外部しきい値を内部しきい値よりも大幅に高くすることによって。完全にシャットダウンするまでの書き込み時間は、VCC 容量を大きくすることで長くすることができます。外部 BOD が VCC の前に比較され、VCC 自体と直接比較されない場合。

ATmegaの粗い外部BOD回路

これは、ATtiny の内部 BOD を有効にする方法を説明するビデオです。他の ATmega とほぼ同じです。ビデオ

于 2014-01-03T15:37:14.013 に答える