Problem mit Formatausgabe bei fprintf



  • Hallo,

    ich habe folgende HEX-Bytefolge "68 00 00 68" vorliegen.

    Wie muss ich also das fprintf benutzen, damit die serielle Schnittstelle versteht, dass da eine HEX-Bytefolge kommt und nicht eine Zeichenkette.

    Analog dazu, wie benutze ich die fscanf Funktion, um den empfangenen Datenstrom wieder in eine HEX-Bytefolge umzuwandeln.

    Wäre echt dankbar, wenn ihr mir helfen könntet.

    MfG

    MTC



  • Könnte ich das zum Beispiel so machen:

    fprintf(fd, "%x", "68000068");
    

    ????



  • nein, weil du einen String angibst, aber ein Integer Format benutzt

    fprintf(foo,"%x",0x68000068);
    //oder für strings
    fputs("68000068",foo); //bzw. mit fprintf
    fprintf(foo,"%s","68000068");
    

    weitere Hilfe bringt dir man 3 fprintf

    ansonsten ist das kein Unix spezifisches Problem und passt gut in das ISO C Forum ➡



  • Erstmal vielen Dank für deine Antwort, aber leider habe ich immer noch ein Problem.

    Wenn ich deinen Befehl so anwende:

    fprintf(fd,"%s","AAAA680404680000000080000AC252C23E9E02165555AAAA680303680000140000000B0F09003700165555");
    

    bekomme ich immer unter Linux einen "Segmentation Fault" !!!

    Woran kann das liegen ???

    Ich habe auch das Problem, wenn ich die anderen Versionen von dir ausprobiere, wie z.B.

    fprintf(fd,"%x",0xAAAA680404680000000080000AC252C23E9E02165555AAAA680303680000140000000B0F09003700165555);
    

    MfG

    MTC



  • kann es sein, dass fd kein gültiger filedescriptor ist? Prüfe vorher mal auf ungleich NULL. Ansonsten hast du vielleicht woanders Fehler gemacht?

    btw. ist die 2. Zeile nicht gültig, da die übergebene Zahl kein Integer ist!



  • also das "fd" ist das Handle für die serielle Schnittstelle !

    Und das Handle ist IO !

    Und verwendet habe ich die Standard C-Quelle aus dem Serial-HowTo.



  • prüf einfach mal ob fd wirklich geöffnet wurde. (assert(fd!=NULL))



  • Ich habe es nochmal getestet und das fd ist geöffnet, es hatte bei mir einen Wert von 3.

    Hier ist nochmal mein kompletter Source .

    Vielleicht erkennst du ja einen groben Fehler.

    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <termios.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    #define BAUDRATE B1200
    #define MODEMDEVICE "/dev/ttyS0"
    #define _POSIX_SOURCE 1 
    
    #define FALSE 0
    #define TRUE 1
    
    volatile int STOP=FALSE; 
    
    main()
    {
    	int fd,c, res,count=0;
    	float t;
    	struct termios oldtio,newtio;
    	char buf[255];
    	unsigned char i;
    
    	fd = open(MODEMDEVICE, O_RDWR | O_NOCTTY );
    	if (fd <0) {perror(MODEMDEVICE); exit(-1); }
    
    	tcgetattr(fd,&oldtio); /* save current serial port settings */
    	bzero(&newtio, sizeof(newtio)); /* clear struct for new port settings */
    
    	newtio.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;
    	newtio.c_iflag = IGNPAR | ICRNL;
    	newtio.c_oflag = 0;
    	newtio.c_lflag = ICANON;
    
             newtio.c_cc[VINTR]    = 0;     /* Ctrl-c */
             newtio.c_cc[VQUIT]    = 0;     /* Ctrl-\ */
             newtio.c_cc[VERASE]   = 0;     /* del */
             newtio.c_cc[VKILL]    = 0;     /* @ */
             newtio.c_cc[VEOF]     = 4;     /* Ctrl-d */
             newtio.c_cc[VTIME]    = 0;     /* inter-character timer unused */
             newtio.c_cc[VMIN]     = 1;     /* blocking read until 1 character arrives */
             newtio.c_cc[VSWTC]    = 0;     /* '\0' */
             newtio.c_cc[VSTART]   = 0;     /* Ctrl-q */ 
             newtio.c_cc[VSTOP]    = 0;     /* Ctrl-s */
             newtio.c_cc[VSUSP]    = 0;     /* Ctrl-z */
             newtio.c_cc[VEOL]     = 0;     /* '\0' */
             newtio.c_cc[VREPRINT] = 0;     /* Ctrl-r */
             newtio.c_cc[VDISCARD] = 0;     /* Ctrl-u */
             newtio.c_cc[VWERASE]  = 0;     /* Ctrl-w */
             newtio.c_cc[VLNEXT]   = 0;     /* Ctrl-v */
             newtio.c_cc[VEOL2]    = 0;     /* '\0' */
    
    	tcflush(fd, TCIFLUSH);
        tcsetattr(fd,TCSANOW,&newtio);
    
    // Hier beginnt das eigentlich senden und empfangen !!!
    
        if (fd!=NULL)
        {
            printf("Der Wert von fd ist: %i",fd);
            fprintf(fd,"%s","AAAA680404680000000080000AC252C23E9E02165555AAAA680303680000140000000B0F09003700165555");
        }
    
    	printf("\n");
    
    	tcsetattr(fd,TCSANOW,&oldtio);
    	exit(0);
    }
    


  • Also: 1. Kannst du in Verbindung mit fprintf() keinen File-Desktriptor (fd) verwenden. Mit "gcc -Wall" solltest du eine entsprechende Warnmeldung bekommen. fprintf() erwartet einen Zeiger auf einen Stream (FILE *stream;) wie er von fopen() geliefert wird. Daher kommt der Seg.-Fault. Hast du einen File-Deskriptor, nimm die Funktion write() zur Ausgabe.

    2. Habe ich dich so verstanden, dass Du eine Byte-Sequenz ausgeben willst, die in HEX-Werten vorliegt. Das ginge dann so:

    int fd;
    
    write(fd, "\x68\0\0\x68", 4);
    

    Martin

    PS.: Weitere Tipps und viele Beispielprogramme (auch zur seriellen Schnittstelle) findest du auch in meinem Buch "C und Linux" 😃


Anmelden zum Antworten