|
Цифровой Фильтр на ATmega, Цифровой Фильтр на ATmega |
|
|
|
Sep 16 2009, 04:18
|
Участник

Группа: Участник
Сообщений: 30
Регистрация: 20-09-08
Пользователь №: 40 344

|
Добрый день, давно не заходил с проблемами. КТо может помочь куском кода к цифровому фильтру для Codevision. Даже с чего начать не знаю, куда не сунусь везде только формулы да теория. Хочу попробовать отфильтровать сигнал снятый с ацп Atmegи, и преобразовать на выход с помощью ШИМ и RC цепи
|
|
|
|
|
 |
Ответов
(1 - 86)
|
Sep 16 2009, 07:30
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Боюсь, что меня сейчас поколотят, но попробую облегчить вам жизнь.  1) Берём прогу расчёта фильтров, которую я приложил. 2) Рисуем фильтр с нужными параметрами. 3) Садимся и вручную округляем коэффициенты до ближайшего двоичного (если непонятно как, то спрашивайте - поясню) 4) Переписываем (на бумаге) формулу каждого звена ч/з сдвиги 5) объединяем сдвиги и получаем общую прогу. 6) Я обычно, проверяю АЧХ полученной проги на IBM, чтобы исключить ошибки. Правда такова, что фильтрация фильтром 2-4 порядка, часто бывает лаконичнее, эфективнее, красивее и, однозначно менее затратно по ресурсам чем скользящее усреднение. Так, например, фильтр Y(i) = X(i) + 0.875Y(i-1) - X(i-1) прекрасно убирает постоянную составляющую. Иногда использовал такое свойство фильтра, как коэффициент передачи. Например требуется ослабить сигнал, либо наоборот его усилить. Конечно, если более-менее сложная задача, то я сначала полностью моделирую процесс и обязательно его визуализирую. На всех этапах. Далее отрабатываю все формулы на модели. Потом уже переношу всё это на однокристалку. Для меня так проще. Могу чего-нибудь на простом примере показать.
Прикрепленные файлы
ciirf1.zip ( 263.7 килобайт )
Кол-во скачиваний: 734
|
|
|
|
|
Sep 16 2009, 07:39
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(SasaVitebsk @ Sep 16 2009, 11:30)  1) Берём прогу расчёта фильтров, которую я приложил. А для КИХ есть что-то подобное? БИХ не всегда подходит из-за длинных "хвостов" Хотя при том же порядке фильтрует намного лучше. У меня дома валяется что-то подобное, но вся проблема в вычислении коэффициентов передачи. Неплохо было бы автоматизировать
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Sep 17 2009, 11:18
|
Участник

Группа: Участник
Сообщений: 28
Регистрация: 19-11-07
Из: Vinnitsa, UA
Пользователь №: 32 472

|
Цитата(SasaVitebsk @ Sep 16 2009, 10:30)  Могу чего-нибудь на простом примере показать. Да покажите пример пожалуйста. Например приведенный Вами же фильтр который убирает постоянку. Думаю топикстартеру будет полезно, да и многим другим тоже(в том числе и мне  ). Заранее благодарю.
|
|
|
|
|
Sep 17 2009, 13:04
|

инопланетянин
  
Группа: Свой
Сообщений: 236
Регистрация: 24-12-06
Из: Питер
Пользователь №: 23 832

|
Цитата(MrYuran @ Sep 16 2009, 11:39)  А для КИХ есть что-то подобное? А почему бы не использовать Matlab? Там есть и КИХ и БИХ. Плюс есть ФЧХ и картинка с полюсами! Плюс всё можно качественно промоделировать.
|
|
|
|
|
Sep 17 2009, 13:17
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(Legotron @ Sep 17 2009, 16:04)  А почему бы не использовать Matlab? Может потому, что он стоит немалых для любителя денег? Есть бесплатная альтернатива - SciLab, но в нем нет таких красивых и удобных надстроек.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Sep 17 2009, 19:45
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(ZVE @ Sep 17 2009, 14:18)  Да покажите пример пожалуйста.... Я очень сильно упрощу. Те кто владеют теорией - пусть лучше не читают.  Основная цель будет - показать, что всё не так уж страшно.  Кто хочет глубже - без учебников не обойтись. Я не буду касаться таких свойств фильтров как фазовые искажения, импульсная х-ка и т.п. Только частотная и амплитудная. Представим себе, что у нас входной сигнал 1200 Гц. Мы его принимаем на АЦП AVR. В связи с тем, что АЦП AVR работает лишь с положительным сигналом, нам пришлось его пропустить ч/з разделительный конденсатор и выставить резисторами 0.5 от опорного напряжения (типичный случай). В результате мы получаем синус от 0 до 1.1V(опора) max, что составит 0-1023 в единицах АЦП. Но для дальнейших расчтётов нам лучше работать с сигналом имеющим знак. Можно, не мудрствуя лукаво вычесть 512 и получить сигнал +/- 512. Но, резистивный делитель может быть сыставлен не совсем точно (например 0.6V) и в результате мы получим сдвинутый сигнал и соответственно постоянную составляющую в нём. Плюс, допустим мы хотим зарезать сетевые помехи (50 и 100 Гц) и какие-то высокочастотные помехи (например 5кГц). Короче мы решили слегка фильтрануть сигнал для уменьшения воздействия внешних помех. Допустим амплитудная характеристика нам важна только относительная. Ну к примеру идёт манипуляция по принципу есть сигнал/нет сигнала.  Таким образом надо его выделить и обработать пиковым детектором.  Скажем частота может плавать незначительно. Берём прогу, что я приложил в прошлом посте (спасибо автору) и строим полосовой фильтр. (clip1) Теперь немного о дробной арифметике. Все знают что если 1 поделить на 2 то получим 0.5. Если ещё раз разделить = 0.25. Что такое деление на 2 - сдвиг вправо на 1 разряд. Таким образом если себе представить дробную часть, то двочное число 1000000B = 0.5, 01000000B = 0.25, 01100000B = 0.25+0125 = 0.375. Из этого понятно, что умножение на дробные коэффициенты можно представить как сдвиги и сложения. Желательно подобрать такие коэффициенты, чтобы число этих операций было минимальным при допустимой погрешности вычислений. Понятно также, что если у нас сигнал 10 бит, то сдвиги на 8-9 разрядов практически не внесут значимых результатов. Надо также учитывать, что фильтр может искажать сигнал по амплитуде. Для этого желательно следить за амплитудным значением на графике АЧХ. Для простоты картины можно отталкиваться от того, что сумма коэффициентов должна быть равна 1. Если это не так, то результирующий сигнал увеличится либо уменьшится. Часто это бывает непринципиально или даже желательно. Исходя из этого "подкорректируем" коэффициенты X фильтра и перерисуем график воспользовавшись программой. (clip2) Поступим аналогично с Y. (clip3) После построения графика - видим что размах полезного сигнала изменился в 1.3 раза. Можно, естественно, подобрать коэффициенты более точно, но для поставленной задачи нам это ни к чему. Теперь перенесём это на бумагу. Теперь поясню, для тех кто непонимает, что это за X, Y, i.  Надо понимать, что фильтр состоит из звеньев (в данном фильтре 1 звено). Звенья независимы. Выходные данные первого звена - входные второго. И так далее. В данном контексте будем считать так: X входные данные первого звена (сигнал с АЦП) Y выходные данные первого звена (выход фильтра). Если у нас более одного звена, то Y это входные данные второго звена. (i) текущее значение (i-1) предыдущее значение (значение полученное в предыдущей выборке) (i-2) значение полученное 2 выборки назад и т.д. Я упрощу выражение и вместо X(i-1) буду писать X1 и так далее. Итак X коэфф. фильтра будут выглядеть так: 0.0625*(X0+X4)-0.125*X2 = ((X0+X4)>>4)-(X2>>3) Y коэф. будут выглядеть так -(-1.875*Y1+2*Y2-1.0625*Y3+0.3125*Y4) = 1.875*Y1-2*Y2+1.0625*Y3-0.3125Y4 = 2*Y1-0.125*Y1-2*Y2+Y3+0.0625*Y3-0.3125*Y4 = (Y1<<1)-(Y1>>3)-(Y2<<1)+Y3+(Y3>>4)-(Y4>>2)-(Y4>>4) Итого общая формула (1): Y0 = ((X0+X4)>>4)-(X2>>3)+(Y1<<1)-(Y1>>3)-(Y2<<1)+Y3+(Y3>>4)-(Y4>>2)-(Y4>>4) Для понимания дальнейшего я перепишу по другому первых 2 члена ((X0+X4)>>4)-(X2>>3) = ((X0+X4)>>1)-X2)>>3 По сути это вынос множителя за скобки и математически ничего не даёт. На самом деле это уменьшает объём вычислений и повышает их точность. Давайте перепишем полученную формулу фильтра (1) с учётом последнего замечания, но не ввиде формулы, а в виде последовательности вычислений. Для этого введём временную переменную Temp и будем выбирать равные коэф. сдвигов. Я в коментах буду указывать номер члена формулы (1) которые я взял. В результате получим: Temp = (X0+X4+Y3-Y4)>>1; // все члены со сдвигом 4 = 1,7,9 Temp += (-X2-Y1); // ... 3 = 2,4 Естественно лучше записать Temp -= X2+Y1; Temp >>= 1; Temp += (-Y4); // .... 2 = 8 Опять таки Temp -= Y4; Temp >>= 2; // Поскольку у нас нет членов со сдвигом >>1 Temp += (Y1<<1)-(Y2<<1)+Y3; Из получившейся проги видно что результирующий коэфф. действительно будет более 1 так как в последней строчки получим 1 а в предпоследней ещё 1/4, но это просто так, для проверки себя. Я не буду сейчас писать кольцевой буфер для входных значений фильтра. Чтобы было понятней что я делаю. Кстати если используем ФНЧ или ФВЧ, то там вообще это без надобности. Тем не менее, я часто пишу кольцевой буфер с отладочными целями, чтобы в процессе отладки увидеть как работает фильтр и некоторые его звенья. После завершения отладки - могу выкинуть, либо сохранить. Итак, будет выглядеть так: X4=X3; // Новый сэмпл сдвигает значения X3=X2; X2=X1; X1=X0; X0=ADCH; Temp = (X0+X4+Y3-Y4)>>1; // все члены со сдвигом 4 = 1,7,9 Temp += (-X2-Y1); // ... 3 = 2,4 Естественно лучше записать Temp -= X2+Y1; Temp >>= 1; Temp += (-Y4); // .... 2 = 8 Опять таки Temp -= Y4; Temp >>= 2; // Поскольку у нас нет членов со сдвигом >>1 Temp += (Y1<<1)-(Y2<<1)+Y3; Y4=Y3; // Новый сэмпл сдвигает значения Y3=Y2; Y2=Y1; Y1=Y0; Y0=Temp; Ну вот и всё. На последок хотелось бы отметить что имеет значение разрядность чисел. Бывает, при сложных фильтрах, где малые коэффициенты происходит потеря точности, которая сводит на нет весь результат. Особенно если пользовать 8 бит данные. Часто бывает, при пограничных значениях (близких к максимому или минимому) что происходит потеря точности из-за переполнений и в этом случае достаточно использовать повышенную разрядность только переменной Temp. Но в этом смысле преимущество Си просто фантастическое. Представим что я написал этот фильтр для разрядности АЦП 8 бит. Тогда объявление переменных следующее: int8_t X0,X1,X2,X3,X4,Y1,Y2,Y3,Y4,Temp; Представим, что в процессе работы/наладки, я пришёл к выводу, что мне надо повысить разрядность до 10 бит. Исправления будут следующие: 1) В строке объявления переменных надо исправить uint8_t на uint16_t (2 символа) 2) в строке программы изменить ADCH на ADC (1 символ) 3) В строке инициализации АЦП убрать (1<<ADLAR) (ещё 10 символов) Итого исправления 13 символов. Тот кто пишет на ассемблере может оценить объём работы необходимый для перевода такого фильтра с 8 на 16 бит. Цитата(Serhiy_UA @ Sep 17 2009, 16:19)  Много лет назад экспериментировал на ATmega16 со звуковыми частотами. То же АЦП-цифровой фильтр-ШИМ-RC. Строил НЧ и ВЧ фильтры с БИХ, с аккумулятором сумм до 32-бит, а также коэффициентами до 16-бит. Фильтры в итоге всегда самовозбуждались. Тема по прежнему актуальна. Кто либо построил и реально использовал такие фильтры, есть ли положительные результаты, чем рассчитывали коэффициенты? Собственно цифровые фильтры хороши именно тем, что без разницы на чем они считаются. Mega16/ARM/PIC - при тех же коэффициентах и разрядностях работать будут одинаково. По моему очевидно, что ATMega не разрабатывалась для обработки звука. Для этого есть более удобные процы. Я работал со звуком только в рамках телефонной линии. При выборке 8кГц и верхней частоте 3.4кГц требуется, для удовлетворительного качества, АЦП разрядностью 14 бит. При этом для обработки двух потоков приходится греметь всеми костями ATMega на частоте 16МГц. Пробовал обеспечить вывод разными способами, в том числе и ШИМом. Понятно что 14 бит ШИМ на 8кГц даёт сотни МГц поэтому упрощали до 8 бит. Даже при 8 бит для получения приемлемого сигнала, требовалась выходная обвеска сопоставимая с размерами изделия. Причём настройка-регулировка была бы непростая. Короче из всех вариантов этот был самым отвратительным. Существуют внешние цапы, в том числе звуковые, в том числе с нелинейной характеристикой и встроенными цифровыми фильтрами. Стоят - копейки. С фильтрами проблем не было. Правда, как я говорил обработка была весьма топорная.
Эскизы прикрепленных изображений
|
|
|
|
|
Sep 18 2009, 21:08
|

Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 6-08-07
Из: Приднестровье, Тирасполь
Пользователь №: 29 581

|
Цитата(SasaVitebsk @ Sep 17 2009, 22:45)  ...Основная цель будет - показать, что всё не так уж страшно... Спасибо за пример. Так красиво все расписали, что решил руками потрогать. То ли что не так, то ли руки неровные..  По-порядку. Система такая: несколько сигналов (16 штук, от 300 до 1800 Гц, амплитуда каждого 0,45В) через сумматор на ОУ с питанием -+15В (плюс добавляется постоянка 7,5В и инвертируется вторым ОУ, им же приводится к диапазону 0-5В вся сумма сигналов). Оцифровку ведет мега48 с частотой 8кГц, ЦАП 8 бит на 2R-R матрице. Схема:
Вкратце работает так: каждые 125мкс переполняется таймер, за ним автотриггером срабатывает запуск преобразования. По окончании преобразования в прерывании ставится флаг, по которому в основном цикле и работаем. Обновлять ЦАП можно и в прерывании, но джиттера нет и в основном цикле по флагу. Взял Вашу реализацию фильтра без переделок, благо частоты близкие... Так вот, если по флагу делать ЦАП без преобразований [PORTD = (unsigned char) ((X0+512)/4);] то получается:
Т.е. все нормально. Даже амплитуды все совпадают. Это при любом количестве сигналов (фильтр при этом продолжает просчитываться)... Далее переходим к использованию фильтра Код: Код volatile unsigned char fl_adc_result; int X0,X1,X2,X3,X4,Y0,Y1,Y2,Y3,Y4,Temp; ... if(fl_adc_result) { PORTB|=(1<<0); //debug time X4=X3; // Новый сэмпл сдвигает значения X3=X2; X2=X1; X1=X0; X0=ADCW-512; /* Temp = (X0+X4+Y3-Y4)>>1; // все члены со сдвигом 4 = 1,7,9 Temp += (-X2-Y1); // ... 3 = 2,4 Естественно лучше записать Temp -= X2+Y1; Temp >>= 1; Temp += (-Y4); // .... 2 = 8 Опять таки Temp -= Y4; Temp >>= 2; // Поскольку у нас нет членов со сдвигом >>1 Temp += (Y1<<1)-(Y2<<1)+Y3; */ Temp = (X0+X4+Y3-Y4)/2; // все члены со сдвигом 4 = 1,7,9 Temp -= X2+Y1; // ... 3 = 2,4 Естественно лучше записать Temp -= X2+Y1; Temp /= 2; Temp -= Y4; // .... 2 = 8 Опять таки Temp -= Y4; Temp /= 4; // Поскольку у нас нет членов со сдвигом >>1 Temp += (Y1-Y2)*2+Y3;
Y4=Y3; // Новый сэмпл сдвигает значения Y3=Y2; Y2=Y1; Y1=Y0; Y0=Temp; //PORTD = (unsigned char) ((X0+512)/4); //без преобразования PORTD= (unsigned char) ((Y0+512)/4); fl_adc_result=0; PORTB&=~(1<<0); //debug
} При этом, получается: когда сигналов нет, на выходе фильтра постоянка 2,5В. Как и на входе, т.е. вроде правильно. Но при подаче любого сигнала на вход, а также любой их комбинации, фильтр начинает "колбасить":
Это продолжается и после отключения сигналов, т.е. Xi и/или Yi не сходятся  Первая мысль была что компилятор (AVRGCC 4.3.2 Binutils 2.19 avr-libc 1.6.6, в протеусе не дебажится у меня) некорректно реализует сдвиги signed чисел. Потому сделал явно делением. Умный к0мпилятор и сам сдвиги сделает. Та же картина... Обрезание результата АЦП до 8-ми бит (дабы избежать переполнения) картины не меняет... Что может быть не так в консерватории?...
--------------------
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
|
|
|
|
|
Sep 18 2009, 21:24
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Скорее всего причина вот тут: Код X0=ADCW-512; Попробуйте заменить на Код X0=(int)ADCW-512;
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Sep 18 2009, 21:38
|

Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 6-08-07
Из: Приднестровье, Тирасполь
Пользователь №: 29 581

|
Цитата(AHTOXA @ Sep 19 2009, 00:24)  Попробуйте заменить на Код X0=(int)ADCW-512; Картина та же...
--------------------
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
|
|
|
|
|
Sep 18 2009, 22:52
|

Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 6-08-07
Из: Приднестровье, Тирасполь
Пользователь №: 29 581

|
Чет не едут у меня лыжи  С флоатами хрень какая-то - время выполнения короче чем int-ми.. Где-то засада (никогда их не пользую)... Насчет минуса - появится если всю сумму Yi приравнять к нулю и вынести Y0... А правильно это или нет - надо глубже смотреть...
--------------------
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
|
|
|
|
|
Sep 18 2009, 23:16
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(Goodefine @ Sep 19 2009, 04:52)  Чет не едут у меня лыжи  С флоатами хрень какая-то - время выполнения короче чем int-ми.. Где-то засада (никогда их не пользую)... Но хоть заработало?  А с минусом оказывается всё в порядке, там в хелпе написано: Цитата y(n)=( a0*x(n)+a1*x(n-1)+a2*x(n-2) ) – ( b1*y(n-1) + b2*y(n-2) )
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Sep 18 2009, 23:43
|

Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 6-08-07
Из: Приднестровье, Тирасполь
Пользователь №: 29 581

|
Цитата(AHTOXA @ Sep 19 2009, 02:16)  Но хоть заработало?  Не-а, не хочет он с включенной оптимизацией считать Код Y0=0.00625*(X0+X4)-0.125*X2 + 1.875*Y1-2*Y2 + 1.0625*Y3 -0.3125*Y4; ну не может за 1,25мкс он это просчитать. Сходу не пойму где грабли А с выключенной - 129мкс, чуть более 125мкс  В любом случае 2,5В на выходе
--------------------
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
|
|
|
|
|
Sep 19 2009, 04:15
|

developer
   
Группа: Свой
Сообщений: 902
Регистрация: 12-04-06
Из: Казань
Пользователь №: 16 032

|
Цитата(Goodefine @ Sep 19 2009, 03:43)  Не-а, не хочет он с включенной оптимизацией считать Код Y0=0.00625*(X0+X4)-0.125*X2 + 1.875*Y1-2*Y2 + 1.0625*Y3 -0.3125*Y4; ну не может за 1,25мкс он это просчитать. Сходу не пойму где грабли А с выключенной - 129мкс, чуть более 125мкс  В любом случае 2,5В на выходе  А вы по ассемблеру посмотрите. А с флоатами лучше не связываться. Я как-то делал генератор синуса, так с флоатами амплитуду колебаний потехоньку возрастала , сделал с фиксированной точкой 1:15 и амплитуда четко стояла (сутки гонял).
--------------------
Все может быть и быть все может, и лишь того не может быть-чего уж точно быть не может, хотя..и это может быть.
|
|
|
|
|
Sep 20 2009, 20:33
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Эээээ... Результат обсуждения меня не порадовал. Я вам давал не теорию и не практику, а методику. Вы должны проследить и... сделать любой. А соответственно найти ошибки в моём.  Я ведь на бумаге всё это писал. Тем не менее там всё правильно... И нет никаких заморочек с компилятором. 1) Если вы посмотрите АЧХ фильтра, то вы поймёте что результат работы при строке Код X0=(int)ADCW-512; и при строке Код X0=(int)ADCW; должен быть одинаков! Фильтр вычитает постоянную составляющую. 2) Если бы я, для того чтобы проверить работу фильтра каждый раз ваял такую схему ... Нет конечно, респект и уважуха, но вы же всётаки прграммисты.  У них подход попроще .... Я написал для себя приложение в билдере по принципу ГКЧ и тестирую свой фильтр целиком, причём если надо, то использую нужные мне размерности переменных. Потом целиком эту прогу вырезаю и вставляю в IAR. Когда прочитал вашу бучу, то проанализировал. Скажем так...  была неточность, но не в фильтре. Можно было и так как я выложил, но нужна небольшая коррекция. Вопрос какая? Прикладываю фильтр, вырезанный из проги и результат тестирования.  Код x4=x3; x3=x2; x2=x1; x1=x0; x0=ADC;
y4=y3; y3=y2; y2=y1; y1=y0;
tek16 = y1>>3; tek16 += x0+x2-y2; tek16 >>= 1; tek16 += x0+x2-x1+y1-y2; tek16 >>= 1; tek16 += y1-x1;
y0 = tek16; Затестите на своей чудо машинке. Ну и найдите причину хомута.
Эскизы прикрепленных изображений
|
|
|
|
|
Sep 21 2009, 13:45
|

Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 6-08-07
Из: Приднестровье, Тирасполь
Пользователь №: 29 581

|
Цитата(SasaVitebsk @ Sep 20 2009, 23:33)  Эээээ... Результат обсуждения меня не порадовал.Я вам давал не теорию и не практику, а методику. Вы должны проследить и... сделать любой. А соответственно найти ошибки в моём. Я ведь на бумаге всё это писал. Тем не менее там всё правильно... Если Вы восприняли мой пост как критику в адрес своей методики, то спешу заверить, что это совершенно не так. Дело было поздно ночью, когда легко проглядеть ньюанс, подобный потерянному здесь... Тот случай - когда вроде все правильно, но не работает. Поэтому, собственно, вопрос и последовал... Цитата(SasaVitebsk @ Sep 20 2009, 23:33)  2) Если бы я, для того чтобы проверить работу фильтра каждый раз ваял такую схему ... Нет конечно, респект и уважуха, но вы же всётаки прграммисты. У них подход попроще .... Я написал для себя приложение в билдере по принципу ГКЧ ... Ну, имхо, модель простейшая и ваяется быстро, при определенных навыках - copy/paste  Когда под рукой нет необходимого инструментария для работы с цифровыми фильтрами - так тоже неплохо - плюс время выполнения в железе оценить можно, и подумать сколько звеньев поставить получится... Цитата(SasaVitebsk @ Sep 20 2009, 23:33)  Когда прочитал вашу бучу, то проанализировал... Подымать бучу и в мыслях не было, уж извините если так получилось.. Цитата(SasaVitebsk @ Sep 20 2009, 23:33)  Скажем так... была неточность, но не в фильтре. Можно было и так как я выложил, но нужна небольшая коррекция. Вопрос какая? Неточность легко ищется незамыленным глазом: читаем хелп: Цитата y(n)=( a0*x(n)+a1*x(n-1)+a2*x(n-2) ) – ( b1*y(n-1) + b2*y(n-2) ) И ключевая Ваша фраза: Цитата Я упрощу выражение и вместо X(i-1) буду писать X1 и так далее.... следование которой и привело к неточности: X(n-4) стал Х4, а Xn -> X0 (и т.д.). А привязка коэфф. не изменилась. В то время как X4 (если его номер рассматривать как порядковый номер следования отсчета во времени) на самом деле Xn. Иными словами перепутались коэффициенты с отсчетами. То же самое и с Yi. при этом следует еще учесть, что выход - это Y4. Тогда код фильтра будет такой: Код X4=X3; X3=X2; X2=X1; X1=X0; X0=(int)ADCW;
Y0=Y1; Y1=Y2; Y2=Y3; Y3=Y4;
Temp = (X4+X0+Y1-Y0)>>1; Temp -= X2+Y3; Temp >>= 1; Temp -= Y0; Temp >>= 2; Temp +=((Y3-Y2)<<1)+Y1;
Y4=Temp;
PORTD= (unsigned char) ((Y4+512)>>2); Т.е. видно, что крайние Xi и Yi поменялись местами соответственно (X4<->X0,Y4<->Y0 и т.д.). Цитата(SasaVitebsk @ Sep 20 2009, 23:33)  Затестите на своей чудо машинке... Затестил. работает. Только хочу заметить, что АЧХ фильтра не такая как на картинке - если верить модели, работает это скорее как ФВЧ, где - то от 400 Гц - далее подъем и спад до 3кГц почти не заметен... А что касается первоначального фильтра - тоже работает, после исправлений - там частота резонанса около 1336,9 Гц... Откуда так точно? Все просто, иногда (не всегда) после снятия сигналов, фильтр звенит на этой частоте. Звон правда достаточно малый - амплитуда около 0,02В (одна градация ЦАПа). Спад АЧХ возле этой частоты заметен на глаз, что называтся... Вот как то так... Еще раз спасибо Вам, что потратили свое время на очевидные объяснения..
--------------------
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
|
|
|
|
|
Sep 21 2009, 20:27
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(Goodefine @ Sep 21 2009, 16:45)  Затестил. работает. Только хочу заметить, что АЧХ фильтра не такая как на картинке - если верить модели, работает это скорее как ФВЧ, где - то от 400 Гц - далее подъем и спад до 3кГц почти не заметен...  Так я и выбрал фильтр собственно весьма пологий. Да ещё и всего-лишь 3-его порядка. Мне кажется, что людям было-бы интересно узнать сколько "завесил" такой фильтр. Сколько он отъел ресурсов. Я, в свою очередь хотел бы отметить, что полосовой фильтр 5-го порядка легко реализуется на 1.8МГц при частоте выборки 6800 вместе с ФНЧ и перемножением сигнала.  AVR при этом кушает менее 1ма.
|
|
|
|
|
Sep 22 2009, 04:58
|
Участник

Группа: Участник
Сообщений: 30
Регистрация: 20-09-08
Пользователь №: 40 344

|
здраствуйте, простите за то что долго не было, и за глупые вопросы.
Вы привели формулу, которую я пытался понять с помощью каких то физических принципов, в результате натыкался на точно такие же формулы.
Первое: мне объясняли принцип действия цифрового фильтра и она заключается в следующем. Допустим первая выборка равна 8, вторая 8, затем третья равная 10, четвертая равная 8, и пятая снова 8. Если на третью приходилась высокочастотная составляющая, и мы ее в соответствующем такте уменьшаем с соответствующим коэффициентом усиления (например отрицательным), то поучается ФНЧ. Если я не прав то поправьте пожалуйста, потому как:,
второе: судя по рисункам которые приводятся в книгах, и по формуле которую привел SASAVITEBSK (за что огромное спасибо, навила хоть на мысли),
Y(i) = X(i) + 0.875Y(i-1) - X(i-1),
каждая последующая выборка еще раз преобразуется по следующему закону, а затем еще раз по следующему, а затем складывается с текущими. И это кажется странным, потому как если высокачстотная составляющая была большой, она так самой большой и пройдет, если не прав прошу поправить потому как:,
третье: Я примерно прикинул формулу на бумажке, она действительно убирает постоянную составляющую, если сигнал постоянный, каждая последующая выборка на выходе будет стремится к нулю. Крутизна фильтра я так понимаю определяется количеством членов формулы (полинома?). А вот коэффициент ослабления? И потом как синтезировать такую формулу исходя из нужного фильтра. Например ФНЧ, или ФВЧ.
И наконец, четвертое. В схемах фильтра нарисован сумматор, можете объяснить его физический смысл. Если мы складываем два аналоговых сигнала с разными частотами (например две палки спектра), мы получаем сигнал с этими двумя палками. Если мы складываем выборки в разные такты мы получаем просто число. Или же весь смысл этого сумматора (и вообще всех кубиков в структуре фильтра) в том, чтобы подобрать такую формулу, чтобы она выполняла нужную для нас манипуляцию с выборками (то есть нужную АЧХ). Заранее спасибо.
|
|
|
|
|
Sep 22 2009, 10:00
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(_Ie0nid @ Sep 22 2009, 07:58)  Вы привели формулу, которую я пытался понять с помощью каких то физических принципов, в результате натыкался на точно такие же формулы. Если вы пытаетесь разобраться в теории, тем более в теории цифровой фильтрации задавая простые вопросы на форуме, то это тупик. Здесь вы единственное, что можете узнать это название книги и имя автора. А далее - только читать. Если не понимаете - берёте другую книгу, читаете несколько раз и так до момента просветления.  Цитата Первое: мне объясняли принцип действия цифрового фильтра и она заключается в следующем. Допустим первая выборка равна 8, вторая 8, затем третья равная 10, четвертая равная 8, и пятая снова 8. Если на третью приходилась высокочастотная составляющая, и мы ее в соответствующем такте уменьшаем с соответствующим коэффициентом усиления (например отрицательным), то поучается ФНЧ. Если я не прав то поправьте пожалуйста, потому как:, Попытка на пальцах объяснить теорию, насчитывающую тома - это глупость. Вы уж извините, не хочу никого обидеть. Я не являюсь знатоком теории фильтрации, но тем не менее убеждён, что попытка упрощения до уровня домохозяйки, даёт только ложные представления. Результат мы видим повсеместно, когда комбайнёты и директора колхозов становятся руководителями страны. Хотите стать проффессионалом в своём деле - попробуйте им стать. Цитата второе: судя по рисункам которые приводятся в книгах, и по формуле которую привел SASAVITEBSK (за что огромное спасибо, навила хоть на мысли),
Y(i) = X(i) + 0.875Y(i-1) - X(i-1),
каждая последующая выборка еще раз преобразуется по следующему закону, а затем еще раз по следующему, а затем складывается с текущими. И это кажется странным, потому как если высокачстотная составляющая была большой, она так самой большой и пройдет, если не прав прошу поправить потому как:, В той программе, которую я выкладывал - есть HELP, как это не странно. Там есть формула. А то что выше я привёл как прикол. Она как раз не очень ложится на теорию. Тем не менее действительно работает. Я её выдрал из какого-то апнота TI. Её АЧХ можно посмотреть той же прогой, что я прикладывал. Цитата третье: Я примерно прикинул формулу на бумажке, она действительно убирает постоянную составляющую, если сигнал постоянный, каждая последующая выборка на выходе будет стремится к нулю. Крутизна фильтра я так понимаю определяется количеством членов формулы (полинома?). А вот коэффициент ослабления? И потом как синтезировать такую формулу исходя из нужного фильтра. Например ФНЧ, или ФВЧ. Формула определяется не типом сигнала, а типом выбранного фильтра. Например в той проге которую я приложил используется фильтр Батерворта. Если запустить знаменитый QED2000, то там этих фильтров - море. А в теории ещё больше. Каждый фильтр имеет свои особенности. Например некоторые имеют минимальные фазовые искажения и т.д. Формула для каждого из этих фильтров уже определена задолго до того, как вы задумались на эту тему. Сама формула представляет собой полином. Прикладная же задача состоит в том, чтобы исходя из характеристик фильтра и частоты дискретезации выбрать коэффициенты полинома и подставить в уже готовую формулу. В этом, как правило помогают готовые программы. Например та же QED или та, что привёл я. Я же рассказывал методику как довести коэффициенты до программы.  То есть всё это теории ни грамма не касается. Ни каким боком. Цитата И наконец, четвертое. В схемах фильтра нарисован сумматор, можете объяснить его физический смысл. Если мы складываем два аналоговых сигнала с разными частотами (например две палки спектра), мы получаем сигнал с этими двумя палками. Если мы складываем выборки в разные такты мы получаем просто число. Или же весь смысл этого сумматора (и вообще всех кубиков в структуре фильтра) в том, чтобы подобрать такую формулу, чтобы она выполняла нужную для нас манипуляцию с выборками (то есть нужную АЧХ). Заранее спасибо. Книги и ещё раз книги.
|
|
|
|
|
Sep 22 2009, 10:35
|

Местный
  
Группа: Свой
Сообщений: 211
Регистрация: 6-08-07
Из: Приднестровье, Тирасполь
Пользователь №: 29 581

|
Цитата(SasaVitebsk @ Sep 21 2009, 23:27)  Мне кажется, что людям было-бы интересно узнать сколько "завесил" такой фильтр. Сколько он отъел ресурсов... При уровне оптимизации -03 (по скорости) тело фильтра занимает 68 байт и выполняется, при тактовой частоте 16384000 Гц примерно за 3мкс. При периоде в 125мкс (8000кГц) это занимает не более 2.5% процессорного времени. Откуда видно, что при снижении тактовой до 1Мгц еще не менее 50% времени останется... При оптимизации по размеру, время незначительно увеличивается, а размер незначительно уменьшается. Ток потребления неизвестен (модель), но существуют широкие возможности для его уменьшения Цитата(_Ie0nid @ Sep 22 2009, 07:58)  ...И наконец, четвертое. В схемах фильтра нарисован сумматор, можете объяснить его физический смысл... Сумматором можете не заморачиваться. Он там только для того, чтобы арифметически правильно сложить сигналы с разными частотами....
--------------------
Любой, заслуживающий внимания, опыт приобретается себе в убыток...
|
|
|
|
|
Sep 22 2009, 10:52
|

Беспросветный оптимист
     
Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646

|
Цитата(_Ie0nid @ Sep 22 2009, 08:58)  Учите матчасть. Кстати, цифровыми методами можно синтезировать физически нереализуемый фильтр Так что физический смысл в цифровой фильтрации искать бесполезно. Кстати, забавная задачка на вшивость, на которой я засыпался на зачёте: Входной аналоговый сигнал -> АЦП -> ЦАП -> Выходной аналоговый сигнал Как будут различаться спектры входного и выходного сигнала? (для простоты, разрядность и частота дискретизации ЦАП и АЦП совпадают)
--------------------
Программирование делится на системное и бессистемное. ©Моё :) — а для кого-то БГ — это Bill Gilbert =)
|
|
|
|
|
Sep 23 2009, 01:37
|
Участник

Группа: Участник
Сообщений: 30
Регистрация: 20-09-08
Пользователь №: 40 344

|
РАЗОБРАЛСЯ, тут еще на работе мне паренек здорово подсказал, так что большое спасибо всем за помощь.
|
|
|
|
|
Dec 27 2009, 18:27
|
Группа: Новичок
Сообщений: 4
Регистрация: 25-11-07
Пользователь №: 32 665

|
Подскажите, пожалуйста. что представляет собой кольцевой буфер для входных значений фильтра (полосового)?
|
|
|
|
|
Dec 27 2009, 22:26
|

山伏
    
Группа: Свой
Сообщений: 1 827
Регистрация: 3-08-06
Из: Kyyiv
Пользователь №: 19 294

|
Цитата(Fix @ Dec 27 2009, 20:27)  Подскажите, пожалуйста. что представляет собой кольцевой буфер для входных значений фильтра (полосового)? Допустим Вы хотите сделать кольцевой буфер размера N на основе массива(можно еще на основе связанного списка, это просто - указатель последнего элемента должен указывать на первый, но он намного "тяжеловеснее" чем на основе массива). Функция которая отвечает за запись и/или чтение из буфера дожна при этом обеспечивать кольцевую адресацию. Тоесть достигнув элемента массива N-1(т.к. в C адресация начинается с "0") начать запись вновь с "0"-го элемента. "Счетчик" сбрасывают многими конструкциями. if(i=N){ i=0}, i=i%N или i=(i)&(N). Последний случай - это наложение маски. Работает очень быстро - но только для порядка из ряда целой степени двойки. Первый - предполагает ветвление - потому, как-бы, чисто теоретически - это не хорошо для кэша(а автомат-способ его работы у каждого процессора свой). Но лучше посмотреть, что наваял компилятор в ассемблерном листинге - т.е.есть ли ветвление вообще. Для многих типов DSP можно инициализировать счетчик как кольцевой, он представляет из себя отдельный автомат - т.е. работает без затрат производительности. Если любите смотреть на вещи не штампами и шаблонами, то можете попробовать сделать кольцевой автомат на основе таймера - тоже никаких затрат в виде тактов на проверки - но там нужно будет просчитать хватит ли Вам производительности такого фильтра - и это чисто asm решение, никакой переносимости... P.S.: Сам кольцевой буфер проистекает от формулы свертки (это той, что по-идее должен знать каждый второкурсник ВТУЗа  ) - потому форма АЧХ(полосовой или какой иной) при этом никакой рояли не играет... P.P.S.: исправил очепятку! Ибо знаю по-себе в какой ступор они приводят начинающих  ...
--------------------
Нас помнят пока мы мешаем другим... //-------------------------------------------------------- Хороший блатной - мертвый... //-------------------------------------------------------- Нет старик, это те дроиды которых я ищу...
|
|
|
|
|
Dec 27 2009, 23:01
|

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

|
Цитата(DRUID3 @ Dec 28 2009, 01:26)  "Счетчик" сбрасывают многими конструкциями. if(i=N){N=0}, i=i%N или i=(i)&(N). Последний случай - это наложение маски. Работает очень быстро - но только для порядка из ряда целой степени двойки. Всё правильно. Только дополню, что существует особый случай, когда кольцевой буфер работает особенно изящно и быстро - это случай, когда он расчитан на 256 элементов. В этом случае, достаточно сделать "счетчик" цикла типа unsigned char, чтобы всё заработало само собой. Ведь в один байт число, большее чем 255 не запихнешь, поэтому такой счетчик будет "автоматически" сбрасываться при переполнении. Кольцевые буферы на 256 элементов оказываются очень удобным инструментом не только для означенной цели, но и для буферизации приема и передачи по UART и USB, т.е. когда прием или получение приходят по прерыванию (UART) или когда отправлять по одному байту неэффективно (USB). Примечание: у некоторых дурных компиляторов (кажется для MSP430) тип char трактуется как 2 байта, тогда ищите там другой однобайтный тип.
|
|
|
|
|
Dec 30 2009, 11:48
|
Группа: Новичок
Сообщений: 4
Регистрация: 25-11-07
Пользователь №: 32 665

|
При расчете коэффициентов полосового фильтра с помощью программы ciirf1, рекомендованной SasaVitebsk, и при расчете в MatLab получаются совершенно разные их значения , ciirf1 постоянно дает значение a1=0 и a3=0, почему?
|
|
|
|
|
Dec 30 2009, 21:35
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(Fix @ Dec 30 2009, 14:48)  ... рекомендованной SasaVitebsk ... Боже упаси.  Я просто привёл, так сказать, для упрощения понимания. Существует большое количество других программ. Например QED. Они позволяют грамотно оценить искажения, импульсную характеристику фильтра и прочее. Кроме того, даже эта примитивная прога, даёт более точные значения коэффициентов в файл. При выборе и обкатке своих фильтров я моделирую их поведение более сложно. Ну а на чёрную иногда ...  Я просто привёл пример, чтобы начинающие программисты не боялись применять такую технологию как цифровая фильтрация.
|
|
|
|
|
Dec 31 2009, 10:31
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата Всё правильно. Только дополню, что существует особый случай, когда кольцевой буфер работает особенно изящно и быстро - это случай, когда он расчитан на 256 элементов. В этом случае, достаточно сделать "счетчик" цикла типа unsigned char, чтобы всё заработало само собой. Правильные пацаны работают прямо с указателями, а не индексами, и в таком случае даже буфер размещают с адреса, кратного 256, и тогда можно прямо младший байт указателя насиловать, не трогая старший. Ну или, если применяется операция and, то тоже можно выбрать правильный адрес начала буфера для уменьшения оверхеда. Второй совет, кстати, куда более универсальный, практически архитектурно-независимый.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Jan 2 2010, 10:51
|
Знающий
   
Группа: Свой
Сообщений: 841
Регистрация: 10-05-07
Из: Чебоксары (Россия)
Пользователь №: 27 640

|
Цитата(SasaVitebsk @ Sep 17 2009, 22:45)  Temp = (X0+X4+Y3-Y4)>>1; // все члены со сдвигом 4 = 1,7,9 Temp += (-X2-Y1); // ... 3 = 2,4 Естественно лучше записать Temp -= X2+Y1; Temp >>= 1; Temp += (-Y4); // .... 2 = 8 Опять таки Temp -= Y4; Temp >>= 2; // Поскольку у нас нет членов со сдвигом >>1 Temp += (Y1<<1)-(Y2<<1)+Y3; Если уж речь идёт о ATmega, то почему бы не использовать вместо этого извращения умножение командами mul...fmuls? Тогда при изменении коэффициентов не придётся каждый раз переписывать код программы. А небольшое увеличение времени (если оно ешё будет) тут, как я понял, совершенно не критично. Я делал что-то подобное (не помню как оно научно называется) без обратных связей. Т.е. все элементы Y=0. Но с FIFO 256 слов. И умножал на коэффициенты в форме с плавающей запятой. Только была одна хитрость. Порядок у моих самодельных флоатов был представлен в виде кодов 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80. Т.е., если сначала перемножить мантисы, а затем умножить командой mul полученную мантису на порядок, получалось собственно число. Мне пришлось сделать таким образом т.к. коэффициенты были заранее неизвестны. Они вычислялись и уточнялись в процессе работы. И с быстродействием проблеммы были. Деление 16/16 из-за этого тоже пришлось переделать - меньше 60 тактов получилось.
|
|
|
|
|
Jan 6 2010, 10:21
|
Группа: Новичок
Сообщений: 1
Регистрация: 21-11-09
Из: Cyberspace
Пользователь №: 53 765

|
Все знают о существовании таких файлов: 1) AVR201: Using the AVR® Hardware Multiplier 2) AVR223: Digital Filters with AVR все знают, и молчат..., короче- двадцать команд на одно умножение с накоплением?: Код mac16x16_32: clr r2 muls r23, r21 ; (signed)ah * (signed)bh add r18, r0 adc r19, r1 mul r22, r20 ; al * bl add r16, r0 adc r17, r1 adc r18, r2 adc r19, r2 mulsu r23, r20 ; (signed)ah * bl sbc r19, r2 add r17, r0 adc r18, r1 adc r19, r2 mulsu r21, r22 ; (signed)bh * al sbc r19, r2 add r17, r0 adc r18, r1 adc r19, r2 ret
fmac16x16_32: clr r2 fmuls r23, r21 ; ( (signed)ah * (signed)bh ) << 1 add r18, r0 adc r19, r1 fmul r22, r20 ; ( al * bl ) << 1 adc r18, r2 adc r19, r2 add r16, r0 adc r17, r1 adc r18, r2 adc r19, r2 fmulsu r23, r20 ; ( (signed)ah * bl ) << 1 sbc r19, r2 add r17, r0 adc r18, r1 adc r19, r2 fmulsu r21, r22 ; ( (signed)bh * al ) << 1 sbc r19, r2 add r17, r0 adc r18, r1 adc r19, r2 ret А теперь для сравнения SAM3S (более удобный проц) : "The SMLAL instruction interprets the values from Rn and Rm as two’s complement signed inte- gers. It multiplies these integers, adds the 64-bit result to the 64-bit signed integer contained in RdHi and RdLo, and writes the result back to RdHi and RdLo." Код SMLAL R4, R5, R3, R8 ; Signed (R5,R4) = (R5,R4) + R3 x R8 Вы рекомендуете использовать mul...fmuls ?...
Сообщение отредактировал rezident - Jan 6 2010, 12:52
Причина редактирования: Оформление цитат исходников.
--------------------
Mens agitat molem
|
|
|
|
|
Jan 6 2010, 10:50
|
Знающий
   
Группа: Свой
Сообщений: 841
Регистрация: 10-05-07
Из: Чебоксары (Россия)
Пользователь №: 27 640

|
Цитата(Rioi @ Jan 6 2010, 13:21)  А теперь для сравнения SAM3S (более удобный проц) : 1. Тема называется "Цифровой Фильтр на ATmega". 2. При умножении 8*16 (как в примере от SasaVitebsk) команд будет в 4 раза меньше.
|
|
|
|
|
Jan 23 2010, 21:46
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(Rioi @ Jan 6 2010, 14:21)  все знают, и молчат..., короче- двадцать команд на одно умножение с накоплением?: У меня в HART модеме при декодировании делается: ФВЧ 2 порядка (убирается постоянная составляющая) АРУ ФНЧ 5 порядка (прямоугольник приводится к синусу ( более-менее )) перемножение со сдвигом фазы относительно несущей ФНЧ 5 порядка (само преобразование) + Разбор на биты/байты и передача. Всё прерывание влазит в 550 тактов по максимуму. На чистом Си. То есть надо понимать, смотря какая задача ставится. Одно дело работа со звуком, а другое детектирование DTMF для примера. Конечно на ARM намного приятнее работать с такими вещами, но знания лишними не бывают. Писать "наотмашь", не беспакоясь за такты это хорошо, но в привычку входит.  Для тех кто ковыряется иногда с малыми кристалами типа PIC/AVR/MSP написал прогу для подбора коэффициентов фильтра. Разбора на сдвиги короче.  Если какие вопросы - пишите подправлю.
|
|
|
|
|
Jan 24 2010, 12:36
|

山伏
    
Группа: Свой
Сообщений: 1 827
Регистрация: 3-08-06
Из: Kyyiv
Пользователь №: 19 294

|
Цитата(SasaVitebsk @ Jan 24 2010, 13:09)  Заниматься такой оптимизацией никто не будет. По нескольким причинам. Во-первых пока провели данное исследование, выйдет новый проц, в котором, банально, изменят предсказатель ветвлений. И всё будет по-диагонали. Во-вторых такого рода исследования, похоже даже мелкософт не делает. Разве только при отладке ядра. Ну а втретьих AVR-PIC-MSP и младшим моделям ARM остаётся только мечтать о таких ошибках.  Ну я бы так не сказал. Я конечно не спец по ядру Win нисколечки, но, думаю, что как раз в таком гигантском и необозримо-нелинейном куске кода как ядро ОС выполнить оптимизацию для того или иного автомата кэша - бесполезно да и невозможно... ...выигрыш ощутим как раз когда ~90% занимают циклические операции "влоб" - в FIR, FFT, FCT, FWT(а особенно многомерных случаях этих преобразований), различной работе с матрицами, etc.. И действительно - кэши ужасно непредсказуемы(и при этом прозрачны) от производителя к производителю и дать универсальный совет невозможно. Но... зачем я вообще бросил эту ссылку - как-то раньше подумать не мог(хоть и читал статью Касперского) что разница может быть столь существенной. Просто это нужно знать! Для утилиток просмотра фото это действительно никто учитывать не будет. Но если кто что считает "по-серьезному"( вот как эти ребята) то и парк машин у них обычно фиксирован - и есть повод для творчества. Думаю форумчанам нелишне будет быть проинформированными, что для "больших ЭВМ" просто перестроив слегка код в сторону большей детерминированности можно поднять производительность своего кода на порядки(!!!)...
--------------------
Нас помнят пока мы мешаем другим... //-------------------------------------------------------- Хороший блатной - мертвый... //-------------------------------------------------------- Нет старик, это те дроиды которых я ищу...
|
|
|
|
|
May 24 2010, 14:40
|
Участник

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

|
Вечер добрый господа электронщики!) У меня проблема с программой для цифрового фильтра на 16й меге.( Задача в следующем осуществлять цифровую фильтрацию, но АЦП мне не требуется, т.к. использую стандартную функцию rand() [пишу на CodeVisionAvr]. На выходе ЦАП (после контроллера) ачх фнч я не наблюдаю.... Вышеописанную тему прочитал, но свою прогу пока не переделывал... Прилагаю злощастную прогу ... ("Я - не волшебник. Я только учусь..." не ругайте сильно) CODE #include <mega16.h> /* Подключение файла содержащего информацию о физических адресах регистров микроконтроллера */
#include <stdlib.h> #include <delay.h> #define WR PORTD.5 #define CS PORTD.6
#define c0 2.467011f // Коэффициенты цифрового #define c1 4.9348022f // ФНЧ , #define c2 2.4674011f // описываемого уравнением #define d1 0.00099788f // y[k]=c0*x[k]+c1*x[k-1]+c2*x[k-2]+ #define d2 -0.071176655f // +d1*y[k-1]+d2*y[k-2] unsigned char x0, x1, x2, x3, y2, y1, y0, yN; void main (void) { DDRA = 0xFF; // настройка порта А на выход DDRD = 0xFF; // настройка порта D на выход
//------------------------------------------------------------------------------------------------------- CS = 0; // #CS - Chip Select - enable delay_ms (10); WR = 0; // #WR - Write Input - enable delay_ms (10); x0 = rand (); // первый входной отсчёт ЦФ:x0 // delay_ms (10); PORTA = c0 * x0; // первый выходной отсчёт ЦФ:y0 y0 = PORTA; // т.к. ЦФ - рекурсивный // delay_ms (10);
WR = 1; // #WR - Chip Select - disable delay_ms (10); CS = 1; // #CS - Write Input - disable delay_ms (10);
//---------------------------------------------------------------------------------------------------------
CS = 0; // #CS - Chip Select - enable delay_ms (10); WR = 0; // #WR - Write Input - enable delay_ms (10); x1 = rand (); // второй входной отсчёт ЦФ:x1 PORTA = c0*x1 + c1*x0 + d1*y0; // второй выходной отсчёт ЦФ:y1 y1 = PORTA; WR = 1; // #WR - Chip Select - disable delay_ms (10); CS = 1; // #CS - Write Input - disable delay_ms (10); //--------------------------------------------------------------------------------------------------------- CS = 0; // #CS - Chip Select - enable delay_ms (10); WR = 0; // #WR - Write Input - enable delay_ms (10);
x2 = rand(); // третий входной отсчёт ЦФ:x2 PORTA = c0*x2 + c1*x1 + c2*x0 + d1*y1 + d2*y0; // третий выходной отсчёт ЦФ:y2 y2 = PORTA;
CS = 1; // #CS - Chip Select - enable delay_ms (10); WR = 1; // #WR - Write Input - enable delay_ms (10);
//--------------------------------------------------------------------------------------------------------- while (1) { CS = 0; // #CS - Chip Select - enable delay_ms (10); WR = 0; // #WR - Write Input - enable delay_ms (10);
x3 = rand (); // {x3.....xN} входной отсчёт ЦФ PORTA = c0*x3 + c1*x2 + c2*x1 + d1*y2 + d2*y1; //{y3.....yN} выходной отсчёт ЦФ yN = PORTA; // временнАя переменная для хранения самого старшего выходного отсчёта
CS = 1; // #CS - Chip Select - enable delay_ms (10); WR = 1; // #WR - Write Input - enable
x1 = x2; x2 = x3; y1 = y2; y2 = yN; } }
Сообщение отредактировал Herz - Jan 1 2016, 18:51
Причина редактирования: Оформление цитаты исходника.
|
|
|
|
|
Jan 1 2016, 18:24
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 1-01-16
Из: Красный Яр
Пользователь №: 89 904

|
Для SasaVitebsk. Интересует тема, не могу написать Вам личное сообщение, не могли бы ВЫ скинуть мне на redd@samtel.ru пустое письмо, я Вам отвечу. Нужно для отладки одной вещи, ....
Вот что не понятно, см первую страницу. 1.Постоил фильтр в проге приложенной 2.Округлил коэффициенты 3. У автора Итак X коэфф. фильтра будут выглядеть так: 0.0625*(X0+X4)-0.125*X2 = ((X0+X4)>>4)-(X2>>3)
Y коэф. будут выглядеть так -(-1.875*Y1+2*Y2-1.0625*Y3+0.3125*Y4) = 1.875*Y1-2*Y2+1.0625*Y3-0.3125Y4 = 2*Y1-0.125*Y1-2*Y2+Y3+0.0625*Y3-0.3125*Y4 = (Y1<<1)-(Y1>>3)-(Y2<<1)+Y3+(Y3>>4)-(Y4>>2)-(Y4>>4)
Далее он упрощает до
Итого общая формула (1): Y0 = ((X0+X4)>>4)-(X2>>3)+(Y1<<1)-(Y1>>3)-(Y2<<1)+Y3+(Y3>>4)-(Y4>>2)-(Y4>>4)
Для понимания дальнейшего я перепишу по другому первых 2 члена ((X0+X4)>>4)-(X2>>3) = ((X0+X4)>>1)-X2)>>3
Далее записывает в виде Temp = (X0+X4+Y3-Y4)>>1; // все члены со сдвигом 4 = 1,7,9 Temp += (-X2-Y1); // ... 3 = 2,4 Естественно лучше записать Temp -= X2+Y1; Temp >>= 1; Temp += (-Y4); // .... 2 = 8 Опять таки Temp -= Y4; Temp >>= 2; // Поскольку у нас нет членов со сдвигом >>1 Temp += (Y1<<1)-(Y2<<1)+Y3;
Непонятно где и как используются коэффициенты полученные при построении фильтра, куда они делись ??????
Ибо в результате он получил вот это
Итак, будет выглядеть так:
X4=X3; // Новый сэмпл сдвигает значения X3=X2; X2=X1; X1=X0; X0=ADCH; Temp = (X0+X4+Y3-Y4)>>1; // все члены со сдвигом 4 = 1,7,9 Temp += (-X2-Y1); // ... 3 = 2,4 Естественно лучше записать Temp -= X2+Y1; Temp >>= 1; Temp += (-Y4); // .... 2 = 8 Опять таки Temp -= Y4; Temp >>= 2; // Поскольку у нас нет членов со сдвигом >>1 Temp += (Y1<<1)-(Y2<<1)+Y3; Y4=Y3; // Новый сэмпл сдвигает значения Y3=Y2; Y2=Y1; Y1=Y0; Y0=Temp;
Где этих коэффициентов то нет совсем ???? А ведь ими сам фильтр то и задаётся ???? Или я чего то не понял ?
Подскажи как АРУ реализовано, ну хотя бы намекни )
Сообщение отредактировал Herz - Jan 11 2016, 20:49
|
|
|
|
|
Jan 1 2016, 19:26
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 1-01-16
Из: Красный Яр
Пользователь №: 89 904

|
Цитата(Herz @ Jan 1 2016, 18:52)  RedD, Вы обратили внимание на то, как выглядит Ваш пост после отправки? Извиняюсь ежели что не так, я человек эмоциональный, если оскорбил чем ВАШ форум Скажи что не так Исправимся Гена Завидовский вижу на форуме, ПРИВЕТ на Питер )
Сообщение отредактировал Herz - Jan 11 2016, 20:47
|
|
|
|
|
Jan 2 2016, 08:49
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 1-01-16
Из: Красный Яр
Пользователь №: 89 904

|
Цитата(Herz @ Jan 1 2016, 22:34)  Вы бы Правила почитали перед регистрацией... А что не так - неужели не заметно? Ваш пост (и второй тоже) состоит из повторений и самоцитирования. Аккуратней бы надо. Нажимать на кнопочку "предварительный просмотр" для надёжности не повредит. И высыпаться после встречи Нового Года. Да, и ещё. У нас тут повелось с собеседниками на "Вы". Буду рад, если поддержите традицию. Я ВАС понял. Так по подбору коэффициентов то подскажите вот например 0.673 разбираем на (Х0>>1+X0>>3+X0>>5+X0>>6)=X0*0.673 потом группируем по сдвигам и упрощаем вынося за скобки так ?
Сообщение отредактировал Herz - Jan 11 2016, 20:47
|
|
|
|
|
Jan 2 2016, 10:31
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 1-01-16
Из: Красный Яр
Пользователь №: 89 904

|
Вобщем правильно, вручную проверил, Но все равно не понятно кое что SasaVitebsk ты где ? Да про АРУ тоже интересно очень )
Шикарная тема )
Сообщение отредактировал RedD - Jan 2 2016, 10:25
|
|
|
|
|
Jan 8 2016, 09:43
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 1-01-16
Из: Красный Яр
Пользователь №: 89 904

|
Слесарь да я смотрю ты местный, Не знаешь как с СашейВитебск списаться ?
|
|
|
|
|
Jan 8 2016, 23:15
|

Практикующий маг
     
Группа: Свой
Сообщений: 3 634
Регистрация: 28-04-05
Из: Дубна, Моск.обл
Пользователь №: 4 576

|
Цитата(RedD @ Jan 2 2016, 12:49)  Я ВАС понял. Так по подбору коэффициентов то подскажите вот например 0.673 разбираем на (Х0>>1+X0>>3+X0>>5+X0>>6)=X0*0.673 потом группируем по сдвигам и упрощаем вынося за скобки так ? Может чего не понял (всю тему читать лень), но такие махинации со сдвигами (особенно если Х0 длиннее 8 бит, а контроллер не поддерживаем сдвиг на нужное число разрядов за раз) займут хучу тактов. Я бы делал проще сначала Х0 умножаем на 172, а потом откидываем один правый байт (т.е делим на 256), итого получаем коэффициент 0,671875  т.е тот же самый, что и в Вашей формуле (Х0>>1+X0>>3+X0>>5+X0>>6).
Сообщение отредактировал Herz - Jan 10 2016, 10:35
|
|
|
|
|
Jan 9 2016, 14:16
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 1-01-16
Из: Красный Яр
Пользователь №: 89 904

|
Цитата(Alexashka @ Jan 9 2016, 00:15)  Может чего не понял (всю тему читать лень), но такие махинации со сдвигами (особенно если Х0 длиннее 8 бит, а контроллер не поддерживаем сдвиг на нужное число разрядов за раз) займут хучу тактов. Я бы делал проще сначала Х0 умножаем на 172, а потом откидываем один правый байт (т.е делим на 256), итого получаем коэффициент 0,671875  т.е тот же самый, что и в Вашей формуле (Х0>>1+X0>>3+X0>>5+X0>>6). Да вы немного не поняли, это только один коэффициент, так раскладываются все ну смотря какой фильтр, допустим 7 штук, потом раскрываем скобки, потом упрощаем вынося за скобки, допустим вынесли за скобки >>2 И потом >>1. Оставшееся раскладываем по сдвигам и записываем как темр=все с 1 сдвигом темр=все с 2 сдвигами и т д а потом темр=темр + (что за скобкой1) >>2 темр=темр + (что за скобкой2) >>1 И наконец темр=темр+целая часть Хотя можно и немного по другому, записать Итого все на сдвигах, да в том то и прикол что для приемлемой точности более 7 сдвигов то и не нужно Там когда график строишь сразу округляешь чтобы поменьше сдвигов было, график то конечно похуже но на практите это даж не заметно особо, а кода меньше и выполняется быстрее, я бы сказал красивое решение ) Цитата(Alexashka @ Jan 9 2016, 00:15)  Может чего не понял (всю тему читать лень), но такие махинации со сдвигами (особенно если Х0 длиннее 8 бит, а контроллер не поддерживаем сдвиг на нужное число разрядов за раз) займут куеву хучу тактов. Я бы делал проще сначала Х0 умножаем на 172, а потом откидываем один правый байт (т.е делим на 256), итого получаем коэффициент 0,671875  т.е тот же самый, что и в Вашей формуле (Х0>>1+X0>>3+X0>>5+X0>>6). Хотя и Ваш вариант нада попробовать )))) и сравнить ))))
Сообщение отредактировал Herz - Jan 10 2016, 10:35
|
|
|
|
|
Jan 10 2016, 10:24
|

Практикующий маг
     
Группа: Свой
Сообщений: 3 634
Регистрация: 28-04-05
Из: Дубна, Моск.обл
Пользователь №: 4 576

|
Цитата Итого все на сдвигах, да в том то и прикол что для приемлемой точности более 7 сдвигов то и не нужно Ну мой вариант это тоже по сути сдвиг максимум на 8 разрядов. Только я снова Вас спрашиваю, сколько тактов уходит на сдвиг на 7 бит? Или Вы не оцениваете вычислительные затраты в тактах, тогда о какой эффективности алгоритма идет речь? Непонятно. Цитата а кода меньше и выполняется быстрее Кода меньше, чем где?
|
|
|
|
|
Jan 10 2016, 10:31
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 1-01-16
Из: Красный Яр
Пользователь №: 89 904

|
Цитата(Alexashka @ Jan 10 2016, 11:24)  Ну мой вариант это тоже по сути сдвиг максимум на 8 разрядов. Только я снова Вас спрашиваю, сколько тактов уходит на сдвиг на 7 бит? Или Вы не оцениваете вычислительные затраты в тактах, тогда о какой эффективности алгоритма идет речь? Непонятно. Кода меньше, чем где? ДЛя avr один сдвиг в право один такт (LSR, Logical Shift Right (asm)), если семь сдвигов то семь тактов, не считая временных буферов для X,Y. Хотя и это можно посчитать А если округлять то вообще не более 4-х тактов выходит на фильтр ) Правда там еще сложения есть, в итоге вместе с буфером больше конечно будет А вообще на ПЛИС это реализуется похоже еще интереснее ....
Сообщение отредактировал RedD - Jan 10 2016, 14:27
|
|
|
|
|
Jan 10 2016, 12:50
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 1-01-16
Из: Красный Яр
Пользователь №: 89 904

|
Цитата(Alexashka @ Jan 10 2016, 11:24)  Кода меньше, чем где? Кода меньше если округлять с подбором, визуально контролируя АЧХ. Допустим если округлять до двух знаков да еще с подбором на мин количество сдвигов, то и сдвигов меньше и слагаемых меньше, а результат будет чуть чуть похуже, а на практике и не заметен вообще, ну это если сделать измерения .... Оно конечно когда там полноценный DSP или STM то можно и не заморачиваться и делать по полной программе, а на avr так не получится, там каждый такт на счету )
Сообщение отредактировал RedD - Jan 10 2016, 12:54
|
|
|
|
|
Jan 10 2016, 17:49
|

Практикующий маг
     
Группа: Свой
Сообщений: 3 634
Регистрация: 28-04-05
Из: Дубна, Моск.обл
Пользователь №: 4 576

|
Цитата(RedD @ Jan 10 2016, 14:31)  ДЛя avr один сдвиг в право один такт (LSR, Logical Shift Right (asm)), если семь сдвигов то семь тактов, С отрицательными числами тоже? (извините, плохо знаю AVR) И потом нужно еще принимать во внимание разрядность исходных данных. Всё хорошо когда они 8-битные, но сейчас даже самый плохенький АЦП в контроллере уже имеет разрядность 10+, так что это уже 2 байта. И потом, если Вы вдруг решите изменить частоту среза фильтра это же все коэффициенты и их группировки нужно пересчитывать (и возможно вводить новые сдвиги). Это весь текст ЦФ надо править.
|
|
|
|
|
Jan 10 2016, 19:24
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 1-01-16
Из: Красный Яр
Пользователь №: 89 904

|
Цитата(Alexashka @ Jan 10 2016, 18:49)  С отрицательными числами тоже? (извините, плохо знаю AVR) И потом нужно еще принимать во внимание разрядность исходных данных. Всё хорошо когда они 8-битные, но сейчас даже самый плохенький АЦП в контроллере уже имеет разрядность 10+, так что это уже 2 байта. И потом, если Вы вдруг решите изменить частоту среза фильтра это же все коэффициенты и их группировки нужно пересчитывать (и возможно вводить новые сдвиги). Это весь текст ЦФ надо править.  Все ответы здесь .... https://ru.wikipedia.org/wiki/%D0%A4%D0%B8%...%BA%D0%BE%D0%B9В том числе и алгоритм, это всего лишь ЦОС, если посмотреть на схему и алгоритм то один в один, остальное тоже там, обычный институтский курс
Сообщение отредактировал RedD - Jan 10 2016, 19:27
|
|
|
|
|
Jan 11 2016, 04:22
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 1-01-16
Из: Красный Яр
Пользователь №: 89 904

|
А вообще меня интересовала практическая реализация вот этого вот Трехполосный эквалайзер + компрессор в полосе 0,3 - 3,4 кГц. На маломощном avr )
Сообщение отредактировал RedD - Jan 11 2016, 05:42
|
|
|
|
|
Jan 11 2016, 06:03
|

Практикующий маг
     
Группа: Свой
Сообщений: 3 634
Регистрация: 28-04-05
Из: Дубна, Моск.обл
Пользователь №: 4 576

|
Цитата(RedD @ Jan 10 2016, 23:24)  Все ответы здесь .... https://ru.wikipedia.org/wiki/%D0%A4%D0%B8%...%BA%D0%BE%D0%B9В том числе и алгоритм, это всего лишь ЦОС, если посмотреть на схему и алгоритм то один в один, остальное тоже там, обычный институтский курс  Вы не поняли, я про то, что изменение даже одного коэффициента влечет переписывание алгоритма обработки в целом (число сдвигов, группировки по сдвигам и т.д.) Про ЦФ я кое что знаю, первый фильтр я написал еще когда учился в 6 классе  , не совсем фильтр конечно, а систему разностных уравнений для получения эффекта вращающихся галактик, но не суть. Писалось это на БК0010, с его быстродействием 300тыс.оп./cек и работало в реальном времени. К слову всё делалось безо всяких википедий и учебников Цитата А вообще меня интересовала практическая реализация вот этого вот Раньше это делалось чисто аналоговым путем (обычный АРУ на пиковом детекторе) безо всяких процессоров, в чем преимущество цифрового метода? Цитата Работоспособность компрессора динамического диапазона подтверждена результатами MATLAB-моделирования. интересно бы еще узнать мнение целевой аудитории.
|
|
|
|
|
Jan 11 2016, 09:31
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 1-01-16
Из: Красный Яр
Пользователь №: 89 904

|
Ну то что я хотел сделать я почти сделал )
На Ваши вопросы 1. То не вижу разницы в том сколько двигать 8 16 32, почему ? Ну хотя бы потому что под 16 бит АЦП и МК нужен 16 бит и т д иначе просто глупость получается. 2. Насчет отрицательных не думал, нужно будет че нить придумаем )
|
|
|
|
|
Jan 11 2016, 15:31
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 1-01-16
Из: Красный Яр
Пользователь №: 89 904

|
Цитата(Alexashka @ Jan 11 2016, 11:27)  Ну в Atmege ядро вроде бы 8-битное. Если речь уже не об atmege, то и сложности с группировкой сдвиговых операций наверно смысла не имеют? В том же кортексе сдвиг на нужное число бит (арифметический, т.е с учетом знака) делается одной инструкцией ASR. Что Вы имеете под группировкой ? Про знак ..... С АЦП не может придти отрицательное значение только положительные .... с ними и работаем, для 8 битного АЦП 0-255, для 10 битного 0-1023 Если про это то Си temp=temp-x2>>2 => temp=temp-(x2)>>2, Да и то только для наглядности, приоритет сдвига выше чем сложение. Сдвиг в 3 группе, сложение в 5 пятой группе приоритетов ) ASM temp=r20, ldi r0,x2, lsr r0, sub temp,r0
Сообщение отредактировал RedD - Jan 11 2016, 15:52
|
|
|
|
|
Jan 11 2016, 17:21
|

Практикующий маг
     
Группа: Свой
Сообщений: 3 634
Регистрация: 28-04-05
Из: Дубна, Моск.обл
Пользователь №: 4 576

|
Цитата(RedD @ Jan 11 2016, 19:31)  Что Вы имеете под группировкой ? Ваши же слова: Цитата(RedD @ Jan 2 2016, 12:49)  Я ВАС понял. Так по подбору коэффициентов то подскажите вот например 0.673 разбираем на (Х0>>1+X0>>3+X0>>5+X0>>6)=X0*0.673 потом группируем по сдвигам и упрощаем вынося за скобки так ? Цитата Про знак .....
С АЦП не может придти отрицательное значение только положительные .... с ними и работаем, для 8 битного АЦП 0-255, для 10 битного 0-1023 Ага, а усиление как делать будем?  Допустим нужно будет усилить какието полосы частот, а какието ослабить -подумайте что будет если просто поделить диапазон 0-255 на N. (подсказка: Ваш сигнал всегда содержит (бесполезную)постоянную составляющую, которая также будет усиливаться/ослабляться вместе с (полезной) переменной)
|
|
|
|
|
Jan 11 2016, 17:46
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 1-01-16
Из: Красный Яр
Пользователь №: 89 904

|
Цитата(Alexashka @ Jan 11 2016, 18:21)  Ваши же слова: Ага, а усиление как делать будем?  Допустим нужно будет усилить какието полосы частот, а какието ослабить -подумайте что будет если просто поделить диапазон 0-255 на N. (подсказка: Ваш сигнал всегда содержит (бесполезную)постоянную составляющую, которая также будет усиливаться/ослабляться вместе с (полезной) переменной) Про усиление или ослабление я Вас понял, но дело даже не в постоянной составляющей, например С АЦП прищло 10, усиливаем в два раза, 10*2=20 но дело в том что усиливаем только положительную полу волну, а отрицательную наоборот ослабляем, и усиление не то, и сигнал искажен. Делаем смещение на 128 при (256, 8 бит) пришло 10 ушло 20, пришло -10 ушло -20. В общем то дельное замечание
|
|
|
|
|
Jan 11 2016, 17:46
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 1-01-16
Из: Красный Яр
Пользователь №: 89 904

|
Но и сигнал тогда на вход двухполярный нужен, операционник с двуполярным питанием, как то так, ну ессно смещение в половину AREF,
Сообщение отредактировал RedD - Jan 11 2016, 18:37
|
|
|
|
|
Jan 11 2016, 19:38
|

Практикующий маг
     
Группа: Свой
Сообщений: 3 634
Регистрация: 28-04-05
Из: Дубна, Моск.обл
Пользователь №: 4 576

|
Цитата(RedD @ Jan 11 2016, 21:46)  но дело даже не в постоянной составляющей, например ... Делаем смещение на 128 ... Вот именно -все дело в ней, в постоянной составляющей  эти 128 на которые смещён сигнал -это и есть постоянная составляющая, которую обычно добавляют специально, чтобы корректно оцифровать знакопеременный сигнал. Делая вычитание 128 Вы удаляете эту постоянку  Проблема в том, что точно Вы не знаете какая именно постоянка присутствует на входе АЦП, поэтому иногда сначала накладывают ФВЧ, который ее удаляет в силу своей природы, а потом уже делают все остальные преобразования с сигналом. Теперь понятно, что для этого удобнее работать со знаковыми (signed) переменными. Цитата Но и сигнал тогда на вход двухполярный нужен, операционник с двуполярным питанием, как то так, ну ессно смещение в половину AREF, Ну это если АЦП у Вас в контроллере позволяет работать с двуполярным сигналом (чаще бывает диф.вход,т.е сигнала подается два - полезный со смещением и собственно смещение (или если хотите парафазные сигналы), при этом оба сигнала однополярные, что гораздо проще реализуется в кристаллах, ну и смещение удаляется автоматически самим АЦП).
|
|
|
|
|
Jan 11 2016, 20:42
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 1-01-16
Из: Красный Яр
Пользователь №: 89 904

|
Да не АЦП однополярный, делаем смещение и ввиду того что сигнал двуполярный он будет играть около точки смещения.
И тогда получается что adc=ADCL, if (adc<128) { x=-(128-adc), } else x=adc-128,
Сообщение отредактировал RedD - Jan 11 2016, 21:41
|
|
|
|
|
Jan 12 2016, 09:01
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 1-01-16
Из: Красный Яр
Пользователь №: 89 904

|
Цитата(Alexashka @ Jan 12 2016, 02:39)  Да можно проще  Код signed char x; x = ADCL - 128; И еще, без использования аналогового АРУ 8 бит для оцифровки звука будет слишком мало. Я бы ориентировался на 12 бит (в крайнем случае 10). x = ADСL - 128; да проще, Напрашивается мысль смещение вычислять автоматически, ну не знаю, допустим при включении, или используя второй канал АЦП, Хотя если хорошо застабилизировать цепь смещения, то и так никуда не денется Про то что 8 бит мало, это понятно, но обкатать можно и на 8 битах, Кстати у 8 бит avr, тоже есть инструкция ASR ....
Сообщение отредактировал RedD - Jan 13 2016, 02:53
|
|
|
|
|
Jan 12 2016, 13:57
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 1-01-16
Из: Красный Яр
Пользователь №: 89 904

|
А понял, если наложить ФВЧ то и получим смещение, .... Но накладно по ресурсам, можно взять резистор 50кОм, подключить к АЦП, заблокировать на корпус ну 10тью МКФдами, и другим каналом мерить, благо их у avr как минимум восемь.
А усиление ослабление как делать правильно? Через коэффициенты передачи фильтров или напрямую можно ?
По эквалайзеру ....
Сделал три полосовых фильтра с перекрытием в 30 процентов в полосе 0,3 - 3,4 кГц, НЧ, СЧ, ВЧ, для каждого фильтра свой Кус, int Kus1,Kus2,Kus3; Прогоняем сигнал через фильтра, каждую полосу или усиливаем или ослабляем или не трогаем Кus=1. Получаем Y1,Y2,Y3 - выходные данные фильтров,
Y1=Y1*Kus1; Y2=Y2*Kus2; Y3=Y3*Kus3;
Правильно ли будет что
Y0=Y1||Y2||Y3, где Y0 общий выходной сигнал ?
По компрессору ... В статье которую я приводил формула SPL такая
X(n)=10log((1/m)*((Сумма i=0,m-1)X2[n-1])
Может я чего не понял, но это формула работает только для положительных значений adc, так х в квадрате.
Как быть ?????????
И еще много вопросов )
А лана со знаком понятно нужно умножить на (x(n)/x(n)), да и есть более удачный вариант ....
Сообщение отредактировал RedD - Jan 13 2016, 00:59
|
|
|
|
|
Jan 13 2016, 01:04
|

Практикующий маг
     
Группа: Свой
Сообщений: 3 634
Регистрация: 28-04-05
Из: Дубна, Моск.обл
Пользователь №: 4 576

|
1) Да как Вам удобней, так и делайте. 2) Y0=Y1||Y2||Y3 а это что? перемножение по модулю? или логическое "или"?  не знаю, я бы просто сложил. 3) Не понял о какой статье идет речь. Цитата но это формула работает только для положительных значений adc, так х в квадрате Да ладно?! (+5) и (-5) в квадрате это не одно и то же?
|
|
|
|
|
Jan 14 2016, 00:56
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 1-01-16
Из: Красный Яр
Пользователь №: 89 904

|
Ок )
Возми в студенты а ? Вторую вышку хочу получить !
Сообщение отредактировал Herz - Feb 6 2016, 09:54
|
|
|
|
|
Feb 5 2016, 05:00
|
Участник

Группа: Участник
Сообщений: 47
Регистрация: 25-09-09
Из: Красноярск
Пользователь №: 52 562

|
Прошу прощение. А не проще ли использовать аппаратный перемножитель (если конечно таковой присутствует в камне). Просто интересно где то год назад делал простенький ПФ 2-рого порядка на MSP430. Точно во сколько он тактов вылез не скажу (не помню). Но возник вопрос не проще, если имеется аппаратный перемножитель с накоплением использовать его, предворительно сместив коэффициенты в целочисленную область. А учитывая что в том же MSP430 два 16-ти разрядных регистра и 32 разрядный аккумулятор то по моему это прямо конфэтка  (там кажется 2 такта всего на перемножение с суммированием уходит). Поругайте если не прав. PS. Ох помню тогда намучился с переносом коэффициентов в целочисленную область (но благо для фильтра это делается 1 раз). И еще подскажите где можно почитать про реализацию кольцевых буферов (особенно заинтересовало про размещение буфера по определенным адресам (в чем преимущество)) и на какие грабли при этом можно наступить.
Сообщение отредактировал IMaxI - Feb 5 2016, 05:08
|
|
|
|
|
Feb 6 2016, 08:43
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 1-01-16
Из: Красный Яр
Пользователь №: 89 904

|
dspic тоже не плох
|
|
|
|
|
Apr 11 2018, 07:29
|
Участник

Группа: Участник
Сообщений: 24
Регистрация: 1-01-16
Из: Красный Яр
Пользователь №: 89 904

|
Не хотел новую тему создавать, а можно загрузить tetris for led display AVR ? Ну и есть под Turbo C 3.2 Dos (отладочная),
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|