seri porta veri yazma formatı

Başlatan F493, 15 Ocak 2008, 12:06:03

F493

arkadaşlar ,seri porta veri yazarken genelde,

         Usart_putstr("hello world !!");
şeklinde kullanıyoruz(hi-tech te)

bunu formatlı yazdırmak istesem ,%d,\n ,\f,\r ,%X,%LF,

nasıl olacak bu iş ...

oturup bunlar için tek tek foksiyonmu yazıcaz.. bununla ilgili ,bir yorumunuzu bekliyorum..

normal şartlarda printf lcd için kullanılıyo...

parda

Merhaba;

Formatlı yazdırmak için printf kullanmalısınız.
printf kullanımı derleyiciye göre farklılıklar içerebilir.
Genel olarak derleyiciye tek karakter gonderen fonksiyonu söylerlesiniz örn: putc() gibi, putc fonksiyonun içini siz yazarsınız com port, lcd vs. gibi, siz printf fonksiyonunu kullanınca derleyici putc yi kullanarak çalışır.
başka bir yol ise printf ile bir buffer a yazılır sonra bu buffer sizin dediğiniz gibi bir fonksiyonla yazdırılır.

umarım izah edebilmişimdir. Detaylar için derleyicinizin dökümanlarında printf ile ilgili bölüme bakınız.

Başarılar
Bildiğim tek şey, hiç bir şey bilmediğimdir.

arslan74

Merhaba,

Bir kaynağa string yazdırmak için bir kaç değişik yol var. En basidi printf ve sprintf fonksiyonudur. Bu fonksiyonları kullanırsanız Ansi-C standarlarında kod yazmış olursunuz. Ancak PIC'in kapasitesini ve performansını kötü etkilediği için, kendi yazdığınız fonksiyonları kullanmanızı tavsiye ediyorum. Bu kodlar daha kısa ve daha hızlı çalışacaktır.

Seri port ve LCD için bu sitede örnek kodlar yayımladım onları inceleyebilrsiniz.

Ama seri port için kısaca örnek vermek gerekirse.

void usart_puts(const char * s)
{
	while(*s)
		usart_ilet(*s++);
}


void usart_ilet (unsigned char ch )
{
   while (!TXIF){;}
   
   TXREG = ch;    //         ; RS232 ye yaz.
}//


şeklinde kullanabilirsiniz.

Burda usart_ilet fonksiyonu tek bir karakter gönderir. usart_puts fonksiyonu ile bir yazıyı seri porta gönderebilirsiniz.

Selamlar

F493

sayın arslan74;

seri porta long bir deger yazmak istiyorum daha dogrusu tüm formatları kullanabilmek..

void usart_puts(const char * s);

ozanman bu fonk.yeterli olmuyor,

ozaman nasıl yapacagız stringlerde bir problem yok,ancak formatlı yazımlarda bir problem var..

bunun için bir öneriniz varmı ,zaten yukarıda söylediklerinizi kullanıyorum ben..


iyi çalışmalar...

parda

Merhaba F493;

Anladığım kadarı ile sizin probleminiz sayıyı ascii karakterlere çevirmek,
bir long değeri seri porttan göndermeniz için gereken şey ile Formatlı yazdırmayı ben biraz daha farklı anlıyorum.

bir sayıyı karaktere çevirmek için sayıyı basamaklarına ayırıp her basamağa 48 eklemeniz yeterli örnek vermek gerekirse;

size 3 basamaklı  bir sayıyı nasıl ascii ye çevirirsiniz ve com porta gönderirsiniz gostereyim bunu long için siz düzeltirsiniz.

void CharToCom(int nSayi)
{
  char[4] sStr;

  char[0] = (nSayi / 100) + 48;
  char[1] = ((nSayi / 10) % 10) + 48;
  char[2] = (nSayi % 10) + 48;
  char[1] = '\0';
  usart_puts(sStr);
}

bu fonksiyon ile sadece 3 basamaklı sayı çevirebilirsiniz 3 basamaktan az sayi başında sıfır olur mesela işte tüm bu detaylar dan dolayı eğer siz sadece bir iki yerde kullanacak ve hep sabit işler yapacaksanız ihtiyacınıza göre düzenlersiniz biter gider

ancak

printf("float deger:%.02F;int deger:%03u;int deger:%05u\r\n",Long,nInt,nInt);

gibi karışık formatlı yazımları her seferinde farklı bir biçimde kullanacaksanız printf en iyi çözüm olur

verdiğim fonksiyonu şöyle kullanırsınız

CharToCom(452);


com portta 452 gondermiş oldunuz

başarılar.
Bildiğim tek şey, hiç bir şey bilmediğimdir.

F493

Normal şartlarda ben printf'i lcd ye yazmak için kullanıyorum

lcd'yi  printf 'in tüm nimetlerinden faydalanarak kullanıyorum..

ancak ben birde seri porta basarkende tüm özelliklerini kullanmak istiyorum,

ama ya lcd  ya seri port 'da kullanabilrim
örnegin printf("long = %lX",data);
burada lcd için kullanıyorum,
bunu seri port içinde kullanmak istiyorum..

**her ikisi için aynı anda kullanmakistiyorum printf'i
ccs de oldugu gibi
printf("lcd_putch"....bu lcd ye yazıyor
printf ise seri porta



   örnegin printf("long = %lX",data); bu fonsiyonu kullanmayıp seri porta long bir degeri ,veya float bir degeri  nasıl yazdıracagım bunun için tüm türlere göre bir fonk.yazmak  gerekiyor normal şartlarda..

     Ortalık kod olacak ,program şişecek,sonuçta bunu ,mükemmel şekilde gereksiz kodlardan kaçınarak  ve derleyicinin  iyi bir şekilde asm ye çevirebilecegi bir program yazmak  gerekiyor.
    Buda zor tabi ,birikim ister

    Ben zaten asccii 'yi desimale çevirip yazdırıyorum,örnegin açılarla ilgili bir işlem yaptırdım bunu nasıl yazdıracagım seri porta ,
double bir deger sonuç olarak
iyi çalışmalar

james

arkadaşlar söylemiş ama gözünden kaçmış sanıyorum.
sprintf ile bir char buffer'a at sonra usart_puts ile buffer'ı yazdır.

örn:
sprintf(buf,"long = %lX",data);
usart_puts(buf);

tabi istediğin formatları derleyici desteklermi bakman lazım.
ARAMIYORUM , BULUYORUM

arslan74

Merhaba,

Arkadaşlar cok güzel acıklamışlar.

Birde Hi-Tech'in kendi web sitesine bununla ilgili örnek kodlar var, onları incelemenizi tavsiye ederim. sprintf fonksiyonunu kullandan bilgiyi iletme kodu.

http://www.htsoft.com/resources/articles/techtip_integer.php

Ayrıca burdada başka güzel acıklamalar var.

http://www.htsoft.com/resources/articles/techtip_letspretend.php

http://www.htsoft.com/resources/articles/techtip_buffer.php

http://www.htsoft.com/resources/articles/techtip_interrupts.php

Selamlar

F493

açıkca söylemek gerekirse

Sizce arkadaşlar güzel açıklamış olabilirler arslan74 arkadaşım ancak ben istedigim cevabı bulamadım,çünkü önerilerin hepsi standart c ,ve sistemi hantallaştıran şeyler yani embedded için değil,

ve oturup kendim bir yöntem düşündüm , ve online çalışan RFID cihazımda bunu kullandım..
ve hatasız çalışmakta

///////////////////////////////////////////////////

       #define    LCD          1                      //printf fonk.için sembolik sabitler
   #define    SERIAL         2                     //istenirse lcd1ye ,istenirse seri porta
   #define    LCD_SERIAL   3                  // formatlı yazmak için

///////////////////////////////////////////////////////

unsigned char printf_mode;

//printf fonksiyonu  putch fonk.çagırdıgı için onu ben gerçekleştirerek konfigirasyonunu ayarladım
//  printf_mode == 1        ise deger lcd ye gönderilir
//  printf_mode == 2         ise deger seri porta  gönderilir
//  printf_mode == 3        yapışarak her ikisine birden gönderilebilir

////////////////////////////////////////////////////////
 void main(void)
{


      Startup();
   LCD_Init();   



////bu yöntem sonucu lcd ye yazar

        printf_mode = LCD;
      printf("\f\r *AKTiF ZAMAN* ");            //başlangıç mesajı
   printf_mode= 0;


     DelayMs(500);
     DelayMs(500);


////bu yöntem sonucu seri porta yazar

        printf_mode = SERIAL;
      printf("\f\r *AKTiF ZAMAN* ");             //başlangıç mesajı
   printf_mode= 0;
 

      while(1)  ;


}




/////////////////////////////////////////////////////////
//LCD gönderme fonk(); üst katmanı

void putch(char c)
{
      
   if (printf_mode & 1) {             //gelen verinin lcd ye yazılacagı anlamınageliyor
      switch (c) {
         case '\r':
            LCD_Home();
            break;
         case '\n':
            LCD_SetCursor(0x40);                 //0X40 == 1000 0000 //0 ile 127 arasında cursor konumlandırma
            break;
         case '\f':
            LCD_Clear();
            break;
         default:
            LCD_PutChar(c);
            break;
      }
   }
   if (printf_mode & 2)           //gelen verinin seri porta yazılcagı anlamına geliyor
      Usart_Putch(c);
}

arslan74 arkadaşım şunuda söylemeden geçemicem,hi-tech sitesindeki kodlarada pek güvenmeyin derim,

şimdi diyeceksin ki , neden adamlar yazmış koymuş,hi-tech sonuçta ,ancak öyle değil

şuan 5 page 300 satır kod oldu ancak  hepsininide kendim yazdım,lcd,seri hab...

nedeni ise hi-tech biraz tutarsız,bazen hatalı derliyor,olaya çok hakim olmanız gerekiyor..

ve microchip C18 IDE sini inceledim ve kütüphane ,tutarlılık,memory management olsun bayagı iyi, işte bit oparatörü yok,kesme süreleri biraz sıkıntlı ve kesme fonk.oluşturmak biraz komplex, hi-tech te yazdıklarımı o ide ye uyarladım birkaç degişiklikle çalıştı.. bilginize


iyi çalışmalar

arslan74

Merhaba,

Sana bir başka yol önereceğim. onları bir dene istersen.

Ayrıca verdiğin örnek kodları code tag içine alırsan yazı ile kod birbirlerine karışmamış olur.


////bu yöntem sonucu lcd ye yazar 

printf_mode = LCD; 
printf("\f\r *AKTiF ZAMAN* "); //başlangıç mesajı 
printf_mode= 0; 


DelayMs(500); 
DelayMs(500); 


////bu yöntem sonucu seri porta yazar 

printf_mode = SERIAL; 
printf("\f\r *AKTiF ZAMAN* "); //başlangıç mesajı 
printf_mode= 0;


Yerine bir tane global string belirtiyorsunuz. bunun uzunluğunun bir yazının max uzunuğuna göre yapabilirsin.

unsigned char outString[16];


	lcd_goto(S2_1);
	sprintf (outString,"\f\r *AKTiF ZAMAN* " );

	lcd_puts(outString);  //lcd gönder
	usart_puts(outString); // Rs 232 gönder


Bu sayede bir dönüştürme işlemi yaptıktan sonra tekrar aynı printf fonksiyonun cağırmana gerek yok. outString tuttuğun yazıyı istediğin kaynağa verebilirsin. Bu şeklide daha verimli kod yapmış olursun.

Selamlar

arslan74

Merhaba,

Sana bir başka yol önereceğim. onları bir dene istersen.

Ayrıca verdiğin örnek kodları code tag içine alırsan yazı ile kod birbirlerine karışmamış olur.


////bu yöntem sonucu lcd ye yazar 

printf_mode = LCD; 
printf("\f\r *AKTiF ZAMAN* "); //başlangıç mesajı 
printf_mode= 0; 


DelayMs(500); 
DelayMs(500); 


////bu yöntem sonucu seri porta yazar 

printf_mode = SERIAL; 
printf("\f\r *AKTiF ZAMAN* "); //başlangıç mesajı 
printf_mode= 0;


Yerine bir tane global string belirtiyorsunuz. bunun uzunluğunun bir yazının max uzunuğuna göre yapabilirsin.

unsigned char outString[16];


	lcd_goto(S2_1);
	sprintf (outString,"\f\r *AKTiF ZAMAN* " );

	lcd_puts(outString);  //lcd gönder
	usart_puts(outString); // Rs 232 gönder


Bu sayede bir dönüştürme işlemi yaptıktan sonra tekrar aynı printf fonksiyonun cağırmana gerek yok. outString tuttuğun yazıyı istediğin kaynağa verebilirsin. Bu şeklide daha verimli kod yapmış olursun.

Selamlar