Değişken tipleri

Başlatan baran123, 27 Nisan 2014, 20:17:29

baran123

Merhaba bu aralar displaylerle çalışıyorum iyice bi çözeyim dedim şu 74hc595'i falan neyse displayde singned int temp olarak -9 ile +99 arası değer gösteriyordum fakat ondalık kısıma geldiğimde zorlandığım bir nokta var şimdi ben 4 lu dısplayde hem negatif hemde ondalık bir değer göstermek istiyorum bunu için ondalık değeri tamam hallettim ama -9.23 gibi bir değeri gösteremedim float olarak tanımladığım bir değişken - değer göstermiyormu çünkü sıfırın altına inince displaylerde saçma sapan şeyler oluşuyor anlatamadıysam 4 lu dısplayde -9.22 değerini nasıl gösteririm ? Şimdiden teşekkürler iyi çalışmalar.

Salih

abs() komutu ile mutlak değerini al. Daha sonra gösterme işlemini yap.


mehmet

*Sayının negatif olması tespit edilir.
*İki noktalı değer olduğu için 100 ile
çarpılır.
*Haneler ayrılır.
*Dördüncü displayda g segmenti yakılır.
*Üçüncü segmentin nokta segmenti
ilave edilerek çıkış verilir.
* İki ve birinci segment normal şekilde
yakılır...
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr

baran123

teşekkürler arkadaşlar mutlak değer alma yöntemiyle projemi tamamladım :)

rugan035

Alıntı yapılan: Baran Ekrem - 28 Nisan 2014, 01:49:05
teşekkürler arkadaşlar mutlak değer alma yöntemiyle projemi tamamladım :)

Bende bu ara displaylerle uğraşıyorum aynı şekilde benim problemim var. İnt olarak iki sayının ortalamasını aldım ve float olarak kaydetip ekranda göstermek istiyorum. 4 haneli displayde 1.254 gibi bir değeri nasıl gösterebilirm. Ben göstermeye çalıştığımda sadece tam kısmı gösterebiliyorum. Benim eksi değer gösterme gibi bir hedefim yok.

mehmet

Float değeri 1000 ile çarpıp 4 haneli int değeri
elde ediniz. Haneleri normal şekilde gösterirken
birinci display noktasını yakınız...
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr

baran123

#6
Bende bir ara aynı konuyla uğraştım ve şöyle bir proje çıkarmıştım ortaya



#include <16F877A.h>
#device adc=16         
#fuses XT,NOWDT,NOBROWNOUT,NOLVP,NOPUT,NOCPD,NOWRT,NOPROTECT,NODEBUG
#use delay(clock=4M)           
                                      
#include "ds18b20.c" 
#include <stdlib.h>
#include <math.h>             
                  
#define DS     pin_B0                 
#define SH_CP  pin_B1                              
#define ST_CP  pin_B2  
           
float temp,tam,ondalik;
const int digit[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7C,0x07,0x7F,0x6F};
                                 
void send(unsigned char data)
{                                  
   unsigned  char i;       
              
   for(i = 0x80; i > 0; i >>= 1)
   {                                
      if(i & data) output_high(DS);
      else output_low(DS);     
      output_high(SH_CP);           
      output_low(SH_CP);   
   }
   output_high(ST_CP);     
   output_low(ST_CP);                             
}              

void main(void)
{
   setup_psp(PSP_DISABLED);                  
   setup_spi(SPI_SS_DISABLED); 
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);   
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_adc_ports(NO_ANALOGS);  
   setup_adc(ADC_OFF); 
   setup_ccp1(CCP_OFF);     
   setup_ccp2(CCP_OFF);
   setup_vref(FALSE);            
   
   set_tris_b(0x08);       
   output_b(0x00); 
   
   temp = ds1820_read(); 
   if(temp == 85) temp = 0;
          
   for(;;)             
   {  
      temp = ds1820_read();
              
      ondalik = modf(temp,&tam);
      ondalik = ondalik * 100; 
       
      if((temp >= -50.99) && (temp <= 125.00))
      {
         if((temp >= 10.00) && (temp <= 99.99))
         { 
            output_low(pin_b4);output_high(pin_b5);output_low(pin_b6); 
            send(digit[(int)ondalik % 10]);     
            send(digit[(int)ondalik / 10]);
            send(digit[(int)tam % 10]);     
            send(digit[(int)tam / 10]);
         }                            
         
         else if((temp > 99.99) && (temp <= 125.00))
         {            
            output_low(pin_b4);output_low(pin_b5);output_high(pin_b6); 
            send(digit[(int)ondalik / 10]);
            send(digit[(int)tam % 10]);
            send(digit[(int)(tam / 10) % 10]);
            send(digit[(int)tam / 100]);
         }                               
                                        
         else if((temp >= 0.00) && (temp < 10.99))                    
         {                           
            output_high(pin_b4);output_low(pin_b5);output_low(pin_b6);
            send(0x63);
            send(digit[(int)ondalik % 10]);
            send(digit[(int)ondalik / 10]);
            send(digit[(int)tam % 10]);
         }
                                      
         else if((temp >= -50.99) && (temp < 0.00))        
         {                                                        
            output_low(pin_b4);output_low(pin_b5);output_high(pin_b6); 
            ondalik = abs(ondalik);
            tam = abs(tam);   
            send(digit[(int)ondalik / 10]);
            send(digit[(int)tam % 10]);
            send(digit[(int)tam / 10]); 
            send(0x40);            
         }                           
                   
         else                 
         {                        
            send(0x77);
            send(0x78);
            send(0x77);
            send(0x76);   
            output_low(pin_b4);output_low(pin_b5);output_low(pin_b6);  
         }                    
      }                    
                         
      else                 
      {                        
         send(0x77);
         send(0x78);
         send(0x77);
         send(0x76);   
         output_low(pin_b4);output_low(pin_b5);output_low(pin_b6);  
         
      } 
   }
}                     


mesaj birleştirme:: 07 Nisan 2015, 18:29:25

Bu arada daha küçük bir PIC kulanabiirsin ben öylesine 877A kullanmıştım.

rugan035

Alıntı yapılan: mehmet - 06 Nisan 2015, 11:19:10
Float değeri 1000 ile çarpıp 4 haneli int değeri
elde ediniz. Haneleri normal şekilde gösterirken
birinci display noktasını yakınız...

Anlattığınız gibi yapmaya çalıştım ama malesef display ekranında alakasız sayılar gösteriyor. Farklı kombinasyonlar denediğimde de sadece tam sayı kısmı gözüküyor.Bir türlü çözemedim delirme noktasında. Kullandığım kod aşağıda.

if(!input(orta))
       {   

			ort=(float)sayi/a;
              
                        ort=(int16)ort*1000;
		
			biro=(int16)ort%10; 		
			ono=(int16)(ort/10)%10;
			yuzo=(int16)(ort/100)%10;
			bino=(int16)(ort/1000)%10;

			while(!input(orta))
			{
		        output_d(digit[bino]|(0b01110000));
                        delay_ms(5);
		        output_d(digit[yuzo]|(0b10110000));
                        delay_ms(5);
		        output_d(digit[ono]|(0b11010000));
                        delay_ms(5);
		        output_d(digit[biro]|(0b11100000));
                        delay_ms(5);
        	}
        }

mehmet

#8
Display üzerinde rakam gösterme sıralamasına bir bakalım:
(Tarama yöntemi kullanılıyor ise...)

* X nolu display ortak ucu pasif edilir. (Tüm display ortakları kapanmış olur.)
* Birinci display için data yollanır.
* Birinci display ortak ucu aktif edilir.
* Gösterme zamanı kadar beklenir.
* Birinci display data boş yollanır.
* Birinci display ortak ucu pasif edilir. (Tüm display ortakları kapanmış olur.)
* Ikinci display data yollanır.
* İkinci display ortak ucu aktif edilir.
* Gösterme zamanı kadar beklenir.
* İkinci display data boş yollanır.
* İkinci display ortak ucu pasif edilir. (Tüm display ortakları kapanmış olur.)
*
*
*.....

Eğer gösterme zamanından sonra segmentler
kapatılmadan değişim yapılır ve diğer display
aktif edilirse; gölgeler oluşur. Bu nedenle önce
segmente boş data, sonra display ortak ucu kapatma,
sonra diğer display segmenti datası ve ortak ucu şeklinde
devam etmelidir.

/---------------------------------------------------------------------------------------/
ANCAK; Shift register kullanıyorsak ortak uçlara Vcc/Vss (ortak anot/katod
olması durumuna göre) direkt bağlanır. Seri olarak datalar verilir ve
latch ile aynı anda displaylar sürülür. Tarama yapılmayacağı için
sadece veri değişiminde displaylar sürülmesi kafidir.
/---------------------------------------------------------------------------------------/
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr

rugan035

Alıntı yapılan: mehmet - 09 Nisan 2015, 03:01:37
Display üzerinde rakam gösterme sıralamasına bir bakalım:
(Tarama yöntemi kullanılıyor ise...)

* X nolu display ortak ucu pasif edilir. (Tüm display ortakları kapanmış olur.)
* Birinci display için data yollanır.
* Birinci display ortak ucu aktif edilir.
* Gösterme zamanı kadar beklenir.
* Birinci display data boş yollanır.
* Birinci display ortak ucu pasif edilir. (Tüm display ortakları kapanmış olur.)
* Ikinci display data yollanır.
* İkinci display ortak ucu aktif edilir.
* Gösterme zamanı kadar beklenir.
* İkinci display data boş yollanır.
* İkinci display ortak ucu pasif edilir. (Tüm display ortakları kapanmış olur.)
*
*
*.....

Eğer gösterme zamanından sonra segmentler
kapatılmadan değişim yapılır ve diğer display
aktif edilirse; gölgeler oluşur. Bu nedenle önce
segmente boş data, sonra display ortak ucu kapatma,
sonra diğer display segmenti datası ve ortak ucu şeklinde
devam etmelidir.

/---------------------------------------------------------------------------------------/
ANCAK; Shift register kullanıyorsak ortak uçlara Vcc/Vss (ortak anot/katod
olması durumuna göre) direkt bağlanır. Seri olarak datalar verilir ve
latch ile aynı anda displaylar sürülür. Tarama yapılmayacağı için
sadece veri değişiminde displaylar sürülmesi kafidir.
/---------------------------------------------------------------------------------------/

Anlatımın için teşekkür ederim mehmet bu olayı çözdüm daha önce ama benim sorunum bu değil. Evet ben tarama yöntemiyle displayleri sürüyorum ama ben hesapladığım ondalıklı değeri ekranda gösteremiyorum. 4 adet display kullanıyorum ve ortalama aldığım iki farklı int değişkeni float olarak ekranda örneğin 1.658 gibi göstermek istiyorum. Kodları derleyip çalıştırdığımda ekranda 1.000 değerini görüyorum sadece.

baran123

Elinde diyelim ki bir float değişken olsun ve değeri 1.234 olsun senin bunu displaye aktarabilmen için int değeri elde etmen gerekiyor.Onun için bu değeri 1000 ile çarpıp int olarak elde etmen lazım.

float data = 1.234
int new_data;

new_data = data * 1000;
//şuan eimizde 1234 değeri oldu. hemde int olarak.daha sonra bu yeni veriyi gerekli işlemler ile hanelerini ekrana basabilirsin
//işlemleri zaten yapmışsın bölümünden kalan vs


şimdi tam kodunu burada paylaşırsan daha detaylı inceleyebiliriz.Muhtemelen veri boyutlarıyla ilgili bir durum.

mehmet

Hesap yapmadan, sadece 1234 yazdırabiliyor
musunuz?
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr

rugan035

Alıntı yapılan: Baran Ekrem - 09 Nisan 2015, 22:36:53
Elinde diyelim ki bir float değişken olsun ve değeri 1.234 olsun senin bunu displaye aktarabilmen için int değeri elde etmen gerekiyor.Onun için bu değeri 1000 ile çarpıp int olarak elde etmen lazım.

float data = 1.234
int new_data;

new_data = data * 1000;
//şuan eimizde 1234 değeri oldu. hemde int olarak.daha sonra bu yeni veriyi gerekli işlemler ile hanelerini ekrana basabilirsin
//işlemleri zaten yapmışsın bölümünden kalan vs


şimdi tam kodunu burada paylaşırsan daha detaylı inceleyebiliriz.Muhtemelen veri boyutlarıyla ilgili bir durum.

Dediğiniz gibi yaptım ama olmuyor. Kodum aşağıdaki gibi.
#include <16f877a.h>
#include <math.h>
#include <stdlib.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 azalt pin_a0
#define arttir pin_a1
#define enter pin_a2
#define reset pin_a3
#define orta pin_a4


int8 sayi=0,birler=0,onlar=0,yuzler=0,kalan=0,ortal=0,a=0;
int8 biro=0,ono=0,yuzo=0,bino=0;
float ort;

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


void ekran()
      {      
        output_b(digit[birler]|(0b00110000));
        delay_ms(5);
        output_b(digit[onlar]|(0b01010000));
        delay_ms(5);
        output_b(digit[yuzler]|(0b01100000));
        delay_ms(5); 

		output_d(digit[bino]|(0b01110000));
        delay_ms(5);
		output_d(digit[yuzo]|(0b10110000));
        delay_ms(5);
		output_d(digit[ono]|(0b11010000));
        delay_ms(5);
		output_d(digit[biro]|(0b11100000));
        delay_ms(5);

        output_c(a);
      }

void goster()
		{
			birler=sayi%10;
          	kalan=sayi/10;
          	onlar=kalan%10;
            yuzler=sayi/100;
		}

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(0x00);
    set_tris_e(0xFF);
    output_b(0);
    output_c(0);
	output_d(0);
    delay_ms(1000);
    
    while(TRUE)
    {   
        ekran();
        if(!input(arttir))
        {   
            sayi++;
			goster();

        while(!input(arttir))
            { 
            ekran();
            }      
        }
        if(!input(azalt)&&(sayi!=0))
        {   
            sayi--;
			goster();
        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(enter))
        {   
            if (++a==10){a=0;}

        while(!input(enter))
            {
            ekran();
            }
        }

       if(!input(orta))
       {   

			ort=(float)sayi/a;
              
      		ortal=ort*1000;
		
			biro=ortal%10; 		
			ono=(ortal/10)%10;
			yuzo=(ortal/100)%10;
			bino=(ortal/1000)%10;

			while(!input(orta))
			{
			ekran();
        	}
        }
}
}

rugan035

Sorunum hala devam ediyor. Güncel. :)

mehmet

Yazımın ikinci bölümünü okumamışsınız. Shift register
kullanıyorsak display ortak uçları mcu da olmayacak.
Anot/katod durumuna göre Vcc/Gnd bağlanacak. Tüm
displaylar için seri bilgi gönderilecek. Yani; 1234 sayısı için
tüm shift registerelere veriler bir seferde gönderilecek.
Veri gönderimi bitince Latch pini değişimi yapılarak
gönderdiğimiz değerlerin ekranda görülmesini sağlayacağız.

Gelismiş shift registerler (üç pinli olanlar) latch pini değişimine
kadar üzerlerindeki veriyi çıkartmazlar. Dolayısıyla display
görüntüsü değişmez. Sadece değer değiştirmek istediğimizde
yeniden tüm displaylara veri gönderebiliriz.
Olan olmuştur,
olacak olan da olmuştur.
Olacak bir şey yoktur.
---------------------------------------------
http://www.mehmetbilgi.net.tr