2010-10-20 21 views
5

Lời nói đầu: Câu hỏi này là về một dự án tôi đang làm việc với một giáo sư tại trường đại học của tôi. Nó KHÔNG phải cho một lớp, nhưng danh tiếng của tôi với giáo sư này không thành vấn đề. Vì vậy, trong khi thành công của tôi về dự án này là quan trọng với tôi, tôi không thấy nó là không công bằng để tìm kiếm sự giúp đỡ từ Stack Overflow.ATmega328 + Bộ nhớ flash SPI

Điều đó nói rằng, đây là mức cao tổng quan về dự án của tôi. Tôi có một vi điều khiển ATmega328. Tôi có một thẻ nhớ Microchip SST 64 Mbit flash. ATmega có phần cứng thực hiện SPI. Bộ nhớ flash có cài đặt phần cứng SPI.

Mục tiêu của tôi là đọc dữ liệu từ và ghi dữ liệu vào chip flash bằng cách sử dụng ATmega trong chế độ chính SPI. Bộ nhớ được tổ chức trong một cấu trúc nhiều lớp phủ mà là tốt đẹp cho tẩy xoá nhưng cho mục đích của tôi, về cơ bản nó chỉ là 32.768 trang của 256 byte mỗi.

Để viết dữ liệu ý tưởng cơ bản là tôi gửi một byte lệnh, sau đó là địa chỉ bắt đầu, sau đó là dữ liệu. Để đọc dữ liệu ý tưởng cơ bản là tôi gửi một byte lệnh, sau đó là địa chỉ bắt đầu, sau đó một byte giả, và sau đó nó bắt đầu gửi dữ liệu cho tôi.

Dưới đây là bảng dữ liệu:

Vi điều khiển: http://www.atmel.com/dyn/resources/prod_documents/doc8271.pdf

Flash: http://www.sst.com/dotAsset/40498.pdf

Code:

#include <SPI.h> 
#include <Peggy2.h> 

#define SS_PIN 16 

Peggy2 frame1; 
byte toDisp = 0; 
byte checker = 0; 

void setup() 
{ 
    frame1.HardwareInit(); 
    pinMode(SS_PIN,OUTPUT); //set pin16 to output, SS pin 
    SPI.setClockDivider(SPI_CLOCK_DIV2); //set the SPI clock to f/2, fastest possible 
    SPI.begin(); //SPI lib function which sets ddr for SCK and MOSI pin 
        //MISO is auto input 
        //see SPI.cpp for more info 

} 

void loop() 
{ 

    if(!checker){ 
       enableProgramming(); 
     programData(); 
     toDisp = receiveByte(0); 
     checker = 1; 
     frame1.WriteRow(0,toDisp); 
    } 
    frame1.RefreshAll(2); 

} 

byte receiveByte(unsigned long startAddress) 
{ 
    //Begin High Speed Read Instruction 
    //See p. 10 of SST data sheet 
    digitalWrite(SS_PIN,LOW); 
    SPI.transfer(0x0B); //high speed read instruction 
    SPI.transfer(0x00); //next 3 transfers are address bits A32 - A0 
    SPI.transfer(0x00); //So this will read the first byte on the chip 
    SPI.transfer(0x00); //last address bits 
    SPI.transfer(0xFF); //dummy byte is required to start sending data back to uP 
    SPI.transfer(0xFF); //I'm hoping that if I transfer a bullshit byte, the flash 
         //chip will transfer it's data to me in the same time 
    digitalWrite(SS_PIN,HIGH); 
    //End High Speed Read Instruction 
    return SPDR;  
} 

//will perform the read instruction starting from 
//startAddress and will receive numOfBytes bytes in 
//succession 
void receiveBytes(int numOfBytes, unsigned long startAddress) 
{ 
    digitalWrite(SS_PIN,LOW); 
    SPI.transfer(0x0B);//high speed read instruction 

} 

//will perform: 
// 1) Chip Erase 
// and loop through: 
// 1) Page Program 
// 2) increment Page 
//until the data has finished **note this can loop and over write beginning of memory 
void programData(){ 
    //Begin ChipErase Instruction 
    //See p. 17 of SST data sheet 
    digitalWrite(SS_PIN,LOW); 
    SPI.transfer(0x60);//chip erase instruction 
    digitalWrite(SS_PIN,HIGH); 
    delay(50);//spec'd time for CE to finish 
       //don't bother polling because time to program is irrelevant 
    //End ChipErase Instruction 

     //Begin WREN Instruction 
    //See p. 18 of SST data sheet 
    digitalWrite(SS_PIN,LOW); 
    SPI.transfer(0x06);//write enable instruction 
    digitalWrite(SS_PIN,HIGH); 
    //End WREN Instruction 

    digitalWrite(SS_PIN,LOW); 
    SPI.transfer(0x02); //page program instruction 
    SPI.transfer(0x00); //first 8 address bits 
    SPI.transfer(0x00); //2nd 8 address bits 
    SPI.transfer(0x00); //3rd 8 address bits 
    SPI.transfer(0xAA); //10101010 is the byte I should be writing 
    digitalWrite(SS_PIN,HIGH); 
    delayMicroseconds(3000); //wait 3 ms for page program 


    /* 
    //Begin Page-Program Instruction 
    //see p. 13 of SST data sheet 
    byte firstAddress = 0; 
    byte secondAddress = 0; 
    //this loop will write to every byte in the chips memory 
    //32,768 pages of 256 bytes = 8,388,608 bytes 
    for(unsigned int i = 0; i < 32,768; ++i) //long variable is number of pages 
    { 
     digitalWrite(SS_PIN,LOW); 
     ++secondAddress; //cycles from 0 to 255, counts pages 
     firstAddress = i>>8; // floor(i/256) 

     SPI.transfer(0x02);//Page-Program instruction byte 
     SPI.transfer(firstAddress); //increments every 256 pages i.e. at page 256 this should be 1 
     SPI.transfer(secondAddress); //increments every 256 bytes, i.e every page 
     SPI.transfer(0x00); //beginning of a page boundary 
     for(int j = 0; j < 256; ++j) //number of bytes per page 
     { 
      SPI.transfer(2program[(256*i) + j]);//data byte transfer    
     } 
     digitalWrite(SS_PIN,HIGH); 
     delayMicroseconds(2500); //2500us (2.5ms) delay for each page-program instruction to execute 
    } 
    //End Page-Program Instruction 
    */ 
} 

//Will prepare the chip for writing by performing: 
// 1) arm the status register 
// 2) Write Enable instruction 
//Only needs to be performed once! 
void enableProgramming(){ 
    //Begin EWSR & WRSR Instructions 
    //See p. 20 of SST data sheet for more info 
    digitalWrite(SS_PIN,LOW); //lower the SS pin 
    SPI.transfer(0x50); //enable write status register instruction 
    digitalWrite(SS_PIN,HIGH); //raise the SS pin 
    delay(10); 
    digitalWrite(SS_PIN,LOW); //lower the SS pin 
    SPI.transfer(0x01); //write the status register instruction 
    SPI.transfer(0x00);//value to write to register 
       //xx0000xx will remove all block protection 
    digitalWrite(SS_PIN,HIGH); 
    //End EWSR & WRSR Instructions 

    //Begin WREN Instruction 
    //See p. 18 of SST data sheet 
    digitalWrite(SS_PIN,LOW); 
    SPI.transfer(0x06);//write enable instruction 
    digitalWrite(SS_PIN,HIGH); 
    //End WREN Instruction 

} 

Vì vậy, đây được coi là một chương trình thử nghiệm mà chương trình 1 byte ont o đèn flash và sau đó đọc nó trở lại và hiển thị byte đó trên một mảng LED tôi có. Nếu bạn quan tâm đến mảng LED, nó có thể được tìm thấy ở đây: http://evilmadscience.com/tinykitlist/157

Tôi tin rằng chức năng đọc của tôi hoạt động vì lần đầu tiên tôi chạy điều này, tất cả 8 đèn LED sáng lên. Điều đó sẽ chỉ ra cho tôi rằng nó đọc bộ nhớ flash khi nó ở trong trạng thái nhà máy của tất cả các 1s. Bây giờ rõ ràng tôi đã vặn một cái gì đó với các văn bản bởi vì các byte mà sáng lên không tương ứng ở tất cả với các byte mà tôi đang cố gắng để chương trình.

Tôi cũng nên lưu ý rằng tôi đang sử dụng thư viện SPI mặc định cho Arduinos và các chức năng của bộ đệm khung hoạt động. Khi tôi làm frame1.WriteRow(toDisp), hoạt động chính xác và đã được thử nghiệm rộng rãi.

Nếu bất kỳ ai có thời gian hoặc kiên nhẫn để tìm ra những gì tôi đang làm sai sẽ cực kỳ tuyệt vời.

EDIT: Để giúp gỡ lỗi:
Các đèn LED đang được điều khiển bởi các chip điều khiển sử dụng giao diện SPI. Tôi đã không viết một phần của mã. Trên một dao động tôi có thể thấy dòng SCK được thúc đẩy bởi một phần của mã. Tuy nhiên, tôi cũng có một đầu dò trên chốt MOSI và nếu tôi không thắp sáng bất kỳ đèn nào, nó sẽ không bao giờ xuất hiện cao. Với tôi điều đó có nghĩa là tôi không gửi thông tin chính xác. AKA ... có lẽ SPI.transfer() của tôi cần một chức năng cho phép hoặc một cái gì đó?

+0

Bạn có các chốt chọn (SS) riêng biệt cho đèn flash và chip điều khiển? – AndrewStone

Trả lời

4

Đối với bất cứ ai vẫn còn tò mò vấn đề là chip bộ nhớ cực kỳ nhạy cảm với thời gian tăng chậm. Sau khi đặt trong một kích hoạt schmitt, tất cả mọi thứ đã làm việc hoàn hảo.

Các vấn đề liên quan