10 buton il 10 sayaç geriye sayıyor, sanırım dizi kullanımımda sorun var, buyrun

Başlatan RaMu, 01 Temmuz 2014, 19:11:10

RaMu

Programı kabaca anlattım aşağıda;
problem şu sayaç 15 dk dan geriye doğru sayarken
genelde 14.30 bazen 14.40 bazende çok farklı değerlerde
tekrar hiç yapmaması gereken şekilde 15 dk ddan yani baştan geri saymaya başlıyor.

Ben kullandığım dizilerde bir sıkıntı olduğunu düşünüyorum,
başka yerdede olabilir ama problem
pek dizi kullanmadığım için
acaba doğrumu yapıyorum
fikir verebilecek var mı?



(Kısaca 15 dk dan geriye sayan 10 tane sayaç var,
1 ana kesme butonu ve ardından ilgili sayaç başlangıç butonlarından birine basılmasıyla
gerisayım başlıyor, ilgili sayaç butonuna basılırsa gerisayım süresi 2*16 lcd gösteriliyor)

Daha önceden yaptığım bir projeye
revizyon yapıyorum, eski programa göre epey farklı yazdım ama problemler var,
programı bu sefer şöyle yazdım;

Ana döngüde dizi taranıp 10 butondan birine basılmışmı bakılıyor,
butona basılmış vede önceden aktifleştirme (yani kesme butonuna) basılmışsa
basılan butonun sayacına değer yükleniyor ve çıkışı set ediliyor led yanıyor.

   
while(1)
{   
  
for(i=0;i<=9;i++)
{
   if( ~input(inp[i]) )
   {
      if(flag_money)
      {
      //output_high(outp[i]);
      flag[i]=1;
      //syc[i]=sure;
      temp_16=sure;
      flag_money=0;
      output_high(outp[i]);    //değişecek silinecek
      }
   
   lcd_gotoxy(1,2);
   //printf(lcd_putc,"SARZ%d     %02ld:%02ld "(i+1)(syc[i]/60)(syc[i]%60) );
   printf(lcd_putc,"SARZ%d     %02ld:%02ld "(i+1)(temp_16/60)(temp_16%60) );
   //while( ~input(inp[i]) );
   }
}
}   
}



Timer kesmesinde 1 periyod 512ms timer1 dahili osilatörle kesme üretiyor,
2 defa olunca 1 saniye kabul ediyorum,
kesme içerisinde daha önce butonu basılıp aktif edilen sayaçlar
for döngüsü ile tespit edilip, değeri herbir saniye 1 azaltılıyor,
değeri sıfır olursa çıkışı sıfır yapılıp pasifleştiriliyor.

#INT_TIMER1
void  TIMER1_isr(void) 
{
k++;                                    //her 0.5 s de i bir artar
output_toggle(pin_d2);

   if( k==2 )                            //1 saniye olursa
   {
   k=0;
      for(i=0;i<=9;i++)                           //bütün sayaçlar sırayla
      {
         if( flag[i])                              //flagları komtrol edilerek
         {
         syc[i]=( (syc[i]) -1);                        //sayaçlarını 1 er azalt
         if( (syc[i]) ==0)  output_low( outp[i] );     //0 olursa sarz sonlandır
         }
      }
    }
}



Çıkış aktifleştirme butonlarının çalışması için önce
bir defa harici kesme butonuna basılması gerekiyor oda burası

#INT_EXT
void  EXT_isr(void)
{
flag_money=1;        //flag_money kur
}


Kullandığım dizileri şöyle tanımladım;

const char  inp[]={buton_0,buton_1,buton_2,buton_3,buton_4,buton_5,buton_6,buton_7,buton_8,buton_9};
const char outp[]={tlf_0,tlf_1,tlf_2,tlf_3,tlf_4,tlf_5,tlf_6,tlf_7,tlf_8,tlf_9};

int16 syc[10];
int1 flag[10];

int1   flag_money=0;
int8   i=0,k=0;

const  int16  sure=900;
int16 temp_16=0;


Ayrıca bazı tanımlamalar yaptım;
#define    buton_0  pin_a4
#define    buton_1  pin_a5
#define    buton_2  pin_e0
#define    buton_3  pin_e1
#define    buton_4  pin_e2
#define    buton_5  pin_c0
#define    buton_6  pin_c1
#define    buton_7  pin_c2
#define    buton_8  pin_c3
#define    buton_9  pin_d0

#define    tlf_0     pin_b4
#define    tlf_1     pin_b3
#define    tlf_2     pin_b2
#define    tlf_3     pin_b1
#define    tlf_4     pin_d7
#define    tlf_5     pin_d6
#define    tlf_6     pin_d5
#define    tlf_7     pin_d4
#define    tlf_8     pin_c7
#define    tlf_9     pin_c6

//bu tanımlar yapılmazsa, programda aşağıdaki gibi kullanmak gerekiyor
//const unsigned char  inp[]={pin_a4,pin_a5,pin_e0,pin_e1,pin_e2,pin_c0,pin_c1,pin_c2,pin_c3,pin_d0};
//const unsigned char outp[]={pin_b4,pin_b3,pin_b2,pin_b1,pin_d7,pin_d6,pin_d5,pin_d4,pin_c7,pin_c6};




Devrenin çalışırken fotosu şöyle;



Programın tamamı şu şekilde;

#include <main_sarz_2.h>
#include <flex_lcd.c>
#include <tanimlar.h>
#priority ext, timer1         //RB0 harici kesmesi öncelikli
//#include <string.h>

const char  inp[]={buton_0,buton_1,buton_2,buton_3,buton_4,buton_5,buton_6,buton_7,buton_8,buton_9};
const char outp[]={tlf_0,tlf_1,tlf_2,tlf_3,tlf_4,tlf_5,tlf_6,tlf_7,tlf_8,tlf_9};
int16 syc[10];
int1 flag[10];
//unsigned int16 syc[]={syc_0,syc_1,syc2,syc_3,syc_4,syc_5,syc_6,syc_7,syc_8,syc_9};

int1   flag_money=0;
int8   i=0,k=0;
const  int16  sure=900;
int16 temp_16=0;

#INT_EXT
void  EXT_isr(void)
{
flag_money=1;        //flag_money kur
}


#INT_TIMER1
void  TIMER1_isr(void) 
{
k++;                                    //her 0.5 s de i bir artar
output_toggle(pin_d2);

   if( k==2 )                            //1 saniye olursa
   {
   k=0;
      for(i=0;i<=9;i++)                           //bütün sayaçlar sırayla
      {
         if( flag[i])                              //flagları komtrol edilerek
         {
         syc[i]=( (syc[i]) -1);                        //sayaçlarını 1 er azalt
         if( (syc[i]) ==0)  output_low( outp[i] );     //0 olursa sarz sonlandır
         }
      }
    }
}




void main()
{

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_CCP1(CCP_OFF);
   setup_CCP2(CCP_OFF);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
   setup_timer_2(T2_DISABLED,0,1);
   enable_interrupts(INT_EXT);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);

   // TODO: USER CODE!!
   lcd_init();   //LCD hazirlaniyor
   
printf(lcd_putc,"\f UCRETI GIRINIZ");
lcd_gotoxy(1,2);
printf(lcd_putc,"    SARZMATIK   ");

DELAY_MS(500);


   while(1)
{   
  
for(i=0;i<=9;i++)
{
   if( ~input(inp[i]) )
   {
      if(flag_money)
      {
      //output_high(outp[i]);
      flag[i]=1;
      //syc[i]=sure;
      temp_16=sure;
      flag_money=0;
      output_high(outp[i]);    //değişecek silinecek
      }
   
   lcd_gotoxy(1,2);
   //printf(lcd_putc,"SARZ%d     %02ld:%02ld "(i+1)(syc[i]/60)(syc[i]%60) );
   printf(lcd_putc,"SARZ%d     %02ld:%02ld "(i+1)(temp_16/60)(temp_16%60) );
   //while( ~input(inp[i]) );
   }
}
}   
}



Proteus 8.1 simulasyonu ve proje dosyaları linkte;
https://www.dropbox.com/s/mdfusmhfnfat4x1/prog_2.rar
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

RaMu

Hatamı konuyu buraya açtıktan saatler sonra buldum,
şimdi paylaşmak nasip oldu,
mesele şu;

Ana döngüde butona basılmışmı kontrolü yapıp
basılan butonun sayacını kuran kısım
ile
kesme rutininde butonuna önceden basılıp kurulmuş sayaçları
geri saydıran kısımda

her ikisindede i global değişkeni kullanılıyor,
ana döngüde i misal 3 iken
timer kesmesine girip i yi 0 dan 9 a saydırıp
gerekli sayaçları azaltma işlemini yapıyor,
fakat timerdan dönünce i değişkeni 9 olmuş oluyor
ve ana döngüde kaldığı yerden devam ederken
i geri 3 değerinde olmasını istiyoruz ama
artık i değişmiş eeee bu yüzden program sapıtıyor,
burada kesme içindeki döngü için ve
ana döngü için 2 farklı değişken tanımladım
bu sayede sorunu çözdüm.
Hatalı hali hatırlatma olarak şuydu;


ana döngüde butonlara basılmışmı kontrolü yapan kısım
while(1)
{   
  
for(i=0;i<=9;i++)
{
   if( ~input(inp[i]) )
   {
      if(flag_money)
      {
      //output_high(outp[i]);
      flag[i]=1;
      //syc[i]=sure;
      temp_16=sure;
      flag_money=0;
      output_high(outp[i]);    //değişecek silinecek
      }
   
   lcd_gotoxy(1,2);
   //printf(lcd_putc,"SARZ%d     %02ld:%02ld "(i+1)(syc[i]/60)(syc[i]%60) );
   printf(lcd_putc,"SARZ%d     %02ld:%02ld "(i+1)(temp_16/60)(temp_16%60) );
   //while( ~input(inp[i]) );
   }


ve kesmeye girince butonuna önceden basılıp kurulmuş sayaçları,
tespit edip geri saydıran kısım

#INT_TIMER1
void  TIMER1_isr(void) 
{
k++;                                    //her 0.5 s de i bir artar
output_toggle(pin_d2);

   if( k==2 )                            //1 saniye olursa
   {
   k=0;
      for(i=0;i<=9;i++)                           //bütün sayaçlar sırayla
      {
         if( flag[i])                              //flagları komtrol edilerek
         {
         syc[i]=( (syc[i]) -1);                        //sayaçlarını 1 er azalt
         if( (syc[i]) ==0)  output_low( outp[i] );     //0 olursa sarz sonlandır
         }
      }
    }
}
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

deNiZciLeR

merhaba bu devre konusunda yardımcı olurmusunuz buton olmadan yapılabilir mi

RaMu

Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

EGE

Buton yerine Jeton atıp şarj süresini aktif tutacaklar sanırım.

Alıntı yapılan: RaMu - 31 Mayıs 2018, 04:50:45Buton olmadan ne yapılabilir mi?
Bu ne devresi ki :)

deNiZciLeR

yada butona basıldığında zaten para veya jeton atılmış mi oluyor link ke ulasamadim bu devrenin şemasını ve kodunu yollarmisiniz

ibrahim96

Jeton kanalları dc 12v ilr çalışan para veya jeton girişi oldugunda 0v çıkış sinyali üretir bunu bir optokuplör ile yalıtarak kullanılabilir buton lar yerine butonların 0 veriyor jeton kanalında bunu veriyor bunları göz önüne alarak kod ve devreni revize eebilirsin yapmazsanız ibrahimk0@hotmail.com mailden ulaşın yardımcı olayım