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

Цифровой Фильтр на ATmega

Все знают о существовании таких файлов:

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
Оформление цитат исходников.

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


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

А теперь для сравнения SAM3S (более удобный проц) :

1. Тема называется "Цифровой Фильтр на ATmega".

2. При умножении 8*16 (как в примере от SasaVitebsk) команд будет в 4 раза меньше.

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


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

все знают, и молчат..., короче- двадцать команд на одно умножение с накоплением?:

У меня в HART модеме при декодировании делается:

ФВЧ 2 порядка (убирается постоянная составляющая)

АРУ

ФНЧ 5 порядка (прямоугольник приводится к синусу ( более-менее ))

перемножение со сдвигом фазы относительно несущей

ФНЧ 5 порядка (само преобразование)

+

Разбор на биты/байты и передача.

 

Всё прерывание влазит в 550 тактов по максимуму. На чистом Си.

 

То есть надо понимать, смотря какая задача ставится. Одно дело работа со звуком, а другое детектирование DTMF для примера.

Конечно на ARM намного приятнее работать с такими вещами, но знания лишними не бывают. Писать "наотмашь", не беспакоясь за такты это хорошо, но в привычку входит. :)

 

Для тех кто ковыряется иногда с малыми кристалами типа PIC/AVR/MSP написал прогу для подбора коэффициентов фильтра. Разбора на сдвиги короче. :)

Если какие вопросы - пишите подправлю.

CoefFltr.zip

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


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

Забавная информация к размышлению для тех кто пишет алгоритмы ЦОС для "больших" ЭВМ (в том числе и старших ARM)...

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


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

Забавная информация к размышлению

 

Информация кагбэ намекает нам, что многостадийные конвейеры в процессорах - унылое гуано. Особенно доставляет то, что это отлично проявилось на пузырьке :)

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


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

:bb-offtopic: Да не на что она не намекает. Заниматься такой оптимизацией никто не будет. По нескольким причинам. Во-первых пока провели данное исследование, выйдет новый проц, в котором, банально, изменят предсказатель ветвлений. И всё будет по-диагонали. Во-вторых такого рода исследования, похоже даже мелкософт не делает. Разве только при отладке ядра. Ну а втретьих AVR-PIC-MSP и младшим моделям ARM остаётся только мечтать о таких ошибках. :)

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


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

Заниматься такой оптимизацией никто не будет. По нескольким причинам. Во-первых пока провели данное исследование, выйдет новый проц, в котором, банально, изменят предсказатель ветвлений. И всё будет по-диагонали.

Во-вторых такого рода исследования, похоже даже мелкософт не делает. Разве только при отладке ядра. Ну а втретьих AVR-PIC-MSP и младшим моделям ARM остаётся только мечтать о таких ошибках. :)

Ну я бы так не сказал. Я конечно не спец по ядру Win нисколечки, но, думаю, что как раз в таком гигантском и необозримо-нелинейном куске кода как ядро ОС выполнить оптимизацию для того или иного автомата кэша - бесполезно да и невозможно...

 

...выигрыш ощутим как раз когда ~90% занимают циклические операции "влоб" - в FIR, FFT, FCT, FWT(а особенно многомерных случаях этих преобразований), различной работе с матрицами, etc.. И действительно - кэши ужасно непредсказуемы(и при этом прозрачны) от производителя к производителю и дать универсальный совет невозможно. Но... зачем я вообще бросил эту ссылку - как-то раньше подумать не мог(хоть и читал статью Касперского) что разница может быть столь существенной. Просто это нужно знать! Для утилиток просмотра фото это действительно никто учитывать не будет. Но если кто что считает "по-серьезному"(вот как эти ребята) то и парк машин у них обычно фиксирован - и есть повод для творчества.

 

Думаю форумчанам нелишне будет быть проинформированными, что для "больших ЭВМ" просто перестроив слегка код в сторону большей детерминированности можно поднять производительность своего кода на порядки(!!!)...

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


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

Вечер добрый господа электронщики!)

У меня проблема с программой для цифрового фильтра на 16й меге.(

Задача в следующем осуществлять цифровую фильтрацию, но АЦП мне

не требуется, т.к. использую стандартную функцию rand() [пишу на CodeVisionAvr].

На выходе ЦАП (после контроллера) ачх фнч я не наблюдаю....

Вышеописанную тему прочитал, но свою прогу пока не переделывал...

Прилагаю злощастную прогу ...

("Я - не волшебник. Я только учусь..." не ругайте сильно)

 

#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
Оформление цитаты исходника.

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


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

Для SasaVitebsk.

Интересует тема, не могу написать Вам личное сообщение, не могли бы ВЫ скинуть мне на [email protected] пустое письмо, я Вам отвечу.

Нужно для отладки одной вещи, ....

 

Вот что не понятно, см первую страницу.

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

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


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

RedD, Вы обратили внимание на то, как выглядит Ваш пост после отправки?

Извиняюсь ежели что не так, я человек эмоциональный, если оскорбил чем ВАШ форум

Скажи что не так

Исправимся

 

Гена Завидовский вижу на форуме, ПРИВЕТ на Питер )

Изменено пользователем Herz

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


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

Извиняюсь ежели что не так, я человек эмоциональный, если оскорбил чем ВАШ форум

Скажи что не так

Исправимся

Вы бы Правила почитали перед регистрацией...

А что не так - неужели не заметно? Ваш пост (и второй тоже) состоит из повторений и самоцитирования. Аккуратней бы надо.

Нажимать на кнопочку "предварительный просмотр" для надёжности не повредит. И высыпаться после встречи Нового Года. :rolleyes:

Да, и ещё. У нас тут повелось с собеседниками на "Вы". Буду рад, если поддержите традицию.

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


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

Вы бы Правила почитали перед регистрацией...

А что не так - неужели не заметно? Ваш пост (и второй тоже) состоит из повторений и самоцитирования. Аккуратней бы надо.

Нажимать на кнопочку "предварительный просмотр" для надёжности не повредит. И высыпаться после встречи Нового Года. :rolleyes:

Да, и ещё. У нас тут повелось с собеседниками на "Вы". Буду рад, если поддержите традицию.

 

Я ВАС понял.

Так по подбору коэффициентов то подскажите вот например 0.673 разбираем на (Х0>>1+X0>>3+X0>>5+X0>>6)=X0*0.673

потом группируем по сдвигам и упрощаем вынося за скобки так ?

Изменено пользователем Herz

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


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

Вобщем правильно, вручную проверил,

Но все равно не понятно кое что SasaVitebsk ты где ?

Да про АРУ тоже интересно очень )

 

Шикарная тема )

Изменено пользователем RedD

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


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

Слесарь да я смотрю ты местный,

Не знаешь как с СашейВитебск списаться ?

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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