1

arduino-tiny coreを使用して Arduino でプログラムされた ATTiny85 を使用して、永続的なビジョン表示を作成しています。

16 個の LED が付いたスティックで構成されており、すばやく回転させて空中に絵を描くことができます。表示バッファは配列で表され、タイマーが起動するたびに次のインデックスが出力されます。INT0 に配線されたホール センサーを使用して、アレイ インデックスをゼロにする上死点を検出します。

これは 8 ビットのプロセッサで、LED ドライバに 16 個の LED が接続されているため、実際にはディスプレイに 2 つのアレイを使用しています。

奇妙なことは、十字パターンでディスプレイを初期化したときに、たくさんの破線が表示されたことです。そのため、メモリにランダムなものが含まれている場合に備えて、最初にゼロにしました。今は何も表示されません (クロスパターンをゼロにした直後に書き込みますが)。何が起こっているのかわかりません。アイデアはありますか?

以前はインデックス値だけを出力していたのですが、トレースした絵が二進数を数えているように見えるので、ハードウェアは動いていると思います。

私は digitalWrite を使用していないことに注意してください。これは、タイミングをずらす可能性のある割り込みを無効にするためです。

コードは次のとおりです: (かなり多くて申し訳ありません)

#define COLUMNCOUNT 180

const int datapin = 4;
const int clockpin = 0;
const int latchpin = 1;
const int rxpin = 3;
const int hallpin = 2;

volatile int columns0[COLUMNCOUNT];
volatile int columns1[COLUMNCOUNT];
volatile int counter = 0;

void setup()
{
  pinMode(datapin, OUTPUT);
  pinMode(clockpin, OUTPUT);
  pinMode(latchpin, OUTPUT);
  pinMode(rxpin, INPUT);
  pinMode(hallpin, INPUT);


  //make sure the arrays are all zeroed
  for (int i = 0; i < COLUMNCOUNT; i++)
  {
    columns0[i] = 0;
    columns1[i] = 0;
  }

  //make a cross pattern
  columns0[0] = 255;
  columns1[0] = 255;
  columns0[45] = 255;
  columns1[45] = 255;
  columns0[90] = 255;
  columns1[90] = 255;
  columns0[135] = 255;
  columns1[135] = 255;

  //turn on the timer (prescale CK/16)
  OCR1A = 255;
  OCR1C = 255;
  TCNT1 = 0;
  TIMSK = _BV(OCIE1A);
  TCCR1 = _BV(CTC1) | _BV(CS12) | _BV(CS10);

  GIMSK = _BV(INT0);

  sei();
}

void loop()
{
  //nothing to do here
}


ISR(TIMER1_COMPA_vect)
{
   if (counter < COLUMNCOUNT)
     counter++;

   outputWord(columns0[counter], columns1[counter]);
}


ISR(INT0_vect)
{
  counter = 0;
}


void outputByte(int b)
{
  int currentBit;

  for (int i = 0; i < 8; i++)
  {
    currentBit = (b & 128) == 128;
    PORTB = _BV(clockpin) | (currentBit ? _BV(datapin) : 0);
    PORTB = PORTB ^ _BV(clockpin);

    b <<= 1;
  }
}


void outputWord(int hi, int lo)
{
  outputByte(hi);
  outputByte(lo);
  PORTB = _BV(latchpin);
  PORTB = 0;
}
4

3 に答える 3

1

私はそれを理解しました:それはSRAMの問題です。ATTiny85 には 512 バイトの SRAM しかないため、そのすべてのデータを同時にメモリに保持することはできません。代わりにPROGMEMディレクティブを使用してフラッシュ メモリにデータを格納することを調査しています。

于 2013-01-18T23:23:34.433 に答える
1

C 標準に従って、グローバル変数は 0 に初期化されます。そのため、

//make sure the arrays are all zeroed
for (int i = 0; i < COLUMNCOUNT; i++)
{
  columns0[i] = 0;
  columns1[i] = 0;
}

は必要ありません。そのアクションは、__do_clear_bssセクションの実行時に自動的に処理されます。

また、C 標準に従って、int 型は少なくとも 16 ビット幅でなければなりません。AVR では、最小値が使用されます。フリー ソフトウェア ツールチェーンを使用している場合は、提供される機能といくつかの追加inttypes.h機能を提供するツールチェーンが含まれています。stdint.hこれは別の回答で言及されました。

ステートメント:

PORTB = PORTB ^ _BV(clockpin);

次のように書き換えることができます。

PINB = _BV(clockpin);

Atmel のデータシートによると、これは 1 つの命令のみにコンパイルされます。

によって提供されるマクロはpgmspace.h、フラッシュから読み取ることができます。プログラムはほとんどの AVR チップで実行されるため、フラッシュの内容を変更できないことに注意してください。

この量のデータを処理するときは、ローカル/グローバル変数とスタック/ヒープの衝突に注意してください。

于 2013-01-23T22:29:38.967 に答える
0

また、Attiny44 で Persistance of Vision (POV) も行っています。(ISPとしてArduino経由でプログラミングしています)

SRAMメモリを節約するためのユーザーBen Jacksonのヒントは的を射ていました:私はもともと配列に「int」を使用していましたが、追加の配列を含めようとするとAttinyがバグアウトしました-しかし、すべての配列を単に「符号なし」と宣言したときchar」の私のコードは、驚くほどうまく機能しました。

次回は attiny45 または同様の SRAM メモリを注文し、配列宣言には unsigned char を引き続き使用します。議論してくれてありがとう!

于 2013-04-22T22:58:52.467 に答える