Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Отрицательный float превращается в 0
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
Haamu
Контролеер 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. Подскажите пожалуйста, что я делаю не так.
Xenia
Цитата(Haamu @ Dec 16 2013, 14:17) *
При заполнении массива проблем не возникает, заполняется числами, соответствующими синусоиде с амплитудой от -2047 до 2047. А вот при дальнейшей обработке есть проблема: с положительной полуволной всё нормально (умножается на коэффициэнт затухания, увеличивается на 2047), а вот в отрицательной полуволне все значения = 2047, то есть где-то здесь ((uint16_t)roundf((float)ModeStruct.SignalData[step_counter] / ModeStruct.Attenuation)) отрицательные значения превращаются в 0. Подскажите пожалуйста, что я делаю не так.


Так у вас же
uint16_t data
беззнаковая, как вы в ней хотите отрицательние числа увидеть?
Fedor
Цитата(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).
Haamu
Цитата(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);

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

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

1. от 0 до +32768 uint16_t и int16_t будут вести себя одинаково, т.е в вашем случае можно записать в архив и проигнорировать предупреждение компилятора
2. преобразование типов может повлиять на исполняемый код, например если в выражении привести float к целым int или к double, FPU для данного выражения может быть _не_ использован. В Вашем случае непонятно что имеется ввиду.
Haamu
Цитата(Fedor @ Dec 17 2013, 08:59) *
В Вашем случае непонятно что имеется ввиду.

В данном случае имел ввиду как-раз приведение int16_t к uint16_t.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.