Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Запись на EEPROM
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Страницы: 1, 2
chajnik
Я совсем начинающий в программировании,нужна помочь спецов.Вот программа для 2-хразрядного семисегментного индикатора,цифры переключается кнопками + и - от 00 до 99,при отключении питания обнуляется,а нужно,чтобы на какой цифре остался,на такой и включался.Понимаю,что надо написать на eeprom,подскажите,пожалуйста,как это сделать,желательно попроще,ткнуть пальцем,как говориться,куда что.
Код
#include <mega16.h>
#include <delay.h>        

#define digit1 PORTD.6      
#define digit2 PORTD.5      
                    
flash char digits[] = {      
0b11000000,                   //0
0b11111001,                   //1
0b10100100,                   //2
0b10110000,                   //3
0b10011001,                   //4
0b10010010,                   //5
0b10000010,                   //6
0b11111000,                   //7
0b10000000,                   //8
0b10010000,                   //9
0b10111111,                   //-
0b11111111                    //пусто
};                  
char digit_out[2], cur_dig;  
char tik;

unsigned int indication;    
                      
void recoding(void) {      
            
   if (indication<100) {              
                                        
       digit_out[0]=indication%10;  
       indication=indication/10;              
        digit_out[1]=indication%10;    
       }                                            
}                                        

interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{    
    switch (cur_dig){
      
       case 0:{digit2=1;digit1=0;break;};  
       case 1:{digit1=1;digit2=0;break;};
    
    }  
    
    PORTA=digits[digit_out[cur_dig]];                    
                                                
    cur_dig++;                                  
                                                                
    if (cur_dig==2) cur_dig=0;                  
}

void main(void)
{

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x01;

#asm("sei")

  while (1)
                
     if(!PIND.1){                                        
     delay_ms(100);                                      
     tik++;                                              
     indication=tik;                                        
        if(indication>100) indication=100;          
     recoding();                                            

     }
     if(!PIND.2){                                    
     delay_ms(100);                                  
     tik--;                                              
     indication=tik;                                      
        if(indication<0) indication=0;          
     recoding();                                    
     }
}
  }
sKWO
по питанию МК диод шоттки + конденсатор достаточной ёмкости (470мкф).
подключить компаратор к диоду с обеих сторон, и исспользуя от него в прерывании по исчезновению питания отключаете периферию + режим слип и сохраняете переменные в энергонезависимую память
chajnik
Ну это совсем сложно,а вот отсюда http://electronix.ru/forum/index.php?showtopic=51328 -это-как сюда вставить?
long a=123456;
eeprom long b;
b=a;
sKWO
Поставьте перед переменной
Код
unsigned int indication;
квалификатор еепром, для код визиона это eeprom.
Правда энергонезависимая ячейка имеет ограниченый ресурс + Вы добавите "тормоз" на милисекунд так до 20 , в период записи чтения переменной когда прерывания запрещены компилятором, будет ли потом ваше устройство правильно - Вам виднее,период переполнения нулевого таймера мне неизвестен. обычно работают спеременными скопироваными в оперативку. еепром переменную обновляют при исчезновении питания.
можна также обявить переменную как неинициализируемую при старте программы МК.
zhevak
Цитата(sKWO @ Aug 26 2008, 00:01) *
Правда энергонезависимая ячейка имеет ограниченый ресурс.

Так-то оно так, но... Давайте посчитаем ресурс.

АТМЕЛ гарантирует 100000 циклов страния/записи.

Предположим, что мы делаем одно нажатие на кнопку в секунду. Без перерывов на обед/сон/туалет, без выходных и отпусков. За час, мы сделаем 3600 нажатий, если, конечно, палец при этом не отвалится. За сутки мы с трудом нагребем 86400, т.е. почти ресурс подойдем к исчерпанию ресурса.

В результате этого убойного теста, что мы имеем?
1. Инвалидность. Убитый в хлам палец.
2. Убитый денежный эквивалент, равный трем сменам.
3. А до гарантированного исчерпания ЕЕПРОМ, еще сра да сра.

Кроме того. Названная цифра 100000 --это та цифра, за которую Атмел отвечает своим лицом. Реально же это может превышать раз в 10. Здесь где-то на форуме кто-то целый год мучал память. И что? -- Не убил!!!

А теперь сравните это все со стоимостью микросхемы и оцените всю тяжесть написанию кода для экстренного сохранения для chajnik. Он не асс, как многие тут. Он -- начинающий.

Так что самый лучший способ -- писать значение в ЕЕПРОМ сразу после нажатия. Быстро, дешево, результативно. А что еще требуется от "стартовой" конструкции?
sKWO
Ну тогда остаётся посоветовать писать переменную в еепром не с нулевого адресса, а к примеру с десятого, тоже рекомендация атмел, а как это сделать по ссылке выше есть.
удачи.
И посмотрите тут, выводы сделайте сами http://electronix.ru/forum/index.php?showtopic=27560&hl=
defunct
Цитата(zhevak @ Aug 25 2008, 21:17) *
Кроме того. Названная цифра 100000 --это та цифра, за которую Атмел отвечает своим лицом. Реально же это может превышать раз в 10. Здесь где-то на форуме кто-то целый год мучал память. И что? -- Не убил!!!

Да нет, как раз мучали подругому. Не целый год, а очень быстро и целенаправленно убивали ячейки постоянной записью в них.
получилось в районе 107-115k записей.
Т.е. на 5-10% сверх заявленных 100k можно расчитывать, а уж никак не в 10 раз.

Цитата
Так что самый лучший способ -- писать значение в ЕЕПРОМ сразу после нажатия. Быстро, дешево, результативно.

С этим можно согласиться.

Цитата
Ну тогда остаётся посоветовать писать переменную в еепром не с нулевого адресса, а к примеру с десятого, тоже рекомендация атмел, а как это сделать по ссылке выше есть.

Эта рекомедация уже устаревшая. Она относилась к AT90 серии.
zltigo
Цитата(zhevak @ Aug 25 2008, 20:17) *
Так что самый лучший способ -- писать значение в ЕЕПРОМ сразу после нажатия. Быстро, дешево, результативно.

Не менее просто, но несколько разумнее, писать через несколько секунд после того, как клиент престанет жать на кнопочки.
Боинг749
Цитата(defunct @ Aug 26 2008, 00:34) *
Да нет, как раз мучали подругому. Не целый год, а очень быстро и целенаправленно убивали ячейки постоянной записью в них.
получилось в районе 107-115k записей.
Т.е. на 5-10% сверх заявленных 100k можно расчитывать, а уж никак не в 10 раз.

Вы не правы. Насколько мне помнится, речь кажется шла о 5,5млн записей.
defunct
Цитата(Боинг749 @ Aug 26 2008, 01:03) *
Вы не правы. Насколько мне помнится, речь кажется шла о 5,5млн записей.

Где? smile.gif В ДШ (если вы их читаете) есть цифра 100K перезаписей.
Производители eeprom не настолько тупы, чтобы писать 100k там, где реально есть 5.5M.

Проверить оч. легко:

Код
void test(void)
{
  static volatile __eeprom char x;
  char cnt = 0;
  long cycle = 0;

  do
  {
      x = ++cnt;
      cycle += 1;
  } while (x == cnt);

  printf("eeprom resource is %d cycles\n", cycle);
}
За 10-20 минут ячейку заелозит и увидите реальное число.
chajnik
Просто написать
Код
eeprom unsigned int indication;
-но это ничего не дает 07.gif
Прошу конкретно обьяснить,в какое место какое слово написать.
ARB
Изучаем ДШ!

Примерно, так:

void eeprom_write( uint16_t address, uint8_t data )
{
while( EECR & ( 1 << EEWE ) );
EEAR = address;
EEDR = data;
EECR |= ( 1 << EEMWE );
EECR |= ( 1 << EEWE );
}

uint8_t eeprom_read( uint16_t address )
{
while( EECR & ( 1 << EEWE ) );
EEAR = address;
EECR |= ( 1 << EERE );
return EEDR;
}


В начале main поставить tik = eeprom_read(0x00);
В recoding - eeprom_write(0x00, tik);
chajnik
CVAVR на эти слова сильно ругается,по всякому пробовал,короче ,никакого продвижения.
zhevak
Цитата(chajnik @ Aug 26 2008, 23:19) *
CVAVR на эти слова сильно ругается,по всякому пробовал,короче ,никакого продвижения.

Боюсь показаться не оригинальными, но попробуйте сделайть так:

Код
// Глобальные переменные
eeprom unsigned char eeVar; // Резервируем место для переменной в EEPROMe
...
void main(void)
{
  ...
  eeVar = 0x12;  // сохраняем значение
  ...
  x = a + b * eeVar; // Используем сохраненное значение при вычислении
}


если нужна начальная инициализация переменной при заливке программы в МК, то можете сделать так
Код
// Глобальные переменные
eeprom unsigned char eeVar = 0x34; // Резервируем место для переменной в EEPROMe
...
Боинг749
Цитата(defunct @ Aug 26 2008, 05:14) *
Где? smile.gif В ДШ (если вы их читаете) есть цифра 100K перезаписей.
Производители eeprom не настолько тупы, чтобы писать 100k там, где реально есть 5.5M.

Проверить оч. легко:

Код
void test(void)
{
  static volatile __eeprom char x;
  char cnt = 0;
  long cycle = 0;

  do
  {
      x = ++cnt;
      cycle += 1;
  } while (x == cnt);

  printf("eeprom resource is %d cycles\n", cycle);
}
За 10-20 минут ячейку заелозит и увидите реальное число.


Дык человек проверил... И написал, что Atmel просто осторожничает и перестраховывается...Тем более что Вы имели ввиду не datasheet а опыты этого чела..
Вот текст ответа этого чела(нашёл в инете):
"EEPROM - циклы чтения - перезаписи
Я прогонял кристаллы Classic (2313,8515,8535 всего 8 м/с)
на количество циклов перезаписи
методика:
1 пишу 0x55
2 проверяю 0x55
3 пишу 0xAA
4 проверяю 0xAA
5 периодически вывожу результаты на ЖКИ
т.е. долговременная сохранность записанного байта не проводилось
РЕЗУЛЬТАТ:
первый сбой 3,5 миллионов записей,
ячейку невозможно прописать через 4,6 миллионов записей.
Современные кристаллы не хуже, я в своих программах
использую щадящий режим записи EEPROM (с предпроверкой - если в ячейке такое же значение, то не пишем),
контролирую записанное значение в EEPROM.
После чтения и записи устанавливаю 0x00 адрес, который не использую (гарантия от произвольной записи при сбое).
При проектировании устройства я закладывал 3млн. записей,
ни секунды об этом не жалею - сбоев не было.
100.000 циклов перезаписи - Атмел очень осторожничает,
реально ресурс как у 24С08.
Удачи!
"
defunct
Цитата(Боинг749 @ Aug 26 2008, 21:23) *
Вот текст ответа этого чела(нашёл в инете):

Вероятно, у этого человека тест неправильно был построен.

IgorKossak приводил несколько другую цифру, и она кореллирует с тем, что написано в ДШ.
Сам я тоже проверял, мои цифры выше.
Всяко лучше самому измерить ресурс чем доверять сомнительным источникам, тем более когда речь идет о разнице в 50 раз.
Боинг749
Цитата(defunct @ Aug 26 2008, 22:48) *
Вероятно, у этого человека просто тест неправильно был построен.

С чего Вы взяли? Я же привёл описание теста, который проводил чел... Что в нём не правильного?

P.S. Врядли Atmel при указании цифры "100000 записей" предполагал, что сбои начнутся на 100001-й записи.. Наверняка заложил какой-то запас.... 100000 он гарантирует.. А вот несколько миллионов записей потребитель должен закладывать в свой проект "на свой страх и риск".
singlskv
Цитата(defunct @ Aug 26 2008, 05:14) *
Где? smile.gif В ДШ (если вы их читаете) есть цифра 100K перезаписей.
Производители eeprom не настолько тупы, чтобы писать 100k там, где реально есть 5.5M.

Проверить оч. легко:

Код
void test(void)
{
  static volatile __eeprom char x;
  char cnt = 0;
  long cycle = 0;

  do
  {
      x = ++cnt;
      cycle += 1;
  } while (x == cnt);

  printf("eeprom resource is %d cycles\n", cycle);
}
За 10-20 минут ячейку заелозит и увидите реальное число.

defunct не все так просто на самом деле...,
100000 это долговременная стабильность при НЕтепличных условиях(по температуре например) и
при питании 2,7(1,8)V, то есть 100000 при любых условиях гарантированны...

В какой-то момент я сам решил проверить работу своего хитрого алгоритма по сохранению
данных в EEPROM, так вот у меня не хватило терпения его проверять...,
в итоге пришлось на симуляторе прогнать все состояния...
При 2-3 миллионах записей на AT90S2313 сбоев не было ни в одной ячейке,
правда условия эксперимента были вполне тепличными.
Так что миллионы записей - вполне реально, НО все рассчеты НУЖНО делать
исходя из 100000...
Боинг749
Цитата(singlskv @ Aug 26 2008, 23:51) *
defunct не все так просто на самом деле...,
100000 это долговременная стабильность при НЕтепличных условиях(по температуре например) и
при питании 2,7(1,8)V, то есть 100000 при любых условиях гарантированны...

В какой-то момент я сам решил проверить работу своего хитрого алгоритма по сохранению
данных в EEPROM, так вот у меня не хватило терпения его проверять...,
в итоге пришлось на симуляторе прогнать все состояния...
При 2-3 миллионах записей на AT90S2313 сбоев не было ни в одной ячейке,
правда условия эксперимента были вполне тепличными.
Так что миллионы записей - вполне реально, НО все рассчеты НУЖНО делать
исходя из 100000...


Ну да.. Если у Вас MCU работает при колебаниях температуры от -40 до +125 при просадках питания и требуется сохранность данных в течении 20-ти лет, то тогда да, не следует рассчитывать что при таких условиях эксплуатации и записи инфы в EEPROM после 100000 перезаписей надеется, что инфа у Вас будет сохранна в течении 20-ти лет .

А если же у Вас MCU работает при комнатной температуре и при стабильном напряжении питания 5В и данные храняться в EEPROM-е не более одного дня (например запись логов каждый день) то на цифру "3 миллиона записей" можно вполне рассчитывать
defunct
Цитата(singlskv @ Aug 26 2008, 22:51) *
В какой-то момент я сам решил проверить работу своего хитрого алгоритма по сохранению
данных в EEPROM, так вот у меня не хватило терпения его проверять...,

Да причем тут хитрый алгоритм.
Давайте остановимся на нехитром счетчике, как в приведенном примере.
на проверку понадобится всего 10-20 минут, максимум полчаса и одна ячейка eeprom'a любого AVR чипа.
sKWO
Цитата(Боинг749 @ Aug 26 2008, 22:59) *
Ну да.. Если у Вас MCU работает при колебаниях температуры от -40 до +125 при просадках питания и требуется сохранность данных в течении 20-ти лет, то тогда да, не следует рассчитывать что при таких условиях эксплуатации и записи инфы в EEPROM после 100000 перезаписей надеется, что инфа у Вас будет сохранна в течении 20-ти лет .

А если же у Вас MCU работает при комнатной температуре и при стабильном напряжении питания 5В и данные храняться в EEPROM-е не более одного дня (например запись логов каждый день) то на цифру "3 миллиона записей" можно вполне рассчитывать

АВР типа Industrial работает в температурном диапазоне (из ДШ мега8) -40°C to 85°C.
Write/Erase Cycles: 10,000 Flash/100,000 EEPROM
Data retention: 20 years at 85°C/100 years at 25°C
может расскажете где взяли Вы другую цифру. Какие программы, алгоритмы использовали, какой чип?
zhevak
ну, блин, понеслась...

У chajnik, задавшего вопрос, стоит вполне конкретная задача типя селектора каналов TV для любимой тещи. Работать скорее всего его конструкция будет внутри помещения, в течении времени максимум -- год. Условия не полевые. Гарантия не требуется.

За год chajnik подрастет и будет делать все как надо. Сейчас ему нужно просто стартовать. Не важно как, не важно с какой надежностью. Главное -- сделать что-нимбудь работающее. Потом это маленький комочек знаний он откатает до размеров снеговика. Сами-то разве не так начинали?

Задача очень простая. А мы тут такой огород вспозали, будто заказчиком является не иначе как NASA.
Боинг749
Цитата(sKWO @ Aug 27 2008, 00:19) *
АВР типа Industrial работает в температурном диапазоне (из ДШ мега8) -40°C to 85°C.
Write/Erase Cycles: 10,000 Flash/100,000 EEPROM
Data retention: 20 years at 85°C/100 years at 25°C
может расскажете где взяли Вы другую цифру. Какие программы, алгоритмы использовали, какой чип?

"Другую цифру" (несколько миллионов записей) я взял из сообщения одного человека на форуме, информацию от которого я рассматриваю как достоверную (ибо врать ему резона не было ни какого)
singlskv
Цитата(defunct @ Aug 27 2008, 00:08) *
Да причем тут хитрый алгоритм.
Почти не при чем, просто я его пытался проверить в реальном железе
запустив запись и потом считывание и проверку по циклу, но проверить его было не суждено...,
ждать надоело...
Цитата
Давайте остановимся на безхитростном алгоритме - тупой счетчик, как в приведенном примере.
на проверку понадобится всего 10-20 минут, максимум полчаса и одна ячейка eeprom'a любого AVR чипа.
Примерно так в итоге и проверял, писал в ячейку счетчик а в соседнюю его побитовую
инверсию, если при считывании ячейки оказывались битыми, переходил на след пару ячеек,
при нажатии кнопки(тестил на STK500) в 4 старшие ячейки прописывал количество записей
в еепром и дальше просто ждал отключения.
После 5-7 часов работы количество записей в eeprom соответствовало
теоритическому(по скорости записи в еепром),
задействованно было только 2 первых ячейки...
Тест проводил раза 3 на следующих ячейках, терпения дождаться сбоя не хватило...

Если есть желание, запостите свой код для проверки под STK500 и AT90S2313
я его потестирую и потом выложу дамп еепрома.
defunct
Цитата(singlskv @ Aug 26 2008, 23:31) *
Если есть желание, запостите свой код для проверки под STK500 и AT90S2313
я его потестирую и потом выложу дамп еепрома.

Поставил на ночь крутиться на m16 до первого сбоя (программка приблизительно такая же как приводил выше, инкрементируется байт и пишется в последнюю ячейку eeprom'a)

Сейчас снял результаты:
77 -- ожидаемое значение
7F -- реальное значение
0x24240 - цикл
итого свалилось на 148032 цикле.
перезапустил тест крутиться дальше.

Вечером отпишусь еще, и выложу код теста.


О, уже упало, даже ждать вечера не пришлось:

AD -- ожидаемое значение
ED -- реальное значение
0x990A - цикл (39178)

После этого упало уже на 6160-м цикле
20 - ожидаемое
62 - прочитанное

А вы говорите миллионы...
Боинг749
Цитата(defunct @ Aug 27 2008, 08:37) *
Поставил на ночь крутиться на m16 до первого сбоя (программка приблизительно такая же как приводил выше, инкрементируется байт и пишется в последнюю ячейку eeprom'a)....

А вы говорите миллионы...

Уговорили.. Пойду тоже запущу тест... Не.. всё же не буду.. Есть всего 3 девайса на руках... И каждый из них нужен... Если угроблю хотя бы один - нЕначем будет отлаживаться..

Подождём .. Мож ещё кто тест EEPROM погоняет и скажет о результатах... Кому не жалко изничтожить для таких целей проц... И будем набирать статистику.. А то пока только всего один участник заявил, что износостойкойсть EEPROM только чуть-чуть больше заявленных в даташите, и один заявил, что износостойкость EEPROM на порядок превышает те "100000 записей", о которых говорится в даташите
zhevak
Цитата(defunct)
А вы говорите миллионы...


Ничего не понимаю... Может это мне так везет. :05:
Почти час "мучал скотину" -- накрутил чуть более миллиона циклов. Проблем не было!
условия испытания:
-- комнатная температура (на столе),
-- STK-500,
-- ATMEGA48-20PU, дата изготовления 0623, снизу на брюхе три строки
6F6183
35573С
1-PЗ0623 e3
-- комп.

В проге задействован пара светодиодов. Один преключается при каждой перезаписи, другой переключается через какждые 100 циклов перезаписи. Так же через каждые 100 циклов через UART отправляю в комп строку, где указываю текущий номер цикла.

На каждом цикле прога записывает младший байт номера цикла в ЕЕПРОМ по адресу 0х00. Выход из цикла по ошибке записи. При этом в комп уйдет строка с номером цикла, а так же это номер будет записан в ЕЕПРОМ по адресам 0х01-0х04.

Код написан CV (исходник "приартачен"). Код проги не является примером, для подражания или обучения.
Боинг749
Цитата(zhevak @ Aug 29 2008, 13:31) *
Почти час "мучал скотину" -- накрутил чуть более миллиона циклов. Проблем не было!

Запись длится где-то 8,5мСек. Чтобы сделать миллион записей потребуется 2,36 часа
singlskv
Цитата(Боинг749 @ Aug 29 2008, 13:39) *
Запись длится где-то 8,5мСек. Чтобы сделать миллион записей потребуется 2,36 часа
В mega48 3,4мсек , так что миллион как раз за час...
zhevak
Цитата(Боинг749 @ Aug 29 2008, 15:39) *
Запись длится где-то 8,5мСек. Чтобы сделать миллион записей потребуется 2,36 часа

Нет, нет. Я сразу же определил время записи. На Меге48 оно было 3.54-3.58 мс (LeCroy WaveJet-322).
Так же определил, что запись действительная, т.е. проц мне "в уши не дует": я останавливал процесс в разное время и смотрел программатором ЕЕПРОМ, каждый раз было случайное число.

После того, как убедился, что процесс записи не "липовый", запустил убивалку. Ожидал, что через 10 минут мега издохнет... крхе!
defunct
Цитата(zhevak @ Aug 29 2008, 12:31) *
Ничего не понимаю... Может это мне так везет. 05.gif

может быть и везет. А может что-то не так с тестом.

Цитата
Код написан CV (исходник "приартачен"). Код проги не является примером, для подражания или обучения.
Атача нет..
Боинг749
Цитата(zhevak @ Aug 29 2008, 14:45) *
Нет, нет. Я сразу же определил время записи. На Меге48 оно было 3.54-3.58 мс

А!!! Понятно... С мегами48 не работал... А в других мегах по 8,5 мСек.. Вот и усомнился wassat.gif
zhevak
Цитата(defunct @ Aug 29 2008, 16:50) *
может быть и везет. А может что-то не так с тестом.

Атача нет..


1. Да, было бы не плохо, что бы еще кто-нибудь помучал (-ся) с проблемой убийства ЕЕПРОМ.
2. Что-то не получилось подключить файлик. sad.gif дублитрую
defunct
Цитата(zhevak @ Aug 29 2008, 13:59) *
2. Что-то не получилось подключить файлик. sad.gif дублитрую

eeprom unsigned char sacrifice;
поменяйте:
volatile eeprom unsigned char sacrifice;
мало ли какие причуды CV оптимизатора, без volatile он вправе брать значение из регистра.
zhevak
Цитата(defunct @ Aug 29 2008, 17:09) *
eeprom unsigned char sacrifice;
поменяйте:
volatile eeprom unsigned char sacrifice;
мало ли какие причуды CV оптимизатора, без volatile он вправе брать значение из регистра.


Да вроде бы все путем. Вот ассемблерный код:

Код
;     148 unsigned char TestEE(unsigned char n)
;     149 {
_TestEE:
;     150   sacrifice = n;
;    n -> Y+0
    LD   R30,Y
    LDI  R26,LOW(_sacrifice)
    LDI  R27,HIGH(_sacrifice)
    RCALL __EEPROMWRB
;     151


а вызов __EEPROMWRB выглядит так:
Код
__EEPROMWRB:
    SBIC EECR,EEWE
    RJMP __EEPROMWRB
    IN   R25,SREG
    CLI
    OUT  EEARL,R26
    SBI  EECR,EERE
    IN   R24,EEDR
    CP   R30,R24
    BREQ __EEPROMWRB0
    OUT  EEDR,R30
    SBI  EECR,EEMWE
    SBI  EECR,EEWE
__EEPROMWRB0:
    OUT  SREG,R25
    RET


Да и просмотр с помощью программатора ЕЕПРОМ-овского байта (по адресу 00) говорит о том, что запись идет.
defunct
Цитата(zhevak @ Aug 29 2008, 14:31) *
Да и просмотр с помощью программатора ЕЕПРОМ-овского байта (по адресу 00) говорит о том, что запись идет.

К записи претензий нет. Я высказал только недоверие по отношению к чтению.

sacrifice = n;
return (sacrifice == n); <--- вот этот код может быть выброшен оптимизатором.

и функция будет возвращать всегда TRUE
zhevak
Цитата(defunct @ Aug 29 2008, 17:42) *
К записи претензий нет. Я высказал только недоверие по отношению к чтению.

sacrifice = n;
return (sacrifice == n); <--- вот этот код может быть выброшен оптимизатором.

и функция будет возвращать всегда TRUE

Ага. Спасибо! Я на это дело тоже обратил внимание. В самом начале, в самой первой версии, я вообще чтение (и сравнение) и запись в ЕЕПРОМ разнес в разные функции (разные вызовы). Тоже боялся, что компайлер заоптимизирует. Но когда посмотрел, что он дает на выходе, то решил сделать так, как это сейчас есть.

А по проге, в целом, -- не проблема! Я для того и выложил ее код, чтобы было от чего отталкиваться. Цель -- хотелось бы оценить границы хотя бы примерно. А то живем и знать не знаем, где "земля заканчивается и начинается небо".
Maik-vs
Цитата(zhevak @ Aug 29 2008, 15:31) *
Да вроде бы все путем. Вот ассемблерный код:

Интересно, однако

Код
;
_TestEE:
    LD   R30,Y                             ; байт в R30
    LDI  R26,LOW(_sacrifice)
    LDI  R27,HIGH(_sacrifice)       ; адрес в R27:R26
    RCALL __EEPROMWRB

__EEPROMWRB:
    SBIC EECR,EEWE
    RJMP __EEPROMWRB             ; подождать пока закончится прошлая запись
    IN   R25,SREG
    CLI
    OUT  EEARL,R26                   ; адрес из R26, r27 не пригодился :)
    SBI  EECR,EERE          
    IN   R24,EEDR                      ; почитали
    CP   R30,R24
    BREQ __EEPROMWRB0          ; ВЫЙТИ БЕЗ ЗАПИСИ, если записываем то же самое, что было
    OUT  EEDR,R30
    SBI  EECR,EEMWE
    SBI  EECR,EEWE                  ; если не то же самое, то записать
__EEPROMWRB0:
    OUT  SREG,R25
    RET


Получается, что если писать одно и то же то даже и никак не узнаешь, что запись реально не происходит! Вот так компилятор заботится об EEPROM'e.
Я вижу, что в сишной программе пишутся разные значения! Но является ли ЗАПИСЬЮ в полном смысле операция записи нулевого бита поверх нулевого и так же единицы поверх единицы? получается, что за цикл 00..255 младший бит перезапишется 255 раз, а старший - всего 2! Или байт портится целиком?
zhevak
Цитата
К записи претензий нет. Я высказал только недоверие по отношению к чтению.


вот кусок отассемблированного кода по чтению:
Код
;     152   return (sacrifice == n);
    LDI  R26,LOW(_sacrifice)
    LDI  R27,HIGH(_sacrifice)
    RCALL __EEPROMRDB
    LD   R26,Y
    RCALL __EQB12
    RJMP _0x78
;     153 }
;     154

оптимизации нет, на что указывает вызов __EEPROMRDB.


Цитата(Maik-vs @ Aug 29 2008, 18:08) *
операция записи нулевого бита поверх нулевого и так же единицы поверх единицы? получается, что за цикл 00..255 младший бит перезапишется 255 раз, а старший - всего 2! Или байт портится целиком?


Я записываю только младший байт.
Maik-vs
Цитата(zhevak @ Aug 29 2008, 16:15) *
Я записываю только младший байт.


При чём байт? Я говорил про бит. Когда испортилось, что Вы читаете? КАК портится ячейка памяти?
zhevak
Цитата(Maik-vs @ Aug 29 2008, 18:51) *
При чём байт? Я говорил про бит. Когда испортилось, что Вы читаете? КАК портится ячейка памяти?

Извините, это я как-то не сразу и понял, о чем Вы говорили. Ну вообще-то да, наверно что-то есть в том, что нужно "передергивать" все биты в байте равномерно.

Ведь, прежде чем записать новое значение в ячейку памяти (байт), автомат записи сначала ее стирает (0хFF). Под действие электрического импульса стирания попадают все биты, вне зависимости от их состояния. А вот под воздействие записи попадают только нулевые биты. Если это так, то тогда теоретически получается, что младший бит "изнашивается" быстрее, чем старший. А как оно практически получается -- х.з. Вот, типа мы все тут пытаемся установить.

Попробуйте переделать прогу, может у Вас быстрее получится убить мегу.
Maik-vs
Цитата(zhevak @ Aug 29 2008, 17:08) *
Ведь, прежде чем записать новое значение в ячейку памяти (байт), автомат записи сначала ее стирает (0хFF). Под действие электрического импульса стирания попадают все биты, вне зависимости от их состояния. А вот под воздействие записи попадают только нулевые биты. Если это так, то тогда теоретически получается, что младший бит "изнашивается" быстрее, чем старший. А как оно практически получается -- х.з. Вот, типа мы все тут пытаемся установить.

Если он сначала стирает, то вообще нужно писать нули постоянно. Естественно, обойдя чтение-сравнение.
Например писать 0-1-0-1... Никто почему-то не пишет, что происходит с битами, а может быть это и есть источник разницы в тестах?

Цитата(zhevak @ Aug 29 2008, 17:08) *
Попробуйте переделать прогу, может у Вас быстрее получится убить мегу.

"Нет уж, лучше Вы к нам!" (с) мои меги запаяны, в маленьких корпусах, как бы убивать из интереса дороговато будет, в смысле перепайки и прочего.
Боинг749
Цитата(Боинг749 @ Aug 27 2008, 10:49) *
Уговорили.. Пойду тоже запущу тест... Не.. всё же не буду.. Есть всего 3 девайса на руках... И каждый из них нужен... Если угроблю хотя бы один - нЕначем будет отлаживаться..

Подождём .. Мож ещё кто тест EEPROM погоняет и скажет о результатах... Кому не жалко изничтожить для таких целей проц... И будем набирать статистику.. А то пока только всего один участник заявил, что износостойкойсть EEPROM только чуть-чуть больше заявленных в даташите, и один заявил, что износостойкость EEPROM на порядок превышает те "100000 записей", о которых говорится в даташите

Я всё же решился lol.gif Пожертвовать ячейкой EEPROM с адресом 0 в одном из своих девайсов и решил провести тест до её убийства.

Тест запустил в 18-40 по московскому времени.. Темп записи примерно 7000 записей в минуту или 420000 записей в час. После каждых 256-ти записей (примерно раз в 2 сек) у меня моргает светодиод. Посмотрим когда он остановится. Если верить даташиту он должен был прекратить моргать в 18-54.. Сейчас 18-54.. Ещё пока моргает biggrin.gif

P.S. Прога написана на АСМ-е.. Так что никаких глюков оптимизатора lol.gif

Цитата(zhevak @ Aug 29 2008, 17:08) *
Ведь, прежде чем записать новое значение в ячейку памяти (байт), автомат записи сначала ее стирает (0хFF). Под действие электрического импульса стирания попадают все биты, вне зависимости от их состояния. А вот под воздействие записи попадают только нулевые биты. Если это так, то тогда теоретически получается, что младший бит "изнашивается" быстрее, чем старший.

Логично. Полностью с Вами согласен
Qwertty
Насчет более быстрого изнашивания младшего бита - defunct в 25 посте привел результаты своего теста, так там отличаются записанный и прочитанный байт вовсе не младшим разрядом. Например 7F <-> 77.
Боинг749
Прервал тест, чтобы доработать прогу тестирования в плане сохранения ожидавшегося значения. Т.е. я пишу в EEPROM по адресу 0 содержимое счётчика R25, а затем считываю содержимое ячейки 0 в R24. Так вот, раньше у меня не было предусмотрено сохранение R25 в случае обнаружения ошибки записи. Теперь же в случае ошибки я записываю R25, на котором остановился тест, в 7-ю ячейку EEPROM.

Расскажу вкратце как я тестирую. У меня есть малый цикл, когда R25 меняется от0 до 255. И большой когда инкрементируется 16-ти разрядный счётчик больших циклов.
После того, как R25 "пробежит" от о до 255 я инкрементирую счётчик больших циклов. Этот 3 копии счётчика больших циклов храню в EEPROM.

Раньше R25, на котором "споткнулся" тест, я не сохранял. Но после слов одного из участников, что при таком тесте более вероятно что первым "накроется медным тазом" самый младший бит, решил проверить эту теорию. Для чего переделал прогу и ПЕРЕзапустил тест.

Да, фусе-бит EESAVE, чтобы содержимое EEPROM не терялось при перепрошивке программы, у меня уже был запрограммирован ранее.

Далее, тест рестартует только после выключения/включения питания. Для чего в программе анализирую бит PORF.


И так.. Глянул сейчас на счётчик больших циклов. Он равен $096A. Значит было произведено $096A х 256 = 616000 записей... И полёт пока нормальный.. Светодиод по-прежнему мигает каждые 2 сек.

(написал это где-то час назад... Светодиод пока мигает lol.gif Ну не хочет никак убивацц ячейка )
Боинг749
Докладываю. Сейчас 22-52. Счётчик больших циклов показывает $183D. Т.е. уже было осуществлено не менее чем $183D х 256 = 1 588 480 УСПЕШНЫХ записей при том, что не было НИ ОДНОЙ не успешной. Засим свой эксперимент прекращаю (надоело ждать cool.gif ) так и не сумев "убить" ячейку EEPROM. Так что Atmel очень осторожничает говоря о ресурсе EEPROM в 100 000 записей 08.gif

Удачи!
Боинг749
Прошло больше 10 дней после того как я произвёл 1 600 000 записей в 0-ю ячейку EEPROM. Она по-прежнему себя "прекрасно чувствует" smile.gif Как было там записано $76 на момент прерывания теста так и до сих пор там $76. Т.е. никакой утечки заряда через 10 дней после 1 600 000 перезаписей не наблюдается. Ячейка не убита, а целёхонька
ARB
Решил проверить на 16 меге - в ячейку записывались поочередно 0x55, 0xAA, до первой ошибки.
Рухнуло примерно на 5млн. записей при температуре 24С.
Нагрел мегу до 80С rolleyes.gif, число циклов сократилось до ~1.2млн.
zhevak
Цитата(ARB @ Sep 9 2008, 18:43) *
Решил проверить на 16 меге - в ячейку записывались поочередно 0x55, 0xAA, до первой ошибки.
Рухнуло примерно на 5млн. записей при температуре 24С.
Нагрел мегу до 80С rolleyes.gif, число циклов сократилось до ~1.2млн.

Пожалуйста уточните -- при втором испытании (при повышенной температуре):
- вы работали с той же самой ячейкой или перестроились на другую,
- вы испытывали тот же экземпляр МК или взяли другой.

Попутно. Просто интересно, а повторная запись в ту же самую ячейку после сбоя дает положительный результат? На каком цикле произойдет следующая ошибка записи в эту же самую ячейку?
ARB
МК тот же, ячейки конечно же были разные.

Сразу после ошибки, для интереса, запускал повторно тест:
Пару раз для 24C - 37774 и 13266 циклов, дальше просто не стал проверять, ячейка возвращала 0х45, ожидалось 0х55.
При 80С - 743, после следующих перезапусков тоже показывало сколько-то циклов, возвращаемое значение - 0х2A.

Думаю, для некоторых ячеек сбой может быть первым и последним, может у кого это подтвердится smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.