Tek PIC'de İki Farklı Sayıcı Sorunu

Başlatan rugan035, 24 Mart 2015, 22:36:43

rugan035

Arkadaşlar merhaba;

CCS C'de henüz yeni sayılırım. Bir problemle karşılaştım. Ben tek işlemcide 2 farklı sayıcı devresi kurmak istiyorum. Birinci sayıcı aşağı yukarı buton ile 0-999 arası diğeri ise yukarı buton ile 0-9 sayıcı. 0-999 sayıcı da her şey normal fakat 0-9 sayıcı arttırma butonuna basınca sapıtıyor. Butona basınca 0-9 sayıcı saymıyor ve 0-999 sayıcının ekranını sapıttırıyor. Ne kadar uğraşsam da yapamadım. Kod ve şema ektedir. Şimdiden teşekürler.

#include <16f877a.h>


#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD

#use delay(clock=4000000)

#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
#use fast_io(e)

#define arttir pin_a1
#define azalt pin_a0
#define reset pin_a2
#define setA pin_e0

int16 birler=0,onlar=0,yuzler=0,kalan=0,sayi=0;

const int digit[10]={0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09};

void main()
{
	setup_psp(PSP_DISABLED);          //PSP birimi devre dışı
	setup_timer_1(T1_DISABLED);       //T1 birimi devre dışı
	setup_timer_2(T2_DISABLED,0,1);   //T2 birimi 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_a(0xFF);
	set_tris_b(0x00);
	set_tris_c(0x00);
	set_tris_d(0xFF);
	set_tris_e(0xFF);

	while(1)
	{	
		output_b(digit[birler]|(0b01000000));
		delay_ms(5);
		output_b(digit[onlar]|(0b00100000));
		delay_ms(5);
		output_b(digit[yuzler]|(0b00010000));
		delay_ms(5);

		if(input(arttir))
		{	
			sayi++;

			birler=sayi%10;
    		kalan=sayi/10;
    		onlar=kalan%10;
    		yuzler=sayi/100;

		while(input(arttir))
			{
			output_b(digit[birler]|(0b01000000));
			delay_ms(10);
			output_b(digit[onlar]|(0b00100000));
			delay_ms(10);
			output_b(digit[yuzler]|(0b00010000));
			delay_ms(10);
			}
		}
		if(input(azalt)&&(sayi!=0))
		{	
			sayi--;

			birler=sayi%10;
    		kalan=sayi/10;
    		onlar=kalan%10;
   			yuzler=sayi/100;

		while(input(azalt))
			{
			output_b(digit[birler]|(0b01000000));
			delay_ms(10);
			output_b(digit[onlar]|(0b00100000));
			delay_ms(10);
			output_b(digit[yuzler]|(0b00010000));
			delay_ms(10);
			}
		}
		if(sayi==1000)
			sayi=0;
	
		if(input(reset))
		{	
			birler=0,onlar=0,sayi=0,yuzler=0;

		while(input(reset))
			{
			output_b(digit[birler]|(0b01000000));
			delay_ms(10);
			output_b(digit[onlar]|(0b00100000));
			delay_ms(10);
			output_b(digit[yuzler]|(0b00010000));
			delay_ms(10);
			}
		}
		int i=0;
		if (input(SetA))
		 {
 			delay_ms(15); 
			output_c(i); 
 			i=i+1; 
 			while(input(SetA)); 
 			if (i==10)
 			{
 				i=0;
 			}
 		}

}
}



RaMu

Kodu iyice incelersen
zaten cevap içinde var.

while(input(SetA));


Kısmını
        while(input(SetA))
            {
            output_b(digit[birler]|(0b01000000));
            delay_ms(10);
            output_b(digit[onlar]|(0b00100000));
            delay_ms(10);
            output_b(digit[yuzler]|(0b00010000));
            delay_ms(10);
            }


Şeklinde değiştirmen gerek.
Neden?
Yukarıdaki 3lü 7 segment
display tarama metodu ile kullanılıyor,
displayleri taramayı bıraktığın an
görüntü anlamsızlaşır bozulur.
7 segment display tarama mantığı şeklinde araştırıp
detaylı bilgiye ulaşabilirsin.

Kodda başka hata var mı bakmadım,
en göze çarpan hata buydu.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

pwm.c

int i=0;
        if (input(SetA))
         {
 			delay_ms(15); 
            output_c(i); 
 			i=i+1; 
 			while(input(SetA)); 
 			if (i==10)
 			{
 				i=0;
 			}
 		}


burası baştan sona mantık hatası dolu.
"i" diye bir değişken atamışın sonra içeriğini sıfırlamışın. butonu test ettikten sonra "i" nin içeriğini portc ye aktarmışın. buraya her geldiğinde "i" içinde "0" değeri olacaktır. sonrasında "i" değerini arttırmanın bir anlamı kalmıyor.
diğer sorunu RaMu söylemiş zaten. bune ek olarak display taramayı tek foknksiyon şeklinde yaparsan sürekli aynı kodları yazmana gerek kalmaz.
_/\/\/\_ -[ı- -ı>|- -|ı|ı|ı- -ı< -||- -l[]l-

rugan035

Teşekkür ederim ilginiz için. Ramu hocamın dediğini hallettim.
@pwm.c ben bu mantığı kendimce yazdım. O yüzden biraz amele işi gibi oldu farkındayım. Tabiki farklı kombinasyonlar vardır ama ben tam olarak bilmiyorum.
Evet son kısımda söylediğin hatayı algıladım. Tekrar üzerinde duracağım.Teşekkür ederim.

rugan035

Arkadaşlar dediğiniz noktlara dikkat ederek sorunlu kısımları hallettim. Sayıcılar doğru çalışıyor fakat. 0-9 sayıcı butonuna basınca 0-999 sayıcının 10lar hanesi sönük kalıyor. Nerde hata yaptığımı bulamıyorum malesef.

#include <16f877a.h>


#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD

#use delay(clock=4000000)

#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
#use fast_io(e)

#define arttir pin_a1
#define azalt pin_a0
#define reset pin_a2
#define setA pin_e0

int16 birler=0,onlar=0,yuzler=0,kalan=0,sayi=0,birler1=0;
int a=0;

const int digit[10]={0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09};




void main()
{
	setup_psp(PSP_DISABLED);          //PSP birimi devre dışı
	setup_timer_1(T1_DISABLED);       //T1 birimi devre dışı
	setup_timer_2(T2_DISABLED,0,1);   //T2 birimi 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_a(0xFF);
	set_tris_b(0x00);
	set_tris_c(0x00);
	set_tris_d(0xFF);
	set_tris_e(0xFF);

	while(1)
	{	
		output_b(digit[birler]|(0b01000000));
		delay_ms(5);
		output_b(digit[onlar]|(0b00100000));
		delay_ms(5);
		output_b(digit[yuzler]|(0b00010000));
		delay_ms(5);

		if(input(arttir))
		{	
			sayi++;

			birler=sayi%10;
    		kalan=sayi/10;
    		onlar=kalan%10;
    		yuzler=sayi/100;

		while(input(arttir))
			{
			output_b(digit[birler]|(0b01000000));
			delay_ms(10);
			output_b(digit[onlar]|(0b00100000));
			delay_ms(10);
			output_b(digit[yuzler]|(0b00010000));
			delay_ms(10);
			}
		}
		if(input(azalt)&&(sayi!=0))
		{	
			sayi--;

			birler=sayi%10;
    		kalan=sayi/10;
    		onlar=kalan%10;
   			yuzler=sayi/100;

		while(input(azalt))
			{
			output_b(digit[birler]|(0b01000000));
			delay_ms(10);
			output_b(digit[onlar]|(0b00100000));
			delay_ms(10);
			output_b(digit[yuzler]|(0b00010000));
			delay_ms(10);
			}
		}
		if(sayi==1000)
			sayi=0;
	
		if(input(reset))
		{	
			birler=0,onlar=0,sayi=0,yuzler=0,a=0;

		while(input(reset))
			{
			output_b(digit[birler]|(0b01000000));
			delay_ms(10);
			output_b(digit[onlar]|(0b00100000));
			delay_ms(10);
			output_b(digit[yuzler]|(0b00010000));
			delay_ms(10);
			}
		}
		output_c(a);

		if(input(SetA))
		{	
			a++;
			birler1=a%10;

		while(input(SetA))
			{
			output_c(digit[birler1]);
			delay_ms(10);
			}
		}
		

}
}

pwm.c

Kodlarını yeniden düzenledim. şunu dene bakalım:
#include <16f877a.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay(clock=4000000)
#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
#use fast_io(e)
#define arttir pin_a1
#define azalt pin_a0
#define reset pin_a2
#define setA pin_e0

int16 sayi=0;
int8 birler=0,onlar=0,yuzler=0,kalan=0;
int8 a=0;

const int digit[10]={0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09};


void ekran()
      {      
        output_b(digit[birler]|(0b01000000));
        delay_ms(5);
        output_b(digit[onlar]|(0b00100000));
        delay_ms(5);
        output_b(digit[yuzler]|(0b00010000));
        delay_ms(5); 
        
        output_c(a);
      }

void main()
{
    setup_psp(PSP_DISABLED);          //PSP birimi devre dışı
    setup_timer_1(T1_DISABLED);       //T1 birimi devre dışı
    setup_timer_2(T2_DISABLED,0,1);   //T2 birimi 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ışı
    setup_comparator(NC_NC_NC_NC);

    set_tris_a(0xFF);
    set_tris_b(0x00);
    set_tris_c(0x00);
    set_tris_d(0xFF);
    set_tris_e(0xFF);
    output_b(0);
    output_c(0);
    delay_ms(1000);
    
    while(TRUE)
    {   
        ekran();
        if(input(arttir))
        {   
            sayi++;

            birler=sayi%10;
          kalan=sayi/10;
          onlar=kalan%10;
          yuzler=sayi/100;

        while(input(arttir))
            { 
            ekran();
            }
            
        }
        if(input(azalt)&&(sayi!=0))
        {   
            sayi--;

            birler=sayi%10;
          kalan=sayi/10;
          onlar=kalan%10;
            yuzler=sayi/100;

        while(input(azalt))
            {
            ekran();
            }
        }
        if(sayi==1000)
            sayi=0;
    
        if(input(reset))
        {   
            birler=0,onlar=0,sayi=0,yuzler=0,a=0;

        while(input(reset))
            {
            ekran();
            }
        }

        if(input(SetA))
        {   
            if (++a==10){a=0;}

        while(input(SetA))
            {
            ekran();
            }
        }
        

}
}

bu arada, butonları PULL-UP mantığı ile yaparsan daha uygun olur. PULL-DOWN sıkıntı olabilir. birde, displey sürmek için 74LS48 kullanacaksan digit[] dizisine gerek yoktur. eğer displeyleri entegresiz direk süreceksen bu sayı dizisi ile karakter dönüşümü yapılır.
_/\/\/\_ -[ı- -ı>|- -|ı|ı|ı- -ı< -||- -l[]l-

rugan035

Alıntı yapılan: pwm.c - 26 Mart 2015, 05:05:21
bu arada, butonları PULL-UP mantığı ile yaparsan daha uygun olur. PULL-DOWN sıkıntı olabilir. birde, displey sürmek için 74LS48 kullanacaksan digit[] dizisine gerek yoktur. eğer displeyleri entegresiz direk süreceksen bu sayı dizisi ile karakter dönüşümü yapılır.

Program için çok teşekkür ederim. Bu tam profesyonelce yazılmış bir program. Çok teşekkürler tekrardan. butonlarda da pull-up kullanırım o zaman dediğiniz gibi.
Bu bilgiler benim için çok önemliydi. Çünkü programla kısmında çok çok baştayım henüz. Hatalarımı net görüyorum bu şekilde.