Sayıcı

Başlatan CaFFeiNe, 31 Aralık 2005, 23:56:20

CaFFeiNe



arkadaşlar programını CCS ile yazdığım bobinajcılar için sipir sayıcı devre+şema+kodlarını gönderiyorum

devreyi mümkün olduğunca az malzeme ile yapmaya çalıştım, board üzerine kurup denedim fakat girişine encoder veya sensörler ile yapılmış devre bağlayıp denemedim (denemeyi iki adet buton bağlayıp yaptım)
devredeki speaker yerine voltajı verince kendiliğinden ses çıkaran buzzer bağlamalısınız
ISIS devresi simülasyon yapmıyor!! yaptırmak istedim ama gösterge taramalı olduğu için simülasyon birşeye benzemiyor.

umarım işinize yarar

küçük bir yeniyıl hediyesi misali :) (saatim 23:58 i gösteriyor)

////////////////////////////////////////////////////////////////////////////////
//                                                                            //
//  Proje Dosyası  : SAYICI.PJT                                               //
//  Proje Adı      : Bobinajcılar için sayıcı                                 //
//  Tarih          : 25.10.2005                                               //
//  Yazar          : CaFFeiNe                                                 //
//                                                                            //
//  Açıklamalar    : * YUKARI ve AŞAĞI butonları ile set değeri ayarlanır     //
//                   * 2 adet sensör ile ileri ve geri dönüşü algılar ve      //
//                     ileri geri sayma yapar                                 //
//                   * Sayılan değer ileri dönüşte set değeri ile aynı        //
//                     olduğunda buzzer öter ve sayılan değer sıfırlanır      //
//                   * Sayılan değer geri dönüşte sıfır olduğunda buzzer öter //
//                     bu özelliğin amacı fazla sarım yapıldığında fazla      //
//                     sarılan tellerin boşaltılması bitince sarımcıyı        //
//                     uyarmaktır                                             //
//                                                                            //
//  Pic Özellikleri                                                           //
//  ------------------------------------------------------------------------  //
//            Tipi : 16F628                                                   //
//         Frekans : 4MHz                                                     //
//   Osilatör Tipi : Dahili                                                   //
//        Watchdog : Kapalı                                                   //
//         RA6,RA7 : Giriş/Çıkış                                              //
//   PowerUp Timer : Açık                                                     //
//      Kod koruma : Açık                                                     //
//  BrownOut Reset : Kapalı                                                   //
//    Düşük voltaj : Kapalı                                                   //
//     programlama                                                            //
//       EPROM kod : Kapalı                                                   //
//          koruma                                                            //
//                                                                            //
//  Malzeme Listesi                                                           //
//  ------------------------------------------------------------------------  //
//              1Ad. 16F628                                                   //
//              3Ad. 7Segment LED ortak anot                                  //
//              2Ad. Hall sensör                                              //
//              1Ad. Mıknatıs                                                 //
//              2Ad. Buton                                                    //
//             10Ad. 1K                                                       //
//              1Ad. 100n                                                     //
//              1Ad. 7805                                                     //
//              1Ad. 12DC Adaptör                                             //
//              1Ad. Buzzer                                                   //
//              1Ad. BC337                                                    //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////

#case
#include <16F628.H>
#fuses   NOWDT, INTRC_IO, PUT, PROTECT, NOBROWNOUT, NOMCLR, NOLVP, NOCPD
#use     DELAY(CLOCK=4000000)
#use     FAST_IO(A)
#use     FAST_IO(B)
#build   (NOSLEEP)

#byte    PORTA  = 0x05
#byte    PORTB  = 0x06
#byte    TRISA  = 0x85
#byte    TRISB  = 0x86
#byte    OPTION = 0x81
#byte    INTCON = 0x8b
#byte    CMCON  = 0x1f
#bit     INTEDG = OPTION.6
#bit     GIE    = INTCON.7
#bit     COM_0  = PORTA.0
#bit     COM_1  = PORTA.1
#bit     COM_2  = PORTA.2
#bit     SENSOR = PORTA.3
#bit     YBUTON = PORTA.4
#bit     BUZZER = PORTA.6
#bit     ABUTON = PORTA.7

#define  BOSLUK   10

int1 Set_Goster;
long Set_Sure;
int1 Flash;
char Flash_Sure;
int1 Hizli_Say;
long Hiz_Sayac;
char Buzz_Sure;
int1 Buzz_Caldi = 1;
char Asagi      = 0;
char Yukari     = 0;
char Rakam      = 1;
char Rakam1     = 0;
char Rakam10    = 0;
char Rakam100   = 0;
char SetRak1    = 0;
char SetRak10   = 0;
char SetRak100  = 0;
// 7 segment desenleri    gfedcba
char const Desen[11] = {0b10000000,  // 0 rakamı
                        0b11110010,  // 1 rakamı
                        0b01001000,  // 2 rakamı
                        0b01100000,  // 3 rakamı
                        0b00110010,  // 4 rakamı
                        0b00100100,  // 5 rakamı
                        0b00000100,  // 6 rakamı
                        0b11110000,  // 7 rakamı
                        0b00000000,  // 8 rakamı
                        0b00100000,  // 9 rakamı
                        0b11111110}; // Boşluk


// Ekran Tarama Altprogramı ////////////////////////////////////////////////////
// * Her çağırıldığında bir basamağı gösterir
// * Gerekli olmayan sıfırların gösterilmesini engeller
void Ekran()
{
   switch(Rakam)
   {
//--- 1'ler basamağı gösteriliyor ----------------------------------------------
      case 1 : if(Set_Goster)
               {
                  if(!Flash) PORTB = Desen[BOSLUK];
                  else PORTB = Desen[SetRak1];
               }
               else PORTB = Desen[Rakam1];
               COM_1 = 0; // 2. basamağı kapat
               COM_2 = 0; // 3. basamağı kapat
               COM_0 = 1; // 1. basamağı aç
               break;
//--- 10'lar basamağı gösteriliyor ---------------------------------------------
      case 2 : if(Set_Goster)
               {
                  if(!Flash) PORTB = Desen[BOSLUK];
                  else
                  {
                     if(SetRak10 == 0 && SetRak100 == 0) PORTB = Desen[BOSLUK];
                     else PORTB = Desen[SetRak10];
                  }
               }
               else
               {
                  if(Rakam10 == 0 && Rakam100 == 0) PORTB = Desen[BOSLUK];
                  else PORTB = Desen[Rakam10];
               }
               COM_0 = 0; // 1. basamağı kapat
               COM_2 = 0; // 3. basamağı kapat
               COM_1 = 1; // 2. basamağı aç
               break;
//--- 100'ler basamağı gösteriliyor --------------------------------------------
      case 3 : if(Set_Goster)
               {
                  if(!Flash) PORTB = Desen[BOSLUK];
                  else
                  {
                     if (SetRak100 == 0) PORTB = Desen[BOSLUK];
                     else PORTB = Desen[SetRak100];
                  }
               }
               else
               {
                  if(Rakam100 == 0) PORTB = Desen[BOSLUK];
                  else PORTB = Desen[Rakam100];
               }
               COM_0 = 0; // 1. basamağı kapat
               COM_1 = 0; // 2. basamağı kapat
               COM_2 = 1; // 3. basamağı aç
               break;
   }
   if(++Rakam > 3) Rakam = 1;
}

// Yukarı Sayma Altprogramı ////////////////////////////////////////////////////
void Yukari_Say()
{
   if(++Rakam1 == 10)
   {
      Rakam1 = 0;
      if(++Rakam10 == 10)
      {
         Rakam10 = 0;
         if(++Rakam100 == 10) Rakam100 = 0;
      }
   }
// Set değeri sıfırdan farklı ise;
   if(SetRak1 != 0 || SetRak10 != 0 || SetRak100 != 0)
   {
//    Sayılan değer set değerine eşitse sıfırla ve buzzeri aç
      if(Rakam1 == SetRak1 && Rakam10 == SetRak10 && Rakam100 == SetRak100)
      {
         Rakam1 = 0;
         Rakam10 = 0;
         Rakam100 = 0;
         BUZZER = 1;
         Buzz_Sure = 0;
         Buzz_Caldi = 0;
      }
   }
}

// Aşağı Sayma Altprogramı /////////////////////////////////////////////////////
void Asagi_Say()
{
   if(Rakam1 != 0 || Rakam10 != 0 || Rakam100 != 0)
   {
      if(--Rakam1 == 255)
      {
         Rakam1 = 9;
         if(--Rakam10 == 255)
         {
            Rakam10 = 9;
            if(--Rakam100 == 255) Rakam100 = 9;
         }
      }
   }
// Sayılan değer sıfırsa buzzeri aç (fazla sarılmış geri sarılıyor)
   if(Rakam1 == 0 && Rakam10 == 0 && Rakam100 == 0)
   {
      if(!Buzz_Caldi)
      {
         BUZZER = 1;
         Buzz_Sure = 0;
         Buzz_Caldi = 1;
      }
   }
}

// Set Değeri Gösterme Ayar Altprogramı ////////////////////////////////////////
void Set_Deger_Goster()
{
   Set_Goster = 1;
   Set_Sure = 0;
   Flash = 1;
   Flash_Sure = 0;
}

// Set Değeri Arttırma Altprogramı /////////////////////////////////////////////
void Set_Arttir()
{
   Set_Deger_Goster();
   if(++SetRak1 == 10)
   {
      SetRak1 = 0;
      if(++SetRak10 == 10)
      {
         SetRak10 = 0;
         if(++SetRak100 == 10) SetRak100 = 0;
      }
   }
}

// Set Değeri Azaltma Altprogramı //////////////////////////////////////////////
void Set_Azalt()
{
   Set_Deger_Goster();
   if(--SetRak1 == 255)
   {
      SetRak1 = 9;
      if(--SetRak10 == 255)
      {
         SetRak10 = 9;
         if(--SetRak100 == 255) SetRak100 = 9;
      }
   }
}

// TMR0 Kesme Altprogramı //////////////////////////////////////////////////////
#int_rtcc
void Kesme_TMR0()
{
   Ekran();         // Ekran tazeleniyor
   if(Set_Goster)   // Set değeri gösterme izni verildi mi?
   {
      if(++Set_Sure >= 244 * 3) Set_Goster = 0; // 3sn ayar yapılmazsa çık
      if(++Hiz_Sayac >= 244 * 2) Hizli_Say = 1; // 2sn sonra hızlı moda geç
      if(++Flash_Sure >= 50)                    // ~2.5Hz flaş
      {
         Flash = !Flash;
         Flash_Sure = 0;
      }
   }
   if(BUZZER && ++Buzz_Sure >= 150) BUZZER = 0; // Buzzer çalıyorsa ~0.6sn
                                                // sonra kapat
}

// RB0 Kesme Altprogramı ///////////////////////////////////////////////////////
#int_ext
void Kesme_RB0()
{
   Set_Goster = 0;
   if(INTEDG)       // Yükselen kenarda;
   {
      if(SENSOR)    // sensör görüyorsa
      {
         Asagi++;   // geri dönüyor
         Yukari = 0;
      }
      else          // sensör görmüyorsa
      {
         Yukari++;  // ileri dönüyor
         Asagi = 0;
      }
      INTEDG = 0;   // Düşen kenarda kesmeye ayarlanıyor
   }
   else             // Düşen kenarda;
   {
      if(SENSOR)    // sensör görüyorsa
      {
         Yukari++;  // ileri dönüyor
         Asagi = 0;
      }
      else          // sensör görmüyorsa
      {
         Asagi++;   // geri dönüyor
         Yukari = 0;
      }
      INTEDG = 1;   // Yükselen kenarda kesmeye ayarlanıyor
   }
   if(Asagi >= 2)   // Geri dönüş çevrimi tamamlandıysa
   {
      Asagi = 0;
      Asagi_Say();  // Sayaç azaltılıyor
   }
   if(Yukari >= 2)  // İleri dönüş çevrimi tamamlandıysa
   {
      Yukari = 0;
      Yukari_Say(); // Sayaç arttırılıyor
   }
}

// Ana Program Bloğu ///////////////////////////////////////////////////////////
void main()
{
   PORTA  = 0;          // Portlar temizleniyor
   PORTB  = 0;
   TRISA  = 0b10111000; // Giriş/Çıkışlar ayarlanıyor
   TRISB  = 0b00000001;
   OPTION = 0b11000011; // Prescaler 1/16 -> TMR0
                        // RB0 Yükselen kenarda kesme
   INTCON = 0b10110000; // TMR0, RB0 kesmeleri açılıyor
   CMCON  = 0b00000111; // Komparatörler kapalı
   while(TRUE)
   {
      if(YBUTON)        // Yukarı butonuna basıldıysa;
      {
         delay_ms(5);
         if(YBUTON) Set_Arttir();
      }
      if(ABUTON)        // Aşağı butonuna basıldıysa;
      {
         delay_ms(5);
         if(ABUTON) Set_Azalt();
      }
      if(Hizli_Say) delay_ms(15);
      else delay_ms(150);
      if(!YBUTON && !ABUTON) // Yukarı ve Aşağı butonları basılı değilse;
      {
         Hizli_Say = 0; // Hızlı sayma modu kapatılıyor
         Hiz_Sayac = 0;
      }
   }
}

bzirapli

Değerli arkadaşım. Devre nasıl çalışıyor yani yukarı butonuna her basıştamı sayıyor yoksa otomatik olarakmi ilerliyor.

CaFFeiNe

yukarı/aşağı butonları ile set değeri ayarlanıyor, sayması için HALL1 ve HALL2 girişlerine resimdeki gibi arasında faz farkı bulunan sinyal girmen gerekli
encoderların A,B çıkışları gibi böylece ileri/geri dönen bir şeyin tur sayısını sayabilirsin
zaten devreyi bobinajcı bir arkadaş için yapmıştım ama vakit darlığından uygulamaya sokamadım daha

stlg

Sevgili  CaFFeiNe
Arkadasım devren bu şekilde duzgun calısmayabilir bildigim kadarıyla hall sensorler acık kollektor cıkıslı ve sen giriş uclarına pullup direncleri koymamıssın  acaba bildigimizi dusunerekmi koymadın bu konuyu bilmeyen arkadaslar bu şekilde deneyebilirler ve sorun yasayabilirler  umarım yanılmıyorumdur kolay gelsin

      ALLAHA EMANET OLUNUZ
ALLAHA EMANET OLUNUZ Hoştur bana senden gelen,  Ya gonca gül yahut diken,  Ya kaftandır yahut kefen,  Kereminde hoş lütfunda hoş.

CaFFeiNe

@stlg

zaten belirttiğim gibi bu devreyi board üzerine koyarak hall sensör girişlerini +5V a butonlar bağlayarak denedim yani yukarı/aşağı butonlarının bağlantısının aynısını hall girişlerinede uygulayarak denedim henüz fırsatım olmadığı için uygulamaya sokamadım.
devreyi sipir sayımında veya başka döner bir aksamı saydırmak isterseniz dediğim gibi hall (yada opto) sensörleri döner aksama çıkışlarında faz farkı olacak şekilde yerleştirmeniz gerekir.
ben denerken şöyle denedim mesela önce HALL1 butonuna basıyorum ardından butonu bırakmadan HALL2 butonuna basıyorum sonra HALL1 i ardından HALL2 yi bırakıyorum ve yukarı 1 adım sayıyor aynı işi ters sırada yaparsanız bu sefer 1 adım aşağı sayıyor yani incremental encoder ın A/B çıkışlarını butonlar ile simüle ediyorum tabiki devreye incremental encoder bağlarsanız bir devirde encoder kaç pals veriyorsa o kadar sayar :)

CaFFeiNe



HALL1 ve HALL2 girişleri için bunun gibi bir düzenek oluşturmanız gerekiyor
ileri dönüşte mıknatıs sırasıyla HALL1 ve HALL2 nin önünden geçecek geri dönüşte ise tersi olacak haliyle
fakat önemli olan HALL sensörleri öyle yerleştirmelisinizki HALL1 çıkış verdikten sonra çıkışı kesilmeden mıknatısın HALL2 nin önüne gelmesi ve HALL2 nin çıkış vermesi gerekli

tek turda tek pals veren basit bir incremental encoder yapacaksınız yani, tek fark encoderlar biraz tuzludur :) 2 adet hall sensör ise (mikro çatal fotoselde olur) oldukça ucuz