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

 
 
> Вопрос по работе с EEPROM в WinAVR, срочно нужна помощь
AlexPT
сообщение May 25 2007, 07:09
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 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.
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 17)
Tcom
сообщение May 25 2007, 07:32
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 360
Регистрация: 3-01-06
Из: Украина Запорожская обл.
Пользователь №: 12 792



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 омпилятор.
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение May 25 2007, 07:38
Сообщение #3


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Цитата(AlexPT @ May 25 2007, 10:09) *
Хотел использовать функции из библиотеки:
uint8_t eeprom_read_byte (const uint8_t *addr);
void eeprom_write_byte (uint8_t *addr,uint8_t value);
Но не понятно как описать и работать с указателями на ячейки в EEPROM.

Очевидно, приведением типа u16 к типу const uint8_t *.
Go to the top of the page
 
+Quote Post
singlskv
сообщение May 25 2007, 07:43
Сообщение #4


дятел
*****

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



Вот это лишнее:
Цитата(AlexPT @ May 25 2007, 11:09) *
EEAR = 0;
Go to the top of the page
 
+Quote Post
aesok
сообщение May 25 2007, 08:42
Сообщение #5


Знающий
****

Группа: Участник
Сообщений: 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);

произойдет прерывание?

Анатолий.
Go to the top of the page
 
+Quote Post
AlexPT
сообщение May 25 2007, 09:56
Сообщение #6


Участник
*

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



С EEAR = 0 это опечатка. Компилирую с уровнем оптимизации 0. Что такое фюз М103С я не знаю (я только недавно начал работать с WinAVR, так что прошу отнестисть с пониманием), но такого слова в makefile нет.
Хотелось бы по подробнее узнать по приведению типа u16 к типу const uint8_t*. Если можно поясните на примере.
Приведенный пример попробывал, не работает да он практически не отличается Даташитовского. Может необходима какая-то запись в makefile или .h файлы.
Go to the top of the page
 
+Quote Post
aesok
сообщение May 25 2007, 10:12
Сообщение #7


Знающий
****

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
AlexPT
сообщение May 25 2007, 11:02
Сообщение #8


Участник
*

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



Большое спасибо за подсказку с оптимизацией. Все заработало.
Go to the top of the page
 
+Quote Post
defunct
сообщение May 25 2007, 13:09
Сообщение #9


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



В WinAVR есть готовые функции для работы с eeprom.
смотрите eeprom.h.
Предпочтительнее использовать их, т.к. они работают вне зависимости от уровня оптимизации.

#include <avr/eeprom.h>

eeprom_write_byte
eeprom_read_byte
и т.п.
Go to the top of the page
 
+Quote Post
Mikron
сообщение Sep 29 2010, 22:10
Сообщение #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
подскажите пожалуйста в чем дело
Go to the top of the page
 
+Quote Post
alexeyv
сообщение Sep 30 2010, 04:51
Сообщение #11


Местный
***

Группа: Участник
Сообщений: 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)));

Go to the top of the page
 
+Quote Post
Mikron
сообщение Sep 30 2010, 04:58
Сообщение #12


Частый гость
**

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



alexeyv, спасибо, но в даташите я не нашел
нужно ли как-то еще настраивать контроллер на запись/чтение
или достаточно использовать только библиотечные функции?
Go to the top of the page
 
+Quote Post
ARV
сообщение Sep 30 2010, 05:47
Сообщение #13


Профессионал
*****

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



Цитата(Mikron @ Sep 30 2010, 08:58) *
alexeyv, спасибо, но в даташите я не нашел
нужно ли как-то еще настраивать контроллер на запись/чтение
или достаточно использовать только библиотечные функции?
достаточно библиотечных, только не забывайте о том, что запись длится относительно долго


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
777777
сообщение Sep 30 2010, 06:40
Сообщение #14


Профессионал
*****

Группа: Участник
Сообщений: 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()
Go to the top of the page
 
+Quote Post
aesok
сообщение Sep 30 2010, 06:50
Сообщение #15


Знающий
****

Группа: Участник
Сообщений: 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, и не делела то чего не должна, тоесть чтобы она не разрешала прерывания.

Анатолий.
Go to the top of the page
 
+Quote Post
777777
сообщение Sep 30 2010, 07:05
Сообщение #16


Профессионал
*****

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



Цитата(aesok @ Sep 30 2010, 10:50) *
Такие сложности нужны для того, чтобы функция EEPROM_write делала только то что от нее требуется - записывала байт в EEPROM, и не делела то чего не должна, тоесть чтобы она не разрешала прерывания.

Так вот для этого и используются псевдофункции cli() и sei(). А зачем при этом еще и сохранять SREG - для меня загадка smile.gif

Цитата(aesok @ Sep 30 2010, 10:50) *
Спасибо большое, я об этом уже 3 года как не знаю, побегу сейчас на рабору перекомпилирую проект, может заработаент!!!

Ответ не тебе, а топикстартеру, а то что он трехлетней давности - что ж, не заметил...

Сообщение отредактировал 777777 - Sep 30 2010, 07:06
Go to the top of the page
 
+Quote Post
alexeyv
сообщение Sep 30 2010, 07:19
Сообщение #17


Местный
***

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
aesok
сообщение Sep 30 2010, 07:27
Сообщение #18


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(777777 @ Sep 30 2010, 11:05) *
Так вот для этого и используются псевдофункции cli() и sei(). А зачем при этом еще и сохранять SREG - для меня загадка smile.gif


Код
cli ();
....
sei();


В этом примере код вначале запрещает прерываня, потом выполняет критичискую секцию затем разрешает преравания. Этот код кроме своей прямой функции выполняет еще одну паразитную, он ВСЕГДА разрешает преравания. Особенно опасно если он используеться в библиотечной функии, код которой програмисту не виден. Почему например при вызове функции EEPROM_write дожны разрешиться преравания? Ведь из имени этой функции следуеть что они пишет в EEPROM, про разрешения прерываний ни слова.


Код
u08 savedSREG;
savedSREG = SREG // keep setting so it can be restored
cli ();
...
SREG = savedSREG; // restore SREG


Этот код не изменяет состояния флага разрешения прерывиний. и никакого паразитного влияния на состояние флага не оказывает.

Анатолий.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 12:44
Рейтинг@Mail.ru


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