26 Kasım 2015 Perşembe

On-line IIR Filtreleme ve STM32F407


IIR filtreleme, mikrodenetleyici uygulaması olarak kullanıldığında FIR filtrelemeye oldukça benzerdir. IIR (Infinite Impulse Response) filtreleme ile ilgili bir uygulama örneği verilecektir.


Matematiksel olarak IIR Filtreleme şu şekilde ifade edilir;


Burada katsayılar (ağırlıklar) “am” ve “bn”, “x” giriş örnekleri ve “y” filtre sonucunu gösterir. Katsayılar FIR katsayıları için kullanılan Fourier dönüşümün tersinden daha karışık bir algoritma kullanılarak belirlenir. Genel olarak “M” , “N”e eşit değildir.

                Bir filtre çıkışının hesaplaması için gereken yol figür 1’de gösterilmiştir. 2 adet dairesel tampon (circular buffer), biri giriş örnekleri için “x” olarak ve diğeri çıkış sonucu içindir “y” olarak isimlendirilmiştir. Yeni sonuç “yk” iki konvolüsyon beraber eklenerek oluşturulmuştur. Üstteki konvolüsyon giriş örnekleri olan “x”i ve katsayıları temsil eden “a”yı,  alttaki konvolüsyon sonuç olarak belirtilen “y”yi ve katsayıları temsil eden “b”yi içerir. Yeni sonuçlar “yk” filtreleme sonrası DAC’a gönderilir.


Figür 1. IIR filtrelemenin grafiksel olarak gösterimi

Mikrodenetleyicide uygulanan filtreleme FIR filtreleme uygulamasının temel halidir. Program Figür 2.de listelenmiştir. Özelliklerin kurulum fonksiyonları FIR filtrelemeyi anlattığımız önceki yazılarımızdaki ile aynıdır. Bu sebepten dolayı burada tekrar anlatılmayacaktır.

Kesme fonksiyonunda da kullanılacak olması sebebi ile genel (global) olarak tanımlanmış 2 (iki) dairesel tampon bulunur. Giriş örnekleri için olan “x1” tamponu integer tipte tanımlanmıştır buna rağmen sonuç çıkış tamponu “y1” float tipte tanımlanmıştır. Hassasiyet şunun için gereklidir; IIR integer sonuçların kullanımdan kaynaklı sayısal hatalar, performansı düşük filtreleme, sayısal istikrarsızlıklar ve osilasyonlara (salınımlara) yol açabilir. Çıkış tamponu da integer olabilir, ama katsayılar FIR filtreleme örneğindeki olduğu gibi yukarı ölçekli olmalıdır.

2 (iki) sinyalinde de eş zamanlı filtrelemesine izin vermek için 2 (iki) parça dairesel tampon bulunur. Tampon uzunlukları biraz abartılmıştır.

Neyse ki bizim için, katsayılar tabloda verilmiştir. Bu örnek programda kullanmak amacı ile katsayı değerleri referanstan kopyalanmıştır[1]. 4ncü dereceden “Chebishew” filtre karakteristikleri uygulanmıştır. Örnekleme frekansının köşe frekansı 0.025 ve bant geçiren kısmın ripple oranı %0.5 olarak kullanılmıştır. Katsayılar;Figür 1. IIR filtrelemenin grafiksel olarak gösterimi

Mikrodenetleyicide uygulanan filtreleme FIR filtreleme uygulamasının temel halidir. Program Figür 2.de listelenmiştir. Özelliklerin kurulum fonksiyonları FIR filtrelemeyi anlattığımız önceki yazılarımızdaki ile aynıdır. Bu sebepten dolayı burada tekrar anlatılmayacaktır.

Kesme fonksiyonunda da kullanılacak olması sebebi ile genel (global) olarak tanımlanmış 2 (iki) dairesel tampon bulunur. Giriş örnekleri için olan “x1” tamponu integer tipte tanımlanmıştır buna rağmen sonuç çıkış tamponu “y1” float tipte tanımlanmıştır. Hassasiyet şunun için gereklidir; IIR integer sonuçların kullanımdan kaynaklı sayısal hatalar, performansı düşük filtreleme, sayısal istikrarsızlıklar ve osilasyonlara (salınımlara) yol açabilir. Çıkış tamponu da integer olabilir, ama katsayılar FIR filtreleme örneğindeki olduğu gibi yukarı ölçekli olmalıdır.

2 (iki) sinyalinde de eş zamanlı filtrelemesine izin vermek için 2 (iki) parça dairesel tampon bulunur. Tampon uzunlukları biraz abartılmıştır.

Neyse ki bizim için, katsayılar tabloda verilmiştir. Bu örnek programda kullanmak amacı ile katsayı değerleri referanstan kopyalanmıştır[1]. 4ncü dereceden “Chebishew” filtre karakteristikleri uygulanmıştır. Örnekleme frekansının köşe frekansı 0.025 ve bant geçiren kısmın ripple oranı %0.5 olarak kullanılmıştır. Katsayılar;


Bu değerler, programın başında tanımlama bölümü içinde kodlanmıştır.

ADC ve DAC’ın ana program içerisinde kurulumları yapılmıştır. Periyodik örnekleme ve sinyal üretimi için Timer kullanılmıştır. Kesme denetleyicisi NVIC, ADC’den gelen kesme isteği için aktif hale getirilmiştir. Daha sonra mikrodenetleyici sonsuz döngü içerisinde zaman harcayarak çalışmasına devam etmektedir(bu döngüde periyodik olarak butonları ve LED’leri kontrol eder).

#include "stm32f4xx.h"

int x1[4096], x2[4096], xyPtr; // giriş için dairesel tamponların tanımlanması
float y1[4096], y2[4096]; // çıkış için dairesel tamponların tanımlanması

// IIR katsayılarının kurulumu: 4ncü derece Chebishew Alçak geçiren [1]
// 0.5%, 250Hz’de -3 dB örnekleme frekansı
float a[5] = {1.504626e-5, 6.018503e-5, 9.027754e-5, 6.018503e-5, 1.504626e-5};
float b[5] = {0 , 3.725385e0 , -5.226004e0 , 3.270902e0 , -7.705239e-1};

int main ()
{
GPIO_setup(); // GPIO kurulumu
DAC_setup(); // DAC kurulumu
ADC_setup(); // ADC kurulumu
Timer2_setup(); // Timer 2 kurulumu
NVIC_EnableIRQ(ADC_IRQn); // ADC kesmesi için NVIC aktif edilir

// zaman gecikmesi
while (1)
{
//LED yak
if (GPIOE->IDR & 0x0001) GPIOA->ODR |= 0x0040;
// değil ise LED söndür
else GPIOA->ODR &= ~0x0040;
};
}


// kesme fonksiyonu
void ADC_IRQHandler(void) // bu kısım yaklaşık 6uS sürer
{
GPIOE->ODR |= 0x0100; // PE08 high yap
x1[xyPtr] = ADC1->DR; // ADC -> dairesel tampon x1
x2[xyPtr] = ADC2->DR; // ADC -> dairesel tampon x2
float conv = 0; // toplama işlemi için tanımlama
for (int i = 0; i < 5; i++) // 0’dan 4’e kadar olan katsayılar için
conv += a[i] * x1[(xyPtr-i) & 4095]; // konvolüsyon girişleri
for (int i = 1; i < 5; i++) // 1’den 4’e kadar olan katsayılar için
conv += b[i] * y1[(xyPtr-i) & 4095]; // konvolüsyon çıkışları
y1[xyPtr] = conv; // filtre sonucu saklanır
y2[xyPtr] = (float)x1[xyPtr]; // orijinal olan saklanır
DAC->DHR12R1 = (int)y1[xyPtr]; // filtrelenmiş değer -> DAC
DAC->DHR12R2 = (int)y2[xyPtr]; // orijinal değer -> DAC
xyPtr = (xyPtr + 1) & 4095; //dairesel tampon işaretçisini bir artır
GPIOE->ODR &= ~0x0100; // PE08 low yap
}
Figür 3. IIR filtreleme uygulamasının program kodları

                Önemli işlemler kesme fonksiyonu içerisinde yapılır. Burada iki ADC’nin sonuçları önce dairesel tampona saklanır. Ardından bir giriş sinyali için iki konvolüsyon hesaplaması yapılır. Konvolüsyonun birinde mevcut ve geçmiş giriş örnekleri ve “am” katsayıları ve diğer konvolüsyon geçmiş filtreleme sonuçları ve “bn” katsayıları ile hesaplanır. Tamamlanan hesaplamada gerekli hassasiyeti sağlamak için kayan nokta aritmetiği kullanılarak yapılır. Çıkan sonuç dairesel tamponda saklanır. Filtre edilmemiş giriş sinyali karşılaştırma yapmak için başka bir çıkış tamponuna saklanır. Son olarak çıkış tamponlarındaki mevcut değerler DAC’a gönderilir ve dairesel tampon işaretçisi güncellenir.

                Tüm hesaplamalar basit olarak port E’de bulunan pin’in kesme fonksiyonu başlangıcında high yapılması ve hesaplama bitiminde yani fonksiyon çıkışında low yapılması ile geçen süre hesaplanır. Bu süre bu uygulamamızda yaklaşık 6uS civarındadır.
[1] Steven W.Smith: The Scientist and Engineer’s Guide to Digital Signal Processing

Şimdilik bu kadar arkadaşlar Gülen
Sorularınız ve önerileriniz için m.hakki.kaplan@gmail.com adresinden her zaman bana ulaşabilirsiniz.
Hakkı KAPLAN

Hiç yorum yok:

Yorum Gönder