Picproje Elektronik Sitesi

DERLEYİCİLER => CCS C => Konuyu başlatan: isa_olcer - 14 Ağustos 2018, 00:09:15

Başlık: Led Display Veri Gelince Sönüyor
Gönderen: isa_olcer - 14 Ağustos 2018, 00:09:15
RS232 den alınan ASCII sayıyı led displayde göstermek için yaptığım devrede veri geldiğinde sayılar displayde gözüküyor taramada çalışıyor titreme sorunu da yok buraya kadar her şey normal. Fakat veri geldiği anda displayler anlık olarak sönüyor ve tekrar rakamları gösteriyor (sanırım rda kesmesinde tarama duruyor). Veri hızlı geldiği için (saniyede bir kez yenileniyor) display sürekli yanıp sönüyor. Kodlarda ne gibi bir düzeltme yapmam gerekiyor?

/******************************************************
      PIC16F877 ile RS232 Seri İletişim Uygulaması

*******************************************************/

#include <16f877A.h>     // Kullanılacak denetleyicinin başlık dosyası tanıtılıyor.

// Denetleyici konfigürasyon ayarları
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD

#use delay(clock=8000000) // Gecikme fonksiyonu için kullanılacak osilatör frekansı belirtiliyor.

#use fast_io(b)
#define display_1 pin_b1
#define display_2 pin_b2
#define display_3 pin_b3
#define display_4 pin_b4
#define display_5 pin_b5

#use rs232 (baud=9600, xmit=pin_C6, rcv=pin_C7, parity=N, stop=1) // RS232 protokolünün 9600 bit/sn baud hızında olacağını ve
                                                                  // TX,RX uçlarının hangi pinler olacağını tanımlıyor
 // parity bitinin olmadığını, stop bitinin 1 bit olacağı belirtiliyor

int  veri[8];  // rs232 den gelen veri
int  a,b,c,d,e; // haberleşme sayıları
const int digit[10]={0X40, 0X79, 0X24, 0X30, 0X19, 0X12, 0X02, 0X78, 0X00, 0X10,};


#int_rda
void serihaberlesme_kesmesi ()

{
   disable_interrupts(int_rda); // int_rda kesmesini pasif yap
  
   gets(veri); // String ifadeyi al ve "veri" adlı dizi değişkenine aktar.
  
   a=((veri[6])-48); // ascii türündeki sayılar decimale çevriliyor
   b=((veri[5])-48);
   c=((veri[4])-48);
   d=((veri[3])-48);
   e=((veri[2])-48);
  
   if(e==-16) // olmayan sayı yerine gönderilen 0x20 hex kodu "0" rakamına çevriliyor
   e=0;
  
   if(d==-16)
   d=0;
  
   if(c==-16)
   c=0;
  
   if(b==-16)
   b=0;
  
   if(a==-16)
   a=0;
  
  
}

/********* ANA PROGRAM FONKSİYONU********/

void main ( )
{
   setup_psp(PSP_DISABLED);        // PSP birimi devre dışı
   setup_timer_1(T1_DISABLED);     // T1 zamanlayıcısı devre dışı
   setup_timer_2(T2_DISABLED,0,1); // T2 zamanlayıcısı devre dışı
   setup_adc_ports(NO_ANALOGS);    // ANALOG giriş yok
   setup_adc(ADC_OFF);             // ADC birimi devre dışı
   setup_CCP1(CCP_OFF);            // CCP1 birimi devre dışı
   setup_CCP2(CCP_OFF);            // CCP2 birimi devre dışı

   set_tris_b(0x00);
   set_tris_d(0x00);
  
   output_low(display_1);
   output_low(display_2);
   output_low(display_3);
   output_low(display_4);
   output_low(display_5);
  
   a=0; //önceden kalan veriler sıfırlanıyor.
   b=0;
   c=0;
   d=0;
   e=0;

  
  
   while(TRUE) // Sonsuz döngü
   {
   clear_interrupt(int_rda);
   enable_interrupts(GLOBAL);  // Aktif edilen tüm kesmelere izin ver
   enable_interrupts(int_rda); // int_rda kesmesi aktif  
  
 
   output_high(display_5); //Display taranıp sayılar gönderiliyor. Sayının solunda sıfır olan dijitler söndürülüyor.
   output_d(digit[a]);
   delay_ms(1);
   output_low(display_5);
  
   if((e==0)&&(d==0)&&(c==0)&&(b==0))
   output_low(display_4);
   else
   output_high(display_4);
  
   output_d(digit[b]);
   delay_ms(1);
   output_low(display_4);
  
   if((e==0)&&(d==0)&&(c==0))
   output_low(display_3);
   else
   output_high(display_3);
  
   output_d(digit[c]);
   delay_ms(1);
   output_low(display_3);
  
   if((e==0)&&(d==0))
   output_low(display_2);
   else
   output_high(display_2);
  
   output_d(digit[d]);
   delay_ms(1);
   output_low(display_2);
  
   if(!(e==0))
   output_high(display_1);
   else
   output_low(display_1);

   output_d(digit[e]);
   delay_ms(1);
   output_low(display_1);
  
   }
  
}



(https://thumb.ibb.co/mg3Pd9/ledgostergesema.jpg) (https://image.ibb.co/gRRcy9/ledgostergesema.jpg)
Başlık: Ynt: Led Display Veri Gelince Sönüyor
Gönderen: ziyaretci - 04 Ekim 2018, 20:22:15
Rs232 iletişim hızını arttırabilirsiniz.

-19200
-57600
Başlık: Ynt: Led Display Veri Gelince Sönüyor
Gönderen: fide - 04 Ekim 2018, 20:47:14
Kesin çözüm istiyorsanız Max7219. Taramaya Kendiniz yaptığınız sürece veri alırken tarama kesilir. Bunun için spi üzerinden hızlı bir şekilde veriyi gönderir, uarttan almaya vakit bırakırsınız.
Başlık: Ynt: Led Display Veri Gelince Sönüyor
Gönderen: mehmet - 04 Ekim 2018, 21:04:15
Display taramasını da timer
kesmesi içine alabilirsiniz.
Başlık: Ynt: Led Display Veri Gelince Sönüyor
Gönderen: OptimusPrime - 04 Ekim 2018, 22:03:01
Similasyonda mi goruyorsun bu sonuclari?

Kisaca gordugum genel sorunlar
- semada led ekrani kollektor yuku olarak bagla
- yazilimsal gecikme kullanmaktan kacin timer kesmesi ile tara
- 16f877 nin uart tampon bellegi 2 kademe sen 5 byte aliyorsun gets ile!  :o
- main icerisinde surekli kesme temizleme
- Ekran tarama asiri hizli 200Hz!

her ne kadar gariplikler olsada 5ms lik tarama suresi olan ekranin uart dan gelen veriden bu kadar etkilenebilecegini sanmiyorum eger gets kesmede farkli fantaziler yapmiyorsa.



Başlık: Ynt: Led Display Veri Gelince Sönüyor
Gönderen: fide - 05 Ekim 2018, 01:45:11
Alıntı yapılan: mehmet - 04 Ekim 2018, 21:04:15Display taramasını da timer
kesmesi içine alabilirsiniz.
Pic bir int içindeyken ikinci interrupt içine gitmiyor. Bu yüzden seri port veri alma içindeyken timer çalışmayacaktır, timer içindeyken de seri port rda.
Başlık: Ynt: Led Display Veri Gelince Sönüyor
Gönderen: RaMu - 05 Ekim 2018, 07:11:18
Konu 2 ay öncenin cevaplar yeni yazılmış,
başka bakan olur diye yinede yazalım.

Alıntı yapılan: fide - 04 Ekim 2018, 20:47:14...
Taramaya Kendiniz yaptığınız sürece veri alırken tarama kesilir.
...
Bu tam olarak doğru değil.
Uart modülü 1 byte veri aldığında
yani 1 byte verinin tamamı uartdan alındığında kesme verir,
yani uart kesmesine girilince 1 byta veri hazır demektir,
gets() değilde get() kullanılır ve fazla işlem yapmadan
uart kesmesinden çıkılırsa taramada problem olmaz.
Kısaca uartta gelmiş olan 1 byte veriyi ufak bir işleme tabi tutup kesmeden çıkmak
4MHz ile çalışan bir işlemci ile dahi taş çatlasa 50~100 mikrosaniyede halledilebilir,
buda tarama işlemi için verilen beklemenin yanında devede kulak.

Yukarıdaki programda sıradaki byte verinin gelmesi
kesme içinde beklendiği için tarama yapılamıyor,
bu hiç sağlıklı değil, zaten kesme içine girer girmez uart kesmesini kapatmış,
yoksa kesme içinde sıradaki veriyi beklerken zaten
tekrar kesme gelmiş olacak ve işler karışacak,
girelen kesmenin içinde o kesmeyi kapatmak bayağı yanlış bir iş,
buna gerek kalmayacak şekilde program yazılmalı.

Zaten tarama işi timer kesmesi ile yapılacak orası açık net en iyi yol,
işlem yükü getirir tabiki,
tasarıma yani programa göre işleri zorlaştırabilir yani kullanılamayabilir ama
uarttan veri alıp taramayla göstermek çerez bir işlemdir.

Timer kesmesi ile tarama için özel bir önlem olarak
tarama pinlerinin (data ve enable) değiştirildiği pin Low High anlarının hemen öncesinde
Uart kesmesi pasif edilebilir,
bu ana denk gelen uart kesmesi o anda işlenmez,
pin low high işi bitince uart kesmesi aktifleştirilir,
eğer bir kesme durumu kesmenin pasif olduğu anda bile oluşmuşsa dahi
kesme aktif edilir edilmez işlemci direk uart kesmesine yönelir.
Aslında buna gerek yok,
önemli olan uart kesmesinin içini mümkün olduğunca hızlı işler hale getirmek ve kısa tutmak.
Başlık: Ynt: Led Display Veri Gelince Sönüyor
Gönderen: isa_olcer - 15 Haziran 2019, 18:10:56
Veriyi gönderen cihaz sadece 1200 baud destekliyor. Kesme içindeki işlemi de azalttım 20 Mhz kristal ile denedim. Sorun devam ediyor.
Başlık: Ynt: Led Display Veri Gelince Sönüyor
Gönderen: isa_olcer - 10 Aralık 2019, 00:13:13
USART destekleyen bir işlemci kullansam sorun çözülür mü?
Başlık: Ynt: Led Display Veri Gelince Sönüyor
Gönderen: RaMu - 10 Aralık 2019, 01:00:29
gets