Перейти к содержанию
    

усреднение сигнала с знаком

Нужно усреднить сигнал с знаком правильно?

в две переменные, в одну отрицательные значения складывать(+) в другую положительные, после разделить на количество сложений каждую переменную. После от той переменной в которой больше отнять меньшее и добавить знак если большая была с знаком?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как то запутанно объяснено. Имхо, варианта 2:

- усреднение "правильно" - то есть в одну переменную сваливать и среднее арифметическое вычислять. Или другие средние - квадратические, геометрические, гармонические и т.п.

- усреднение модулей - то же что и первый вариант, только всегда брать модуль значения.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нужно усреднить сигнал с знаком правильно?

в две переменные, в одну отрицательные значения складывать(+) в другую положительные, после разделить на количество сложений каждую переменную. После от той переменной в которой больше отнять меньшее и добавить знак если большая была с знаком?

Смотря, где у вас знак. Если отрицательные числа у вас в дополнительном коде (т.е. -1 = FFFF), то все складывается в одну кучу (в один сумматор), а в самом конце поделите. Надо только обеспокоиться, чтобы в процессе сложения не произошло переполнение. Для этого куча должна быть у вас типа long.

Если же знак хранится где-то еще, а положительные и отрицательные числа хранятся в одном том же формате, то можно делать так, как вы сами предложили, только сократив сумматор до одной переменной, а в которую вы будете прибавлять число, если оно положительное или вычитать, если оно отрицательное. Тогда в конце процесса в ней как раз и образуется разность.

И, наконец, самый трудный случай, когда знак хранится в разрядной сетке числа, например, старший бит числа зарезервирован под знаковый бит. Тогда, на мой взгляд, проще преобразовывать каждое число к стандартному виду (т.е когда отрицателные числа представляются в дополнительном коде) и тут же складывать их в один сумматор.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

- усреднение "правильно" - то есть в одну переменную сваливать и среднее арифметическое вычислять

Сначала так же подумал, а как потом определить знак ?

 

Смотря, где у вас знак. Если отрицательные числа у вас в дополнительном коде (т.е. -1 = FFFF), то все складывается в одну кучу (в один сумматор), а в самом конце поделите. Надо только обеспокоиться, чтобы в процессе сложения не произошло переполнение. Для этого куча должна быть у вас типа long.

Если же знак хранится где-то еще, а положительные и отрицательные числа хранятся в одном том же формате, то можно делать так, как вы сами предложили, только сократив сумматор до одной переменной, а в которую вы будете прибавлять число, если оно положительное или вычитать, если оно отрицательное. Тогда в конце процесса в ней как раз и образуется разность.

И, наконец, самый трудный случай, когда знак хранится в разрядной сетке числа, например, старший бит числа зарезервирован под знаковый бит. Тогда, на мой взгляд, проще преобразовывать каждое число к стандартному виду (т.е когда отрицателные числа представялются в дополнительном коде) и тут же складывать их в один сумматор.

Переменная 12 бит старший бит знак

от 0до 2047 +

и

от 4095 до 2048 -

пробовал в одну складывать почему то не получается, складывал 100раз потом делил на 100, получается цифра постоянна пляшет, на входе все нормально пульсация +5-5.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сначала так же подумал, а как потом определить знак ?

 

 

Переменная 12 бит старший бит знак

от 0до 2047 +

и

от 4095 до 2048 -

пробовал в одну складывать почему то не получается, складывал 100раз потом делил на 100, получается цифра постоянна пляшет, на входе все нормально пульсация +5-5.

Преобразуйте в нормальное 16-битное целое со знаком и дальше работайте с этими величинами, используя стандартную арифметику. Я обычно преобразую прямо во время считывания из АЦП, дальше не нужно помнить о спецкодировании и что-то менять в обработке после смены типа АЦП.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нужно усреднить сигнал с знаком правильно?

в две переменные, в одну отрицательные значения складывать(+) в другую положительные, после разделить на количество сложений каждую переменную.

Скачайте книгу Digital Design: An Embedded Systems Approach Using VHDL, автор Peter Ashenden

И читайте главу Numeric Basics

http://www.scribd.com/doc/66037569/Digital...oach-Using-VHDL

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Переменная 12 бит старший бит знак

от 0 до 2047 +

и

от 4095 до 2048 -

Значит, у вас АЦПовая система в дифференциальном режиме :). Могли бы сразу назвать тип АЦП, чтобы не мучить отвечающих догадками.

Прежде всего вам надо понять, где у вас "минус единица". Т.е. какое число выдает минимальное отрицательное напряжение на входе.

Понятно, что при 0 вольтах ваш АЦП показывает тоже 0. А если чуточку ниже в отрицательную область? 4095 или 2049? Куда ближе?

 

Возможных вариантов два:

1) Если минимальное отрицательное входное напряжение дает 4095.

Это значит, что число выдается в дополнительном коде, но обрезано 12-ю битами.

В этом случае, чтобы отрицательные числа стали правильными для двухбатового типа int, нужно расширить знак на всю разрядную сетку влево.

Делается это так:

if(value > 0x07FF) value |= 0xF000; // при наличии 12-го знакового бита размножаем его на всю разрядкую сетку влево.

 

2) Если минимальное отрицательное входное напряжение дает 2049:

Значит код прямой, а знак выдается отдельно.

В этом случае надо перейти в дополнительный код, заодно подавив знаковый бит.

Делается это так:

if(value > 0x07FF) value = 0x07FF - value;

 

Если выбран правильный вариант, то переход через 0 вольт должен выглядеть так (в 16-ричном виде):

..........

0x0003 // понижаем нпряжение

0x0002

0x0001

0x0000 // достигли нуля

0xFFFF // пошли ниже нуля

0xFFFE

0xFFFD

.........

При этом такое число будет нормально печататься в десятичном знаковом формате %d

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо за подробное объяснение

А если чуточку ниже в отрицательную область? 4095 или 2049? Куда ближе?

-1 соответствует коду 4095.

Если усреднять без перевода в 16 разрядный, разделять значение на две переменные отрицательное и положительное... или можно проще сделать?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

-1 соответствует коду 4095.

Если усреднять без перевода в 16 разрядный, разделять значение на две переменные отрицательное и положительное... или можно проще сделать?

Да куда уж проще:

 

long sum = 0;
for(i=0; i < N; i++)
{ int value = Y[i];
   sum += (value > 0x07FF) ?  value|0xF000 : value;
}
sum /= N;

где Y[N] - массив с данными, данные в процессе вычисления среднего не изменяются.

Среднее получается в переменной sum

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Одно ограничение

если int занимает 2 байта то суммировать не больше 8 измерений

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нужно дополнить каждое отрицательное значение до полного int:

 

if(value & BIT11) value |= 0xf000;

 

Дальше суммируете как обычно.

 

А, Ксения уже написала, не заметил.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да куда уж проще:

А просто вычитать из каждого отсчёта половину полной шкалы АЦП (2048) не проще?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А просто вычитать из каждого отсчёта половину полной шкалы АЦП (2048) не проще?

Спасибо за мысль. Очень просто и понятно получилось.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...