7 Parçalı Göstergeler

Amatörler tarafından sıkça kullanılan 7 parçalı göstergelerin kullanımı çok kolay olmasına rağmen, mikroişlemcilere bağlanış şekillerinde farklılıklar olabilir. Genel olarak her bir göstergeye 7 ayrı bağlantı yapıp, örneğin 4 haneli bir sayaç yapmak için kıymetli 28 adet portu bu işe vakfetmek doğru olmaz. Bu yüzden bu tür göstergeler birbirine paralel bağlanır ve bir birim zamanda sadece bir gösterge görünür hale getirilir. İnsan gözü belli bir sürenin altında gerçekleşen olayları algılayamaz. Bu şekilde dört ya da daha fazla gösterge sırayla saniyede 40-50 kez görünür kılındığında sayılar sabit bir şekilde duruyormuş gibi görünürler. Bu projeyi gerçekleştirdiğinizde göstergelerin yenilenme süresini azaltıp çoğaltarak sonucun nasıl değiştiğini izleyebilirsiniz.

Ben bu devrede 4543 BCD'yi (Binary Coded Decimal - İkili Kodlanmış Onlu) 7 segment bilgisine çeviren bir entegre kullandım, bu entegre LED'leri doğrudan sürebilir ve ayrıca veri için kullanacağınız port sayısı 7'den 4' düşer.

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h> //kesmeler ile ilgili baslik dosyasi

#define DISPLAY1 1
#define DISPLAY2 2
#define DISPLAY3 4
#define DISPLAYPORT PORTB
#define DATAPORT PORTD
#define DISPLAY_DELAY 6

//global counter degiskeni
//kesme tarafindan degistirelecegi icin
//volatile olarak tanimlanmali
volatile uint16_t counter=0;

//kesme fonksiyonu
ISR(TIMER1_OVF_vect){ //Kesme rutini detaylar AVR Libc el kitabinda
counter++;
TCNT1H=0xFF; //Timer1'i yeniden 100ms de kesme olusturacak
TCNT1L=0x9B; // sekilde doldur
}

//bekleme fonksiyonu
static void delay_ms(uint16_t ms){
for(uint16_t x=0;x<ms;x++){
_delay_ms(1);
}
}

//islemciyi hazirla
static void mcu_init(void){
//port ayarlari
DDRB =0xFF; //B portunu cikis yap
PORTB =0xFF; //tum pinler 1 olsun
DDRD =0xFF; //D portunu cikis yap
PORTD =0x00;

//Timer1 Ayarlari
TCCR1A =0x00;
TCCR1B =0x05; //Calisma frekansi/1024=976.56 Hz yani 1,024ms
TCNT1H =0xFF;
TCNT1L =0x9B; //FE18 ondalik olark 65435'e esittir, bu deger
ICR1H =0x00; //16 bitlik en buyuk deger olan 65535'i gecince
ICR1L =0x00; //sifirlar ve kesme olusur. Bunun icin 100 adim
OCR1AH =0x00; //gerekir bu da 100*1,024=102,4 ms'ye esittir
OCR1AL =0x00;
OCR1BH =0x00;
OCR1BL =0x00;

TIMSK =0x04; //Timer1 icin interrupt etkin
}

//bir sayiyi basamaklarina ayirarak
//her basamagi ilgili displaye gonderir
void static sayi_goster(uint16_t sayi){
uint8_t birler,onlar,yuzler;
yuzler=sayi/100;
sayi-=yuzler*100;
onlar=sayi/10;
sayi-=onlar*10;
birler=sayi;
DISPLAYPORT=~DISPLAY1; //birinci display aktif
DATAPORT=birler; //birler basamagini PORTD'ye gonder
delay_ms(DISPLAY_DELAY);

DISPLAYPORT=~DISPLAY2; //ikinci display aktif
DATAPORT=onlar; //onlar basamagini PORTD'ye gonder
delay_ms(DISPLAY_DELAY);

DISPLAYPORT=~DISPLAY3; //ucuncu display aktif
DATAPORT=yuzler; //yuzler basamagini PORTD'ye gonder
delay_ms(DISPLAY_DELAY);
}

//ana fonksiyon
int main(void){
mcu_init(); //islemciyi hazirla
sei(); //kesmeleri etkinlestir
while(1){
if(counter>999)counter=0; //counter 999'dan buyukse, sifirla
sayi_goster(counter); //counter'i display'e gonder
}
}

Nasıl Çalışıyor

Devrenin şemasından göreceğiniz üzere (Resim1), göstergelerin data bacakları (a,b,c,d,e,f,g) birbirlerine paralel bağlanır. Benim kullandığım göstergeler ortak katot oldukları için BC327 transistorları göstergelerin eksi(-) uçları ile devrenin eksisi arasında anahtar gibi çalışmaktadır. Siz eğer ortak anot göstergeler kullanırsanız, devreyi buna göre değiştirmeli, yani göstergelerin artısı(+) ile devrenin artısı arasında anahtar görevi yapacak uygun bir transistor kullanmalısınız.

Bu proje basitlik açısından data uçlarını D portuna, kontrol uçlarını da B portuna bağladım, bu doğru bir yaklaşım değil, siz devrenizi geliştirirken kontrol ve data uçlarının aynı porta olmasını sağlamaya çalışmalısınız. Bunu yaparken bazı sorunlarla karşılaşacaksınız. Programda göstergeleri aktifleştirdiğimiz satır şöyle:

DISPLAYPORT=~DISPLAY1;

Programın başında tanımlandığından DISPLAY1 sabitinin 1'e eşit olduğunu biliyoruz. Bu sabitin önündeki tersleme (~) işareti, önüne geldiği sayının iki tabanına göre karşılığının tüm bitlerini ters çeviri, sıfırları bir, birleri de sıfır yapar.

Sayımız 1 idi, bu iki tabanına göre 0b00000001 demektir, bunu terslersek sonuç 0b11111110 olur. Bu durumda PB0 haricindeki tüm çıkışlar sıfır olur sadece birinci gösterge yanar diğerleri söner.

DISPLAYPORT=~DISPLAY2;

komutunda PORTB'nin değeri Ob11111101 ve

DISPLAYPORT=~DISPLAY3;

komutunda ise PORTB'nin alacağı değer 0b11111011 olur. Burada dikkat edilmesi gereken husus, PORTB'nin sadece PB0, PB1, PB2 pinleri kullanıldığı halde, kullanılmayan pinler de bu işlemlerden etkilenmektedir ve dolayısıyla kullanılmaz hale gelmektedirler. Mikro işlemci programcılığında bu önemli bir konudur. Öncelikle, portların sayısı sınırlı olduğundan ve portların genellikle özel ikncil görevleri olduğundan hangi portların hangi amaçla kullanılacağı dikkatlice tasarlanmalıdır. Daha sonra bir portun belli pinlerinin değerlerini değiştirirken aynı portun diğer pinlerinin bu işlemden etkilenmemelerine dikkat emek gerekir, bunun için de ikili sayı siteminin, bit işlemlerinin ve mantıksal operatörlerin çok iyi kavranması gerekir.

Proje Dosyaları

Proje Dosyaları