Страница 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:

Код: Выделить всё

unsigned char EEMEM MyVar;
Записать значение:
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 пристствует, тогда да, после него МК уйдет в пустой цикл...
Ниче, быват :) Я сам аж перепугался, неужто в бесконечный цикл засунул :shock:

ЗЫ: Кстати еще одну весч читал на фриксе - там чел один решил принудительно увалить епром и посчитать циклы, типа правду ли Атмел пишет нащет 100 000 циклов. Так вот, во время экспериментов выяснилось, что за неделю работы проги, ошибки не появились :shock: Потом выяснилось, что чел писал одно и то-же значение, что не приводит к деградации епром. Дохнет епром только от перезаписи с 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 ченить не поставишь, хрен оно скомпилится, я это хорошо помню, посему и леплю ретурны "на автомате".