seri porttan integer gönderme

Başlatan pax, 13 Aralık 2014, 10:08:26

pax

seri port'tan karakter gönderebiliyorum ancak integer gönderemiyorum. integer ı string e çevirip göndermeye çalışıyorum o zamanda istenmeyen karakter ortaya çıkıyor. örneğin aşağıdaki programda 1023 sayısını itoa() fonksiyonu ile stringe çevirip gönderiyorm. virtual terminalde ise 1023ü şeklinde çıkıyor.
#include "main.h"
#include <stdint.h>
#include <stdlib.h>

void seriport_textyaz(char *text );
void seriport_karakteryaz(char data );
void seriport_ayar(uint16_t);
void ilk_ayar(void);
void bekle(uint16_t );

uint16_t  sayi=1023;
char gecici[4];

int  main(void)
{  
   ilk_ayar();
   seriport_ayar(9600);

   for(;;)
   {
        itoa(gecici,sayi,10);
        seriport_textyaz(gecici);
        seriport_karakteryaz('\r');
        bekle(1000);
      
   }
}
void ilk_ayar()
{
     PORTA  = 0X00;
     LATA   = 0X00;

     ADCON1 = 0X00;
     CMCON  = 0X07;

     TRISA  = 0xff;

     PORTB  = 0X00;
     LATB   = 0X00;

     LATC   = 0X00;
     PORTC  = 0X00;

     LATD   = 0X00;
     PORTD  = 0X00;

     LATE   = 0X00;
     PORTE  = 0X00;

     TRISC =  0X00;
     TRISD =  0X00;
     TRISB  = 0X00;
     TRISE  = 0Xff;
}
void bekle(uint16_t x)
{
   unsigned int i;

   for(i = 0; i < x; i++)
   {
      __delay_ms(1);
   }
}
void seriport_ayar(uint16_t baudrate)
{

 
    SPBRG = ((_XTAL_FREQ /baudrate)/64)-1 ;

    TXSTAbits.BRGH    = 0 ;      // Baud Rate Select bit           : 0 = low, 1=high
    BAUDCONbits.BRG16 = 0 ;      // Baud Rate Register Enable bit  : 0 = 8 bit, 1=16-bit

    TXSTAbits.SYNC    = 0 ;      // EUSART Mode Select bit         : 1 = Synchronous mode ,0 = Asynchronous mode
    RCSTAbits.SPEN    = 1 ;      // Serial Port Enable bit         : 1 = Serial port enabled , 0 = Serial port disabled

    PIE1bits.TXIE     = 0 ;      // EUSART Transmit Interrupt Enable bit  : 1 = Enables 0 = Disables

    TXSTAbits.TX9     = 0 ;      // 9-bit Transmit Enable bit      : 1 = 9-bit transmission, 0 = 8-bit transmission
    TXSTAbits.TXEN    = 1 ;      // Transmit Enable bit            : 1 = Transmit enabled ,0 = Transmit disabled


    TRISCbits.TRISC6  = 0 ;
    TRISCbits.TRISC6  = 1 ;

}
void seriport_karakteryaz(char data )  {
    while(!TRMT)
        continue ;
    TXREG = data;
}
void seriport_textyaz(char *text)  {
    uint8_t i;

     for(i=0;text[i]!='\n';i++)
     {
      
               seriport_karakteryaz(text[i] );
     }
   
}


integer göndermek için kullandığım yöntem doğru mu? başka bir yöntem var mı?

Huzame

integer'i ikiye böl 8 bit 8bit olarak gönder

Kabil ATICI

//16 biti 8 bite parçalama için...
#define  LOWBYTE(v)   ((unsigned char) (v))
#define HIGHBYTE(v)  ((unsigned char) (((unsigned int) (v)) >>  8 ))
16 bit sayıları 8 bit parçalamak için bu kodu kullanıyorum.
LOWBYTE(sayi) ;
HIGHBYTE(sayi);
şeklinde kullanımı var. Bunları nerede kullanacağın sana kalmış.
ambar7

pax

benim derdim 16 biti 8 bite düşürmek değilki  ben örneğin herhangi bir hesaplamada ortaya çıkan 102 sayisini seriporttan göndermek istiyorum. ancak benim yazdığım fonksiyonlar sadece karakter gönderiyor. bu yüzden 102 sayisini itoa() ile stringe çevirip göndermeye çalışıyorum .

pea

Sizin derdiniz 16 bit'i 8 bit'e düşürmek aslında ama öyle olduğunu bilmiyorsunuz.
Seri haberleşme char/byte üzerine kuruludur. Yani 8 bit/1 byte'tan büyük sayı zaten gönderemezsiniz, bölmeniz gerekir.

Seri haberleşme genellikle karakter/string gönderimi üzerine kurulu olduğu için gönderici de alıcı da Char olarak yorumlar genellikle.
Alıcı tarafında Char, Hex, Dec gösterim seçeneği vardır. Yoksa da başka program deneyin.

pax

Alıntı yapılan: pea - 13 Aralık 2014, 15:16:33
Sizin derdiniz 16 bit'i 8 bit'e düşürmek aslında ama öyle olduğunu bilmiyorsunuz.
Seri haberleşme char/byte üzerine kuruludur. Yani 8 bit/1 byte'tan büyük sayı zaten gönderemezsiniz, bölmeniz gerekir.

Seri haberleşme genellikle karakter/string gönderimi üzerine kurulu olduğu için gönderici de alıcı da Char olarak yorumlar genellikle.
Alıcı tarafında Char, Hex, Dec gösterim seçeneği vardır. Yoksa da başka program deneyin.


tamam ben de diyorum ki göndereceğim sayi 102 olsun ve programda şu şekilde olsun

#include "main.h"
#include <stdint.h>
#include <stdlib.h>

void seriport_textyaz(char *text );
void seriport_karakteryaz(char data );
void seriport_ayar(uint16_t);
void ilk_ayar(void);
void bekle(uint16_t );

char sayi=102;
char gecici[4];

void main(void)
{  
   ilk_ayar();
   seriport_ayar(9600);

   for(;;)
   {
        //itoa(gecici,sayi,10);
       // seriport_textyaz(gecici);
         seriport_karakteryaz(sayi);
        seriport_karakteryaz('\r');
        bekle(1000);
      
   }
}
void ilk_ayar()
{
     PORTA  = 0X00;
     LATA   = 0X00;

     ADCON1 = 0X00;
     CMCON  = 0X07;

     TRISA  = 0xff;

     PORTB  = 0X00;
     LATB   = 0X00;

     LATC   = 0X00;
     PORTC  = 0X00;

     LATD   = 0X00;
     PORTD  = 0X00;

     LATE   = 0X00;
     PORTE  = 0X00;

     TRISC =  0X00;
     TRISD =  0X00;
     TRISB  = 0X00;
     TRISE  = 0Xff;
}
void bekle(uint16_t x)
{
   unsigned int i;

   for(i = 0; i < x; i++)
   {
      __delay_ms(1);
   }
}
void seriport_ayar(uint16_t baudrate)
{


    SPBRG = ((_XTAL_FREQ /baudrate)/64)-1 ;

    TXSTAbits.BRGH    = 0 ;      // Baud Rate Select bit           : 0 = low, 1=high
    BAUDCONbits.BRG16 = 0 ;      // Baud Rate Register Enable bit  : 0 = 8 bit, 1=16-bit

    TXSTAbits.SYNC    = 0 ;      // EUSART Mode Select bit         : 1 = Synchronous mode ,0 = Asynchronous mode
    RCSTAbits.SPEN    = 1 ;      // Serial Port Enable bit         : 1 = Serial port enabled , 0 = Serial port disabled

    PIE1bits.TXIE     = 0 ;      // EUSART Transmit Interrupt Enable bit  : 1 = Enables 0 = Disables

    TXSTAbits.TX9     = 0 ;      // 9-bit Transmit Enable bit      : 1 = 9-bit transmission, 0 = 8-bit transmission
    TXSTAbits.TXEN    = 1 ;      // Transmit Enable bit            : 1 = Transmit enabled ,0 = Transmit disabled


    TRISCbits.TRISC6  = 0 ;
    TRISCbits.TRISC6  = 1 ;

}
void seriport_karakteryaz(char data )  {
    while(!TRMT);
        //continue ;
    TXREG = data;
}
void seriport_textyaz(char *text)  {
    uint8_t i;

     for(i=0;text[i]!='\n';i++)
     {
      
               seriport_karakteryaz(text[i] );
     }
   
}


karşı alıcı proteus virtual terminal .
bu programa göre virtual terminalde  ben gelen veriyi f olarak görüyorum.

pea

tamam ben de diyorum ki Proteus Virtual Terminal, gelen veriyi Char olarak yorumluyor. Sanırım başka seçenek de yok.
Başka bir terminal kullanırsanız(simülasyon sırasında yapacak bir şey yok herhalde), 102 aldığınızı göreceksiniz.
Char f = Dec 102 zaten: http://benborowiec.com/wp-content/uploads/2011/07/better_ascii_table.jpg

Burak B

#7
@pax
...
char gecici[4];
...


Bu yanlış. itoa() fonksiyonu C string işlemi yaptığına göre tüm stringler '\0' ile bitmelidir. Ancak senin tanımlaman sadece rakamları barındırabilecek büyüklükte.

İlla rakamı stringe çevirip göndereyim diyorsan. Doğrusu şöyle olmalı;
...
static char gecici[5]; // static tanımladığımız için derleyici tarafından içeriği sıfırlanır.
...


Böylece itoa() verdiğin integeri ASCII yapacak ve dizinin son indeksine de '\0' koyacaktır.

Ancak şunuda belirteyimki bu yöntem pek efektif bir yöntem değil. @pea' nın da dediği gibi direkt 2 byte veri göndererek bu işi halletmen daha hızlı olur.
En az iki byte gerekiyor çünkü 1024 iki byte ile ifade edilebilir malum. Ama 2 byte 5 byte veriden daha azdır. :)
"... a healthy dose of paranoia leads to better systems." Jack Ganssle

pax

Alıntı yapılan: Burak BAYRAK - 13 Aralık 2014, 16:32:58
Ancak şunuda belirteyimki bu yöntem pek efektif bir yöntem değil. @pea' nın da dediği gibi direkt 2 byte veri göndererek bu işi halletmen daha hızlı olur.
En az iki byte gerekiyor çünkü 1024 iki byte ile ifade edilebilir malum. Ama 2 byte 5 byte veriden daha azdır. :)

anladım. teşekkür ederim .