Работа eeprom в AVR.

Обсуждаем контроллеры компании Atmel.
Ответить
Прорезались зубы
Сообщения: 238
Зарегистрирован: Сб янв 29, 2011 20:26:48

Сообщение 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
}



Спасибо! Смотрел разные статьи и библиотеки. Там намудренно, и не всё понятно. Помогите на моём примере, мне будет так нагляднее.
Реклама
Друг Кота
Аватара пользователя
Сообщения: 6337
Зарегистрирован: Вт апр 24, 2007 07:45:40
Откуда: Minsk

Сообщение 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К памяти программ - баловство. Это мое мнение, и я с ним полностью согласен :))
Реклама
Прорезались зубы
Сообщения: 238
Зарегистрирован: Сб янв 29, 2011 20:26:48

Сообщение king-live »

К сожалению с ассемблером не знаком! Кристалл - attiny13 - кристал 1Кб. Работаю в С. Есть следующий кусок программы. Но как его применить не знаю.

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

....
#define ERB eeprom_read_byte
#define ERS eeprom_read_block
#define EWB eeprom_write_byte
#define EWS eeprom_write_block
....
YS
Друг Кота
Аватара пользователя
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05

Сообщение YS »

Э, товарищ, это Вам AVR-libc reference manual читать надо.

Объявить переменную в EEPROM:

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

unsigned char EEMEM MyVar;
Записать значение:
eeprom_write_byte(&MyVar,<байт>);
Прочитать значение:
<байт>=eeprom_read_byte(&MyVar);
Для каждого типа есть соответствующие функции, типа eerpom_read_word(...) и т.п.
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Контактная информация:
Реклама
Эиком - электронные компоненты и радиодетали
Опытный кот
Аватара пользователя
Сообщения: 838
Зарегистрирован: Вт апр 12, 2011 18:38:19
Откуда: с Земли

Сообщение 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()
Все будет только лучше, в крайнем случае - хуже.
Реклама
Прорезались зубы
Сообщения: 238
Зарегистрирован: Сб янв 29, 2011 20:26:48

Сообщение king-live »

Спасибо! Попробую поработать с поступившей информацией.
Реклама
YS
Друг Кота
Аватара пользователя
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05

Сообщение YS »

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

#define EEPROM_SECTION  __attribute__ ((section (".eeprom")))
Зачем переопределять EEMEM?
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Контактная информация:
Опытный кот
Аватара пользователя
Сообщения: 838
Зарегистрирован: Вт апр 12, 2011 18:38:19
Откуда: с Земли

Сообщение coredumped »

YS писал(а):

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

#define EEPROM_SECTION  __attribute__ ((section (".eeprom")))
Зачем переопределять EEMEM?
А кто его переопределяет?
Все будет только лучше, в крайнем случае - хуже.
Вымогатель припоя
Аватара пользователя
Сообщения: 672
Зарегистрирован: Вт окт 27, 2009 22:39:19
Откуда: Москва

Сообщение md5sum »

coredumped писал(а):
YS писал(а):Зачем переопределять EEMEM?
А кто его переопределяет?
определяет #include <avr/eeprom.h>
king-live писал(а):Спасибо! Попробую поработать с поступившей информацией.
Только не советую указанный пример в таком виде в контролере проверять...
А то, через примерно 180 секунд еепрому кирдык будет...
— Не говорите мне что делать и я не скажу куда Вам идти...
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18783
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

чтобы не было кирдыку вместо eeprom_write_xxxxx надо использовать eeprom_update_xxxxx. последняя функция перед тем. как что-то писать в ячейку, проверяет, не то же самое там записано? и, если то же самое, то запись не делает - это сильно увеличивает ресурс записей, хотя на 100% и не снимает проблему...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Опытный кот
Аватара пользователя
Сообщения: 838
Зарегистрирован: Вт апр 12, 2011 18:38:19
Откуда: с Земли

Сообщение coredumped »

md5sum писал(а): Только не советую указанный пример в таком виде в контролере проверять...
А то, через примерно 180 секунд еепрому кирдык будет...
Это почему?
Все будет только лучше, в крайнем случае - хуже.
Вымогатель припоя
Аватара пользователя
Сообщения: 672
Зарегистрирован: Вт окт 27, 2009 22:39:19
Откуда: Москва

Сообщение md5sum »

coredumped писал(а):
md5sum писал(а): Только не советую указанный пример в таком виде в контролере проверять...
А то, через примерно 180 секунд еепрому кирдык будет...
Это почему?
eeprom_write_ пишет в eeprom всегда.
программа получается примерно 180 байт.
При тактовой частоте 1 МГц программа выполнится милион раз (заявленный ресурс eeprom) всего за 180 секунд....
Как поведет себя eeprom после исчерпания ресурса - можно только гадать....
— Не говорите мне что делать и я не скажу куда Вам идти...
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18783
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение ARV »

md5sum писал(а):При тактовой частоте 1 МГц программа выполнится милион раз (заявленный ресурс eeprom) всего за 180 секунд....
Как поведет себя eeprom после исчерпания ресурса - можно только гадать....
ну дык кагбэ в примере coredumped-а нет цикла... запись произойдет 1 раз и все... опасения излишни
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Вымогатель припоя
Аватара пользователя
Сообщения: 672
Зарегистрирован: Вт окт 27, 2009 22:39:19
Откуда: Москва

Сообщение md5sum »

coredumped Извиняюсь...Не досмотрел...
return 0 пристствует, тогда да, после него МК уйдет в пустой цикл...
— Не говорите мне что делать и я не скажу куда Вам идти...
Опытный кот
Аватара пользователя
Сообщения: 838
Зарегистрирован: Вт апр 12, 2011 18:38:19
Откуда: с Земли

Сообщение coredumped »

md5sum писал(а):coredumped Извиняюсь...Не досмотрел...
return 0 пристствует, тогда да, после него МК уйдет в пустой цикл...
Ниче, быват :) Я сам аж перепугался, неужто в бесконечный цикл засунул :shock:

ЗЫ: Кстати еще одну весч читал на фриксе - там чел один решил принудительно увалить епром и посчитать циклы, типа правду ли Атмел пишет нащет 100 000 циклов. Так вот, во время экспериментов выяснилось, что за неделю работы проги, ошибки не появились :shock: Потом выяснилось, что чел писал одно и то-же значение, что не приводит к деградации епром. Дохнет епром только от перезаписи с 0 на 1 - именно это вызывает стирание ячейки и соответственно уменьшение числа оставшихся циклов. Следующий эксперимент, где последовательно заносились значения 0x00 и 0xFF подтвердили догадку, и то епром отработал по-моему 3-х кратную норму, точно не помню.
Последний раз редактировалось coredumped Вс май 15, 2011 17:37:27, всего редактировалось 1 раз.
Все будет только лучше, в крайнем случае - хуже.
YS
Друг Кота
Аватара пользователя
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05

Сообщение YS »

return 0 пристствует, тогда да, после него МК уйдет в пустой цикл...
Посмотрите, что генерирует GCC - после main() он всегда вставляет rjmp PC-0x0000. Так что программа выполнится один раз и повиснет.

А return тут нафиг не нужен. Куда выходить-то? Только лишние два байта занимает.

***

Но в любом случае EEPROM имеет ограниченный ресурс. И это надо учитывать и не писать туда почем зря.
Последний раз редактировалось YS Вс май 15, 2011 17:43:30, всего редактировалось 1 раз.
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Контактная информация:
Опытный кот
Аватара пользователя
Сообщения: 838
Зарегистрирован: Вт апр 12, 2011 18:38:19
Откуда: с Земли

Сообщение coredumped »

YS писал(а):
return 0 пристствует, тогда да, после него МК уйдет в пустой цикл...
Посмотрите, что генерирует GCC - после main() он всегда вставляет rjmp PC-0x0000. Так что программа выполнится один раз и повиснет.

А return тут нафиг не нужен. Куда выходить-то? Только лишние два байта занимает.
Ну это какбэ является хорошим тоном :)) Чтоб компайлер не ругался.
Все будет только лучше, в крайнем случае - хуже.
YS
Друг Кота
Аватара пользователя
Сообщения: 7518
Зарегистрирован: Вс мар 29, 2009 22:09:05

Сообщение YS »

Ну это какбэ является хорошим тоном
Угу, угу. :) Но головой думать тоже иногда надо. И если программа никогда не выйдет, то зачем писать очевидную бессмыслицу?
Разница между теорией и практикой на практике гораздо больше, чем в теории.
Контактная информация:
Прорезались зубы
Сообщения: 238
Зарегистрирован: Сб янв 29, 2011 20:26:48

Сообщение king-live »

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

чтобы не было кирдыку вместо eeprom_write_xxxxx надо использовать eeprom_update_xxxxx. последняя функция перед тем. как что-то писать в ячейку, проверяет, не то же самое там записано? и, если то же самое, то запись не делает - это сильно увеличивает ресурс записей, хотя на 100% и не снимает проблему...
А это уже интересно! Не нужно отдельно проверять разницу информации. Но всёже запутался в полученной информации, вернее недопонимаю. Хожу гдето рядом....
Всёже опишите пожалуйста на моём примере. Я ещё слаб в программировании.
Спасибо.
Опытный кот
Аватара пользователя
Сообщения: 838
Зарегистрирован: Вт апр 12, 2011 18:38:19
Откуда: с Земли

Сообщение coredumped »

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

Вернуться в «AVR»