|
Вопрос по работе с EEPROM в WinAVR, срочно нужна помощь |
|
|
|
May 25 2007, 07:09
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 22-12-06
Пользователь №: 23 780

|
Здравствуйте! Прошу помочь. Нужны функции записи и чтения из/в EEPROM AT90CAN128. Беру примеры из Даташита и компилирую WinAVR, не работают. Преверяю в AVRStudio - не работают. Вот эти функции из Даташита:
/********************************* * * ЗАПИСЬ БАЙТА В int-EEPROM * *********************************/ void RTEEPROMwrite (u16 adrEEPROM, u08 databyte) { u08 savedSREG; while(EECR & (1<<EEWE)); savedSREG = SREG // keep setting so it can be restored SREG &= ~0x80; EEAR = adrEEPROM; // set address EEDR = databyte; // set data EECR |= (1<<EEMWE); // set "write enable" bit EECR |= (1<<EEWE); // set "write" bit SREG = savedSREG; // restore SREG EEAR = 0;
} // end of RTEEPROMwrite
/********************************** * * ЧТЕНИЕ БАЙТА ИЗ int-EEPROM * **********************************/ u08 RTEEPROMread (u16 adrEEPROM) { while(EECR & (1<<EEWE)); EEAR = adrEEPROM; // set address EECR |= (1<<EERE); // set "read enable" bit EEAR = 0; return (EEDR);
} // end of RTEEPROMread
Хотел использовать функции из библиотеки:
uint8_t eeprom_read_byte (const uint8_t *addr);
void eeprom_write_byte (uint8_t *addr,uint8_t value);
Но не понятно как описать и работать с указателями на ячейки в EEPROM.
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 17)
|
May 25 2007, 08:42
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(AlexPT @ May 25 2007, 11:09)  Здравствуйте! Прошу помочь. Нужны функции записи и чтения из/в EEPROM AT90CAN128. Беру примеры из Даташита и компилирую WinAVR, не работают. Преверяю в AVRStudio - не работают. Вот эти функции из Даташита: С каким уровнем оптимизации компилируете? Состояния фюза M103C? Анатолий. Цитата(Tcom @ May 25 2007, 11:32)  unsigned char EEPROM_read (unsigned int uiAdress)// Чтение eeprom { while (EECR & (1<<EEWE)); EEAR = uiAdress; EECR |= (1<<EERE); return EEDR;} void EEPROM_write(unsigned int uiAdress , unsigned char ucData) // Запись eeprom { while(EECR & (1<<EEWE)); EEAR = uiAdress ; EEDR = ucData; EECR |= (1<<EEMWE); EECR |= (1<<EEWE); }
Вот рабочий пример с моей проги под WinAVR омпилятор. А что будет если между строками EECR |= (1<<EEMWE); EECR |= (1<<EEWE); произойдет прерывание? Анатолий.
|
|
|
|
|
May 25 2007, 09:56
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 22-12-06
Пользователь №: 23 780

|
С EEAR = 0 это опечатка. Компилирую с уровнем оптимизации 0. Что такое фюз М103С я не знаю (я только недавно начал работать с WinAVR, так что прошу отнестисть с пониманием), но такого слова в makefile нет. Хотелось бы по подробнее узнать по приведению типа u16 к типу const uint8_t*. Если можно поясните на примере. Приведенный пример попробывал, не работает да он практически не отличается Даташитовского. Может необходима какая-то запись в makefile или .h файлы.
|
|
|
|
|
May 25 2007, 10:12
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(AlexPT @ May 25 2007, 13:56)  С EEAR = 0 это опечатка. Компилирую с уровнем оптимизации 0. Что такое фюз М103С я не знаю Про М103С извините ошибся, подумал что речь идет о ATmega128. Посмотрите код который генериться для строк: EECR |= (1<<EEMWE); EECR |= (1<<EEWE); Не уровне оптимизации -O0: Код EECR |= (1<<EEMWE); 92: 80 91 3c 00 lds r24, 0x003C 96: 84 60 ori r24, 0x04; 4 98: 80 93 3c 00 sts 0x003C, r24 EECR |= (1<<EEWE); 9c: 80 91 3c 00 lds r24, 0x003C a0: 82 60 ori r24, 0x02; 2 a2: 80 93 3c 00 sts 0x003C, r24 И на -O1: Код EECR |= (1<<EEMWE); 8e: e2 9a sbi 0x1c, 2; 28 EECR |= (1<<EEWE); 90: e1 9a sbi 0x1c, 1; 28 В первом случае не соблюдается условие установки бита EEWE не позже 4 циклов после установки EEMWE. Не используйте уровень оптимизации -O0, он нужен в очень редких случаях для отладки. Используйте библиотечные функции, как с ними работать описано в avr-libc-user-manual в директори WinAVR/doc/avr-libc. Анатолий.
Сообщение отредактировал aesok - May 25 2007, 10:16
|
|
|
|
|
May 25 2007, 11:02
|
Участник

Группа: Участник
Сообщений: 19
Регистрация: 22-12-06
Пользователь №: 23 780

|
Большое спасибо за подсказку с оптимизацией. Все заработало.
|
|
|
|
|
Sep 29 2010, 22:10
|

Частый гость
 
Группа: Участник
Сообщений: 82
Регистрация: 1-03-10
Пользователь №: 55 731

|
добрый вечер решил поднять тему, просто проблема с Atmega128 в WinAVR как и у автора почти Код unsigned char EEPROM_read(unsigned int uiAdress)// Чтение { while (EECR & (1<<EEWE)); EEAR = 0x10; EECR |= (1<<EERE); return EEDR; }
void EEPROM_write(unsigned int uiAdress , unsigned char ucData) // Запись { char cSREG; while(EECR & (1<<EEWE)); EEAR = uiAdress; EEDR = ucData;
cSREG = SREG; cli(); EECR |= (1<<EEMWE); EECR |= (1<<EEWE); SREG = cSREG; } функция записи почему то не работает, так как читаю постоянно 0xff оптимизация -O1 подскажите пожалуйста в чем дело
|
|
|
|
|
Sep 30 2010, 04:51
|
Местный
  
Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940

|
используйте библиотечные функции. Например, для записи Код eeprom_write_word ((void*)0x10, power_s ); eeprom_write_word ((void*)0x12, syplsec ); eeprom_write_word ((void*)0x14, worksec ); Например, для чтения (в цикле) Код #define EEPROM_BASE 0x10 for(byte i=0; i<PARAM_COUNT; i++) sav_param.masu[i] = eeprom_read_word((void *)(EEPROM_BASE + i*sizeof(word)));
|
|
|
|
|
Sep 30 2010, 06:40
|

Профессионал
    
Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357

|
Цитата(aesok @ May 25 2007, 14:12)  Посмотрите код который генериться для строк: EECR |= (1<<EEMWE); EECR |= (1<<EEWE);
Не уровне оптимизации -O0: -O0 это полное отсутствие оптимизации, компилировать программу без нее глупо. Обычно это импользуется тогда, когда вы подозреваете оптимизатор в глючности, тогда отключив оптимизацию можно убедиться, что проблема в самой программе. Обычно для боевой программы используется уровень -Os Цитата(AlexPT @ May 25 2007, 11:09)  savedSREG = SREG // keep setting so it can be restored SREG &= ~0x80; А к чему такие сложности? Не проще ли написать cli(), sei()
|
|
|
|
|
Sep 30 2010, 06:50
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(777777 @ Sep 30 2010, 10:40)  -O0 это полное отсутствие оптимизации, .... Обычно для боевой программы используется уровень -Os Спасибо большое, я об этом уже 3 года как не знаю, побегу сейчас на рабору перекомпилирую проект, может заработаент!!! Цитата(777777 @ Sep 30 2010, 10:40)  А к чему такие сложности? Не проще ли написать cli(), sei() Такие сложности нужны для того, чтобы функция EEPROM_write делала только то что от нее требуется - записывала байт в EEPROM, и не делела то чего не должна, тоесть чтобы она не разрешала прерывания. Анатолий.
|
|
|
|
|
Sep 30 2010, 07:05
|

Профессионал
    
Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357

|
Цитата(aesok @ Sep 30 2010, 10:50)  Такие сложности нужны для того, чтобы функция EEPROM_write делала только то что от нее требуется - записывала байт в EEPROM, и не делела то чего не должна, тоесть чтобы она не разрешала прерывания. Так вот для этого и используются псевдофункции cli() и sei(). А зачем при этом еще и сохранять SREG - для меня загадка  Цитата(aesok @ Sep 30 2010, 10:50)  Спасибо большое, я об этом уже 3 года как не знаю, побегу сейчас на рабору перекомпилирую проект, может заработаент!!! Ответ не тебе, а топикстартеру, а то что он трехлетней давности - что ж, не заметил...
Сообщение отредактировал 777777 - Sep 30 2010, 07:06
|
|
|
|
|
Sep 30 2010, 07:19
|
Местный
  
Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940

|
Цитата(Mikron @ Sep 30 2010, 10:58)  alexeyv, спасибо, но в даташите я не нашел нужно ли как-то еще настраивать контроллер на запись/чтение или достаточно использовать только библиотечные функции? 1. Перед использованием необходимо подключить заголовочный файл #include <avr/eeprom.h> Настраивать ничего не надо Посмотрите файл <avr/eeprom.h>, там вы найдете еще несколько необходимых функций и макросов для работы с EEPROM 2. Если в EEPROM хранятся данные которые не надо терять при каждом программировании МК, то необходимо выставить FUSE-бит EESAVE 3. Т.к. запись происходит медленно и ресурс EEPROM ограничен, то запись необходимо производить как можно реже и в местах где быстродействие вашего алгоритма не критично (например, в прерываниях не рекомендуется). При перезаписи значений используйте функции eeprom_update_ХХХ 4. У некоторых МК встречал баг - при записи в EEPROM по адресу 0х00 процессор перестает работать. Так что не используйте этот адрес to 777777 Цитата А зачем при этом еще и сохранять SREG - для меня загадка Сохранение/восстановление SREG - для использования функции в критических местах/секциях (например, в прерываниях), чтобы корректно восстановить флаг глобального разрешения прерываний (т.к. функция его меняет). То есть если они были разрешены, то после выполнения функции останутся разрешены, а если запрещены - то останутся запрещены
Сообщение отредактировал alexeyv - Sep 30 2010, 07:19
|
|
|
|
|
Sep 30 2010, 07:27
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(777777 @ Sep 30 2010, 11:05)  Так вот для этого и используются псевдофункции cli() и sei(). А зачем при этом еще и сохранять SREG - для меня загадка  Код cli (); .... sei(); В этом примере код вначале запрещает прерываня, потом выполняет критичискую секцию затем разрешает преравания. Этот код кроме своей прямой функции выполняет еще одну паразитную, он ВСЕГДА разрешает преравания. Особенно опасно если он используеться в библиотечной функии, код которой програмисту не виден. Почему например при вызове функции EEPROM_write дожны разрешиться преравания? Ведь из имени этой функции следуеть что они пишет в EEPROM, про разрешения прерываний ни слова. Код u08 savedSREG; savedSREG = SREG // keep setting so it can be restored cli (); ... SREG = savedSREG; // restore SREG Этот код не изменяет состояния флага разрешения прерывиний. и никакого паразитного влияния на состояние флага не оказывает. Анатолий.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|