Работа с памятью. Запись в EEPROM.

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
king-live
Прорезались зубы
Сообщения: 238
Зарегистрирован: Сб янв 29, 2011 20:26:48

Работа с памятью. Запись в EEPROM.

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

Доброго времени суток! Выпускаются множество устройств, охранных сигнализаций. При прошивке контроллера, приходилось в ручную редактировать EEPROM (записовал только "0"). Если не редактировать, то устройство не запускается. Как написать код так, чтобы без редактирования в ручную EEPROM, автоматически при первом включении устройства, в EEPROM записались "0" по адресу указанным в коде! Повторяю, только при первом включении устройства. При последующих включениях, устройство должно считывать с EEPROM, только данные которые были записанны при работе устройства, которые зависят от действия человека. Пример кода ниже.
Спасибо!

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


#include <avr/io.h>
#define F_CPU 1000000UL
#include <avr/eeprom.h>
#include <util/delay.h>
#define EEPROM_SECTION  __attribute__ ((section (".eeprom"))) // для удобства написания/чтения программы 

unsigned char ON=1;
unsigned char OFF=0;
unsigned char e=0;
unsigned char CANAL1;

uint8_t Mem1   EEPROM_SECTION=0; 

void Memori()
{
eeprom_update_byte(&Mem1,CANAL1);
}

int main(void)
{
DDRD=1;

CANAL1=OFF;

CANAL1=eeprom_read_byte(&Mem1);
while(1)
	{
	_delay_ms(500);
	e=e+1;
	if (e>200)
		{
		Memori();
		e=0;
		}
	if (bit_is_set(PIND,1))
	CANAL1=OFF;
	if (bit_is_set(PIND,2))
	CANAL1=ON;

	if(CANAL1==ON)	PORTD |= _BV(PD0);
	else	PORTD &=~_BV(PD0); 
	}
}
Реклама
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

Re: Работа с памятью. Запись в EEPROM.

Сообщение Мастер Ломастер »

а разве подготовить файл с данными для EEPROM и прошить его на этапе изготовления устройства нельзя? зачем вручную что-то править?
эта задача решается просто: надо использовать макрос EEMEM для описания переменных, тогда их начальные значения попадут в отдельный файл при компиляции:

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

#include <avr/io.h>
#define F_CPU 1000000UL
#include <avr/eeprom.h>
#include <util/delay.h>

EEMEM uint8_t Mem1 = 12; // в файл запишется 12 - начальное значение ячейки
битва с дураками проиграна, победители торжествуют. слава победителям!
Реклама
king-live
Прорезались зубы
Сообщения: 238
Зарегистрирован: Сб янв 29, 2011 20:26:48

Re: Работа с памятью. Запись в EEPROM.

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

Спасибо! Сейчас попробую!
king-live
Прорезались зубы
Сообщения: 238
Зарегистрирован: Сб янв 29, 2011 20:26:48

Re: Работа с памятью. Запись в EEPROM.

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

Вместо этой строчки EEMEM uint8_t Mem1=0; я написал EEMEM uint16_t Mem1=0; Но запоминаются только первые 8 бит. Так как у меня 10 каналов. значение в EEPROM должно было записаться в 2 байта. Последние 2 бита не записываются. Почему?
Реклама
Эиком - электронные компоненты и радиодетали
king-live
Прорезались зубы
Сообщения: 238
Зарегистрирован: Сб янв 29, 2011 20:26:48

Re: Работа с памятью. Запись в EEPROM.

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

А может архитектура памяти EEPROM не позволяет записать 2 байтовое значение?
Реклама
Аватара пользователя
Dmitry Dubrovenko
Поставщик валерьянки для Кота
Сообщения: 2360
Зарегистрирован: Вс янв 09, 2011 16:51:39
Откуда: Санкт-Ленинград
Контактная информация:

Re: Работа с памятью. Запись в EEPROM.

Сообщение Dmitry Dubrovenko »

king-live писал(а):А может архитектура памяти EEPROM не позволяет записать 2 байтовое значение?
Так это у Вас спросить надо, что у Вас за МК. :)))
ICQ нет, и, в ближайшее время, не будет.
Реклама
king-live
Прорезались зубы
Сообщения: 238
Зарегистрирован: Сб янв 29, 2011 20:26:48

Re: Работа с памятью. Запись в EEPROM.

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

Atmega8A
Аватара пользователя
coredumped
Опытный кот
Сообщения: 838
Зарегистрирован: Вт апр 12, 2011 18:38:19
Откуда: с Земли

Re: Работа с памятью. Запись в EEPROM.

Сообщение coredumped »

Обычно, для того чтобы проверить валидность данных в eeprom используют такой прием, как запись magic number в определенную ячейку. Я обычно использую 0x55AA.
Идея проста. Читаем из eeprom по адресу magic (я обычно использую 0 адрес, но это не обязательно). Если там находится магическое число, то значит конфигурация записана, можно считывать. Если магического числа нет, используем значения по умолчанию.
Вот кусочек кода. Метода проверена уже мульён раз, берите и пользуйтесь.

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

#include <avr/eeprom.h>
#define EEPROM_SECTION  __attribute__ ((section (".eeprom")))

uint16_t		eeprom_magic 	EEPROM_SECTION  = 0x55AA;	
uint16_t		eeprom_param 	EEPROM_SECTION  = 0;		


int main(void)
{
	uint16_t param;


	//load params
	if(eeprom_read_word(&eeprom_magic)==0x55AA)	
	{
		param=eeprom_read_word(&eeprom_param);
	}
	else
	{
	//set default values
		param= 0; 
// вот здесь можно сделать эту Вашу запись при первом включении
		eeprom_write_word(&eeprom_magic, 0x55AA); //write the magic number
		eeprom_write_word(&eeprom_param, param); //save parameter

	} 

}

PS: Ежели чего непонятно, спрашивайте не стесняйтесь :)
Все будет только лучше, в крайнем случае - хуже.
king-live
Прорезались зубы
Сообщения: 238
Зарегистрирован: Сб янв 29, 2011 20:26:48

Re: Работа с памятью. Запись в EEPROM.

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

Спасибо!
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

Re: Работа с памятью. Запись в EEPROM.

Сообщение Мастер Ломастер »

king-live писал(а):Вместо этой строчки EEMEM uint8_t Mem1=0; я написал EEMEM uint16_t Mem1=0; Но запоминаются только первые 8 бит. Так как у меня 10 каналов. значение в EEPROM должно было записаться в 2 байта. Последние 2 бита не записываются. Почему?
вы используете eeprom_update_word() для записи и eeprom_read_word() для чтения 16-битнгого числа?
битва с дураками проиграна, победители торжествуют. слава победителям!
king-live
Прорезались зубы
Сообщения: 238
Зарегистрирован: Сб янв 29, 2011 20:26:48

Re: Работа с памятью. Запись в EEPROM.

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

Вот где ошибка! Теперь проверю код! Спасибо!
king-live
Прорезались зубы
Сообщения: 238
Зарегистрирован: Сб янв 29, 2011 20:26:48

Re: Работа с памятью. Запись в EEPROM.

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

вы используете eeprom_update_word() для записи и eeprom_read_word() для чтения 16-битнгого числа?
И как теперь исправить? Вместо eeprom_read_word() пишу eeprom_read_int(). Компилятор выдаёт ошибку на int.
Аватара пользователя
coredumped
Опытный кот
Сообщения: 838
Зарегистрирован: Вт апр 12, 2011 18:38:19
Откуда: с Земли

Re: Работа с памятью. Запись в EEPROM.

Сообщение coredumped »

:idea: Совет: старайтесь избегать описаний int, word итп. Я вот пишу под разные платформы, и чтоб не вспоминать какая там размерность int, я всегда использую описания типа int16_t, uint16_t, int8_t итд. Сразу все становится предельно ясно.
Все будет только лучше, в крайнем случае - хуже.
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

Re: Работа с памятью. Запись в EEPROM.

Сообщение Мастер Ломастер »

king-live писал(а):
вы используете eeprom_update_word() для записи и eeprom_read_word() для чтения 16-битнгого числа?
И как теперь исправить? Вместо eeprom_read_word() пишу eeprom_read_int(). Компилятор выдаёт ошибку на int.
используйте те функции, что я указал.
битва с дураками проиграна, победители торжествуют. слава победителям!
king-live
Прорезались зубы
Сообщения: 238
Зарегистрирован: Сб янв 29, 2011 20:26:48

Re: Работа с памятью. Запись в EEPROM.

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

Спасибо! Буду разбираться!
Аватара пользователя
md5sum
Вымогатель припоя
Сообщения: 672
Зарегистрирован: Вт окт 27, 2009 22:39:19
Откуда: Москва

Re: Работа с памятью. Запись в EEPROM.

Сообщение md5sum »

king-live писал(а):Спасибо! Буду разбираться!
Загляните в файл avr/eeprom.h и увидите, что функции eeprom_read_int() там нет.
Вам надо самому ее писать или использовать те, что описаны в этом заголовочном файле.
А по Вашей задачке используйте явное преобразование типа:

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

EEMEM uint16_t A;
int B;
eeprom_write_word(&A,(uint16_t)B);
— Не говорите мне что делать и я не скажу куда Вам идти...
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»