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

 
 
> Работа с EEPROM в WinAVR
PhX
сообщение Jan 5 2009, 07:25
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 473
Регистрация: 10-09-06
Из: Тольятти. Самарская обл.
Пользователь №: 20 249



Добрый день!

Встала проблема – сохранять и затем читать несколько переменных (10-15) в/из EEPROM. Посмотрел примеры здесь, но не понравилось, как-то громоздко получается, байты считать приходится... Если кто сталкивался, подскажите нет ли решений поэлегантней?

Пусть набор переменных будет такой:
Код
uint8_t a1;
double a2;
uint16_t a3;


Заранее спасибо.

p.s. Компилятор Winavr, камень atmega128


--------------------
Если все, то не я...
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
ReAl
сообщение Jan 5 2009, 08:20
Сообщение #2


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(PhX @ Jan 5 2009, 09:25) *
Встала проблема – сохранять и затем читать несколько переменных (10-15) в/из EEPROM.
...
p.s. Компилятор Winavr, камень atmega128


Ну в самом простом виде как-то так (несколько переменных независимо от места хранения, удобно группировать по смыслу):

Код
#include <stdint.h>

#include <avr/eeprom.h>

typedef struct {
    uint8_t a;
    uint16_t b;
    float f;
} config;

config cfg;

config ee_cfg EEMEM =
{
    12, 1078, 3.5
};

uint16_t ee_u EEMEM = 65000;

float ff;
uint16_t u;

uint16_t foo(void)
{
    ff = 7.5;
    eeprom_read_block( &cfg, &ee_cfg, sizeof(cfg) );        // можно всю структуру
    eeprom_write_block( &ff, &ee_cfg.f, sizeof(float) );    // можно одно поле
    uu = eeprom_read_word( &ee_cfg.b );    
    return eeprom_read_word( &ee_u);            // само собой, можно и одночные переменные
}


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jan 5 2009, 09:02
Сообщение #3


;
******

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



Цитата(ReAl @ Jan 5 2009, 12:20) *
Ну в самом простом виде как-то так (несколько переменных независимо от места хранения, удобно группировать по смыслу):

Несколько уточнений.
1. На кой икс держать множество инлайновых вызовов eeprom_read_*** ?
2. eeprom_write_block() туповат - придется переписать, чтобы не трогал ячейки, в которых нет изменений.
3. После хорошего совета здесь делаю так:
Код
//все, что в еепроме, тотально объединено в структуру
typedef struct
{
****
} paramset_t;
// __MAIN__ определен там, где у нас main()
#ifdef __MAIN__
EEMEM paramset_t paramset = {большой блок инициализации};
#else
extern paramset_t paramset;
#endif
Go to the top of the page
 
+Quote Post
ReAl
сообщение Jan 5 2009, 14:58
Сообщение #4


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(_Pasha @ Jan 5 2009, 11:02) *
1. На кой икс держать множество инлайновых вызовов eeprom_read_*** ?
Я всего лишь показал, как можно обращаться и к структуре целиком и к отдельному её полю и к независимой переменной. И в комментариях отметил, что можно так, а можно сяк.

Цитата(_Pasha @ Jan 5 2009, 11:02) *
2. eeprom_write_block() туповат - придется переписать, чтобы не трогал ячейки, в которых нет изменений.
"а ещё они гнутся и сваливаются", т.е. "а ещё eeprom_write_block() останаваливает работу всего, кроме обработчиков прерываний, на время записи".
Я же говорю - пример в самом простом виде, ведь можно и так:
Код
void
eeprom_manager::write( const void *buf, uint16_t addr, uint16_t len)
{
    ee_guard pg; // тута мьютекс спрятан

    const uint8_t *ptr = reinterpret_cast< const uint8_t* >(buf);

    do {
        uint8_t to_write = *ptr++;
        EEAR = addr++;
        EECR |= 1 << EERE;
        if( EEDR == to_write)
            continue;

        write_done.Clear();
        EEDR = to_write;
        {
            TCritSect cs;
            EECR |= 1 << EEMWE;
            EECR |= 1 << EEWE;
            EECR |= 1 << EERIE;
        }
        write_done.Wait();
    } while( --len);
}


OS_INTERRUPT void
EE_READY_vect()
{
    OS::TISRW isrw;
    EECR &= ~(1 << EERIE);
    eeprom_manager::write_done.SignalISR();
}


Цитата(_Pasha @ Jan 5 2009, 11:02) *
3. После хорошего совета здесь делаю так:
Код
//все, что в еепроме, тотально объединено в структуру
typedef struct
{
****
} paramset_t;
// __MAIN__ определен там, где у нас main()
#ifdef __MAIN__
EEMEM paramset_t paramset = {большой блок инициализации};
#else
extern paramset_t paramset;
#endif
Я нарисовал выше и структуру, и "большой" (на все три поля структуры) блок инициализации. Единственное отличие - в примере всё как бы в одном файле показал.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post



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

 


RSS Текстовая версия Сейчас: 24th July 2025 - 18:31
Рейтинг@Mail.ru


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