Elektronik / Mikrodenetleyici Projeleri/

14 Segment Display

Sponsorlu Bağlantılar

Stajdı, oydu, buydu derken uzun zamandır siteyle ilgilenemedim; son yazımdan bu yana iki hafta geçmiş bile. İlginç ve daha önce kullanmadığım neyi eklesem siteye diye düşünürken bir arkadaşın “nasıl oluyor da tarama işlemi ile 4 adet 7 segmenti kontrol edebiliyoruz” diye sorması, bu çalışmamı yapmamda ön ayak oldu.

Bir çok sitede tarama mantığı anlatılıyordu yalnız port genişletme kullanan çok az devre gördüm. Benim bu konuda favori port genişletme entegrem ise 74HC595. Projede ayrıca 0-9999 sayıcıdan farklı olsun (ayıp olur artık) diye pek az sitede kullanımını gördüğüm 14 segment display’leri ele almaya karar verdim.

Ayrıca hemen burada belirtmek isterim, kodlarımı deneysel olmadıktan sonra artık PIC’de değil AVR’de yazmaya karar verdim. “Peki biz PIC kullanıcıları ne olacak?” diye soranlara şimdiden söylüyorum, Hi-Tech C’ye geçin, kodları direk kullanın.

– 8×14 segment display kullanıldı (ortak katot),
– 74HC595 ile port genişletilmesi yapıldı,
– Programda 14 segment için çoğu karakter tanımlandı,
– DS1307 kullanılarak tarih/saat gösterimi yapıldı,
– Açılışta çeşitli efektlerin kullanımı gösterildi,
– Yeni yıl kutlama mesajı eklendi ve
– Tarih saat arasında periyodik geçiş sağlandı.
– Devreyi kurarken 74HC595 ile ledler arasına seri direnç konulmalıdır,
– Ortak uç çıkışlarına NPN (BC337 gibi) konulmalıdır.[/important]

Projenin çalışan videosu:

Projenin kodları:

#include "avr/io.h"
#include "util/delay.h"
#include "avr/interrupt.h"
#include "ds1307.h"

static volatile unsigned int buffer[8];
static volatile unsigned char a=0;
static volatile unsigned int tick=0;

const unsigned char tanitim[]="BIR FXDEV ORG PROJESIDIR";
const unsigned int  round[8]={0x0040,0x0080,0x0100,0x0200,0x0400,0x0800,0x1000,0x2000};

#define PORT_595	PORTC		//74LS595 Clk girişi, yükselen kenar
#define Clock		0x00		//74LS595 Clk girişi, yükselen kenar
#define DataIO		0x01		//74LS595 Data girişi
#define Enable		0x02		//74LS595 Enable girişi

void three_wire_control(unsigned int temp)
{
	char i;
	PORT_595 &= ~(0x01 < < Enable);
	for(i=0;i < 14;i++)
	{
		PORT_595 &= ~(0x01 << (Clock));
		if((temp<<(i))&0x2000)
			PORT_595 |= (0x01 << (DataIO));
		else
			PORT_595 &= ~(0x01 << (DataIO));
		PORT_595 |= (0x01 << (Clock));
	}
	PORT_595 |= (0x01 << Enable);
}

unsigned int character(unsigned char c)
{
	switch(c)
	{
		case 'A': return 0x2237; break;
		case 'B': return 0x0A8F; break;
		case 'C': return 0x2218; break;
		case 'D': return 0x088F; break;
		case 'E': return 0x2239; break;
		case 'F': return 0x2031; break;
		case 'G': return 0x023D; break;
		case 'I': return 0x0889; break;
		case 'J': return 0x001E; break;
		case 'K': return 0x2530; break;
		case 'L': return 0x0038; break;
		case 'N': return 0x0476; break;
		case 'O': return 0x003F; break;
		case 'P': return 0x2233; break;
		case 'R': return 0x2633; break;
		case 'S': return 0x222D; break;
		case 'T': return 0x0881; break;
		case 'U': return 0x003E; break;
		case 'X': return 0x1540; break;
		case 'V': return 0x1130; break;
		case 'Y': return 0x028E; break;
		case 'Z': return 0x1109; break;
		case ' ': return 0x0000; break;
		case '/': return 0x1100; break;

		case '0': return 0x003F; break;
		case '1': return 0x0006; break;
		case '2': return 0x221B; break;
		case '3': return 0x220F; break;
		case '4': return 0x2226; break;
		case '5': return 0x222D; break;
		case '6': return 0x223D; break;
		case '7': return 0x0007; break;
		case '8': return 0x223F; break;
		case '9': return 0x222F; break;
	}
}

void shift_left(const unsigned char *s)
{
	unsigned char j=0,i;
	while(*s)
	{
		for(i=0;i < 7;i++)
			buffer[i]=buffer[i+1];

		buffer[7]=character(*s++);
		_delay_ms(25);
	}
	for(j=0;j < 8;j++)
	{
		for(i=0;i < 7;i++)
			buffer[i]=buffer[i+1];
		buffer[7]=0x0000;
		_delay_ms(25);
	}
}

void left_and_right(const unsigned char word[],unsigned char tekrar)
{
	unsigned char word_length=0,i,j;
	signed char t;

	while(word[word_length]!='\0')
	{
		buffer[word_length]=character(word[word_length]);
		word_length++;
	}
	_delay_ms(25);
	for(i=0;i < tekrar;i++)
	{
		for(j=0;j < 8-word_length;j++)
		{
			for(t=6;t > -1;t--)
			{
				buffer[t+1]=buffer[t];
			}
			buffer[0]=0x0000;
			_delay_ms(25);
		}

		for(j=0;j < 8-word_length;j++)
		{
			for(t=0;t < 7;t++)
			{
				buffer[t]=buffer[t+1];
			}
			buffer[7]=0x0000;
			_delay_ms(25);
		}
	}
}

void clear_segments(void)
{
	unsigned char i;
	for(i=0;i < 8;i++)
		buffer[i]=0x0000;
}

int main(void)
{
	unsigned char gun,ay,yil,hafta,saat,dakika,saniye;
	unsigned char prev_yil;
	PORTB=0x00;
	DDRB=0x00;
	PORTC=0x00;
	DDRC=0xFF;
	PORTD=0xFF;
	DDRD=0xFF;

	ds1307_init();

	TCCR0|=0x02;	// Prescaler 1:8
	TIMSK=0x01;		// Timer0 taşması kesmesi aktif
	TCNT0=0x83;		// 1ms kesme için ön değer yükleniyor

	sei();			// Genel kesmeler aktif ediliyor

	shift_left(tanitim);

	left_and_right("F",1);
	left_and_right("FX",1);
	left_and_right("FXD",1);
	left_and_right("FXDE",1);
	left_and_right("FXDEV",1);

	clear_segments();

	ds1307_set_date_time(31,12,10,4,23,59,55);
	ds1307_get_date(&gun,&ay,&yil,&hafta);

	prev_yil=yil;

	for(;;)
	{
		ds1307_get_date(&gun,&ay,&yil,&hafta);
		ds1307_get_time(&saat,&dakika,&saniye);

		if(prev_yil < yil)
		{
			prev_yil=yil;
			clear_segments();
			shift_left("YENI YILINIZ KUTLU OLSUN");
		}
		else if(tick < 10000)
		{
			buffer[0]=character((saat/10)+48);
			buffer[1]=character((saat%10)+48);
			buffer[2]=round[saniye%8];
			buffer[3]=character((dakika/10)+48);
			buffer[4]=character((dakika%10)+48);
			buffer[5]=round[7-saniye%8];
			buffer[6]=character((saniye/10)+48);
			buffer[7]=character((saniye%10)+48);
		}
		else if(tick > 10000 && tick < 12000)
		{
			buffer[0]=character((gun/10)+48);
			buffer[1]=character((gun%10)+48);
			buffer[2]=character('/');
			buffer[3]=character((ay/10)+48);
			buffer[4]=character((ay%10)+48);
			buffer[5]=character('/');
			buffer[6]=character((yil/10)+48);
			buffer[7]=character((yil%10)+48);
		}
	}
}

ISR(TIMER0_OVF_vect)	// Timer0 taşma kesmesi
{
	TCNT0=0x83;			// 1ms kesme için tekrar ön değer yükleniyor

	if(tick < 12000) tick++; else tick=0;

	switch(a)
	{
		case 0:	PORTD=0xFF; three_wire_control(buffer[a]); PORTD=~0x01; a=1; break;
		case 1:	PORTD=0xFF; three_wire_control(buffer[a]); PORTD=~0x02; a=2; break;
		case 2:	PORTD=0xFF; three_wire_control(buffer[a]); PORTD=~0x04; a=3; break;
		case 3:	PORTD=0xFF; three_wire_control(buffer[a]); PORTD=~0x08; a=4; break;
		case 4:	PORTD=0xFF; three_wire_control(buffer[a]); PORTD=~0x10; a=5; break;
		case 5:	PORTD=0xFF; three_wire_control(buffer[a]); PORTD=~0x20; a=6; break;
		case 6:	PORTD=0xFF; three_wire_control(buffer[a]); PORTD=~0x40; a=7; break;
		case 7:	PORTD=0xFF; three_wire_control(buffer[a]); PORTD=~0x80; a=0; break;
	}
}

Herkese çalışmalarında başarılar dilerim..

  • Sinan Şahin

    Kardeş Allah aşkına şu 0-9999 8051 ile uygulanan sayıcı devresinin kodlarını bana göster, okul bitmiyor yoksa kurbanın olayım.

  • FxDev

    10TL’ye vereyim kodları ya da öğrenip sen yaz, hangisini tercih edersin?

  • Saadettin

    Merhaba,
    Ben de atmel mcu’ları ile uğraşmaya başlayacağım, kullandığınız derleyici nedir?

    Arduino’nun derleyicisi ile bu kodlar yazılıp compile edilebilir mi?

    Include ettiğiniz kodları siz mi yazdınız?
    Sadece hobici.

    Saadettin

  • FxDev

    @Saadettin: Kullandığım derleyici WinAVR.
    Arduino ile hiç ilgilenmediğimden bilemiyorum.
    #include dosyalarından sadece “ds1307.h” olanını ben yazdım.

  • Saadettin

    Cevap için teşekkürler.