我正在使用一个使用arduino-tiny core的Arduino编程的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;
}发布于 2013-01-24 06:29:39
根据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);pgmspace.h提供的宏可以从闪存中读取。请注意,您不能更改闪存的内容,因为您的程序在大多数AVR芯片上运行。
在处理如此多的数据时,要注意局部/全局变量和堆栈/堆冲突。
发布于 2013-01-19 07:23:34
我已经弄清楚了:这是一个SRAM问题。ATTiny85只有512字节的静态随机存取存储器,所以它不能同时在内存中保存所有数据。我正在研究使用PROGMEM指令将数据存储在闪存中。
发布于 2013-04-23 06:58:52
我还用Attiny44做了一个视觉持久性(POV)。(我以ISP的身份通过Arduino对其进行编程)
用户Ben Jackson关于节省SRAM内存的建议很正确:我最初使用的是“int”的数组,如果我试图包含额外的数组,我的Attiny就会出错--然而,当我简单地将所有数组都声明为"unsigned char“时,我的代码就像它应该的那样工作得很好!
下一次我将订购attiny45或类似的,以获得更多的SRAM内存,并继续使用无符号字符作为我的数组声明。感谢大家的讨论!
https://stackoverflow.com/questions/14408191
复制相似问题