Форум обсуждения систем  

Вернуться   Форум обсуждения систем "Умный дом", проектов Ардуино, OpenWRT и других DIY устройств > Форум умного дома > Сделай сам

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
Старый 18.01.2013, 11:46   #1
Admin
Administrator
 
Аватар для Admin
 
Регистрация: 12.04.2010
Адрес: Москва
Сообщений: 9,618
Вес репутации: 9825
Admin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant future
По умолчанию Подключение Flash ROM AT26DF321, AT26DF161A, AT26DF081A, AT26DF041 к Arduino

Очень часто сталкиваемся с тем что у Arduino слишком маленький объем памяти.
И как всегда не хватает места, для того что бы разместить графические, звуковые или текстовые файлы
Самое оптимальное решение это подключить микросхему Atmel AT26DFxxx по SPI. Она имеет малогабаритный 8-ми пиновый корпус SOIC. На сегодняшний день максимальный объем этой линейки микросхем составляем 64 мегабит что равняется 8 мГб
Datasheet на микросхему AT26DF161 AT26DF161A.rar

Схема подключения AT26DFxxx к Arduino
Нажмите на изображение для увеличения
Название: AT26DFxxx.png
Просмотров: 540
Размер:	8.0 Кб
ID:	743
Admin вне форума   Ответить с цитированием
Старый 18.01.2013, 14:24   #2
NEXT
Member
 
Регистрация: 23.11.2012
Сообщений: 47
Вес репутации: 186
NEXT has much to be proud ofNEXT has much to be proud ofNEXT has much to be proud ofNEXT has much to be proud ofNEXT has much to be proud ofNEXT has much to be proud ofNEXT has much to be proud ofNEXT has much to be proud ofNEXT has much to be proud of
По умолчанию

Хотелось бы видеть пример работы с дополнительной памятью.
NEXT вне форума   Ответить с цитированием
Старый 19.01.2013, 00:44   #3
Admin
Administrator
 
Аватар для Admin
 
Регистрация: 12.04.2010
Адрес: Москва
Сообщений: 9,618
Вес репутации: 9825
Admin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant future
По умолчанию

Функций для флешек AT26DF041, AT26DF081
Нашел здесь
PHP код:
// DataFlash code
#define DATAFLASH   1   // check for presence of DataFlash memory on JeeLink
#define FLASH_4MBIT 1   // original JL2 had 8 Mbit flash, new ones have 4 Mbit

#if DATAFLASH


#define DF_ENABLE_PIN   8           // PB0


#if FLASH_8MBIT
// settings for 1 Mbyte flash in JLv2
#define DF_PAGE_SIZE    256         // bytes
#define DF_BLOCK_SIZE   16          // number of pages erased at same time
#define DF_LOG_BEGIN    32          // first 2 blocks reserved for future use
#define DF_LOG_LIMIT    0x0F00      // last 64k is not used for logging
#define DF_MEM_TOTAL    0x1000      // 4096 pages, i.e. 1 Mbyte
#define DF_DEVICE_ID    0x1F45      // see AT26DF081A datasheet
#endif


#if FLASH_4MBIT
// settings for 0.5 Mbyte flash in JLv2
#define DF_PAGE_SIZE    256         // bytes
#define DF_BLOCK_SIZE   16          // number of pages erased at same time
#define DF_LOG_BEGIN    32          // first 2 blocks reserved for future use
#define DF_LOG_LIMIT    0x0700      // last 64k is not used for logging
#define DF_MEM_TOTAL    0x0800      // 2048 pages, i.e. 0.5 Mbyte
#define DF_DEVICE_ID    0x1F44      // see AT25DF041A datasheet
#endif


// structure of each page in the log buffer, size must be exactly 256 bytes
typedef struct {
    
byte data [248];
    
word seqnum;
    
long timestamp;
    
word crc;
} 
FlashPage;


// structure of consecutive entries in the data area of each FlashPage
typedef struct {
    
byte length;
    
byte offset;
    
byte header;
    
byte data[RF12_MAXDATA];
} 
FlashEntry;


static 
FlashPage dfBuf;     // for data not yet written to flash
static word dfLastPage;     // page number last written
static byte dfFill;         // next byte available in buffer to store entries


static byte df_present () {
    return 
dfLastPage != 0;
}


static 
void df_enable () {
    
// digitalWrite(ENABLE_PIN, 0);
    
bitClear(PORTB, 0);
}


static 
void df_disable () {
    
// digitalWrite(ENABLE_PIN, 1);
    
bitSet(PORTB, 0);
}


static 
byte df_xfer (byte cmd) {
    
SPDR = cmd;
    while (!
bitRead(SPSR, SPIF))
        ;
    return 
SPDR;
}


void df_command (byte cmd) {
    for (;;) {
        
cli();
        
df_enable();
        
df_xfer(0x05); // Read Status Register
        
byte status = df_xfer(0);
        
df_disable();
        
sei();
        
// don't wait for ready bit if there is clearly no dataflash connected
        
if (status == 0xFF || (status & 1) == 0)
            break;
    }    


    
cli();
    
df_enable();
    
df_xfer(cmd);
}


static 
void df_writeCmd (byte cmd) {
    
df_command(0x06); // Write Enable
    
df_deselect();
    
df_command(cmd);
}


static 
void df_deselect () {
    
df_disable();
    
sei();
}


void df_read (word block, word off, void* buf, word len) {
    
df_command(0x03); // Read Array (Low Frequency)
    
df_xfer(block >> 8);
    
df_xfer(block);
    
df_xfer(off);
    for (
word i = 0; i < len; ++i)
        ((
byte*) buf)[(byte) i] = df_xfer(0);
    
df_deselect();
}


void df_write (word block, const void* buf) {
    
df_writeCmd(0x02); // Byte/Page Program
    
df_xfer(block >> 8);
    
df_xfer(block);
    
df_xfer(0);
    for (
word i = 0; i < DF_PAGE_SIZE; ++i)
        
df_xfer(((const byte*) buf)[(byte) i]);
    
df_deselect();
}


// wait for current command to complete
void df_flush () {
    
df_read(0, 0, 0, 0);
}


static 
void df_wipe () {
    
Serial.println("DF W");
    
    
df_writeCmd(0x60);      // Chip Erase
    
df_deselect();
    
df_flush();
}


static 
void df_erase (word block) {
    
Serial.print("DF E ");
    
Serial.println(block);
    
    
df_writeCmd(0x20);      // Block Erase (4 Kbytes)
    
df_xfer(block >> 8);
    
df_xfer(block);
    
df_xfer(0);
    
df_deselect();
    
df_flush();
}


static 
word df_wrap (word page) {
    return 
page < DF_LOG_LIMIT ? page : DF_LOG_BEGIN;
}


static 
void df_saveBuf () {
    if (
dfFill == 0)
        return;


    
dfLastPage = df_wrap(dfLastPage + 1);
    if (
dfLastPage == DF_LOG_BEGIN)
        ++
dfBuf.seqnum; // bump to next seqnum when wrapping
    
    // set remainder of buffer data to 0xFF and calculate crc over entire buffer
    
dfBuf.crc = ~0;
    for (
byte i = 0; i < sizeof dfBuf - 2; ++i) {
        if (
dfFill <= i && i < sizeof dfBuf.data)
            
dfBuf.data[i] = 0xFF;
        
dfBuf.crc = _crc16_update(dfBuf.crc, dfBuf.data[i]);
    }
    
    
df_write(dfLastPage, &dfBuf);
    
dfFill = 0;
    
    
// wait for write to finish before reporting page, seqnum, and time stamp
    
df_flush();
    
Serial.print("DF S ");
    
Serial.print(dfLastPage);
    
Serial.print(' ');
    
Serial.print(dfBuf.seqnum);
    
Serial.print(' ');
    
Serial.println(dfBuf.timestamp);
    
    
// erase next block if we just saved data into a fresh block
    // at this point in time dfBuf is empty, so a lengthy erase cycle is ok
    
if (dfLastPage % DF_BLOCK_SIZE == 0)
        
df_erase(df_wrap(dfLastPage + DF_BLOCK_SIZE));
}


static 
void df_append (const void* buf, byte len) {
    
//FIXME the current logic can't append incoming packets during a save!


    // fill in page time stamp when appending to a fresh page
    
if (dfFill == 0)
        
dfBuf.timestamp = now();
    
    
long offset = now() - dfBuf.timestamp;
    if (
offset >= 255 || dfFill + 1 + len > sizeof dfBuf.data) {
        
df_saveBuf();


        
dfBuf.timestamp = now();
        
offset = 0;
    }


    
// append new entry to flash buffer
    
dfBuf.data[dfFill++] = offset;
    
memcpy(dfBuf.data + dfFill, buf, len);
    
dfFill += len;
}


// go through entire log buffer to figure out which page was last saved
static void scanForLastSave () {
    
dfBuf.seqnum = 0;
    
dfLastPage = DF_LOG_LIMIT - 1;
    
// look for last page before an empty page
    
for (word page = DF_LOG_BEGIN; page < DF_LOG_LIMIT; ++page) {
        
word currseq;
        
df_read(page, sizeof dfBuf.data, &currseq, sizeof currseq);
        if (
currseq != 0xFFFF) {
            
dfLastPage = page;
            
dfBuf.seqnum = currseq + 1;
        } else if (
dfLastPage == page - 1)
            break; 
// careful with empty-filled-empty case, i.e. after wrap
    
}
}


static 
void df_initialize () {
    
// assumes SPI has already been initialized for the RFM12B
    
df_disable();
    
pinMode(DF_ENABLE_PIN, OUTPUT);
    
df_command(0x9F); // Read Manufacturer and Device ID
    
word info = df_xfer(0) << 8;
    
info |= df_xfer(0);
    
df_deselect();


    if (
info == DF_DEVICE_ID) {
        
df_writeCmd(0x01);  // Write Status Register ...
        
df_xfer(0);         // ... Global Unprotect
        
df_deselect();


        
scanForLastSave();
        
        
Serial.print("DF I ");
        
Serial.print(dfLastPage);
        
Serial.print(' ');
        
Serial.println(dfBuf.seqnum);
    
        
// df_wipe();
        
df_saveBuf(); //XXX
    
}
}


static 
void discardInput () {
    while (
Serial.read() >= 0)
        ;
}


static 
void df_dump () {
    
struct { word seqnum; long timestamp; word crc; } curr;
    
discardInput();
    for (
word page = DF_LOG_BEGIN; page < DF_LOG_LIMIT; ++page) {
        if (
Serial.read() >= 0)
            break;
        
// read marker from page in flash
        
df_read(page, sizeof dfBuf.data, &curr, sizeof curr);
        if (
curr.seqnum == 0xFFFF)
            continue; 
// page never written to
        
Serial.print(" df# ");
        
Serial.print(page);
        
Serial.print(" : ");
        
Serial.print(curr.seqnum);
        
Serial.print(' ');
        
Serial.print(curr.timestamp);
        
Serial.print(' ');
        
Serial.println(curr.crc);
    }
}


static 
word scanForMarker (word seqnum, long asof) {
    
word lastPage = 0;
    
struct { word seqnum; long timestamp; } last, curr;
    
last.seqnum = 0xFFFF;
    
// go through all the pages in log area of flash
    
for (word page = DF_LOG_BEGIN; page < DF_LOG_LIMIT; ++page) {
        
// read seqnum and timestamp from page in flash
        
df_read(page, sizeof dfBuf.data, &curr, sizeof curr);
        if (
curr.seqnum == 0xFFFF)
            continue; 
// page never written to
        
if (curr.seqnum >= seqnum && curr.seqnum < last.seqnum) {
            
last = curr;
            
lastPage = page;
        }
        if (
curr.seqnum == last.seqnum && curr.timestamp <= asof)
            
lastPage = page;
    }
    return 
lastPage;
}


static 
void df_replay (word seqnum, long asof) {
    
word page = scanForMarker(seqnum, asof);
    
Serial.print("r: page ");
    
Serial.print(page);
    
Serial.print(' ');
    
Serial.println(dfLastPage);
    
discardInput();
    
word savedSeqnum = dfBuf.seqnum;
    while (
page != dfLastPage) {
        if (
Serial.read() >= 0)
            break;
        
page = df_wrap(page + 1);
        
df_read(page, 0, &dfBuf, sizeof dfBuf); // overwrites ram buffer!
        
if (dfBuf.seqnum == 0xFFFF)
            continue; 
// page never written to
        // skip and report bad pages
        
word crc = ~0;
        for (
word i = 0; i < sizeof dfBuf; ++i)
            
crc = _crc16_update(crc, dfBuf.data[i]);
        if (
crc != 0) {
            
Serial.print("DF C? ");
            
Serial.print(page);
            
Serial.print(' ');
            
Serial.println(crc);
            continue;
        }
        
// report each entry as "R seqnum time <data...>"
        
byte i = 0;
        while (
i < sizeof dfBuf.data && dfBuf.data[i] < 255) {
            if (
Serial.available())
                break;
            
Serial.print("R ");
            
Serial.print(dfBuf.seqnum);
            
Serial.print(' ');
            
Serial.print(dfBuf.timestamp + dfBuf.data[i++]);
            
Serial.print(' ');
            
Serial.print((int) dfBuf.data[i++]);
            
byte n = dfBuf.data[i++];
            while (
n-- > 0) {
                
Serial.print(' ');
                
Serial.print((int) dfBuf.data[i++]);
            }
            
Serial.println();
        }
        
// at end of each page, report a "DF R" marker, to allow re-starting
        
Serial.print("DF R ");
        
Serial.print(page);
        
Serial.print(' ');
        
Serial.print(dfBuf.seqnum);
        
Serial.print(' ');
        
Serial.println(dfBuf.timestamp);
    }
    
dfFill = 0; // ram buffer is no longer valid
    
dfBuf.seqnum = savedSeqnum + 1; // so next replay will start at a new value
    
Serial.print("DF E ");
    
Serial.print(dfLastPage);
    
Serial.print(' ');
    
Serial.print(dfBuf.seqnum);
    
Serial.print(' ');
    
Serial.println(millis());
}


#else // DATAFLASH


#define df_present() 0
#define df_initialize()
#define df_dump()
#define df_replay(x,y)
#define df_erase(x)


#endif 
Admin вне форума   Ответить с цитированием
Старый 08.03.2013, 10:35   #4
aszxx
Junior Member
 
Регистрация: 29.11.2012
Сообщений: 28
Вес репутации: 0
aszxx is a splendid one to beholdaszxx is a splendid one to beholdaszxx is a splendid one to beholdaszxx is a splendid one to beholdaszxx is a splendid one to beholdaszxx is a splendid one to beholdaszxx is a splendid one to behold
По умолчанию

По моему, оптимальнее SD карту сейчас подключать - и доступнее, и дешевле и даже размер можно меньше найти (если припаять разьем для microSD сможете). И ног столько же занимает. Да и стандартные библиотеки есть готовые...
aszxx вне форума   Ответить с цитированием
Ответ


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра
Комбинированный вид Комбинированный вид

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход


Текущее время: 02:41. Часовой пояс GMT +3.


Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Яндекс.Метрика