Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: eeprom avr
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
RicLab
Добрый день.
в проекте необходимо записать переменную изменяемую пользователем в eeprom если она не изменяется в течении ~1сек.

Записываю так:
Код
eeprom int Datamemory=40;  // обьявляю переменную

void xxx (void)                      // функция вызываемая прерыванием таймера

if(oldvariable==newvariable){
x++;
                                          }
else                              {
x=0;
                                    };
if (x==3921){
Datamemory=variable;
x=0;
};

void main()void

variable2=Datamemory;


запись происходит не всегда и если записывается то мусор.
Как правильно организовать запись в eeprom?
Палыч
Запись в EEPROM длится несколько миллисекунд, поэтому делать это из прерываний таймера - нежелательно. Наверное, нужно в таймере выставлять флаг требования записи, а в бесконечном цикле основной программы его проверять, при необходимости - делать запись данных и сброс флага.
_Pasha
Обычно, делаю так
Код
{
  static timer_t time;
  if(oldvar != newvar)
  {
    time = get_tick();
    newvar = oldvar;
  }
  else if(tick_diff(time) > T1SEC)
  {
    EE_write(&Datamemory, &newvar, sizeof(newvar)); // void EE_write(void *dst, void*src, size_t size)
  }
}

Несколько пояснений.
1.timer_t, get_tick(), tick_diff(time) - не думаю, что будут вопросы, но - есть некоторая переменная, которая каждые 1мС инкрементируется в прерывании. Но она доступна только через get_tick().

2. Я бы нагло проигнорировал эту сладенькую фичу
Код
Datamemory=variable;
потому что запись в еепром это и ожидание его освобождения, и сравнение считанных данных с записываемыми для того, чтобы не допускать лишней перезаписи, и выполнение критических задач на время записи. Это как минимум. Можно добавлять еще и коррекцию контрольной суммы, запись в резервную страницу памяти, обновление образа еепром в озу - кому и что надобно для конкретного девайса.

3. Приведенная операция производится в бесконечном цикле обработки событий, собсна как и построено 99,9% задач для МК без оси. Но никак не в прерывании. Задача прерывания - быстро все сделать и выйти. Подобные зависоны, как у Вас - очень большая редкость, и они должны быть сильно обоснованы
RicLab
сделал так

Код
eeprom int Datamemory=40;             // обьявляем переменные
int readydata,var;

interrupt [TIM0_OVF] void timer0_ovf_isr(void){

readydata++;                                  //  в прерывании инкрементируем
};

while (1)
      {
    
      if (readydata==392) {                 // каждые ~ 100мсек
      readydata=0;                            
      if (Datamemory!=var) {       // если значение в eeprom не равно текущему значению
      Datamemory=var;               // записываем текущее значение в eeprom  
                                              };                      
                                     };
                };
}


временной интервал проверки уменьшил до 100мсек так как при оном равном 1 сек при выключении питания записывался мусор(при сбросе все нормально biggrin.gif ).
понимаю что так записывать наверно неправильно, так что жду критики. smile3046.gif
Палыч
Условие лучше записать так:
Код
if (readydata >= 392)
а к переменной readydata добавить спецификатор volatile
RicLab
Палыч
Спасибо, полностью согласен с вами! biggrin.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.