Elektronik / Mikrodenetleyici Projeleri/

PIC16F88 128X8 PC Kontrol Kayan Yazı CCS C ile

Sponsorlu Bağlantılar

Hazırlayan: Eyüp KAPLAN – Emeği geçen Kişilere Teşekkürler Aşağıda ki açıklamalar kendisine aittir.

Merhaba…

128×8 Matrix ile hem kayan yazı ve hem de Matrix Display projemi az önce tamamladım. Sizlerle paylaşmak istedim. İnşaAllah işinize yarar.

Kaydırılacak yazı EEProm’a kaydediliyor ve kaydırma esnasında buradan okunuyor. Bu nedenle kaydırılacak yazı istenildiği zaman değiştirilebilir ve veri kaybı olmaz. Veriyi PC yardımı ile RS232 bağlantısı ile gerçekleştiriyoruz. Bunun için:

pic16f88 ccs c kayan yazi panosu 128x8 display eeprom

İlk enerji verme anında PIN_A5 ‘e bağlı Switch eğer kapalı ise PIC yeni veri girilmek istendiğini anlıyor ve yeni giriş olup olmadığını soruyor. Yeni giriş değilse “ é ” karakterini giriyoruz. Eğer yeni giriş yapılacaksa o zaman gireceğimiz veriyi yazıyoruz.

Program otomatik olarak büyük harfe çeviriyor. Zamanım olmadığı için küçük harfin fontlarını oluşturamadım. Türkçe karakterlerden de bazıları eksik. Sadece “Ü” ve “İ” şimdilik tanımlı. Projenin diğer aşamalarında tüm karakterleri tanıtacağım. Lakin bu kadarısı bile beni bayağı yordu.

Yeni veriyi girdikten sonra son karakter olarak mutlaka “ é “ karakterini giriyoruz k,; PIC veri sonuna gelindiğini bilsin. Aksi halde veri okumaya devam eder. Veri girişi bittikten sonra Switch ‘i açarak cihaza tekrar enerji verdiğimizde bize hiçbirşey sormadan girmiş olduğumuz yazıyı ekranda kaydırmaya başlar.

Ekranda meydana gelen hafif titremenin gerçek uygulamada olmayacağını sanıyorum. Çünkü Proteus simulasyonda zamana bağlı olarak bilgisayarın takıldı her anda görüntü de donuyor ve bu bize titreşim olarak aksediyor.

Projede PIC16F88 kullandım. Ortak Katod Matrix kullandım. Fakat LED uygulaması yapılabilir ve Ortak Katod bağlanabilir. Tabi ki bu durumda transistorler ile satır ve sütunları sürmek gerekecektir.

Bu tip projelerde eğer sadece kaydırma amaçlansa idi; adresleme kısmı(taranan sütunlar) dışarıdan bir osilatör ile veya PIC ‘in bir bacağında kontrol edilen tetikleler ile çok daha kolay ve sütun sayısı çok daha fazla display elde edebilirdik. Fakat burada istediğimiz anda istediğiniz satır ve sütuna doğrudan ulaşmak amçlandığı için en fazla şimdilik bu kadar (128) sütuna sayısına ulaşmış oluyoruz. Gerçi birçok uygulama için ihtiyaçtan daha fazla zaten.

Hem sütun sayısı arttıkça tarama süresi artacağından görüntüde titremeler meydana gelecektir.
Benim için bu kadarısı fazla bile… Girilebilecek maksimum karakter sayısı 255 ‘i geçmemelidir. Çünkü PIC’in hafızası bu kadardır. Giriş anında eğer 255’e ulaşılırsa otomatik olarak kaydırmaya başlayacaktır.

Bu şekilde daha fazla giriş engellenmiş olur. Giriş için en güzel yöntem: PC ‘de Delphi, VB, C gibi programlarla bir arayüz yazılır ve gönderilecek yazı burada önce hazırlanır ve hataları düzeltilir. Daha sonra doğrudan PC’nin RS232 portundan yollanabilir veya bir uzaktan kumada yardımı ile bilgi yollanabilir.

128X8 Kayan Yazı Devre Şeması

pic16f88 ccs c kayan yazi devre semasi

Elimden geldiğince minimum malzeme ve maksimum PIC perfonmansını amaçlayan ve çok amaca hizmet eden matriks display projesi yapmaya çalıştım. Dediğim gibi eğer amaç sadece kaydırma olsa o zaman daha farklı mantıklar kullanılabilirdi. Projenin en önemli özelliklerinden birisi de noktasal olarak kaymasıdır. Karaktersel olarak kaydırmak çok daha basit bir yazılım gerektiriyor. Noktasal olunca iş biraz daha karmaşıklaşıyor.

Hem dikkat edilecek olusa 128/6=21.33 karakteri ediyor. Son karakter eksik olmasına rağmen ekranda bu
bölüm boş bırakılmamış ve 128 sütunun tamamı kullanılmıştır. Bunlar ince detaylar ama yazılımı kaliteli yapan da bu ince ayrıntılardır. Eğer harf kaydırma yapılsa bu son 2 sütun boş kalacaktı.

Yazılımın ilerleyen aşamalarında kaydırma hızı ve bekleme süreleri de PC kontrollü olarak yapılmaya hazır hale getirildi ama bu bölüm bu projeye eklenmedi. Ben burada projenin temelini verdim ki, fikir sahibi olmak isteyenlere bir ışık tutsun diye. Ben de ilk başladığımda bayağı sıkıntılar yaşadım. Hangi entegreyi ve göstergeyi kullanacağıma ve bunlarını nasıl kullanacağıma karar vermem bile 1-2 gün sürdü. Şimdi bu proje ile bu tip çalışmalar yapmak isteyenler hardware olarak neye ihtiyaçları olduğunu ve çalıştığı zaman sonucun neler olabilieceğini görmüş olacaklar. Kendi source kodlarını da kendileri geliştireceklerdir.

PIC16F88 Kayan Yazı_Source.c

#include <16F88.h>
#device *=16
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES INTRC_IO                 //Internal RC Osc, no CLKOUT
#FUSES NOPUT                    //No Power Up Timer
//#FUSES MCLR                     //Master Clear pin enabled
#FUSES BROWNOUT                 //Reset when brownout detected
//#FUSES LVP                      //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOPROTECT                //Code not protected from reading
#FUSES FCMEN                    //Fail-safe clock monitor enabled
#FUSES IESO                     //Internal External Switch Over mode enabled
//#FUSES CCPB0

#use delay(clock=8000000)
#use rs232(baud=9600,parity=N,rcv=PIN_B7,bits=8)
#use fast_io(a)
#use fast_io(b)

#include 

char digit[6];
Char Yazi_Len;
Long Yazi_Bin_Len;

char mesaj1[]="YENİ KAYIT ?";

void Char_5x7_Matrix(char opt);     //Program sonuna INCLUDE olan fonksiyon

Char Set_Output_A(int8 d,s)
{
char s1;

   s1=((s<<5)& 0b11000000) |((s & 0b00000001)<<4);
   Return(d | s1);
}

Char Set_Mesaj_Output_A(int8 s)     //Count Girilirse X-Poz hesaplaması
{
char s1;
   
   s1=((s<<1)& 0b11000000) | (s & 0b00011111);
   Return(s1);
}

Char Set_Data_Output_B(int8 Kay_Data)
{
Char D,S;

   D=Kay_data / 6; //idiv.quot;
   S=Kay_Data % 6; //idiv.rem;
   Char_5x7_Matrix(Read_EEprom(D));
   
   Return(Digit[s]);
}

Char Set_Mesaj_Output_B(int8 Kay_Data)
{
Char D,S;

   D=Kay_data / 6; //idiv.quot;
   S=Kay_Data % 6; //idiv.rem;
   Char_5x7_Matrix(Mesaj1[D]);
   
   Return(Digit[s]);
}

Void Clr_Matrix()
{
Char s,j;
   
   for(s=0;s<8;s++)  //Select Bitleri Gönder
   {                    
      for(j=0;j<=15;j++) //Data Bitleri Gönder
      { 
         Output_A(Set_Output_A(j,s));
         Output_B(0x00);
         delay_us(300);
      }
   }
}

Void Tara()
{
char i,j,s,count=0,Kay_Ep=0;
   
Kay_Ep=0;   //Kaydırma için Data 'nın başlangıç pozisyonunu saklar
Count = 0;

While(True)
{
   Count = Kay_Ep;
   Clr_Matrix();
   for(i=0;i<7;i++)                     //Kaydırmazdan önceki tarama süresi. Gecikmeli kayma!...
   {
      count= Kay_Ep;
      for(s=0;s<8;s++)                    //Select Bitleri Gönder
      {                    
         for(j=0;j<=15;j++) //Data Bitleri Gönder
         {         
            Output_A(Set_Output_A(j,s));   
            Output_B(Set_Data_Output_B(Count));
            delay_us(1);                  //Data görünme süresi
            output_B(0x00);               //bu nedenle datayı işi bitince sıfırlıyoruz. Yeni select önce sıfır sonra gerçek datayı göstersin diye.
            Count++;            
            If(Count == Yazi_Bin_Len) Count = 0;    //Verinin Pixel sonuna gelidi ise tekrar başa dön              
         }
      }
   }
   Kay_Ep++;
   If(Kay_Ep == Yazi_Bin_Len) Kay_Ep=0;
}
}

Void Mesaj_Yaz(char X,*Mes)
{
char i,s,count=0,Xs=0,Xsm,Ss, *Msg;
      
   Msg = Mes;   
   Xs = X;   
   Xsm = (Xs + 10 * 6);
   If (Xsm >= 128) Xsm=128;
   
   Clr_Matrix();
   
   for(i=0;i<255;i++)                     //Kaydırmazdan önceki tarama süresi. Gecikmeli kayma!...
   {
      count= 0;
      for(s=Xs; s 0) write_eeprom (255, Poz);
}

void main()
{

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);

   set_tris_b (0b10000000);      
   set_tris_a (0b00100000);      //PIN_A5 MCLR is Input Others Output
   
   Output_A(0x00);
   Output_B(0x00);
   
   If(Input(PIN_A5))
   {
      Mesaj_Yaz(21,Mesaj1);
   }
   
   If(Input(PIN_A5))            //Bilgisayardan veri girişi
   {
      Write_Eprom_Yazi();
   }        
   
   Yazi_Len=Read_EEprom(255);
   Yazi_Bin_Len = (int16)Yazi_Len * 6;   
   
   While(True)
   {
      Tara();
   }
}

#include 

PIC16F88 Kayan Yazı_Karakter_Source.c

void Char_5x7_Matrix(char opt)
{
   switch (opt)
   {                            
      case 'A':   Digit[0]=0x3F;  
                  Digit[1]=0x48;
                  Digit[2]=0x48;
                  Digit[3]=0x48;
                  Digit[4]=0x3F;   
                  Digit[5]=0x00;   
                  break;
      case 'B':   Digit[0]=0x7f;  
                  Digit[1]=0x49;
                  Digit[2]=0x49;
                  Digit[3]=0x49;
                  Digit[4]=0x36;   
                  Digit[5]=0x00;   
                  break;
      case 'C':   Digit[0]=0x3e;  
                  Digit[1]=0x41;
                  Digit[2]=0x41;
                  Digit[3]=0x41;
                  Digit[4]=0x22;   
                  Digit[5]=0x00;   
                  break;
      case 'D':   Digit[0]=0x7f;  
                  Digit[1]=0x41;
                  Digit[2]=0x41;
                  Digit[3]=0x41;
                  Digit[4]=0x3e;   
                  Digit[5]=0x00;   
                  break;
      case 'E':   Digit[0]=0x7f;  
                  Digit[1]=0x49;
                  Digit[2]=0x49;
                  Digit[3]=0x49;
                  Digit[4]=0x41;   
                  Digit[5]=0x00;   
                  break;
      case 'F':   Digit[0]=0x7f;  
                  Digit[1]=0x48;
                  Digit[2]=0x48;
                  Digit[3]=0x48;
                  Digit[4]=0x40;   
                  Digit[5]=0x00;   
                  break;
      case 'G':   Digit[0]=0x3E;  
                  Digit[1]=0x41;
                  Digit[2]=0x49;
                  Digit[3]=0x49;
                  Digit[4]=0x2E;   
                  Digit[5]=0x00;   
                  break;
      case 'H':   Digit[0]=0x7F;  
                  Digit[1]=0x08;
                  Digit[2]=0x08;
                  Digit[3]=0x08;
                  Digit[4]=0x7F;   
                  Digit[5]=0x00;   
                  break;
      case 'I':   Digit[0]=0x41;  
                  Digit[1]=0x7F;
                  Digit[2]=0x41;
                  Digit[3]=0x00;
                  Digit[4]=0x00;  
                  Digit[5]=0x00;   
                  break;
      case 'İ':   Digit[0]=0x11;  
                  Digit[1]=0x5F;
                  Digit[2]=0x11;
                  Digit[3]=0x00;
                  Digit[4]=0x00;  
                  Digit[5]=0x00;   
                  break;                  
      case 'J':   Digit[0]=0x02;  
                  Digit[1]=0x01;
                  Digit[2]=0x41;
                  Digit[3]=0x7e;
                  Digit[4]=0x40;
                  Digit[5]=0x00;   
                  break;
      case 'K':   Digit[0]=0x7f;  
                  Digit[1]=0x08;
                  Digit[2]=0x14;
                  Digit[3]=0x22;
                  Digit[4]=0x41;  
                  Digit[5]=0x00;   
                  break;
      case 'L':   Digit[0]=0x7f;  
                  Digit[1]=0x01;
                  Digit[2]=0x01;
                  Digit[3]=0x01;
                  Digit[4]=0x01;   
                  Digit[5]=0x00;   
                  break;
      case 'M':   Digit[0]=0x7f;  
                  Digit[1]=0x20;
                  Digit[2]=0x18;
                  Digit[3]=0x20;
                  Digit[4]=0x7F;   
                  Digit[5]=0x00;   
                  break;
      case 'N':   Digit[0]=0x7F;  
                  Digit[1]=0x10;
                  Digit[2]=0x08;
                  Digit[3]=0x04;
                  Digit[4]=0x7F;  
                  Digit[5]=0x00;   
                  break;  
      case 'O':   Digit[0]=0x3E;  
                  Digit[1]=0x41;
                  Digit[2]=0x41;
                  Digit[3]=0x41;
                  Digit[4]=0x3E;   
                  Digit[5]=0x00;   
                  break;
      case 'P':   Digit[0]=0x7f;  
                  Digit[1]=0x48;
                  Digit[2]=0x48;
                  Digit[3]=0x48;
                  Digit[4]=0x30;   
                  Digit[5]=0x00;   
                  break;
      case 'Q':   Digit[0]=0x3e;  
                  Digit[1]=0x41;
                  Digit[2]=0x45;
                  Digit[3]=0x42;
                  Digit[4]=0x3d;   
                  Digit[5]=0x00;   
                  break;
      case 'R':   Digit[0]=0x7f;  
                  Digit[1]=0x48;
                  Digit[2]=0x4C;
                  Digit[3]=0x4a;
                  Digit[4]=0x31;   
                  Digit[5]=0x00;   
                  break;
      case 'S':   Digit[0]=0x32;  
                  Digit[1]=0x49;
                  Digit[2]=0x49;
                  Digit[3]=0x49;
                  Digit[4]=0x26;   
                  Digit[5]=0x00;   
                  break;
      case 'T':   Digit[0]=0x40;  
                  Digit[1]=0x40;
                  Digit[2]=0x7F;
                  Digit[3]=0x40;
                  Digit[4]=0x40;   
                  Digit[5]=0x00;   
                  break;
      case 'U':   Digit[0]=0x7E;  
                  Digit[1]=0x01;
                  Digit[2]=0x01;
                  Digit[3]=0x01;
                  Digit[4]=0x7E;   
                  Digit[5]=0x00;   
                  break;
      case 'Ü':   Digit[0]=0x1E;  
                  Digit[1]=0x41;
                  Digit[2]=0x01;
                  Digit[3]=0x41;
                  Digit[4]=0x1E;   
                  Digit[5]=0x00;   
                  break;                  
      case 'V':   Digit[0]=0x7C;  
                  Digit[1]=0x02;
                  Digit[2]=0x01;
                  Digit[3]=0x02;
                  Digit[4]=0x7C;   
                  Digit[5]=0x00;   
                  break;
      case 'W':   Digit[0]=0x7E;  
                  Digit[1]=0x01;
                  Digit[2]=0x0E;
                  Digit[3]=0x01;
                  Digit[4]=0x7E;   
                  Digit[5]=0x00;   
                  break;
      case 'X':   Digit[0]=0x63;  
                  Digit[1]=0x14;
                  Digit[2]=0x08;
                  Digit[3]=0x14;
                  Digit[4]=0x63;   
                  Digit[5]=0x00;   
                  break;
      case 'Y':   Digit[0]=0x70;  
                  Digit[1]=0x08;
                  Digit[2]=0x07;
                  Digit[3]=0x08;
                  Digit[4]=0x70;   
                  Digit[5]=0x00;   
                  break;
      case 'Z':   Digit[0]=0x43;  
                  Digit[1]=0x45;
                  Digit[2]=0x49;
                  Digit[3]=0x51;
                  Digit[4]=0x61;
                  Digit[5]=0x00;   
                  break;                  
      case ' ':   Digit[0]=0x00;  
                  Digit[1]=0x00;
                  Digit[2]=0x00;
                  Digit[3]=0x00;
                  Digit[4]=0x00;
                  Digit[5]=0x00;   
                  break;
                  
      case '0':   Digit[0]=0x3E;  
                  Digit[1]=0x45;
                  Digit[2]=0x49;
                  Digit[3]=0x51;
                  Digit[4]=0x3E;
                  Digit[5]=0x00;   
                  break;
                  
      case '1':   Digit[0]=0x21;  
                  Digit[1]=0x7F;
                  Digit[2]=0x01;
                  Digit[3]=0x00;
                  Digit[4]=0x00;
                  Digit[5]=0x00;   
                  break;
                  
      case '2':   Digit[0]=0x21;  
                  Digit[1]=0x43;
                  Digit[2]=0x45;
                  Digit[3]=0x49;
                  Digit[4]=0x31;
                  Digit[5]=0x00;   
                  break;
                  
      case '3':   Digit[0]=0x42;  
                  Digit[1]=0x41;
                  Digit[2]=0x51;
                  Digit[3]=0x69;
                  Digit[4]=0x46;
                  Digit[5]=0x00;   
                  break;
                  
      case '4':   Digit[0]=0x0c;  
                  Digit[1]=0x14;
                  Digit[2]=0x24;
                  Digit[3]=0x7f;
                  Digit[4]=0x04;
                  Digit[5]=0x00;   
                  break;
                  
      case '5':   Digit[0]=0x72;  
                  Digit[1]=0x51;
                  Digit[2]=0x51;
                  Digit[3]=0x51;
                  Digit[4]=0x4e;
                  Digit[5]=0x00;   
                  break;
                  
      case '6':   Digit[0]=0x1e;  
                  Digit[1]=0x29;
                  Digit[2]=0x49;
                  Digit[3]=0x49;
                  Digit[4]=0x06;
                  Digit[5]=0x00;   
                  break;
                  
      case '7':   Digit[0]=0x40;  
                  Digit[1]=0x47;
                  Digit[2]=0x48;
                  Digit[3]=0x50;
                  Digit[4]=0x60;
                  Digit[5]=0x00;   
                  break;
                  
      case '8':   Digit[0]=0x36;  
                  Digit[1]=0x49;
                  Digit[2]=0x49;
                  Digit[3]=0x49;
                  Digit[4]=0x36;
                  Digit[5]=0x00;   
                  break;
                  
      case '9':   Digit[0]=0x30;  
                  Digit[1]=0x49;
                  Digit[2]=0x49;
                  Digit[3]=0x4a;
                  Digit[4]=0x3c;
                  Digit[5]=0x00;   
                  break;
                 
      case '?':   Digit[0]=0x20;  
                  Digit[1]=0x40;
                  Digit[2]=0x45;
                  Digit[3]=0x48;
                  Digit[4]=0x30;
                  Digit[5]=0x00;
                  break; 
      case '$':   Digit[0]=0x32;  
                  Digit[1]=0x49;
                  Digit[2]=0x7F;
                  Digit[3]=0x49;
                  Digit[4]=0x26;   
                  Digit[5]=0x00;
                  break;
      case '%':   Digit[0]=0x62;  
                  Digit[1]=0x64;
                  Digit[2]=0x08;
                  Digit[3]=0x13;
                  Digit[4]=0x23;   
                  Digit[5]=0x00;
                  break;
      case '#':   Digit[0]=0x14;  
                  Digit[1]=0x7F;
                  Digit[2]=0x14;
                  Digit[3]=0x7F;
                  Digit[4]=0x14;   
                  Digit[5]=0x00;
                  break;
      case '&':   Digit[0]=0x36;  
                  Digit[1]=0x49;
                  Digit[2]=0x39;
                  Digit[3]=0x16;
                  Digit[4]=0x05;   
                  Digit[5]=0x00;
                  break;
      case '.':   Digit[0]=0x00;
                  Digit[1]=0x03;
                  Digit[2]=0x03;
                  Digit[3]=0x00;
                  Digit[4]=0x00;
                  Digit[5]=0x00;
                  break;                  
      case ',':   Digit[0]=0x00;  
                  Digit[1]=0x01;
                  Digit[2]=0x01;
                  Digit[3]=0x06;
                  Digit[4]=0x00;
                  Digit[5]=0x00;
                  break;
      case ';':   Digit[0]=0x00;
                  Digit[1]=0x01;
                  Digit[2]=0x01;
                  Digit[3]=0x36;
                  Digit[4]=0x30;
                  Digit[5]=0x00;
                  break; 
      case '"':   Digit[0]=0x00;
                  Digit[1]=0x60;
                  Digit[2]=0x00;
                  Digit[3]=0x60;
                  Digit[4]=0x00;
                  Digit[5]=0x00;
                  break;
      case '`':   Digit[0]=0x00;
                  Digit[1]=0x60;
                  Digit[2]=0x10;
                  Digit[3]=0x00;
                  Digit[4]=0x00;
                  Digit[5]=0x00;
                  break;                  
      case '!':   Digit[0]=0x00;
                  Digit[1]=0x00;
                  Digit[2]=0x7D;
                  Digit[3]=0x00;
                  Digit[4]=0x00;
                  Digit[5]=0x00;
                  break;                          
      case '-':   Digit[0]=0x00;
                  Digit[1]=0x08;
                  Digit[2]=0x08;
                  Digit[3]=0x08;
                  Digit[4]=0x00;
                  Digit[5]=0x00;
                  break;
      case '+':   Digit[0]=0x08;
                  Digit[1]=0x08;
                  Digit[2]=0x3E;
                  Digit[3]=0x08;
                  Digit[4]=0x08;
                  Digit[5]=0x00;
                  break;
      case '=':   Digit[0]=0x00;
                  Digit[1]=0x14;
                  Digit[2]=0x14;
                  Digit[3]=0x14;
                  Digit[4]=0x00;
                  Digit[5]=0x00;
                  break;
      case '(':   Digit[0]=0x00;
                  Digit[1]=0x1C;
                  Digit[2]=0x22;
                  Digit[3]=0x41;
                  Digit[4]=0x00;
                  Digit[5]=0x00;
                  break;                  
      case ')':   Digit[0]=0x00;
                  Digit[1]=0x41;
                  Digit[2]=0x22;
                  Digit[3]=0x1C;
                  Digit[4]=0x00;
                  Digit[5]=0x00;
                  break;
      case '[':   Digit[0]=0x00;
                  Digit[1]=0x7F;
                  Digit[2]=0x41;
                  Digit[3]=0x41;
                  Digit[4]=0x00;
                  Digit[5]=0x00;
                  break;                  
      case ']':   Digit[0]=0x00;
                  Digit[1]=0x41;
                  Digit[2]=0x41;
                  Digit[3]=0x7F;
                  Digit[4]=0x00;
                  Digit[5]=0x00;
                  break;                  
      case '*':   Digit[0]=0x2A;
                  Digit[1]=0x1C;
                  Digit[2]=0x08;
                  Digit[3]=0x1C;
                  Digit[4]=0x2A;
                  Digit[5]=0x00;
                  break;
      case '/':   Digit[0]=0x02;
                  Digit[1]=0x04;
                  Digit[2]=0x08;
                  Digit[3]=0x10;
                  Digit[4]=0x20;
                  Digit[5]=0x00;
                  break;                  
      case '_':   Digit[0]=0x01;  
                  Digit[1]=0x01;
                  Digit[2]=0x01;
                  Digit[3]=0x01;
                  Digit[4]=0x01;
                  Digit[5]=0x00;
                  break;
      case '<':   Digit[0]=0x08;  
                  Digit[1]=0x14;
                  Digit[2]=0x22;
                  Digit[3]=0x41;
                  Digit[4]=0x00;
                  Digit[5]=0x00;
                  break;
      case '>':   Digit[0]=0x00;  
                  Digit[1]=0x41;
                  Digit[2]=0x22;
                  Digit[3]=0x14;
                  Digit[4]=0x08;
                  Digit[5]=0x00;
                  break;                  
      case 'é':   Digit[0]=0x0E;  
                  Digit[1]=0x15;
                  Digit[2]=0x35;
                  Digit[3]=0x55;
                  Digit[4]=0x0D;
                  Digit[5]=0x00;
                  break;                  
      case 0x27:  Digit[0]=0x00; //  '  
                  Digit[1]=0x00;
                  Digit[2]=0x10;
                  Digit[3]=0x60;
                  Digit[4]=0x00;
                  Digit[5]=0x00;
                  break;                  
                  
      }                         
}

Kayan Yazı Devrelerinin Temel Mantığı

Kayan yazı devrelerinin mantığı tamamen göz aldanmasına dayanır. Kayan yazı devrelerinde tüm sütunlar aynı anda enerjinemeyeceği için kullanılan devrenin mantığına göre; ya harf harf (bu tür devreler için çok sayıda çıkış ucu gerekenceği için pek tercih edilmez), ya da sadece tek bir sütuna karşılık gelen satırlar hızla taranarak ve bu süre gözün algılayabileceği süreden hızlı olmak şartı ile yapılırsa göz aldanır ve sanki tüm satır ve sürtünlar aynı anda enerjilenmiş izlenimine kapılır.

Bu mantığa dayanarak o halde öncelikle her bir karakterin

5x7-matris-kodlama

Yukarıdaki programa benzer bir programla kodlanması gerekiyor. Ekranda göstermek istenilen her karakter için teker teker bunu yapmak lazım. Biryerlerden hazır fontları da alıp kullanmak elbette mümkündür. Fakat işin en zevkli yönlerinden birisi kendi fontlarını oluşturmak olacaktır. Bu programı da zip dosyası içerisine ekledim. Bu yazıda işin elektronik devre kısmına değinmeyeceğim. Herkes kendisine uygun devreyi tasarlayabilir. Zaten birçok hazır örnek de mevcut.

Şimdi fontları oluşturduk ve bunları ekranda göstermeye sıra geldi. Bunun için genelde 2 yönten tercih edilir.

– Ya karakter karakter kaydırma yapılır.
– Ya da her bir sütün kaydırılır. Bu durumda 1 karakter için 5 tane kaydırma yapmamız gerekir.

Bu sizin tercihinize kalmış bir şey. Karakter karakter kaydırmak çok daha basit bir uygulma oluyor. Hesaplamlar da daha kolay oluyor. Ama sütün sütün kaydırmada daha biraz zorlanılıyor ve daha dikkatli hesaplamalar yapmak gerekiyor. Aşağıya örnek olarak bazı harflerin fontlarının kodlanmış halini veriyorum:

'A': Digit[0]=0x3F;
Digit[1]=0x48;
Digit[2]=0x48;
Digit[3]=0x48;
Digit[4]=0x3F;
Digit[5]=0x00;

'B': Digit[0]=0x7f;
Digit[1]=0x49;
Digit[2]=0x49;
Digit[3]=0x49;
Digit[4]=0x36;
Digit[5]=0x00;

'1': Digit[0]=0x21;
Digit[1]=0x7F;
Digit[2]=0x01;
Digit[3]=0x00;
Digit[4]=0x00;
Digit[5]=0x00;

'2': Digit[0]=0x21;
Digit[1]=0x43;
Digit[2]=0x45;
Digit[3]=0x49;
Digit[4]=0x31;
Digit[5]=0x00;

Gibi…

Dikkat ederseniz burada 0..5 arası bir dizi tanımlanmış oluyor ve son sütün 0x00 oluyor. Bu son sütundaki 0x00, karakterler arasındaki boşluğu oluşturmak için ekleniyor. Ben kendi programımda her bir harf için ayrı bir dizi oluşturarak yukarıdaki şekilde programlama yaptım. Ayrıca toplu olarak tek bir dizide de bu karakterler tanımlanabilir ve hesaplama yöntemi ile her bir karaktere ulaşılabilinir. Genelde bu yönten tercih edilmekle birlikte bana göre bazı kısıtlamaları da bereberinde getirdiği için ben tek tek tanımlamayı tercih ettim.Burada dikkat edilecek bir diğer nokta ise herkesin kodlarının farklı farklı olacağıdır

int harf_deg[264] = {0x3F,0x48,0x48,0x48,0x3F,0, //A
0x7f,0x49,0x49,0x49,0x36,0, //B
0x3e,0x41,0x41,0x41,0x22,0, //C
0x7f,0x41,0x41,0x41,0x3e,0, //D
0x7f,0x49,0x49,0x49,0x41,0, //E
0x7f,0x48,0x48,0x48,0x40,0, //F
0x3E,0x41,0x49,0x49,0x2E,0, //G
0x7F,0x08,0x08,0x08,0x7F,0, //H
0x41,0x7F,0x41,0x00,0x00,0, //I
0x11,0x5F,0x11,0x00,0x00,0, //İ
0x02,0x01,0x41,0x7e,0x40,0, //J
0x7f,0x08,0x14,0x22,0x41,0, //K
0x7f,0x01,0x01,0x01,0x01,0, //L
0x7f,0x20,0x18,0x20,0x7F,0, //M
0x7F,0x10,0x08,0x04,0x7F,0, //N
0x3E,0x41,0x41,0x41,0x3E,0, //O
0x7f,0x48,0x48,0x48,0x30,0, //P
0x3e,0x41,0x45,0x42,0x3d,0, //Q
0x7f,0x48,0x4C,0x4a,0x31,0, //R
0x32,0x49,0x49,0x49,0x26,0, //S
0x40,0x40,0x7F,0x40,0x40,0, //T
0x7E,0x01,0x01,0x01,0x7E,0, //U
0x1E,0x41,0x01,0x41,0x1E,0, //Ü
0x7C,0x02,0x01,0x02,0x7C,0, //V
0x7E,0x01,0x0E,0x01,0x7E,0, //W
0x63,0x14,0x08,0x14,0x63,0, //X
0x70,0x08,0x07,0x08,0x70,0, //Y
0x43,0x45,0x49,0x51,0x61,0, //Z
0x00,0x00,0x00,0x00,0x00,0, //Space
0x3E,0x45,0x49,0x51,0x3E,0, //0
0x21,0x7F,0x01,0x00,0x00,0, //1
0x21,0x43,0x45,0x49,0x31,0, //2
0x42,0x41,0x51,0x69,0x46,0, //3
0x0c,0x14,0x24,0x7f,0x04,0, //4
0x72,0x51,0x51,0x51,0x4e,0, //5
0x1e,0x29,0x49,0x49,0x06,0, //6
0x40,0x47,0x48,0x50,0x60,0, //7
0x36,0x49,0x49,0x49,0x36,0, //8
0x30,0x49,0x49,0x4a,0x3c,0}; //9

Örneğin yukarıdaki tekli dizi matriksde “A” karakterinin fonları ; 0x3F,0x48,0x48,0x48,0x3F,0 olarak tanımlanmıştır. Bu kodları 5×7 Font kodlayıcıya koyunca aşağıdaki görüntüyü elde ederiz. Bu program bize hesaplayıp sonucu verirken satıra göre veriyor. Bize ise sütuna göre lazın. Buna dikkat edelim.

5x7 matris kodlama ccs c program

Bu şekilde kodların yazılımı tamamlanınca sıra geldi bunları ekranda göstermeye… Kullanacağımız LED Matrix Ekranı 8×8 lik hazır Matrix Display ‘ler kullanılarak yapılmış ise bu durumda bizler ya 5×7 font değil de 5×8, 6×8, 7×8 veya 8×8 gibi istediğimiz font tipini oluşturabiliriz ya da küçük fon tipine giren 5×7 font tipini kullanarak satırlardan birisini kullanmayız, boş bırakırız. Eğer 2 satırlık ekran yapıyorsak zaten araya boşluk bırakmak gerekeceğinden bu boş bıraktığımız satırda aralık olarak işlem görmüş olacaktır.

Eğer kendimiz LED ‘leri kullanarak bir Display yapacaksak o zaman bu 8. satırı yapmayabiliriz.
Bu tamamen size kalmış bir olay. Şimdi ilk önce eğer soldan sağa kaydıracaksak ki; doğru olan da budur. Aksi halde okumakda aksaklıklar olacaktır.

– Kaydırılacak olan dizide sırası gelen karakteri oluşturmuş olduğumuz karakter dizinden okuruz. Bunu eğer toplu tanımlama yapmış isek zaten sırasıyla ilk sütünu okuduktan sonra 5 tane oluncaya kadar okuruz. Yok eğer her karakter için benim yaptığım gibi ayrı ayrı yapmışsak daha kolay bir şekilde hemen 0 ‘dan 5 ‘e kadar sırasıyla okuruz.

– 0. bayttaki bilgiyi okuduk. Mesela “A” harfi için bu değer; 0:0x3F, 1:0x48, 2: 0x48, 3:0x48, 4:0x3F, 5:0x00

– Önce 0. bayttaki h3F değeri elektronik devremizde veriyi aktaracak olan (7 tane satırdaki bitleri gösterek olan) çıkışlara aktarılır. Ben programımda bunu 16F88 için PORT_B olarak seçtim ve bu durumda 1 adet çıkışım da hala boşta kaldı. Bunu da başka bir amaç için RS232 girişi olarak kullandım. Bacak sınırlaması olunca her bacaktan maksimum performans elde etmek lazım. Öyle bol keseden fazla fazla bacak kullanalarak yapanlar işin basitine kaçanlardır. İleride çok daha karmaşık devrelerde zoranmamak için kendimizi maksimum performans elde etmeye alıştırmalıyız.

– Şimdi Matrik ekranınızın en son sütununda göndermiş olduğunuz bayt bilgisi yani ilk karakterin ilk baytı gönderildi. Ama henüz bu görüntülenmedi. Görüntülenmesi içinse elektronik devre ile ve MCU aracılığı ile ilgili sütunun seçilmesi gerekiyor ki; ışıklar yansın ve seçtiğimiz sütun görünsün. Bu da 2 şekilde oluyor. Ortak Katot veya Ortak Anode olarak kullandığımız LED Matrikse bağlı. Bu durumda ilgili çıkışı “0” ya da
“1” yapmamız gerekecek.

– İlk karakterin ilk sütununu yazdık şimdi bunu 1 soldaki yere taşımamız lazım. Eğer karakter karakter gösterse idik çok çok basit olarak önce ilk harfi tamamen gösterecektik. Yani “A” harfini göstermek için 6 sütün geriye gelecek ve “A” harfini buradan itibaren tarayacaktık. Sonra 2. harfe geçtiğimiz zaman komple bir karakter sütun sayısı olan 6 karakter kadar (0..5 = 6 karakter) sola gelecek ve bu defa yine ilk karakterden (12 sütün sola doğru pozisyondan) itibaren verileri ilgili sütuna yazıp tarama yapacaktık. Bu durumda 2 karakter ekranda görünmüş olacaktı.

– Bu tarama işlemini basitçe yapmak için kaç tane sütün varsa o kadar her zaman baştan sona doğru yapabiliriz. 128 sütun varsa 1..128 arasındaki tüm sütunları sırasıyla tararız. İlgili karşılık gelen sütun bilgisi yüklendiği zaman ekranda görüntü belirir. Bu durumda biraz yavaşlama olacaktır ve ayrıca da istenilen sütuna doğrudan ulaşmak suretiyle, kaydırma dışı normal ekran gibi kullanım imkanı olmayacaktır. Bunu önlemek için biraz hesaplama yaparak hangi sütundayız bunu bileceğiz ve sadece ve sadece ilgili olan o sütunu taramak için seçeceğiz. Sonuçta ne oluyor: sadece bizi ilgilendiren sütunu seçmekle hızdan kazanmış oluyoruz. Ayrıca kaydırma dışında ekranı normal bir display gibi kullanıp istediğimiz konumuna istediğimiz karekteri yazabiliriz. Bunu sağlamak için de elektronik kısmını bu özelliğe uygun seçmek lazım. Benim yaptığım devre bu özelliği sağlıyor.

– Bazı kişiler tarama işlemini sabit bir osilatör çıkışı ile yapıyorlar veya program da bir bacağı osilatör gibi kullanıp, her bir palsde tarama yaptırıyorlar. Bunlar da çalışır ve iş görür ama devreniz ve programlarınız başka projeler için veya elinizdeki projeyi başka talepler doğrultusunda geliştirmeyi engeller. Normal bir ekran olarak kullanım imkanınız da olmaz. Sadece kaydırma yapabilirsiniz. Sabit yazıları yazmanız çok zorlaşır. Bu tamamen sizin talebinize kalmış birşey.

– Bu şekilde ilk sütuna kadar kaydırarak geldiniz. Hangi sütunda olduğumuzu daha önceden takip ettiğimiz bir değişken ile biliyoruz. İlk sütun olduğu için kayma işlemi esasen burada başlayacak. Yani yazının baş bölümü görünmez olacak. Burası da tamamen sizin programlama stilinize kalmış. Hangi mantığı kullanacağınız sorun değil. İster her karakteri yine tarayın ama ekranda (-) konuma düştüğünüz için göstermeyin, isterseniz de doğrudan hangi karakterde olduğunuzu da takip edin ve bu defa ekrana yazdırmaya oradan başlayın. Bu durumda biz ilk defa karakteri görünmez yapacağımız için bunun “1” olduğunu tanımladığımız bir değişken ile bilebiliriz. Sonra yazı içerisinde sırasıyla karakterleri okurken bu defa 1. karakter değil de 2. karakterden okumaya başlıyoruz.

– Sonra yine sırasıyla karakterleri ve karakterlerin ilgili baytlarını sırasıyla okumaya devam ediyoruz ve ekrana tarama usulü ile yazdırıyoruz.

– Ekranın boyu yeterince uzun değilse yazacağımız yazının tamamını gösterene kadar baştan birçok karakter görünmez olurken sondan hep yeni karakter gelecek. Son karakteri de yazdıktan sonra ekranda artık yeniden ilk karakterden itibaren bir çevrimi başlatmak durumundayız. Bunun için de birçok mantık geliştirmek mümkün. Ya kaçıncı karakterde olduğumuzu zaten bildiğimiz değişknei kullanarak sok karakterden sonra tekrar 1. karakterin ve daha sonra sırasıyla diğerlerinin de aynı şekilde gösterilmesini sağlarız ya da yeni bir dizi tanımlayıp her karakter kaydırdığımızda ekranın alabildiği kadar karakteri bu yeni ekrana sığan değişken diziye aktarırız. Sonuçta tarama yaparken sadece bu yeni diziyi ekrana basarız. Sonra kayma işleminde tekrar baştan kırpar sona bir sonraki karakteri ekler ve döngüyü sağlarız. Bunlar tamamen programlama yeteneğine ve zevkine bağlı.

– Burada dikkat edilmesi gereken bir şeyi hatırlatmak istiyorum. Eğer ekrandaki karakterlerle ekranın sütun sayısı tam bölünebilir değilse bu durumda kaydırma anında ekranın soldan 1. sütununa geldiğinizde ilk karakteri tam olarak değilde yarım olarak görürsünüz veya kaydırma işlemi saçmalamaya başlar. Bunu önlemek için baştan itibaren her karakter için 6 sütun hesaplayarak ekranın en son hangi noktasında tam bir karakter gösterilebildiğini bulup ona göre programı yazmanız.

– Sütun sütun kaydırmak ise biraz daha karmaşık. Bu durumda da hangi sütunda olduğumuzu bilmemiz lazım. Bunun için de ekstra bir değişken daha tanımlamak ve ç içe döngü yapmak lazım. Artık bu kısmı da yukarıdaki sisteme uygun olarak geliştirebilirsiniz.

Dosyalar, 128×8 MATRIX Display ve Kayan Yazı.pdf , PIC16F88 Kayan Yazı.DSN, PIC16F88 Kayan Yazı.hex, 5x7_matris_karakter_kodlayici.exe, KAYAN YAZI DEVRELERİNİN TEMEL MANTIĞI.pdf, PIC16F88 Kayan Yazı_Karakter_Source.c, PIC16F88 Kayan Yazı_Source.c PIC16F88 128X8 PC Kontrol Kayan Yazı CCS C ile

Dosya indirme LINK listesi (HTML formatında) link-3751.zip şifre-pass: 320volt.com

  • Erhan

    Elinize sağlık ne kadar hoş olmuş ;)

  • walter

    porque no puedo abrir el circuito con el proteus????no lo puedo abrir me da un error el proteus?:(

  • ismael

    code hex (file not found), proteus (schema not exist)

  • selim dumlu

    Selam
    Hocam RS232 yerine klavyenin 2. data ucundan direk karekter girebilirmiyiz?
    Her hangi bir sorun çıkarmı? Yoksa klavyenin Clock sinyalini de bir şekilde girmek zorundamıyız?Teşekkürler.

  • Narkosiss

    Elinize sağlık cok güzel anlatmışsınız.

  • Narkosiss

    Proğramın sonunda verilem”#include “bu dizeyi proğramda nasıl kullanacağz yeniden Compile edeyim dedim proğram yokarıda ki verilen satırda hata veriyor .

  • eproment

    Kardeş Eline sağlık güzel açıklamışsın fakat bu devreyi yaptıktan sonra simulasyon güzel çalışıyor ama gerçekte led ler çok düşük yanıyor transistor yada başka ne varsa kullandım sürüm ama ışık şiddeti ne yazıkki artmıyor……

  • mehmet bağcı–AKSEKİ

    10 numara olmuş hocam eline koluna sağlıkta hangi programda yazılmış hala çözemedim

  • okan

    bu yazılım diğer animasyonlara elverişli değil gibi geldi.Mesela harflerin sırayla soldan fırlatılıp sağda birikmesi animasyonu.Sizce bunu nasıl yaparız?Bu tarama işlemi işlemciyi meşkul ettiği için bu tür animasyonlar nasıl yapılır?

  • yakup

    Program İsisde çalışıyor fakat uygulamada çalışmıyor.Display ler gerçekten ortak katot mu? C kod derleme hatası vermiyor ama simule edilemiyor

  • umut

    eline koluna sağlık hocam güzel bir anlatım olmuş..