Главная » Микроконтроллеры
Призовой фонд
на июль 2017 г.
1. Осциллограф DSO138
Паяльник
2. Регулируемый паяльник 60 Вт
Паяльник
3. 200 руб.
От пользователей

Защита памяти EEPROM

Многие модели AVR раннего времени выпуска, как и другие микроконтроллеры семейства MCS-51, производимые фирмой Atmel, имели один существенный недостаток. Их память EEPROM была очень не надежной. Без каких-либо на то оснований ее содержимое могло изменится до неузнаваемости; имелись проблемы, при записи данных. В дальнейшем технология производства была улучшена и  положение вещей со временем, конечно, изменилось. Но, не смотря на это, ошибки при работе с EEPROM все-таки иногда случаются. Практика показывает, что наиболее распространенными причинами повреждения памяти являются импульсные помехи и сбои в цепях питания. Кроме того разрушение EEPROM может произойти на этапе программирования (даже если команды касаются только работы с fuse-битами или FLASH-памятью программ). Таким образом, для повышения достоверности хранимой в EEPROM информации иногда могут понадобиться дополнительные программные средства.

Проще всего это сделать, если отвести сохраняемой переменной несколько ячеек энергонезависимой памяти. Вероятность того, что все ячейки повредятся одновременно намного меньше. Хранить одно значение по двум адресам имеет смысл тогда, когда необходимо выявить только саму ошибку, но никак не восстановить утерянные данные. Дублирование по трем и более адресам EEPROM уже дает возможность найти и устранить проблему, когда один или несколько байтов случайно претерпели изменения. Подпрограммы, приведенные ниже, производят восстановление 8-разрядной величины, для хранения которой отведено 4 б памяти EEPROM. При считывании, сначала, проверяется условие равенства всех байтов памяти. Если значение хотя бы одного из них отличается от остальных, то данные были повреждены. В этом случае производится по парное сравнение между собой содержимого всех ячеек (всего 6 операций сравнения). В случае равенства хотя бы одной пары число, размещенное в этих двух ячейках, считается уцелевшим. Иначе данные не подлежат восстановлению.

    .def data  = R16 ;регистр c байтом данных
    .def eadrl = R24 ;регистр с младший байтом адреса EEPROM 
    .def eadrh = R25 ;регистр со старшим байтом адреса EEPROM
    .
	ldi   data,0x55         ;записываем число 0x55 в 
	ldi   eadrh,high(_var)  ;переменную _var из EEPROM-памяти
     ldi   eadrl,low(_var)   ;продублированную в 4-х байтах
     rcall ee_write_check
    . 
     ldi   eadrh,high(_var)  ;считываем переменную _var из
     ldi   eadrl,low(_var)   ;EEPROM-памяти 
	rcall ee_read_check
    .

           .eseg
           .org  0
       _var: .byte 4 ;4 зарезервированных ячейки в EEPROM-памяти 

;     Подпрограмм записи переменной в EEPROM-память 
; R16 – регистр с байтом для записи на входе из подпрограммы
; R25:R24 – регистровая пара для передачи адреса переменной 
;  EEPROM-памяти при входе в подпрограмму
; R17 – регистр для промежуточных операций
                        
ee_write_check:
     ldi   R17,4      ;инициализируем счетчик записанных байт
wc1: sbic  EECR,EEWE  ;ожидаем пока запись не будет закончена
     rjmp  wc1
     out   EEARH,R25  ;передаем адрес по которому 
     out   EEARL,R24  ;будет записано число
     out   EEDR,R16   ;передаем число
     sbi   EECR,EEMWE ;разрешаем запись
     sbi   EECR,EEWE  ;начинаем запись байта в EEPROM
     adiw  R24,1      ;увеличиваем адрес на 1
     dec   R17        ;производим запись числа во все 4 ячейки
     brne  wc1
     ret

;     Подпрограмм чтения переменной из EEPROM-памяти 
; R16 – регистр с прочитанным байтом на выходе из подпрограммы
; R25:R24 – регистровая пара для передачи адреса переменной 
;  EEPROM-памяти при входе в подпрограмму
; R17,R18,R19 – регистры для промежуточных операций
;   На выходе во Флаге T находится признак ошибки. Если T=0, то 
; данные успешно считаны, если T=1, то данные повреждены и не
; подлежат восстановлению                          

ee_read_check:
     set             ;при входе устанавливаем флаг ошибки
     rcall read_byte ;считываем 1-ый байт блока памяти
     in    R16,EEDR  ;EEPROM и размещаем его в R16
     rcall read_byte ;считываем 2-ой байт блока памяти 
     in    R17,EEDR  ;EEPROM и размещаем его в R17
     rcall read_byte ;считываем 3-ий байт блока памяти 
     in    R18,EEDR  ;EEPROM и размещаем его в R18
     rcall read_byte ;считываем 4-ый байт блока памяти 
     in    R19,EEDR  ;EEPROM и размещаем его в R19
     sbiw  R24,4     ;восстанавливаем адрес 
     push  R16       ;сохраняем регистр с 1-ым байтом
     and   R16,R17   ;сравниваем четыре байта 
     and   R16,R18   
     and   R16,R19 
     pop   R16       ;восстанавливаем регистр с 1-ым байтом
     brne  rc1       ;если все они равны между собой, то 
     clt             ;очищаем флаг ошибки и выходим из
     ret             ;подпрограммы с байтом в R16
rc1: cp    R16,R17   ;сравниваем 1-ый и 2-ой байты  
     brne  rc2       ;если они не равны то продолжаем сравнение  
     push  R16
     rjmp  rc7
rc2: cp    R16,R18   ;сравниваем 1-ый и 3-ий байты  
     brne  rc3       ;если они не равны то продолжаем сравнение  
     push  R16       
     rjmp  rc7
rc3: cp    R16,R19   ;сравниваем 1-ый и 4-ый байты  
     brne  rc4       ;если они не равны то продолжаем сравнение  
     push  R16
     rjmp  rc7
rc4: cp    R17,R18   ;сравниваем 2-ой и 3-ий байты  
     brne  rc5       ;если они не равны то продолжаем сравнение  
     push  R17
     rjmp  rc7
rc5: cp    R17,R19   ;сравниваем 2-ой и 4-ый байты
     brne  rc6       ;если они не равны то продолжаем сравнение  
     push  R17
     rjmp  rc7
rc6: cpse  R18,R19   ;сравниваем 3-ий и 4-ый байты и если
     ret             ;они не равны, то данные утеряны  
     push  R18
rc7: pop   R16       ;если найдена хотя бы одна одинаковая пара 
     rcall ee_write_check ;чисел, то восстанавливаем их в памяти 
     clt             ;и очищаем флаг ошибки на выходе  
     ret	       

read_byte:
     sbic  EECR,EEWE ;ожидаем пока запись не будет закончена
     rjmp  read_byte
     out   EEARH,R25 ;передаем адрес числа для чтения 
     out   EEARL,R24 
     adiw  R24,1     ;увеличиваем адрес на 1
     sbi   EECR,EERE ;разрешаем чтение
     ret

Перейти к следующей части:

Теги:

Котов Игорь Юрьевич Опубликована: 2012 г. 0 0
Я собрал 0 0
x

Оценить статью

  • Техническая грамотность
  • Актуальность материала
  • Изложение материала
  • Полезность устройства
  • Повторяемость устройства
  • Орфография
0

Средний балл статьи: 0 Проголосовало: 0 чел.

Комментарии (0) | Я собрал (0) | Подписаться

Статью еще никто не комментировал. Вы можете стать первым.
Добавить комментарий
Имя:
E-mail:
не публикуется
Текст:
Защита от спама:
В чем измеряется электрическая мощность?
Файлы:
 
Для выбора нескольких файлов использйте CTRL

Pickit 2 - USB-программатор PIC-микроконтроллеров
Pickit 2 - USB-программатор PIC-микроконтроллеров
Осциллограф DSO138 DC-DC регулируемый преобразователь 1.5-37В 2А с индикатором
вверх