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

 
 
 
Reply to this topicStart new topic
> Отрицательный float превращается в 0
Haamu
сообщение Dec 16 2013, 10:17
Сообщение #1


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

Группа: Участник
Сообщений: 90
Регистрация: 12-12-13
Пользователь №: 79 587



Контролеер STM32F4, среда CoIDE, включен HARD FPU.
Есть такая вот структура:
Код
typedef struct{
   char Mode;
   uint16_t Amplitude;   //4095
   uint16_t Freqency;
   uint16_t Discreteness;  //10000
   uint8_t Periods;
   uint8_t   Waveform;
   float Attenuation;   //1
   int16_t SignalData[10000];
}ModeStructTypeDef;

Тут заполняется массив SignalData[]:
Код
for (i = 0; i < ModeStruct->Discreteness; i++)
      {
         ModeStruct->SignalData[i] = (int16_t)roundf((sinf(M_TWOPI * i / 10000) * (ModeStruct->Amplitude / 2)));
      }

Тут провожу некоторые вычисления и после этого выдаю данные на ЦАП:
Код
uint16_t data = ((uint16_t)roundf((float)ModeStruct.SignalData[step_counter] / ModeStruct.Attenuation)) + (ModeStruct.Amplitude / 2);

Проблема следующая... Как видно из кода, он генерирует синусоиду с нужными мне параметрами на выходе ЦАП. При заполнении массива проблем не возникает, заполняется числами, соответствующими синусоиде с амплитудой от -2047 до 2047. А вот при дальнейшей обработке есть проблема: с положительной полуволной всё нормально (умножается на коэффициэнт затухания, увеличивается на 2047), а вот в отрицательной полуволне все значения = 2047, то есть где-то здесь ((uint16_t)roundf((float)ModeStruct.SignalData[step_counter] / ModeStruct.Attenuation)) отрицательные значения превращаются в 0. Подскажите пожалуйста, что я делаю не так.
Go to the top of the page
 
+Quote Post
Xenia
сообщение Dec 16 2013, 11:46
Сообщение #2


Гуру
******

Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237



Цитата(Haamu @ Dec 16 2013, 14:17) *
При заполнении массива проблем не возникает, заполняется числами, соответствующими синусоиде с амплитудой от -2047 до 2047. А вот при дальнейшей обработке есть проблема: с положительной полуволной всё нормально (умножается на коэффициэнт затухания, увеличивается на 2047), а вот в отрицательной полуволне все значения = 2047, то есть где-то здесь ((uint16_t)roundf((float)ModeStruct.SignalData[step_counter] / ModeStruct.Attenuation)) отрицательные значения превращаются в 0. Подскажите пожалуйста, что я делаю не так.


Так у вас же
uint16_t data
беззнаковая, как вы в ней хотите отрицательние числа увидеть?
Go to the top of the page
 
+Quote Post
Fedor
сообщение Dec 16 2013, 11:46
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 73
Регистрация: 26-10-05
Пользователь №: 10 125



Цитата(Haamu @ Dec 16 2013, 16:17) *
Тут провожу некоторые вычисления и после этого выдаю данные на ЦАП:
Код
uint16_t data = ((uint16_t)roundf((float)ModeStruct.SignalData[step_counter] / ModeStruct.Attenuation)) + (ModeStruct.Amplitude / 2);

По видимому, Ваше приведение типа (uint16_t) от отрицательного float на выходе ф-ии round и дает 0.
Используйте (int16_t).
Go to the top of the page
 
+Quote Post
Haamu
сообщение Dec 16 2013, 12:31
Сообщение #4


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

Группа: Участник
Сообщений: 90
Регистрация: 12-12-13
Пользователь №: 79 587



Цитата(Fedor @ Dec 16 2013, 15:46) *
По видимому, Ваше приведение типа (uint16_t) от отрицательного float на выходе ф-ии round и дает 0.
Используйте (int16_t).

И правда, как то рано я к беззнаковому привожу, там ведь еще есть отрицательные значения. А вот когда ModeStruct.Amplitude / 2 прибавлю, тут уже от 0 до 4095 значения будут.
Скажите, в таком случае конечный результа надо приводить к uint16_t или можно без приведения сразу записать в массив?
Код
uint16_t data = ((int16_t)roundf((float)ModeStruct.SignalData[step_counter] / ModeStruct.Attenuation)) + (ModeStruct.Amplitude / 2);

И еще один глупый вопрос... Преобразования типов же только для компилятора делаются? На количество цыклов выполнения всего вычисления они же не повлияют?
Go to the top of the page
 
+Quote Post
Fedor
сообщение Dec 17 2013, 04:59
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 73
Регистрация: 26-10-05
Пользователь №: 10 125



Цитата(Haamu @ Dec 16 2013, 18:31) *
Скажите, в таком случае конечный результа надо приводить к uint16_t или можно без приведения сразу записать в массив?

И еще один глупый вопрос... Преобразования типов же только для компилятора делаются? На количество цыклов выполнения всего вычисления они же не повлияют?

1. от 0 до +32768 uint16_t и int16_t будут вести себя одинаково, т.е в вашем случае можно записать в архив и проигнорировать предупреждение компилятора
2. преобразование типов может повлиять на исполняемый код, например если в выражении привести float к целым int или к double, FPU для данного выражения может быть _не_ использован. В Вашем случае непонятно что имеется ввиду.
Go to the top of the page
 
+Quote Post
Haamu
сообщение Dec 17 2013, 05:12
Сообщение #6


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

Группа: Участник
Сообщений: 90
Регистрация: 12-12-13
Пользователь №: 79 587



Цитата(Fedor @ Dec 17 2013, 08:59) *
В Вашем случае непонятно что имеется ввиду.

В данном случае имел ввиду как-раз приведение int16_t к uint16_t.

Сообщение отредактировал Haamu - Dec 17 2013, 05:13
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 23rd August 2025 - 22:22
Рейтинг@Mail.ru


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