Bu sene geç kalmış olsam da C# dilini öğrenmeye başladım.
Özellikle en ufak ihtiyacımda bile başkalarının programlarını aramaktan bıktığımdan ele almaya karar verdiğim C#’ı, özellikle C’den sonra, biraz da nesne tabanlı bir dil olmasından dolayı oldukça zevkli buldum.
Şu anda öğrenimimin başında da olsam ufak ve faydalı olabilecek bir uygulama paylaşmaya karar verdim.
AVR’nin PWM kısmı ile çalışırken aklıma sinüs, cosinüs dizilerini otomatik yazdırabileceğim bir program yapma fikri geldi. Bunu elbette PIC ya da AVR’ye kod yazarken kendim de oluşturabilirdim, yalnız dizi tanımlamak hem yerden, hem hızdan kazandırdığı için ben, yapabiliyorsam, dizi kullanmaya özen gösteriyorum.
Peki yaptığım program ne işe yarıyor?
- Örnekleme sayısını azaltıp artırabilme,
- Sinüs ya da cosinüs sinyallerinden birini çizdirebilme,
- Örnekleme sayısına göre otomatik değişken tipi tanımlaması,
- Oluşturulan dizinin çeşitli formatlarda (dot, line, spline) grafiğinin çizilmesi,
- Oluşan dizinin tek butonla kopyalanması,
- Aynı örnek sayısı içerisinde frekansın artırılması işlemlerini yapabilmektedir.
Programın çalışma mantığında ise sinyal işleme dersinde sıkça kullandığımız discrete yapılar yer alıyor.
M genlikli, toplamda N sayıda örnek için n. örneğin sinüs sinyal formülü, M*sin(4*pi*(n/N)) olmaktadır. Program temel olarak bu formül üzerine çalışmaktadır.
Programa ait ekran görüntüleri aşağıda görülebilir. (Resimlerin üzerilerine tıklarsanız büyürler)


Programı kullanmak için AVR ile çift PWM kullanarak 50 ve 100Hz frekansında iki sinüs sinyali oluşturalım.
#include "avr/io.h"
#include "util/delay.h"
#include "avr/interrupt.h"
const unsigned char fifty_HZ_sinus[100]={
127,142,158,173,188,201,213,224,
234,241,247,251,253,253,251,247,
241,234,224,213,201,188,173,158,
142,127,112,96,81,66,53,41,
30,20,13,7,3,1,1,3,
7,13,20,30,41,53,66,81,
96,112
};
const unsigned char hundred_HZ_sinus[100]={
127,158,188,213,234,247,253,251,
241,224,201,173,142,112,81,53,
30,13,3,1,7,20,41,66,
96,127,158,188,213,234,247,253,
251,241,224,201,173,142,112,81,
53,30,13,3,1,7,20,41,
66,96
};
volatile unsigned char i=0;
int main(void)
{
// 1MHz => 1us, prescalerden dolayı => 8us, 65536-65486=50
// 25*8us=200us
TCNT1=0xFFD1; // TCNT1, 16 bitlik registerine 65511 yükleniyor
TCCR1B=0x02; // Prescaler değeri 1:8
TIMSK|=0x04; // Timer1 taşması kesmesi aktif
TCNT0=0x00;
TCNT2=0x00;
TCCR0|=(0< <(CS02))|(0<<(CS01))|(1<<(CS00)); // Prescaler 1:1
// 1.000.000/256~3906Hz sinyal çıkması gerekiyor
// OC0 ile Timer0 kesiştiğinceye kadar OC0 pinini set et
TCCR2|=(0<<(CS02))|(0<<(CS01))|(1<<(CS00)); // Prescaler 1:1
// 1.000.000/256~3906Hz sinyal çıkması gerekiyor
// OC2 ile Timer2 kesiştiğinceye kadar OC0 pinini set et
TCCR0|=(1<<(WGM00))|(1<<(WGM01))|(1<<(COM01))|(0<<(COM00));
// Fast PWM modu açık
// OC0 ile Timer0 kesiştiğinceye kadar OC0 pinini clear et
TCCR2|=(1<<(WGM00))|(1<< (WGM01))|(1<<(COM01)|(0<<(COM00));
// Fast PWM modu açık
// OC0 ile Timer0 kesiştiğinceye kadar OC0 pinini clear et
DDRB|=(1<<(PB3)); // OCR0 bacağı çıkış oluyor
DDRD|=(1<<(PD7)); // OCR2 bacağı çıkış oluyor
OCR0=127; // OCR0/255=Duty Cyle yapar. Şimdilik Duty %50
OCR2=127; // OCR2/255=Duty Cyle yapar. Şimdilik Duty %50
sei(); // Genel kesmeler aktif ediliyor
for(;;);
}
ISR(TIMER1_OVF_vect) // Timer1 overflow kesmesi
{
TCNT1=0xFFD1; // TCNT1, 16 bitlik registerine 65511 yükleniyor
i++;
if(i > 49) i=0;
OCR0=fifty_HZ_sinus[i];
OCR2=hundred_HZ_sinus[i];
}
Yukarıdaki kodu incelediğinizde aslında işlemin çok basit olduğunu göreceksiniz; Timer’ı kur, PWM yüzdesini belirle, low-pass filtreden geçir. Aşağıda ise simülasyon görüntüsünü görebilirsiniz. Aşağıda da görüleceği üzere filtreleme sağlıklı olmadığından kesikli çizgiler meydana çıkmaktadır, bu da hormonic distortion’u artırmakta ve sinüs sinyalimizi bozmaktadır. Eğer istenilen sinüs sinyalinin kesintisiz olması isteniyorsa pasif yerine aktif filtre kullanılarak daha güzel bir sinüs sinyali elde edilebilirsiniz.

Programın 32 ve 64 bitlik sürümlerini buradan indirebilir, yeni sürümün güncellemelerini Mühendislik/C# bölümünden takip edebilirsiniz. Programın çalışması için sisteminizde Microsoft .NET Framework kurulu olması gerekmektedir. Microsoft .NET Framework kurulum dosyasına buradan ulaşabilirsiniz. Ayrıca programı istediğiniz şekilde paylaşıp, kullanabilirsiniz.
Son olarak C# ve chart kullanımı üzerine daha önce çalışma yapmış olanlar, örneklerini benimle paylaşırlarsa sevinirim.
Herkese kolay gelsin.


Emrah Budak