|
|
  |
Цифровой Фильтр на ATmega, Цифровой Фильтр на ATmega |
|
|
|
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

|
Слесарь да я смотрю ты местный, Не знаешь как с СашейВитебск списаться ?
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|