2013-01-18 66 views
1

我正在使用ATTiny85進行視覺顯示的持久性,使用arduino-tiny core通過Arduino編程。ATTiny陣列更新錯誤

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

回答

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); 

其編譯成只有1個指令,按照Atmel的數據表。

pgmspace.h提供的宏可以從閃存讀取。請注意,由於程序在大多數AVR芯片中運行,因此無法更改閃存的內容。

當處理這麼多的數據時,要小心局部/全局變量和棧/堆衝突。

1

我已經想通了:這是一個SRAM的問題。 ATTiny85只有512字節的SRAM,所以它不能同時把所有的數據保存在內存中。我正在研究使用PROGMEM指令將數據存儲在閃存中。

+0

請注意'int'在'avr-gcc'中是16位,所以你可以通過切換到'unsigned char'來回收很多內存,這可能適合512B。 –

+0

謝謝。這是一個8位處理器,所以我認爲每種數據類型都是8位;它是否正確? – stewartml

+2

寄存器是8位的,但是您可以在C代碼中使用8,16和32位類型,編譯器會爲您處理。在這種特殊情況下,類型「int」是16位,但是在像這樣的嵌入式系統中,我使用'stdint.h'和顯式類型如'int8_t'和'int16_t'來避免混淆。 –

0

我也在用Attiny44做視力保持(POV)。(我通過Arduino的編程它作爲一個ISP)

用戶奔傑克遜貼士節約SRAM存儲器是在現貨:我原來是用「詮釋」是爲了我的陣列和我Attiny將錯誤,如果我試圖包含額外的數組 - 但是,當我簡單地將所有數組聲明爲「unsigned char」時,我的代碼工作得非常好!

下一次,我將命令attiny45's或類似的更多的SRAM內存,並繼續使用unsigned char的我的數組聲明。 感謝您的討論!