Страница 1 из 4
Работа eeprom в AVR.
Добавлено: Вс май 15, 2011 10:56:24
king-live
Доброго времени суток! Тема! Сохранение переменных (самым коротким путём) в eeprom и считывание из них при работе МК - в WinAVR . к примеру.
Код: Выделить всё
#include <avr/io.h>
#define F_CPU 4800000UL
#include <avr/eeprom.h>
char a;//переменная в eeprom
char b;//переменная в eeprom
void main()
{
....//считать переменную a из eeprom
....//считать переменную b из eeprom
.......
......
....//запись переменной a в eeprom
....//запись переменной b в eeprom
}
Спасибо! Смотрел разные статьи и библиотеки. Там намудренно, и не всё понятно. Помогите на моём примере, мне будет так нагляднее.
Re: Работа eeprom в AVR.
Добавлено: Вс май 15, 2011 13:29:28
Jack_A
king-live писал(а):Доброго времени суток! Тема! Сохранение переменных (самым коротким путём) в eeprom и считывание из них при работе МК - в WinAVR . к примеру.
Спасибо! Смотрел разные статьи и библиотеки. Там намудренно, и не всё понятно. Помогите на моём примере, мне будет так нагляднее.
Идти самым коротким путем - значит, я думаю, идти путем правильным. А еще более коротким - оставаться на месте.
Если поможет, то подпрограммы чтения и записи EEPROM - вот они.
Код: Выделить всё
;---------------------------------
; Процедура чтения массива из EEPROM
; Z - указатель на адрес для приема
; R18 - счетчик записываемых байт
; R17 - младший байт адреса EEPROM
; R16 - старший байт адреса EEPROM.
; Адрес и указатель модифицируется.
; Не переходит на следующую страницу EEPROM.
;---------------------------------
ERd: push r16
push r17
push r18
out EEARH,r16 ;адрес EEPROM L
Erlop: sbic EECR,EEWE ;ждем готовности
rjmp Erlop
out EEARL,r17 ;адрес EEPROM L
inc r17
sbi EECR,EERE ;строб чтения _
in r16,EEDR ;чтение данных
st z+,r16
dec r18
brne ERlop
pop r18
pop r17
pop r16
ret
; Процедура записи массива в EEPROM
; Z - указатель на записываемый массив.
; Если ZH<0, то это обнуление EEPROM ! ! !
; R18 - счетчик записываемых байт
; R17 - младший байт адреса
; R16 - старший байт адреса
; Не переходит на следующую страницу EEPROM.
;---------------------------------
EWr: nop
Ewr0: sbic EECR,EEWE ;ждем готовности к записи
rjmp EWr0
out EEARH,R16 ;пишем адрес
EWr00: tst ZH ; ||
brpl EWp ; ||
ldi r16,0 ; ||
rjmp EWr5 ; ||
EWp: ld R16,z+ ;читаем данные
EWr5: sbic EECR,EEWE ;ждем готовности к
rjmp EWr5
out EEARL,R17 ;пишем адрес
inc R17
out EEDR,R16
cli ; =============
sbi EECR,EEMWE ;разрешим доступ к EEPOM
sbi EECR,EEWE ;даем строб
sei ; =============
dec R18
brne EWr00 ;пишем остальные данные
EWr7: sbic EECR,EEWE ;ждем готовности к
rjmp EWr7
ldi R16,0 ;сбрасываем режим
out EECR,R16
ret
Написаны, увы, на ассемблере, бо я считаю, что применять ЯВУ для кристалла с 4К памяти программ - баловство. Это мое мнение, и я с ним полностью согласен

Re: Работа eeprom в AVR.
Добавлено: Вс май 15, 2011 13:57:27
king-live
К сожалению с ассемблером не знаком! Кристалл - attiny13 - кристал 1Кб. Работаю в С. Есть следующий кусок программы. Но как его применить не знаю.
Код: Выделить всё
....
#define ERB eeprom_read_byte
#define ERS eeprom_read_block
#define EWB eeprom_write_byte
#define EWS eeprom_write_block
....
Re: Работа eeprom в AVR.
Добавлено: Вс май 15, 2011 14:15:39
YS
Э, товарищ, это Вам
AVR-libc reference manual читать надо.
Объявить переменную в EEPROM:
Записать значение:
eeprom_write_byte(&MyVar,<байт>);
Прочитать значение:
<байт>=eeprom_read_byte(&MyVar);
Для каждого типа есть соответствующие функции, типа eerpom_read_word(...) и т.п.
Re: Работа eeprom в AVR.
Добавлено: Вс май 15, 2011 14:36:54
coredumped
Вот, лови (для WinAVR). Проще не бывает.
Код: Выделить всё
#include <avr/eeprom.h> // прототипы епромных функций
#define EEPROM_SECTION __attribute__ ((section (".eeprom"))) // для удобства написания/чтения программы
uint8_t eeprom_param1 EEPROM_SECTION = 0; // param1
uint16_t eeprom_param2 EEPROM_SECTION = 0; // param2
int main()
{
uint8_t value8 = 0xA5;
uint16_t value16 = 0x55AA;
//write to eeprom
eeprom_write_byte(&eeprom_param1, value8);
eeprom_write_word(&eeprom_param2, value16);
//read from eeprom
value8=eeprom_read_byte(&eeprom_param1);
value16=eeprom_read_word(&eeprom_param2);
return 0;
}
PS:Есть еще функции:
eeprom_read_dword()
eeprom_write_dword()
eeprom_read_block()
eeprom_write_block()
Re: Работа eeprom в AVR.
Добавлено: Вс май 15, 2011 14:58:16
king-live
Спасибо! Попробую поработать с поступившей информацией.
Re: Работа eeprom в AVR.
Добавлено: Вс май 15, 2011 15:20:32
YS
Код: Выделить всё
#define EEPROM_SECTION __attribute__ ((section (".eeprom")))
Зачем переопределять EEMEM?
Re: Работа eeprom в AVR.
Добавлено: Вс май 15, 2011 15:46:46
coredumped
YS писал(а):Код: Выделить всё
#define EEPROM_SECTION __attribute__ ((section (".eeprom")))
Зачем переопределять EEMEM?
А кто его переопределяет?
Re: Работа eeprom в AVR.
Добавлено: Вс май 15, 2011 15:54:09
md5sum
coredumped писал(а):YS писал(а):Зачем переопределять EEMEM?
А кто его переопределяет?
определяет #include <avr/eeprom.h>
king-live писал(а):Спасибо! Попробую поработать с поступившей информацией.
Только не советую указанный пример в таком виде в контролере проверять...
А то, через примерно 180 секунд еепрому кирдык будет...
Re: Работа eeprom в AVR.
Добавлено: Вс май 15, 2011 16:27:44
ARV
чтобы не было кирдыку вместо eeprom_write_xxxxx надо использовать eeprom_update_xxxxx. последняя функция перед тем. как что-то писать в ячейку, проверяет, не то же самое там записано? и, если то же самое, то запись не делает - это сильно увеличивает ресурс записей, хотя на 100% и не снимает проблему...
Re: Работа eeprom в AVR.
Добавлено: Вс май 15, 2011 16:54:56
coredumped
md5sum писал(а):
Только не советую указанный пример в таком виде в контролере проверять...
А то, через примерно 180 секунд еепрому кирдык будет...
Это почему?
Re: Работа eeprom в AVR.
Добавлено: Вс май 15, 2011 17:10:02
md5sum
coredumped писал(а):md5sum писал(а):
Только не советую указанный пример в таком виде в контролере проверять...
А то, через примерно 180 секунд еепрому кирдык будет...
Это почему?
eeprom_write_ пишет в eeprom всегда.
программа получается примерно 180 байт.
При тактовой частоте 1 МГц программа выполнится милион раз (заявленный ресурс eeprom) всего за 180 секунд....
Как поведет себя eeprom после исчерпания ресурса - можно только гадать....
Re: Работа eeprom в AVR.
Добавлено: Вс май 15, 2011 17:16:48
ARV
md5sum писал(а):При тактовой частоте 1 МГц программа выполнится милион раз (заявленный ресурс eeprom) всего за 180 секунд....
Как поведет себя eeprom после исчерпания ресурса - можно только гадать....
ну дык кагбэ в примере
coredumped-а нет цикла... запись произойдет 1 раз и все... опасения излишни
Re: Работа eeprom в AVR.
Добавлено: Вс май 15, 2011 17:25:12
md5sum
coredumped Извиняюсь...Не досмотрел...
return 0 пристствует, тогда да, после него МК уйдет в пустой цикл...
Re: Работа eeprom в AVR.
Добавлено: Вс май 15, 2011 17:29:17
coredumped
md5sum писал(а):coredumped Извиняюсь...Не досмотрел...
return 0 пристствует, тогда да, после него МК уйдет в пустой цикл...
Ниче, быват

Я сам аж перепугался, неужто в бесконечный цикл засунул
ЗЫ: Кстати еще одну весч читал на фриксе - там чел один решил принудительно увалить епром и посчитать циклы, типа правду ли Атмел пишет нащет 100 000 циклов. Так вот, во время экспериментов выяснилось, что за неделю работы проги, ошибки не появились

Потом выяснилось, что чел писал одно и то-же значение, что не приводит к деградации епром. Дохнет епром только от перезаписи с 0 на 1 - именно это вызывает стирание ячейки и соответственно уменьшение числа оставшихся циклов. Следующий эксперимент, где последовательно заносились значения 0x00 и 0xFF подтвердили догадку, и то епром отработал по-моему 3-х кратную норму, точно не помню.
Re: Работа eeprom в AVR.
Добавлено: Вс май 15, 2011 17:30:40
YS
return 0 пристствует, тогда да, после него МК уйдет в пустой цикл...
Посмотрите, что генерирует GCC - после main() он всегда вставляет rjmp PC-0x0000. Так что программа выполнится один раз и повиснет.
А return тут нафиг не нужен. Куда выходить-то? Только лишние два байта занимает.
***
Но в любом случае EEPROM имеет ограниченный ресурс. И это надо учитывать и не писать туда почем зря.
Re: Работа eeprom в AVR.
Добавлено: Вс май 15, 2011 17:39:27
coredumped
YS писал(а):return 0 пристствует, тогда да, после него МК уйдет в пустой цикл...
Посмотрите, что генерирует GCC - после main() он всегда вставляет rjmp PC-0x0000. Так что программа выполнится один раз и повиснет.
А return тут нафиг не нужен. Куда выходить-то? Только лишние два байта занимает.
Ну это какбэ является хорошим тоном

Чтоб компайлер не ругался.
Re: Работа eeprom в AVR.
Добавлено: Вс май 15, 2011 17:45:05
YS
Ну это какбэ является хорошим тоном
Угу, угу.

Но головой думать тоже иногда надо. И если программа
никогда не выйдет, то зачем писать очевидную бессмыслицу?
Re: Работа eeprom в AVR.
Добавлено: Вс май 15, 2011 17:48:35
king-live
Код: Выделить всё
чтобы не было кирдыку вместо eeprom_write_xxxxx надо использовать eeprom_update_xxxxx. последняя функция перед тем. как что-то писать в ячейку, проверяет, не то же самое там записано? и, если то же самое, то запись не делает - это сильно увеличивает ресурс записей, хотя на 100% и не снимает проблему...
А это уже интересно! Не нужно отдельно проверять разницу информации. Но всёже запутался в полученной информации, вернее недопонимаю. Хожу гдето рядом....
Всёже опишите пожалуйста на моём примере. Я ещё слаб в программировании.
Спасибо.
Re: Работа eeprom в AVR.
Добавлено: Вс май 15, 2011 17:53:11
coredumped
YS писал(а):Ну это какбэ является хорошим тоном
Угу, угу.

Но головой думать тоже иногда надо. И если программа
никогда не выйдет, то зачем писать очевидную бессмыслицу?
По здравому смыслу, Вы правы, но по стандарту языка - функция main() должна иметь тип int, опять-же, по стандарту, функция, которая не является void, должна возвращать значение. Это сейчас умный GCC warning кинет и скомпилит, а в старые времена, пока return ченить не поставишь, хрен оно скомпилится, я это хорошо помню, посему и леплю ретурны "на автомате".