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.
- 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.
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..


Emrah Budak