реклама на сайте
подробности

 
 
> Кто использовал EEPROM AVR, подскажите что не так?
Sirko
сообщение Feb 5 2009, 15:01
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795



Не получается сохранить данные в EEPROM ATMega8515.

Упростил код до минимума

Код
[font="Courier New"]int main(void){
     u08 eeData = 0x22;
     u16 eeAddr = 20;
     while(EECR & _BV(EEWE));       //    Ждать завершения предыдущей записи
     EEAR = (eeAddr & 0x01ff);      //    Проинициализировать регистр адреса
     EEDR = eeData;
     EECR |= _BV(EEMWE);            //    Установить флаг EEMWE
     EECR |= _BV(EEWE);             //    Начать запись в EEPROM

     while(EECR & _BV(EEWE));       //    Ждать завершения предыдущей записи
//   EEAR = 0;                      //    Сбросить адрес EEPEROM в "0"

     while(EECR & _BV(EEWE));       //    Ждать завершения предыдущей записи
     EEAR = (eeAddr & 0x01ff);      //    Проинициализировать регистр адреса
     EECR |= _BV(EERE);             //    Выполнить чтение
     eeData = EEDR;

     while(EECR & _BV(EEWE));       //    Ждать завершения предыдущей записи
//   EEAR = 0;                      //    Сбросить адрес EEPEROM в "0"[/font]

и тем не менее на выходе 0xFF.
Потратил много времени на поиск причины, но где ошибка, так и не понял. unsure.gif
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Sirko
сообщение Feb 5 2009, 18:35
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795



Народ, Огромное Вам Спасибо.
Конечно же -O0 имело место быть.

Уже даже начал кусочек ASMa цитировать, как обратил внимание на "кучу, кучу всего".
Жалко времени, гадко, что у самого ума не хватило, но опыта нет, а опыт - сын ...

Включил оптимизацию, все заработало.
Не знаю, как дальше пойдет дело, но просьба, если не сложно, прокоментируйте фрагмент кода, с которого все началось.
Возможно есть откровенные бока.
На счет маски 0x01ff - это была последняя надежда, хоть и глупая (где-то увидел).

CODE
void
EEPROM_write(volatile u08 bankNumber, volatile void *data, volatile u08 length){
cli();
u16 address = 1 + bankNumber * length;
u16 endAddress = address + length;
u08* pointer = (u08*) data;
while(address < endAddress){
while(EECR & _BV(EEWE)); // Ждать завершения предыдущей записи
EEAR = address++; // Проинициализировать регистр адреса
EEDR = *(pointer++);
EECR |= _BV(EEMWE); // Установить флаг EEMWE
EECR |= _BV(EEWE); // Начать запись в EEPROM
}
while(EECR & _BV(EEWE)); // Ждать завершения предыдущей записи
EEAR = 0; // Сбросить адрес EEPEROM в "0"
sei();
}

void
EEPROM_read(volatile u08 bankNumber, volatile void *data, volatile u08 length){
cli();
u16 address = 1 + bankNumber * length;
u16 endAddress = address + length;
u08* pointer = (u08*) data;
while(address < endAddress){
while(EECR & _BV(EEWE)); // Ждать завершения предыдущей записи
EEAR = address++; // Проинициализировать регистр адреса
EECR |= _BV(EERE); // Выполнить чтение
*(pointer++) = EEDR;
}
while(EECR & _BV(EEWE)); // Ждать завершения предыдущей записи
EEAR = 0; // Сбросить адрес EEPEROM в "0"
sei();
}


Может подскажите, как написать Си код, что бы без оптимизации нормально компилился.

Еще раз всем огромное Спасибо.

Сообщение отредактировал rezident - Feb 5 2009, 20:05
Причина редактирования: Уменьшение видимого объема цитаты исходника.
Go to the top of the page
 
+Quote Post
singlskv
сообщение Feb 5 2009, 20:09
Сообщение #3


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(Sirko @ Feb 5 2009, 21:35) *
Может подскажите, как написать Си код, что бы без оптимизации нормально компилился.
ИМХО, не нужно и пытаться без оптимизации что либо компилить, иначе Вы очень сильно
рискуете когда перестанет хватать флеши или скорости и Вы оптимизацию включите.
Вместо ловли ошибок по-одной по мере увеличения проги, Вы рискуете получить массу ошибок казалось бы на ровном месте...

Цитата
Код
    cli();
    while(EECR & _BV(EEWE));            //    Ждать завершения предыдущей записи
..............................................
        EECR |= _BV(EEMWE);            //    Установить флаг EEMWE
        EECR |= _BV(EEWE);            //    Начать запись в EEPROM
.............................................
    while(EECR & _BV(EEWE));            //    Ждать завершения предыдущей записи
.............................................                        //    Сбросить адрес EEPEROM в "0"
    sei();

запрещать прерывания необходимо только на время:
EECR |= _BV(EEMWE);
EECR |= _BV(EEWE);

ну и мне всегда не нравилось вот такое:
while(EECR & _BV(EEWE));//Ждать завершения предыдущей записи

Зачем ждать если в это время можно что-нить другое делать ?
А ждать там мб несколько миллисекунд...
Хотя конечно если реалтайм совсем не нужен, то можно и так...
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Feb 5 2009, 21:26
Сообщение #4


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(singlskv @ Feb 5 2009, 23:09) *
while(EECR & _BV(EEWE));//Ждать завершения предыдущей записи
Зачем ждать если в это время можно что-нить другое делать ?
А ждать там мб несколько миллисекунд...
Это точно. Проверять на занятость eeprom имеет смысл лишь единожды перед началом новых с ним операций.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 26th June 2025 - 08:49
Рейтинг@Mail.ru


Страница сгенерированна за 0.01365 секунд с 7
ELECTRONIX ©2004-2016