Segmentte Titreme

Başlatan Mr.Java, 16 Temmuz 2013, 14:12:36

Mr.Java

Arkadaşlar merhaba.Sorunum segmentlerle ilgili. 74LS138 ile display sürüyorum.Fakat displaylarda görüntü bozukluğu oluyor.Daha önce gelmişti delay ile çözüyorduk fakat bu defa değişik gibi.DelayUs denedim yine olmadı.Kodları veriyorum sizce nerede hata.4mhz crystal hızım bu arada;

void sayi_goster(char f)
{
    U5A = 0;
    U5B = 0;
    U5C = 0;
    PORTD = LED[f / 1000];
    DelayMs(5);
    /////////////////////////////////////////
    U5A = 1;
    U5B = 0;
    U5C = 0;
    PORTD = LED[(f % 1000) / 100];
    DelayMs(5);
    //////////////////////////////////////////
    U5A = 0;
    U5B = 1;
    U5C = 0;
    PORTD = LED[(f % 100) / 10];
    DelayMs(5);
    //////////////////////////////////////////
    U5A = 1;
    U5B = 1;
    U5C = 0;
    PORTD = LED[f % 10];
    DelayMs(5);
    //////////////////////////////////////////
}

Kabil ATICI

delay'dan sonra led ekranı söndür, kapat (yeni adreslemeden önce). Çünkü yeni adresleme esnasında hala sürülmeye devam ediyor...
ambar7

Mr.Java

Hocam yaptım titreme yine devam ediyor.

Kabil ATICI

#3
ayırabileceğin bir tane daha bacağın varsa 74138 devre dışı bırak
şu hali ile zaten 3 tane bacağı 74138 adreseme için kullanıyorsun.

ek: Yoksa 74138'in çip enable ucunu kullanmanı önerebilirim.
ambar7

Mr.Java

Hocam kartta entegreli.G2A ve G2B'yi toprakladım.Bu şekilde yapmak zorundayım.Bunu fonksyon haline getirmem gerekiyor fakat kuramadım algoritmasını.

Kabil ATICI

    U5A = 0;
    U5B = 0;
    U5C = 0;
    PORTD = LED[f / 1000];
    DelayMs(5);
PORTD =0x00

şeklinde olmadığımı söylüyorsun yani..
Ozaman
   U5A = 0;
    U5B = 0;
    U5C = 0;
    PORTD = 01001101 ;>>>bu kısımdan emin değilim
    DelayMs(5);
PORTD =0x00

tümüne sabit aynı şeyi yazdırmayı dene..  eğer birbirine karışmıyorsa zamanlama veya adresleme sorunu vardır. Yine karışıyorsa 74138'i değiştir.
İşi biliyorsundur ama yinede sorayım74138'in besleme bacakları arasında 100nF var mı?
ambar7

Mr.Java

Hocam sorun çok ilginç gerçekten.Şimdi displayi main altında sonsuz döngüye soktuğumda ekran tertemiz fakat fonksyon haline getirip main altında çağırdığımda titreme oluyor.Şimdi basit bir örnekle izzah edeyim..

//üst kısım segment tanımlamar v.s.
void main(void) de sonsuz döngüye giriyorum..
while(1)
  	{ 		
		if(++a>250)
		{
			a=0;	
			if(++c>200)
			{
				c=0;
				if(++d>9999) d=0;
			}
			PORTD=0;            //LED Kapat
			if(++b>3) b=0; 	    		
			PORTB=b;            
			switch(b)
			{
				case 0:				  
					PORTD=LED[d/1000];  	    									
				break;
				case 1:				  
					PORTD=LED[(d%1000)/100];  	   				
				break;
				case 2:				  
					PORTD=LED[(d%100)/10];  	   				
				break;
				case 3:				  
					PORTD=LED[d%10];  	    						
				break;			    
				default:
				break;
			}		
		}  			      	
  	}
}

Dediğiniz gibi led silmeyi başta tanımladım ve 0000-9999 arası sorun çıkmadı.Aynı işlemi fonksyon haline getirdiğimde ise sıkıntı oluyor.Gerçekten şuan kitlendim bulamıyorum sorunu.

AsHeS

hitech c example delay fonksiyonu istediğinizi yapmıyor timer kurarak deneme imkanınız varsa öyle yapın burada yapılanlara ek olarak

Kabil ATICI

fonksiyon olarak çağırma sıklığınız nasıl.?Eğer uzun işlemler içeren bir programda ise işlemler arasında ekran tazeleme çağrıldığında titreme olabiliyor. O durumda timer kullanımı gerekiyor. Yapılan işlem ne olursa olsun belirli aralıklarla timer ile ekran yenileniyor.

Yaptığın programı tam olarak bilemiyorum ama bu da bir çözüm olabilir. Yani normal program akışından bağımsız çalışması... Tek sıkıntısı bazı özel işlemler kesmeye gelmez. O zaman kapatılması gerekebilir.
ambar7

Mr.Java

Yok hocam kütüphane şekline getirip istediğim zaman kullanmak istedim fakat olmadı.Uğraşıyorum.Tavsiyeler için teşekkürler.Sonucu paylaşacağım burada.

hasankara

#10
ambar ın dediği gibi her adımda 5milisaniye bekletiyorsun ama son aşamadan sonra fonksiyondan çıktığında başka işlemlere de giriyorsa, atıyorum 5 milisaniyede başka işlemlerde vakit harcamış olsan son aşamada toplamda 10 milisaniye vakit harcatmış olursun. her aşamada eşit süre harcatmadığından dolayı ekranda titreme olması kaçınılmaz olur. timer ile aradaki geciktirme olayını yapabilirsen bu fonksiyonun dışında başka işlemler yapsanda ortalama hep eşit sürelerde ekranı sürmüş olursun. diğer işlerdede 3-5 milisaniyelik delay komutu kullanıyorsan titreşimin etkiside artar. bu yüzden ekrana yazdırma işini timer in kesmesi ile kontrol edersen daha stabil daha titreşimsiz hale getirebilirsin.

mesaj birleştirme:: 16 Temmuz 2013, 16:10:27


void sayi_goster(char f)
{static unsigned char buff,index;

switch(index){
case 0:
   buff=f;
    U5A = 0;
    U5B = 0;
    U5C = 0;
    PORTD = LED[buff / 1000];
    break;
    /////////////////////////////////////////
case 1:
    U5A = 1;
    U5B = 0;
    U5C = 0;
    PORTD = LED[(buff % 1000) / 100];
    break;
    //////////////////////////////////////////
case 2:
    U5A = 0;
    U5B = 1;
    U5C = 0;
    PORTD = LED[(buff % 100) / 10];
    break;
    //////////////////////////////////////////
case 3:
    U5A = 1;
    U5B = 1;
    U5C = 0;
    PORTD = LED[buff % 10];
    break;
    //////////////////////////////////////////
}

if(index<3)index++; else index=0;

// TMR0=175; // bu komutu aktif edersen süreyi dahada kısaltırsın
}


sen anadöngüde bu fonksiyonla hiç ilgilenmeyeceksin ve anadöngüde sadece segmente göndermek istediğin veriyi, anadöngüde tanımlayacağın SEGBUF gibi bir değişkene yazdığın zaman kendi kendine interrupt olduğunda segmente gönderecek.

tabi diğer bir hususta "interrupt(){}" fonksiyonu içerisinde TMR0 kesmesini kontrol ettiğin  yerde sana yazdığım fonksiyonu çağırman yeterli olacak.
"if(T0IF){T0IF=0; sayi_goster(SEGBUF);}" gibi...

hatırlatma: TMR0 modülünü çalıştırmak gerekir.

Mr.Java

Arkadaşlar kodu yazdık fakat switch nedense girmiyor fonksyona sizce nedir sorun ?
#include <config.h>
#include <pic.h>

#define U5A RB0
#define U5B RB1
#define U5C RB2

volatile unsigned int SEGf = 1234;

const unsigned char LED[10] = {
    0B00111111, //"0"
    0B00000110, //"1"
    0B01011011, //"2"
    0B01001111, //"3"
    0B01100110, //"4"
    0B01101101, //"5"
    0B01111101, //"6"
    0B00000111, //"7"
    0B01111111, //"8"
    0B01101111, //"9"
};
//Timer0
//Prescaler 1:256; TMR0 Preload = 60; Actual Interrupt Time : 49.92 ms

//Place/Copy this part in declaration section

void sayi_goster(char f)
{
    static unsigned char index;
    if (++index > 3)index = 0;
    switch (index)
    {
    case 0:
        U5A = 0;
        U5B = 0;
        U5C = 0;
        PORTD = LED[f / 1000];
        break;
        /////////////////////////////////////////
    case 1:
        U5A = 1;
        U5B = 0;
        U5C = 0;
        PORTD = LED[(f % 1000) / 100];
        break;
        //////////////////////////////////////////
    case 2:
        U5A = 0;
        U5B = 1;
        U5C = 0;
        PORTD = LED[(f % 100) / 10];
        break;
        //////////////////////////////////////////
    case 3:
        U5A = 1;
        U5B = 1;
        U5C = 0;
        PORTD = LED[f % 10];
        break;
        //////////////////////////////////////////
    }
    TMR0 = 60; // bu komutu aktif edersen süreyi dahada k?salt?rs?n
}

void InitTimer0()
{
    OPTION = 0x87;
    TMR0 = 60;
    INTCON = 0xB0;
}

static void interrupt kesme(void)
{
    if (TMR0IF)
    {
        TMR0IF = 0;
        TMR0 = 60;
        sayi_goster(SEGf);
    }
}

void main(void)
{

    TRISD = 0x00;
    PORTD = 0x00;
    InitTimer0();
    for (;;);
}

AsHeS

Kesme içinde fonksiyon çağırmaktansa kendine bir değişken ve onu yönet case içinde.Mesela sayı tanımladın global olarak uint8_t i=0; diyelim;
kesme içinde şöyle yapabilirsin.
i++;
switch içinde (i%10) yaparsın. PIC  değil ama fikir olsun diye C51 de yazdığım kodları vereyim inceleyin isterseniz.
Bunlar kesme içinde ki kodlarım.
{
    TR0 = 0; //Timer 0 dursun
    TH0 = 0xD8;//16 bitlik timer en düşük bit
    TL0 = 0xEF;
    timer_isr++;
    sec_5ms_flag = 1;//main e 5 ms geçtiğini bildir.
    if (timer_isr > 200)
    {
        sec_1_flag = 1;
        timer_isr = 0;
    }
    TF0 = 0; //Kesme bayragi temizlenir
    TR0 = 1; //Timer 0 isine devam etsin
}

Mr.Java

Yok hocam sorun çok değişik bende.Timer kuruyorum veriyi gönderirken timer kesmesine takılıyor fonksyonum ve ekranda abuk subuk değerler görüyorum.timer kullanmıyorum displayler silik çıkıyor.2 saat uğraştım tek tek debug yaptım çözemedim bir türlü.

Mr.Java

#14
@AsHeS35
Merhaba hocam dediğiniz gibi yaptım olmadı.Sorunum ise ekrana sabit bir değer yazdırdığımda fonksyon sorunsuz çalışıyor.Lakin ne zaman ki SGBf değişkenini yazdırmaya kaksam işlemci sapıtıp duruyor.Fonksyonu timer içerisine gömdüm olmadı,timer0 içerisinde değişkeni koydum yine olmadı.Nerede hata yapıyorum , neden işlemci sapıtıyor böyle anlamadım gitti.Buyrun en son kod;

#include <config.h>
#include <pic.h>

#define U5A RB0
#define U5B RB1
#define U5C RB2

unsigned int SEGf = 1234;
unsigned int index=0;

const unsigned char LED[10] = {
    0B00111111, //"0"
    0B00000110, //"1"
    0B01011011, //"2"
    0B01001111, //"3"
    0B01100110, //"4"
    0B01101101, //"5"
    0B01111101, //"6"
    0B00000111, //"7"
    0B01111111, //"8"
    0B01101111, //"9"
};

void sayi_goster(unsigned int f)
{
    unsigned char a, b;
    PORTD = 0x00;
    switch (index % 10)
    {
    case 0:
        U5A = 0;
        U5B = 0;
        U5C = 0;
        PORTD = LED[f / 1000];
        break;
        /////////////////////////////////////////
    case 1:
        U5A = 1;
        U5B = 0;
        U5C = 0;
        PORTD = LED[(f % 1000) / 100];
        break;
        //////////////////////////////////////////
    case 2:
        U5A = 0;
        U5B = 1;
        U5C = 0;
        PORTD = LED[(f % 100) / 10];
        break;
        //////////////////////////////////////////
    case 3:
        U5A = 1;
        U5B = 1;
        U5C = 0;
        PORTD = LED[f % 10];
        break;
        //////////////////////////////////////////
    }
}

void InitTimer0()
{
    T0CS = 0;
    T0SE = 0;
    PSA = 0;
    PS2 = 0;
    PS1 = 1;
    PS0 = 1;
    TMR0 = 252;
    // Interrupt Registers
    INTCON = 0; // kesme kontrol registerlerini temizle
    TMR0IE = 1;
    TMR0IF = 0;
    GIE = 1;
}

static void interrupt kesme(void)
{
    if (TMR0IF)
    {
        TMR0IF = 0;
        TMR0 = 252;
        index++;
    }
}

void main(void)
{
    TRISB = 0xF8;
    PORTB = 0x00;
    TRISD = 0x00;
    PORTD = 0x00;
    InitTimer0();
    sayi_goster(SEGf);
    for (;;);
}


mesaj birleştirme:: 18 Temmuz 2013, 11:56:07

Tamam arkadaşlar konu çözüldü.Switch case içerisinde kontrolü farklı oldu sadece.Teşekkürler..