|
|
  |
Запись float в EEPROM. |
|
|
|
Apr 12 2015, 10:18
|
Профессионал
    
Группа: Участник
Сообщений: 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); } ерунда какая то получается. может кто подскажет как правильно?
|
|
|
|
|
Apr 12 2015, 10:53
|

Знающий
   
Группа: Участник
Сообщений: 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
--------------------
Верить нельзя никому, даже себе. Мне - можно.
|
|
|
|
|
Apr 12 2015, 11:20
|
Профессионал
    
Группа: Участник
Сообщений: 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')
|
|
|
|
|
Apr 12 2015, 12:00
|

Знающий
   
Группа: Участник
Сообщений: 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); ..
--------------------
Верить нельзя никому, даже себе. Мне - можно.
|
|
|
|
|
Apr 12 2015, 12:22
|
Профессионал
    
Группа: Участник
Сообщений: 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 . может тут проблема?
|
|
|
|
|
Apr 12 2015, 13:07
|
Профессионал
    
Группа: Участник
Сообщений: 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
|
|
|
|
|
Apr 12 2015, 13:37
|
Гуру
     
Группа: Свой
Сообщений: 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; }
|
|
|
|
|
Apr 12 2015, 13:50
|
Профессионал
    
Группа: Участник
Сообщений: 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; }
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|