Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как записать/считать float в/из EEPROM
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
LexRoss
МК ATmega8, компилятор WinAvr. Нужно записать число float в eeprom. Была идея сначала домножить число на 10, потом искать остаток от деления на 100, и писать по 2 цифры с помощью eeprom_write_byte(). Что-то мне подсказывает, что можно проще rolleyes.gif Может с помощью eeprom_write_block() ? Тогда как?
proba
напр так:

extern eeprom_write_block(unsigned char *dat, unsigned char count);

void write_float2eep(float val)
{
union{
float fnum;
unsigned char vl[sizeof (float)];
}eep;
eep.fnum = val;
eeprom_write_block(eep.vl,sizeof (float));
}
Палыч
Цитата(proba @ Oct 26 2010, 18:42) *
напр так

А, почему сразу не так:
eeprom_write_block( (unsigned char *) &val, sizeof (float));
LexRoss
Цитата(proba @ Oct 26 2010, 18:42) *
напр так:

Непонятно как заполняется массив vl. Объясните, пожалуйста где val делится на байты и записывается в массив.
demiurg_spb
Зачем что-то делить? Память и так зачастую имеет байтовую организацию.
Просто передаётся указатель на память (на массив из 4 байт - он же float), и телемаркет:-)

Цитата(Палыч @ Oct 26 2010, 18:48) *
А, почему сразу не так:
eeprom_write_block( (unsigned char *) &val, sizeof (float));

eeprom_update_block поинтереснейwink.gif
LexRoss
А прочитать как?
Код
unsigned char read_var[5];
eeprom_read_block(read_var, 0x10, 5);
ерунду какую-то выводит
sergeeff
Вы в функции

Код
eeprom_write_block( (unsigned char *) &val, sizeof (float));


знаете по какому адресу в eeprom запишется массив байт?

Я не знаю. Вы, похоже, тоже. Тогда почему вы чего-то считываете с адреса 0x10?
LexRoss
я писал
Код
eeprom_write_block( (unsigned char *) &val, 0x10, sizeof (float));
sergeeff
Ну тогда сделайте так:

Код
float f2;

eeprom_read_block((unsigned char *)&f2, 0x10, sizeof(float));
printf("f2 = %f\n", f2);
LexRoss
Работает, спасибо.
drvlas
Когда нужно много чего разного в ЕЕПРОМ писать-читать, всегда использую предложенный здесь подход - объявления union.
Например:

#define ucha unsigned char
...
typedef union {
struct {
ucha csL, csH, N1, N2, N3, Coeff, R1[TABLES_SIZE], R2[TABLES_SIZE], R3[TABLES_SIZE];
}s;
ucha mc[SIZEOFEEPROM];
}Type_My_Data_in_EEPROM;

extern Type_My_Data_in_EEPROM u;

Теперь в программе везде обращаюсь к элементам союза так

u.s.N1
u.s.Coeff
u.s.R1[...]

и только в подпрограммах записи-чтения "вспоминаю", что это еще и массив:

for( i = 2; i < SIZEOFEEPROM; i++ )
{
u.mc[i] = EEPROM_read_byte(i);
cs2 += u.mc[i];
}

Т.е. мне пофиг, каковы данные, входящие в союз - там и байты, и флоаты, и массивы... Важно под их размерчик разместить "поверх" еще и массив ucha mc[SIZEOFEEPROM] (что и есть сутью союза)



rezident
Цитата(drvlas @ Oct 27 2010, 02:33) *
Т.е. мне пофиг, каковы данные, входящие в союз
А вы не интересовались оверхедом, возникающим при таком "союзном" доступе к данным?
Dog Pawlowa
А откуда там оверхэд берется, не подскажете?
sigmaN
Я чё-та не соображу, вы переменную заводите с этим типом(Type_My_Data_in_EEPROM) и она кушает свои честные SIZEOFEEPROM байт оперативки в не зависимости от того, что возможно в конкретный момент времени программе нужны всего пара байт из EEPROM?
Думаю это и есть тот самый оверхед, о котором говорил rezident.
sergeeff
Цитата(drvlas @ Oct 26 2010, 23:33) *
Когда нужно много чего разного в ЕЕПРОМ писать-читать, всегда использую предложенный здесь подход - объявления union.


Ну и для чего вся эта лабуда с union, когда можно просто и ясно:

Код
struct {
ucha csL, csH, N1, N2, N3, Coeff, R1[TABLES_SIZE], R2[TABLES_SIZE], R3[TABLES_SIZE];
}s

s s1, s2;

eeprom_write_block((unsigned char *) &s1, 0x0, sizeof(s));
eeprom_read_block ((unsigned char *) &s2, 0x0, sizeof(s));
Сергей Борщ
Цитата(sergeeff @ Oct 27 2010, 09:12) *
Код
0x0, sizeof(s));
А для чего явное задание адреса цифрами, да еще и без приведения к указателю?
Код
s s1, s2;
s EEMEM s1_ee, s2_ee;
eeprom_write_block(&s1, &s1_ee, sizeof(s1));
eeprom_read_block(&s2, &s2_ee, sizeof(s2));

sergeeff
Я просто хотел показать, как писать/читать структуру в/из eeprom. Ясно, что указатель "куда" в eeprom надо как-то по-приличнее определить, но и
Код
s EEMEM s1_ee, s2_ee;
что-то напутанное собой представляет.
Сергей Борщ
Цитата(sergeeff @ Oct 27 2010, 11:53) *
но и
Код
s EEMEM s1_ee, s2_ee;
что-то напутанное собой представляет.
Это с непривычки. ведь
Код
s const s1_const, s2_const;
читается вполне ясно.
sergeeff
AVR-овские штучки.
rezident
Цитата(Dog Pawlowa @ Oct 27 2010, 09:16) *
А откуда там оверхэд берется, не подскажете?
Я не утверждаю, а спрашиваю/интересуюсь. laughing.gif Для данных в EEPROM может и не будет оверхеда, а вот для памяти данных при использовании union некоторый оверхед все же возникает.
sergeeff
Нет там никакого оверхеда. Беда в том, что это непереносимая конструкция. Для записи/чтения это не играет никакой роли - все на одной системе под одним компилятором. Вопрос в том, на кой это надо, если безо всяких union работает.

Вообще все это относится к сериализации данных. Про это много чего понаписано.
drvlas
Цитата(sergeeff @ Oct 27 2010, 17:01) *
Нет там никакого оверхеда

Конечно нет. И про ОЗУ тут напрасно беспокоятся. Совершенно нормально, что я переношу из ЕЕПРОМ в ОЗУ все оперативные данные, работаю с ними - а при необходимости прячу снова в ЕЕПРОМ. Вытаскивать 1 байт из ЕЕПРОМ во время обработки данны - это чуднО smile.gif

Цитата(sergeeff @ Oct 27 2010, 17:01) *
Беда в том, что это непереносимая конструкция.

Почему? Куда непереносимая? Или просто Вы ее не переносите wink.gif

Цитата(sergeeff @ Oct 27 2010, 17:01) *
Вопрос в том, на кой это надо, если безо всяких union работает.

Ну, я это использую потому, что при чтении из ЕЕПРОМ и записи туда подсчитываю контрольную сумму. И мне удобно обращаться поэлементно к массиву. Если и при Вашем подходе можно подсчитывать побайтно сумму - то признаю с готовностью, что много лет у меня болталась напрасно усложненная конструкция smile.gif Спасибо за подсказку!
sergeeff
Цитата(drvlas @ Oct 27 2010, 20:24) *
Почему? Куда непереносимая? Или просто Вы ее не переносите wink.gif


Например, тут : http://www.cplusplus.com/doc/tutorial/other_data_types/

написано: "The exact alignment and order of the members of a union in memory is platform dependant."

Или здесь: http://www.drdobbs.com/184403890

Цитата
Ну, я это использую потому, что при чтении из ЕЕПРОМ и записи туда подсчитываю контрольную сумму. И мне удобно обращаться поэлементно к массиву. Если и при Вашем подходе можно подсчитывать побайтно сумму - то признаю с готовностью, что много лет у меня болталась напрасно усложненная конструкция smile.gif Спасибо за подсказку!


Вас же, наверное, интересует crc всей структуры? Кто тогда мешает сделать:

Код
s s1;
uint crc_val =  crc(&s1, sizeof(s1));
sigmaN
Цитата
И про ОЗУ тут напрасно беспокоятся. Совершенно нормально, что я переношу из ЕЕПРОМ в ОЗУ все оперативные данные, работаю с ними
Ну я немного погодя додумал, что погорячился.

Кстати говоря, никто не мешает натравить на начало структуры поинтер char *ptr и прогнать его по всем байтам. Зачем там массив явно объявлять?
Более того, к этому поинтеру можно скобочки нарисовать ptr[] и синтаксически будет выглядеть как массив smile.gif
Правда, засада может быть если там в структуре для выравнивания дырки имеются. Но, как уже говорилось, нас то интересует crc всей структуры и ничего не мешает посчитать его в месте с теми дырками и с ними же и хранить в EEPROM. Ну а вообще структуру сделать packed чтоб без дырок была....

В общем я тоже не вижу смысла в юнионе. Одни минусы от его использования получаются.
drvlas
Убедили меня smile.gif По второму пункту. Ибо, что касается приведенных ссылок

Цитата(sergeeff @ Oct 27 2010, 23:38) *
Например, тут...
написано: "The exact alignment and order of the members of a union in memory is platform dependant."

...то здесь я же говорил: использую массив только при записи-чтении всей структуры в ЕЕПРОМ. И мне в это время до лампочки, какое там выравнивание и размещение. Согласны?

Цитата(sergeeff @ Oct 27 2010, 23:38) *
Вас же, наверное, интересует crc всей структуры? Кто тогда мешает сделать:
Код
s s1;
uint crc_val =  crc(&s1, sizeof(s1));

Ну, так кто ж знал smile.gif Спасибо, буду знать. Если crc() есть во всех компиляторах, то даже переносимость не ухудшится.

Но все же не могу не отметить, что в моем случае (с учетом вышеобозначенного способа использования союза) удобство предложенного уважаемым товарищем ergeeff способа - только в обращении к элементам структуры без лишнего .u
_Pasha
cranky.gif какая-то белиберда. Откровенно железозависимые вещи, которые просто обязаны скрываться за каким-нить write///read(void *src, void * dst, size_t size) зачем туда union - ваще непонятно. Структура - это да, без нее сложно.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.