Отговори на тема  [ 12 мнения ] 
Проблем с 24LC0x памети на Microchip 
Автор Съобщение
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Нед Дек 11, 2005 8:07 pm
Мнения: 10
Мнение Проблем с 24LC0x памети на Microchip
Здравейте,

За първи път пиша във форум и то по проблем който от 10 месеца ще ми изяде главата.
Та значи, имам си едно устройство което пише чат-пат в EEPROM (24LC01,04) по I2C. Софта за управлението на I2C е от 2000 година (за Atmel 89C52), но този април забелязах необясним проблем върху някои екземпляри чипове памет: ако се наложи в EEPROM-a да се запише стойност по-голяма от 127 (7FH), всички следващи байтове които четя, са твърдо 255 (FFH).
Гледах кода, чудех се, маех се, променях времена та белкем докарам всички възможни и невъзможни режими на работа, но за тези екземпляри този проблем оставаше в сила. Веднага установих че не е endurance проблем, защото ако сменях адреса на байта > 127, то проблемите започваха оттам.
Стигнах до там че си поръчах DSO+LA от Dynon (ELAB-080 - може лесно да се намери описание+free soft в нет-а). Гледам му диаграмките - приказка. Обаче при четене... от първия байт в който съм бил записал 255(или > 127) до последния - все 255-ци. И това от април месец насам. Чиповете са купувани от Комет-а (Comet) горе-долу малко преди април. Интересно, но старите устройства правени преди да купя тези чипове от 2000 година насам, са железни. Същевременно закупих всякакви I2C Microchip-ски памети от комет-а с различни дати на производство, но все се появяваше този проблем. Дори взех 33 MIPS-ов процесор (DS89C420).

Най-голямата гадост обаче е че ако един чип днес работи, нищо не ми гарантира че след (макс. до) 2 месеца няма да започне да прави тази магария. А аз, време да поддържам устройството в другия край на страната нямам, затова и не го развивам. Но държа клиентите да са доволни и да нямат проблеми.

Та има ли някой подобен проблем?
Ако някой може да помогне, много ще ме зарадва защото вече нямам идеи време и нерви да го чопля. Мога да приложа и диаграми на сигналите в случай на "добра" памет и "лоша" за моя уред ELAB-080). При изтегляне на софта, може лесно да се разгледат сигналите.

Поздрави, Иван.


Нед Дек 11, 2005 8:49 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Фев 25, 2005 1:58 pm
Мнения: 4585
Местоположение: US
Мнение 
...

_________________
Ето аз дишам, работя, живея и програми пиша тъй както умея, с проца под вежди се гледаме строго и боря се с него доколкото мога....


Последна промяна на Пет Фев 03, 2012 5:15 am, променена общо 1 път



Нед Дек 11, 2005 10:56 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пон Сеп 27, 2004 9:22 am
Мнения: 15501
Местоположение: София
Мнение 
Прилича ми на софтуерен бъг или бъг в хардуера на процесора. I2C памети се ползват вече 10 години къде ли не, няма начин подобен проблем да остане скрит. А и както го описваш не е само на конкретен тип. Така, че съм склонен да оневиня паметите в твоя случай.

_________________
"Да еба и шибаната държава" мислеше си Гошо, докато се опитваше да улучи кофата за боклук от балкона на осмия етаж.


Пон Дек 12, 2005 12:03 pm
Профил ICQ
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Нед Дек 11, 2005 8:07 pm
Мнения: 10
Мнение 
Току що минах през Futurel-a и взех памети на Atmel и SGS Tompson. Да ги видя те как ще се държат.
А иначе възможно е и софта да не е наред, но сравнявах версиите от 2001,2 година - същото, не съм пипал тази част от кода изобщо.
Тази вечер ще сложа във форума диаграмите които свалих с ELAB-a. За да ги рагледате и Вие ще Ви е нужно само да изтеглите софт-а от сайта на производителя. Дано някой нещо забележи. За мен са добри. Докарвах и на честота и на времена... Според мен са добри сигналите. Протокола мисля също че е спазен. Не знам - лудост някаква.

Седя и си мисля дали пък не е нещо от рода: изморена памет :) в смисъл такъв че аз записвам целия ми буфер (145 байта) наведнъж. Може Charge помпата да се успива след тези 'F'-ки и да не пълни за последващите '0'.


Пон Дек 12, 2005 3:36 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Фев 25, 2005 1:58 pm
Мнения: 4585
Местоположение: US
Мнение 
Нещо не мога да разбера, как така ще записваш 145 байта наведнъж ? Най-големите памети позволяват запис на 128 байта буфер наведнъж, т.е. ако искаш повече от 128 байта, трябва първо да генерираш стоп сигнала, да полираш до края на записа или просто да изчакаш няколко милисекунди и тогава да продължиш със следващия запис. Ако I2C-то ти е софтуерно и е на C, постни ако не е проблем кода, оттам най-лесно може да се ориентира човек. Значи аз използвам следния код и нямам дертове:
Код:
//
// I2C Master interface for PIC16/PIC18, software implementation
//
// Written by Svetoslav Pirev, Bulgaria, Plovdiv, ICQ: 321848589
// ver 1.0 - 30 Oct 2001
// ver 1.1 - 16 Jul 2003
// ver 1.2 - 08 Oct 2005
//

#bit _SCL=PORTC.3
#bit _SDA=PORTC.4
#bit _SCLTRIS=TRISC.3
#bit _SDATRIS=TRISC.4

//#define M2416
//#define M2432
//#define M2465
//#define M24128
//#define M24256
//#define M24512
#define M24515

#ifdef M2416   // 24LC16B
const int8 I2C_SLAVE = 0xA0;
const int16 I2C_EEPROM_SIZE = 2048;
const int8 I2C_PAGE_SIZE = 16;
#else

#ifdef M2432   // 24LC32
const int8 I2C_SLAVE = 0xA0;
const int16 I2C_EEPROM_SIZE = 8192;
const int8 I2C_PAGE_SIZE = 32;
#else

#ifdef M2465   // 24LC65
const int8 I2C_SLAVE = 0xA0;
const int16 I2C_EEPROM_SIZE = 8192;
const int8 I2C_PAGE_SIZE = 8;
#else

#ifdef M24128   // 24LC128
const int8 I2C_SLAVE = 0xA0;
const int16 I2C_EEPROM_SIZE = 16384;
const int8 I2C_PAGE_SIZE = 64;
#else

#ifdef M24256   // 24LC256
const int8 I2C_SLAVE = 0xA0;
const int16 I2C_EEPROM_SIZE = 32768;
const int8 I2C_PAGE_SIZE = 64;
#else

#ifdef M24512   // 24LC512
const int8 I2C_SLAVE = 0xA0;
const int32 I2C_EEPROM_SIZE = 65536;
const int8 I2C_PAGE_SIZE = 128;
#else

#ifdef M24515   // 24LC515
const int8 I2C_SLAVE = 0xA2;
const int32 I2C_EEPROM_SIZE = 65536;
const int8 I2C_PAGE_SIZE = 64;
#endif

#endif
#endif
#endif
#endif
#endif
const int8 I2C_NORMAL_BUS = 5;    // 5us - 100kHz bus
const int8 I2C_FAST_BUS = 2;    // 2us - 400kHz bus
const int8 I2C_WRITE_DELAY = 5;   // 5ms

// Variables for I2C interface
int16   i2caddr;
int8   i2cslave,   // I2C address of slave device
      i2cflags,   // I2C bus flags
      i2cdata,
      i2ccount,
      i2ccount2,
      i2ctemp;

#bit i2c_error=i2cflags.0
#bit i2c_page_cross=i2cflags.1

void I2CFreeBus(void);

void I2CInitMaster(void) {
   i2cslave = I2C_SLAVE;
   I2CFreeBus();
}

void I2CDelay(void)   {
   delay_us( I2C_NORMAL_BUS );
}

void I2CWriteDelay(void)   {
   delay_ms( I2C_WRITE_DELAY );
}

void InSDA(void)   {
   _SDATRIS = 1; _SDA = 0;
}

void OutSDA(void)   {
   _SDATRIS = 0;
}

void I2CFreeBus(void)   {
   _SDATRIS = 1; _SCLTRIS = 1;
}

void I2CGetBus(void)   {
   _SDA = 1; _SCL = 1;
   _SDATRIS = 0; _SCLTRIS = 0;
}

void IsI2CFree(void)   {
#asm
   bcf      i2c_error
   btfsc   _SDA
   btfss   _SCL
   bsf      i2c_error
#endasm
}

void I2CStart(void)   {
   _SCL = 1; I2CDelay();
   _SDA = 0; I2CDelay();
   _SCL = 0; I2CDelay();
}

void I2CStop(void)   {
   _SDA = 0; I2CDelay();
   _SCL = 1; I2CDelay();
   _SDA = 1; I2CDelay();
}

void I2CWrite(int8 data)   {
   i2ccount = 8;
   do {
      _RLF_F( data );
      if( _C )
         _SDA = 1;
        else
         _SDA = 0;
        _SCL = 1; I2CDelay();
       _SCL = 0; I2CDelay();
   } while( --i2ccount != 0 );
}

int8 I2CRead(void)   {
   InSDA();
     i2ccount = 8;
     do {
         _SCL = 1; I2CDelay();
         _C = 0;
      if( _SDA )
         _C = 1;
         _RLF_F( i2cdata );
         _SCL = 0; I2CDelay();
     } while( --i2ccount != 0 );
     OutSDA();
     return i2cdata;
}

void I2CReadAck(void)   {
   InSDA();      // Make _SDA to be input
   _SCL = 1; I2CDelay();
   i2c_error = 0;
   if( _SDA )
      i2c_error = 1;
    _SCL = 0; I2CDelay();
   OutSDA();
}

// Master in receive mode must generate AckNo signal for slave
void I2CWriteAck(void)   {
   _SDA = 0; I2CDelay();
   _SCL = 1; I2CDelay();
   _SCL = 0; I2CDelay();
}

void I2CWriteNotAck(void) {
   _SDA = 1; I2CDelay();
   _SCL = 1; I2CDelay();
   _SCL = 0; I2CDelay();
}

void I2CRepStart(void)   {
   _SDA = 1; I2CDelay();
   I2CStart();
   // Write device address for read operation
   I2CWrite( i2cslave | 0x01 );
   I2CReadAck();
}

void I2CWriteAddr(void)   {
   IsI2CFree();
   if( i2c_error )
      return;
   I2CGetBus();
   I2CStart();
#ifdef M24515
   i2cslave &= ~0x08;
   if( bit_test(i2caddr,15) )
      i2cslave |= 0x08;
#endif
   // Write device address
   I2CWrite( i2cslave ); I2CReadAck();
   if( i2c_error )
      return;
   // Write high byte of address in memory
   I2CWrite( (int8)(i2caddr>>8) ); I2CReadAck();
   if( i2c_error )
      return;
   // Write low byte ot address in memory
   I2CWrite( (int8)i2caddr); I2CReadAck();
}

void I2CCheckPageCross(void) {
   i2c_page_cross = 0;
   if( ++i2caddr % I2C_PAGE_SIZE == 0 )
      i2c_page_cross = 1;
}

// I2CReadByte() - Ok !
int8 I2CReadByte(int16 addr)   {
   i2caddr = addr;
   I2CWriteAddr( );
   if( i2c_error )
      goto RdByteErr;
   I2CRepStart();
   if( i2c_error )
      goto RdByteErr;
   i2cdata = I2CRead();
   I2CWriteNotAck();
   I2CStop(); I2CFreeBus();
   return i2cdata;
RdByteErr:
    I2CFreeBus();
   return 0;
}

// I2CReadBuffer() - Ok !
void I2CReadBuffer(int16 addr, char *dst,int8 count )   {
   i2caddr = addr;
   I2CWriteAddr( );
    if( i2c_error )
      goto RdSeqErr;
   I2CRepStart();
   if( i2c_error )
      goto RdSeqErr;
   do {
        *dst++ = I2CRead();
      if( --count == 0 )
         break;
#ifdef M24515
      if( ++i2caddr == 0x8000 )   {
         I2CStop();
         I2CWriteAddr( );
         if( i2c_error )
            break;
         I2CRepStart();
         if( i2c_error )
            break;
      } else
         I2CWriteAck();
#else
      I2CWriteAck();
#endif
   } while( 1 );
   I2CWriteNotAck();
   I2CStop();
RdSeqErr:
   I2CFreeBus();
   i2caddr = addr;
}

void I2CWriteByte(int16 addr,int8 data)   {
   i2caddr = addr;
   I2CWriteAddr( );
   if( i2c_error )
      goto WrByteErr;
   I2CWrite( data );
   I2CReadAck();
   if( i2c_error )
      goto WrByteErr;
   I2CStop();
   // Polling for end of write operation
   i2caddr = addr;
   while( 1 ) {
      I2CWriteAddr( );
      if( ! i2c_error )
         break;
      I2CInitMaster();
   }
   // Verify data
   I2CRepStart();
   if( i2c_error )
      goto   WrByteErr;
   if( data != I2CRead() )
      i2c_error = 1;
   I2CWriteNotAck();
WrByteErr:
   I2CStop();
   I2CFreeBus();
}

/*
Note: 24xx512, 24xx515, 24xx256, 24xx128 ( MicroChip & Atmel )
   Page write operations are limited to writing
   bytes within a single physical page, regardless
   of the number of bytes actually being
   written. Physical page boundaries start at
   addresses that are integer multiples of the
   page buffer size (or ‘page size’) and end at
   addresses that are integer multiples of
   [page size - 1]. If a page write command
   attempts to write across a physical page
   boundary, the result is that the data wraps
   around to the beginning of the current page
   (overwriting data previously stored there),
   instead of being written to the next page as
   might be expected. It is therefore necessary
   for the application software to prevent
   page write operations that would attempt to
   cross a page boundary.
*/
void I2CWriteBuffer(int16 addr,int8 *src,int8 count)   {
   i2ccount2 = count;
   i2caddr = addr;
   I2CWriteAddr( );
   if( i2c_error )
      goto I2CWriteBufferNotOk;
   while( 1 ) {
      I2CWrite( *src++ );
      I2CReadAck();
      if( i2c_error )
         goto I2CWriteBufferNotOk;
      if( --i2ccount2 == 0 )
         break;
#ifdef M24515
      I2CCheckPageCross();
      if( i2c_page_cross ) {
         I2CStop();
         while( 1 ) {
            I2CWriteAddr();
            if( ! i2c_error )
               break;
            I2CInitMaster();
         }
      }
#endif
   }
   I2CStop();
   i2caddr = addr;
   // Waiting memory with polling
   while( 1 ) {
      I2CWriteAddr();
      if( ! i2c_error )
         break;
      I2CInitMaster();
   }
   I2CRepStart();
   if( i2c_error )
      goto I2CWriteBufferNotOk;
   // Veryfication
   src -= count;
   i2ccount2 = count;
   do {
      if( *src++ != I2CRead() )
         goto I2CWriteBufferNotOk;
      if( --i2ccount2 == 0 )
         break;
#ifdef M24515
      I2CCheckPageCross();
      if( i2c_page_cross ) {
         I2CWriteNotAck();
         I2CStop();
         I2CWriteAddr();
         if( i2c_error )
            goto I2CWriteBufferNotOk;
         I2CRepStart();
         if( i2c_error )
            goto I2CWriteBufferNotOk;
      } else
         I2CWriteAck();
#else
      I2CWriteAck();
#endif
   } while( 1 );
   I2CWriteNotAck();      // Send Not Acknowledge signal
   goto I2CWriteBufferOk;
I2CWriteBufferNotOk:
   i2c_error = 1;
I2CWriteBufferOk:
   I2CStop();
   I2CFreeBus();
   i2caddr = addr;
}

_________________
Ето аз дишам, работя, живея и програми пиша тъй както умея, с проца под вежди се гледаме строго и боря се с него доколкото мога....


Последна промяна на Пет Фев 03, 2012 5:14 am, променена общо 1 път



Пон Дек 12, 2005 4:20 pm
Профил WWW
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Нед Дек 11, 2005 8:07 pm
Мнения: 10
Мнение 
Точно това правя: на микрочип паметите имат буфер 8 или 16 байта (LC04 e 16). Пиша в него започвайки от хххх0000 за младшите битове и при превъртане пращам Stop. След което пуулвам докато АСК-а ми се потвърди (свали), след което продължавам със следващата порция от 16 байта.
И това се върти докато завърша с буфера. Изял съм им даташеет-а до последната буква.

Инак малко по-нататък ще погледна кода който си постнал да видя дали няма да изкочи някой заек :).
Благодаря за отзивчивостта.


Пон Дек 12, 2005 5:22 pm
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Нед Дек 11, 2005 8:07 pm
Мнения: 10
Мнение 
На Паскал е кода, но чак довечера ще мога да го постна.


Пон Дек 12, 2005 5:25 pm
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Нед Дек 11, 2005 8:07 pm
Мнения: 10
Мнение 
Пустите му ланки, нямах нет снощи.
Ето резултатите от теста на паметите на Atmel, SGS-Thomson ИИИИИ победителя отзад напред Microchip:
1. Участници: по 10 броя от всяка марка, устройство с CPU DS89C420+Reset схема, индикатори-12 броя.
2. Начин на тестване:
2.1. Нормален
- Запис на 145 байта с пуулинг (буфер 16)
- Последователно четене на 145 байта.
2.2. Стресов - шашкане на захранването, статично напрежение, магнитно поле - от демагнетизатор на кинескопи
- Запис на 145 байта с пуулинг (буфер 16)
- Последователно четене на 145 байта.

Резултати.
Демагнетизатора шашка всички, но в най-малка степен SGS-Thomson. Този тест специално не ми се струва много коректно да съотнасям само към паметите, защото CPU-то и RESET схемата особено най-много се шашкат.
По другите показатели :
1. Атмел: Нито един чип който да откаже, или да извърши некоректна операция. Средно време за запис на буфера
[/b]1.349 мс[b]
2. SGS-Thomson: Нито един чип който да откаже, или да извърши некоректна операция. Средно време за запис на буфера 2.4 мс
3. Out of order-Мicrochip: от 10 чипа, само 4 отказоха да се справят с FF проблема. Държа да отбележа обаче че информацията записана до преди FF беше и остана коректна на цели 4 от "останалите работещи" 6. Разликата от 2 чипа дойде от стресовия тест-там не издържаха завалиите.

Та за моите нужди най-добър се оказа Атмелския чип.

Ако мога да съм полезен, ето и маркировката на Микрочипския звяр:
24LC04BI/P28K
0426
За останалите... просто не си ги записах но са все 2004 година произведени.

В заключение:
1. Не съм тествал чиповете на RHOM, които могат да се вземат от Комет-а. Но не се съмявам че ще работят коректно. Те обаче са с по-слаби характеристики: време на запис около 10мс, брой записи макс 100 000.
2. За моментното състояние на пазара в БГ аз лично препоръчвам Атмел и SGS-Thomson. И да не правя реклама, но май бях постнал от къде съм ги взел.
3. Както бях обещал ще публикувам листинга на кода писан на паскал за 8051. Имам един допотопен компилатор :) Все на някой може да влезе в работа.

Специални благодарности на всички които се отзоваха по този проблем!


Вто Дек 13, 2005 3:17 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пон Сеп 27, 2004 9:22 am
Мнения: 15501
Местоположение: София
Мнение 
Ей това е полезна информация. Тестове - резултати, статистика. Браво.

Естествено всеки може да подложи на съмнение Микрочипския провал, ама при положение че цената на паметите е в един порядък, що да си вкарва човек излишни проблеми.

_________________
"Да еба и шибаната държава" мислеше си Гошо, докато се опитваше да улучи кофата за боклук от балкона на осмия етаж.


Вто Дек 13, 2005 3:51 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пет Фев 25, 2005 1:58 pm
Мнения: 4585
Местоположение: US
Мнение 
...

_________________
Ето аз дишам, работя, живея и програми пиша тъй както умея, с проца под вежди се гледаме строго и боря се с него доколкото мога....


Последна промяна на Пет Фев 03, 2012 5:11 am, променена общо 1 път



Вто Дек 13, 2005 5:08 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Съб Сеп 25, 2004 12:32 pm
Мнения: 8382
Местоположение: София
Мнение 
Знам ли, аз използвах в Устройството памет тип 24LC515 на Майкрочип, забележки не са се появявали. Даже при четене стигнах до скорост от около 800 KHz. :)


Вто Дек 13, 2005 6:17 pm
Профил
Ранг: Минаващ
Ранг: Минаващ

Регистриран на: Нед Дек 11, 2005 8:07 pm
Мнения: 10
Мнение 
Едни проблеми ме утрепаха, като за капак и Windows-a ми искаше да активирам копието си съвместно с Microsoft... Само бели...

Та, ето го кода на Pascal:

--------------------------------
const
I2CMask = %00011000; I2CSlave = $A0; I2CRead = I2CSlave or $01;
{$IFDEF 04}
I2CRollOver = %0000000000001111; { 16 bytes for 24LC04 }
I2CRollOverNOT = %1111111111110000;
{$ELSE}
I2CRollOver = %0000000000000111; { 8 bytes for 24LC01 }
I2CRollOverNOT = %1111111111111000;
{$ENDIF}
var
I2Cbit, ByteToSend: byte DATA;
I2CAddr, I2CBegin: word DATA;


procedure PD;
begin
GA:=GA; GA:=GA; { Fictive. }
{$IFDEF CheckStack} if SP > MaxSP then MaxSP:=SP; {$ENDIF}
end;

procedure Start;
begin
Port_OR(P3, I2CMask); PD; { SCLSDA(1, 1); }
{ SDA:=true; SCL:=true; PD;}
SDA:=false; PD; PD; PD; PD; SCL:=false; PD;
end; { Start }

procedure StartInit;
begin
Port_OR(P3, I2CMask); PD; { SCLSDA(1, 1); }
while not SDA do
begin
SCL:=false; PD; SCL:=true; PD;
end;
SDA:=false; PD; PD; PD; PD; SCL:=false; PD;
end; { StartInit }

procedure Stop;
begin
Port_AND(P3, not I2CMask); PD; { SCLSDA(0, 0); }
{ SDA:=false; PD;}
SCL:=true; PD; PD; PD; PD; SDA:=true; PD;
end; { Stop }

procedure StopInit;
begin
Port_AND(P3, not I2CMask); PD; { SCLSDA(0, 0); }
SCL:=true; PD; PD; PD; PD; SDA:=true; PD;
end; { StopInit }

procedure OneCycle;
begin
SCL:=true; PD; PD; PD; PD; SCL:=false; PD;
end; { OneCycle }

procedure GetAck;
begin
{ Port_OR(P3, I2CMask); PD; { SCLSDA(1, 1); }
SDA:=true; PD; SCL:=true; PD; PD; PD; PD;
GA:=SDA;
SCL:=false; PD;
end; { GetAck }

procedure SendAck;
begin
{ Port_AND(P3, not I2CMask); PD; { SCLSDA(0, 0); }
SDA:=false; PD;
OneCycle;
end; { SendAck }

procedure NoAck;
begin
{ Port_OR(P3, I2CMask); PD; { SCLSDA(1, 1); }
SDA:=true; PD; SCL:=true; PD;
SCL:=false; PD;
end; { NoAck }

procedure SendByte;
begin
for I2Cbit:=1 to 8 do
begin
ACC:=ByteToSend; SDA:=ACC.7;
ByteToSend:=ByteToSend shl 1;
OneCycle;
end;
end; { SendByte }

const mo = 0 {3*48};

procedure SetI2CSlave;
begin
ByteToSend:=Hi(I2CAddr + mo) and %00000001;
ByteToSend:=I2CSlave or (ByteToSend shl 1);
SendByte;
GetAck;
end; { SetI2CSlave }

procedure SetI2CRead;
begin
ByteToSend:=Hi(I2CAddr + mo) and %00000001;
ByteToSend:=I2CRead or (ByteToSend shl 1);
SendByte;
GetAck;
end; { SetI2CRead }

procedure Load;
var i: byte XDATA;
begin
{ I2CAddr:=0;}
if I2CAddr > MaxBuffPerSave-1 then exit;
repeat
ResetWDT;
Start;
SetI2CSlave;
if not GA then
begin
ByteToSend:=Lo(I2CAddr +mo); SendByte;
GetAck;
if not GA then
begin
Start;
SetI2CRead;
end;
end;
if GA then
begin
Stop;
end;
until not GA;
for i:=I2CAddr to MaxBuffPerSave-1 do
begin
B:=0;
for I2Cbit:=1 to 8 do
begin
Port_OR(P3, I2CMask); { SCLSDA(1, 1); }
B:=B shl 1;
B:=B + ord(SDA);
SCL:=false; PD;
end;
if i = MaxBuffPerSave then NoAck
else SendAck;
Buff[i]:=B;
end;
Stop;
ResetWDT;
end; { Load }

procedure Save;
begin
{ I2CAddr:=$00;}
if I2CAddr > MaxBuffPerSave-1 then exit;
I2CBegin:=I2CAddr;
repeat
ResetWDT;
Start;
SetI2CSlave;
if not GA then
begin
ByteToSend:=Lo(I2CAddr +mo); SendByte;
GetAck;
if not GA then
begin
repeat
ByteToSend:=Buff[I2CAddr]; SendByte;
GetAck;
if not GA then inc(I2CAddr);
until (I2CAddr and I2CRollOver = %0000000000000000) or (I2CAddr >= MaxBuffPerSave) or GA;
if not GA then Stop
else if I2CBegin > (I2CAddr and I2CRollOverNOT) then I2CAddr:=I2CBegin
else I2CAddr:=I2CAddr and I2CRollOverNOT;
end;
end; { if not GA then }
until (I2CAddr >= MaxBuffPerSave);
ResetWDT;
HaveToSave:=false;
end; { Save }

----------------------------------------------------------------------------------------------------

Може нещо да съм изпуснал но бързо ще се разбере като се разгледа добре. Коментирания код на I2C примитивите е резултат от опитите да докарам всички скорости и времена на импулсите.

Инак Атмелските памети си работят така както и Микрочипските преди да ги развалят. :lol:
А и се сетих че за някой може да е интересен DSO-то който си купих. Малко е дървено откъм интерфейс но инак става:
http://www.dynoninstruments.com/index.html

Още веднъж благодаря на всички които взеха присърце терзанията ми. Много нерви щях да спестя ако се бях поразтърсил по-отрано и бях купил някакви други памети... но така разбрах че има и други доставчици на този свят :)


Вто Дек 20, 2005 1:30 am
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 12 мнения ] 

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 8 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни