ATTiny阵列更新错误

时间:2013-01-18 21:47:29

标签: arduino avr

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

它由一根带有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;
}

3 个答案:

答案 0 :(得分:1)

我已经弄明白了:这是一个SRAM问题。 ATTiny85只有512字节的SRAM,因此无法同时将所有数据保存在内存中。我正在调查使用PROGMEM指令将数据存储在闪存中。

答案 1 :(得分: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提供的宏可以从flash中读取。请注意,由于程序在大多数AVR芯片中运行,因此无法更改闪存的内容。

处理这么多数据时要小心本地/全局变量和堆栈/堆冲突。

答案 2 :(得分:0)

我也在使用Attiny44进行持久视觉(POV)。 (我通过Arduino作为ISP进行编程)

用户Ben Jackson保存SRAM内存的提示很明显:我最初使用“int”代替我的数组,如果我试图包含其他数组,我的Attiny就会出错 - 但是当我简单地声明我的所有数组时作为“unsigned char”,我的代码工作得非常棒!

下次我将订购attiny45或类似的更多SRAM内存,并继续使用unsigned char进行我的数组声明。 感谢您的讨论!