Aktiivinen analogielektroniikka 2 - keskiviikkoisin 18:00 syksy 2016

Tässä vielä vaihtoehtoinen, hieman tehokkaampi suodatintoteutus. Sama alipäästö ja suodattimen kerroinjono voidaan laskea samoilla kaavoilla. Tässä kuitenkin hyödynnetään sitä seikkaa, että kun kerroinjonon pituus on parillinen, lukuarvot ovat peilisymmetrisiä jonon puolivälin suhteen. Tämä tarjoaa helpon optimointikeinon eli folded filterin. Sen sijaan, että jokainen näyte ensin kerrotaan kertoimella ja sitten summataan, voidaankin jonon järjestyksessä ensimmäinen ja viimeinen näyte summata ensin ja sen jälkeen kertoa kumman tahansa kertoimella (koska kerrointen lukuarvo on sama). Sen jälkeen summataan edellinen ja viimeistä edellinen näyte jne jne. Lopputuloksena saadaa selvästi laskentatehokkaampi suodin koska kertolaskujen ja silmukkaiteraatioiden määrä puolittuu.

int16_t realTimeFIR_folded(int16_t signal, realTimeFIR_t *FIR) {
	uint16_t convCnt;
	volatile int16_t tempSum, filteredSignal;
	int16_t tempIndex1, tempIndex2;

	tempIndex1 = FIR->signalIndex;
	if (tempIndex1 == 0) tempIndex2 = FIR->signalLength -1;
	else tempIndex2 = FIR->signalIndex -1;

	*(FIR->signalBuffer + FIR->signalIndex++) = signal;
	if (FIR->signalIndex >= FIR->signalLength ) FIR->signalIndex =0;
	filteredSignal = 0;

	for ( convCnt = 0; convCnt < FIR->coeffLength/2; convCnt++ ) {
		tempSum = *(FIR->signalBuffer + tempIndex1++) + *(FIR->signalBuffer + tempIndex2--);
		filteredSignal += tempSum * *(FIR->FIRCoeff + convCnt);
		if (tempIndex1 >= FIR->signalLength ) tempIndex1 =0;
		if (tempIndex2 <0 ) tempIndex2 = FIR->signalLength -1;
	}

	return filteredSignal;
}

Annetuilla kertoimilla ylläoleva koodi kuormittaa STM32F303-prosessoria 15,6% kokonaiskapasiteetista, kun suora laskenta kuormitti yli 20%, eli ero on selvästi jälkimmäisen eduksi.