我使用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;
}
答案 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进行我的数组声明。 感谢您的讨论!