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

 
 
 
Reply to this topicStart new topic
> Запись float в EEPROM.
Jenya7
сообщение Apr 12 2015, 10:18
Сообщение #1


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

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Раньше без проблем писал char и int во внешнюю память пользуясь функцией.
Код
void SPIEEPROM_Write(uint32_t address, uint32_t lenght, uint8_t *buffer)
{
    // Note!!!Every write operation demands a write enable!!!
    SPI2_CSlow();
    SPI_SendByte(USART2,SPIEEPROM_CMD_WREN);
    SPI2_CShigh();

    // start write
    SPI2_CSlow();
    // send write command
    SPI_SendByte(USART2,SPIEEPROM_CMD_WRITE);
    // send address
    SPI_SendByte(USART2,address>>8);
    SPI_SendByte(USART2,address&0x00FF);
    while(lenght--)
    {
        // send data to be written
         SPI_SendByte(USART2,*buffer++);
    }
    // stop write
    SPI2_CShigh();
}

Теперь понадобилось записать float.
пробую так
Код
void SPIEEPROM_WriteFloat(uint32_t addr, float *fval)
{
    uint8_t i;
    uint8_t farr[4];
    uint8_t *num;
    num=(uint8_t *)fval;
    for(i=0;i<4;i++)
    {
        num++;
        farr[i]=*num;
    }
    SPIEEPROM_Write(addr,4,farr);
}

и так
Код
void SPIEEPROM_WriteFloat(uint32_t addr, float fval)
{
    uint8_t farr[4];
    farr[0] = (uint8_t)fval & 0xFF;
    farr[1] = (uint8_t)fval >> 8;
    farr[2] = (uint8_t)fval >> 16;
    farr[2] = (uint8_t)fval >> 24;
    SPIEEPROM_Write(addr,4,farr);
}

ерунда какая то получается. может кто подскажет как правильно?
Go to the top of the page
 
+Quote Post
krux
сообщение Apr 12 2015, 10:48
Сообщение #2


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

Группа: Свой
Сообщений: 1 700
Регистрация: 2-07-12
Из: дефолт-сити
Пользователь №: 72 596



сначала точно выяснить sizeof(float) на вашей платформе.
после чего сделать union нужной размерности, чтобы не заниматься левыми преобразованиями типов.


--------------------
провоцируем неудовлетворенных провокаторов с удовольствием.
Go to the top of the page
 
+Quote Post
A. Fig Lee
сообщение Apr 12 2015, 10:53
Сообщение #3


Знающий
****

Группа: Участник
Сообщений: 974
Регистрация: 4-04-08
Из: далека
Пользователь №: 36 467



Или так:

Код
void SPIEEPROM_WriteFloat(uint32_t addr, float *fval)
{
    SPIEEPROM_Write(addr,sizeof(float),(uint8_t*) fval);
}

или так:

Код
void SPIEEPROM_WriteFloat(uint32_t addr, float fval)
{
    uint8_t farr[4];
    farr[0] = (uint8_t)((uint32_t)*fval & 0xFF);
    farr[1] = (uint8_t)((uint32_t)*fval >> 8);
    farr[2] = (uint8_t)((uint32_t)*fval >> 16);
    farr[2] = (uint8_t)((uint32_t)*fval >> 24);
    SPIEEPROM_Write(addr,4,farr);
}

Cast - (uint8_t) и подобные должен выполнится первым, поэтому лучше ставить скобки.
http://en.cppreference.com/w/c/language/operator_precedence
Ну и разыменование пойнтера пропущено.

(

Сообщение отредактировал A. Fig Lee - Apr 12 2015, 10:54


--------------------
Верить нельзя никому, даже себе. Мне - можно.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Apr 12 2015, 11:20
Сообщение #4


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

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



если так
Код
void SPIEEPROM_WriteFloat(uint32_t addr, float *fval)
{
    SPIEEPROM_Write(addr,sizeof(float),(uint8_t*) fval);
}

то
Код
//TEST
float fval = 7.7;
SPIEEPROM_WriteFloat(10, &fval);

и посылается 'f' 'f' '246' '@'

а так
Код
void SPIEEPROM_WriteFloat(uint32_t addr, float fval)
{
    uint8_t farr[4];
    farr[0] = (uint8_t)((uint32_t)*fval & 0xFF);
    farr[1] = (uint8_t)((uint32_t)*fval >> 8);
    farr[2] = (uint8_t)((uint32_t)*fval >> 16);
    farr[2] = (uint8_t)((uint32_t)*fval >> 24);
    SPIEEPROM_Write(addr,4,farr);
}

ругается
invalid type argument of unary '*' (have 'float')
Go to the top of the page
 
+Quote Post
A. Fig Lee
сообщение Apr 12 2015, 12:00
Сообщение #5


Знающий
****

Группа: Участник
Сообщений: 974
Регистрация: 4-04-08
Из: далека
Пользователь №: 36 467



Цитата(Jenya7 @ Apr 12 2015, 07:20) *
если так
...и посылается 'f' 'f' '246' '@'

Ну.. Это не правильно? Что должно быть?

Цитата(Jenya7 @ Apr 12 2015, 07:20) *
а так
Код
void SPIEEPROM_WriteFloat(uint32_t addr, float fval)
{
    uint8_t farr[4];
    farr[0] = (uint8_t)((uint32_t)*fval & 0xFF);
    farr[1] = (uint8_t)((uint32_t)*fval >> 8);
    farr[2] = (uint8_t)((uint32_t)*fval >> 16);
    farr[2] = (uint8_t)((uint32_t)*fval >> 24);
    SPIEEPROM_Write(addr,4,farr);
}

ругается
invalid type argument of unary '*' (have 'float')

Да, ашипся.
Код
farr[0] = (uint8_t) (*((uint32_t*) fval) & 0xFF);
farr[1] = (uint8_t) (*((uint32_t*) fval) >> 8);
..



--------------------
Верить нельзя никому, даже себе. Мне - можно.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Apr 12 2015, 12:22
Сообщение #6


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

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(A. Fig Lee @ Apr 12 2015, 17:00) *
Ну.. Это не правильно? Что должно быть?


Да, ашипся.
Код
farr[0] = (uint8_t) (*((uint32_t*) fval) & 0xFF);
farr[1] = (uint8_t) (*((uint32_t*) fval) >> 8);
..

послаю я fval= 7.7
а считываю 1089890048.0

кстати заметил что мое fval = 7.7 компилятор преобразует в 7.69999981 . может тут проблема?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Apr 12 2015, 12:33
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Jenya7 @ Apr 12 2015, 15:22) *
послаю я fval= 7.7
а считываю 1089890048.0

1089890048 - это и есть 7.7, если считать его как int вместо float.
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Apr 12 2015, 13:07
Сообщение #8


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

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



Цитата(aaarrr @ Apr 12 2015, 17:33) *
1089890048 - это и есть 7.7, если считать его как int вместо float.

читаю так
Код
float SPIEEPROM_ReadFloat(uint32_t addr)
{
    uint8_t buf[4];
    SPIEEPROM_Read(addr, 4, buf);
    return (float) (buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24));
}

вроде должен вернуть float
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Apr 12 2015, 13:37
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(Jenya7 @ Apr 12 2015, 16:07) *
вроде должен вернуть float

Не должен. То есть вернет он действительно float, но совсем не с тем содержимым.

Читайте так же, как пишете:
Код
float SPIEEPROM_ReadFloat(uint32_t addr)
{
     float value;
     SPIEEPROM_Read(addr, sizeof(float), (uint8_t*)&value);
     return value;
}
Go to the top of the page
 
+Quote Post
Jenya7
сообщение Apr 12 2015, 13:50
Сообщение #10


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

Группа: Участник
Сообщений: 1 778
Регистрация: 29-03-12
Пользователь №: 71 075



громадное спасибо друзья. очень помогли. кстати есть и такое решение которое сейчас попробовал. вроде работает.
Код
union
{
  float float_variable;
  uint8_t bytes_array[4];
} float_union;

void SPIEEPROM_WriteFloat(uint32_t addr, float fval)
{
    float_union.float_variable = fval;
    SPIEEPROM_Write(addr,sizeof(float),float_union.bytes_array);
}

float SPIEEPROM_ReadFloat(uint32_t addr)
{
    uint8_t buf[4];
    SPIEEPROM_Read(addr, 4, buf);
    memcpy(float_union.bytes_array, buf, 4);
    return float_union.float_variable;
}

хотя я буду пользоватся этим
Код
void SPIEEPROM_WriteFloat(uint32_t addr, float *fval)  
{
    SPIEEPROM_Write(addr,sizeof(float),(uint8_t*) fval);
}

float SPIEEPROM_ReadFloat(uint32_t addr)
{
    float value;
    SPIEEPROM_Read(addr, sizeof(float), (uint8_t*)&value);
    return value;
}

Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 17:49
Рейтинг@Mail.ru


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