1

我正在使用 Arduino 使用arduino-tiny core编程的 ATTiny85 进行视觉持久性显示。

它由一根带有 16 个 LED 的棒组成,它可以快速旋转以在空中“画”出一幅画。显示缓冲区由一个数组表示,每次定时器触发时都会输出其下一个索引。它使用连接到 INT0 的霍尔传感器来检测上死点,并将阵列索引归零。

它是一个 8 位处理器,我有 16 个 LED 连接到 LED 驱动器,所以我实际上使用两个阵列进行显示。

所以奇怪的是,当我用十字图案初始化显示时,它显示了一堆虚线;所以我先把它归零,以防内存中有一些随机的东西。现在它不显示任何东西(即使我在将其归零后直接将十字图案写入它)。我不知道发生了什么,有什么想法吗?

我之前让它只输出索引值,它跟踪的图片看起来像计数二进制,所以我认为硬件正在工作。

请注意,我没有使用 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 进行视觉持久性 (POV)。(我通过 Arduino 作为 ISP 对其进行编程)

用户 Ben Jackson 关于保存 SRAM 内存的提示很明确:我最初使用“int”作为我的数组,如果我尝试包含其他数组,我的 Attiny 会出错 - 但是,当我简单地将所有数组声明为“无符号”时char" 的代码运行得非常好!

下次我将订购 attiny45 或类似的以获得更多 SRAM 内存,并继续使用 unsigned char 进行我的数组声明。谢谢小伙伴们的讨论!

于 2013-04-22T22:58:52.467 回答