Pobieranie danych z portu szeregowego w j

Potrzebujesz pomocy z C, C++, perl, python, itp.
devaster
Posty: 1
Rejestracja: 09 lipca 2009, 17:32

Pobieranie danych z portu szeregowego w języku C

Post autor: devaster »

Witam.

Chciałbym napisać program, który komunikuje się z mikrokontrolerem za pomocą portu rs232. Mikrokontroler pobiera dane i buforuje je, aż otrzyma znak powrotu karetki (\r). Następnie wypisuje je na wyświetlaczu i odsyła do komputera. Sprawdziłem działanie mikrokontrolera za pomocą CuteCom i wszystko działa prawidłowo. Napisałem dwie proste funkcje:

Kod: Zaznacz cały

#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <stdio.h>
#include <sys/ioctl.h> /* Dla ioctl */
#include "ATCommand.h"

// Wlasne funkcje
int Open(int fd, char* port){
    struct termios options;
    
    fd=open(port, O_RDWR | O_NOCTTY | O_NDELAY);
    if (fd<0){
        printf("Blad podczas otwierania portu\n");
        return -1;
        }
    else{
        /* Getting the current settings for the port */
        tcgetattr(fd, &options);
        
        /* Setting baudrate (19200) */
        cfsetispeed(&options, B9600);
        cfsetospeed(&options, B9600);
        
        options.c_cflag &= ~CSIZE;   /* Wylaczenie maski bitowej */
        options.c_cflag |= CS8;      /* Osiem bitow danch */
        options.c_cflag &= ~CSTOPB;  /* 1 bit stopu */
        options.c_cflag |= PARENB;   /* Wlacz kontrole parzystosci */
        options.c_cflag &= ~PARODD;   /* even parity */
        
        options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /* raw input (bez przetwarzania) */

        options.c_iflag &= ~(ICRNL | INLCR | IGNCR | IUCLC); /* Wylaczenie mapowania */
        options.c_iflag &= ~(IXON | IXOFF | IXANY); /* Wylaczenie kontroli przeplywu */

        options.c_oflag &= ~OPOST; /* Bez przetwarzania danych wyjsciowych */
        
        /* Setting the new settings for the port immediately */
        tcsetattr(fd, TCSANOW, &options);
        printf("Port otwarty i skonfigurowany\n");
        return fd;
        }
}

void ATI(char* port, char *odpowiedz)
{
    int fd = 0; /* File descriptor */
    int wynik; /* Wynik operacji na pliku */
    int bytes;  /* Ilosc bajtow gotowych do odebrania */
    
    fd = Open(fd,port); /* Otwarcie portu */

    /* Wyslanie danych */ 
    if(fd >= 0){
        wynik = write(fd, "ATI\r", 4); /* \r to <CR> */
        if(wynik > 0){
            printf("Wyslano dane\n");
            }
        else {
            printf("Blad wysylania danych\n");
            wynik = 0;
            }
        }
    else{
        wynik = 0;
        printf("Blad otwarcia portu przy wysylaniu danych\n");
        }    
    close(fd);
    
    sleep(0.5); /* Czekanie na odpowiedz układu */
    
    fd = 0;
    fd = Open(fd,port); /* Otwarcie portu */

    /* Odebranie danych z urzadzenia */
    if(fd >= 0){
        ioctl(fd, FIONREAD, &bytes); /* Pobranie infiracji o ilosci bajtow czekajacych po pobrania */
        if(bytes > 0){
            wynik = read(fd, odpowiedz, bytes);
            if(wynik > 0){
                printf("Pobrano dane");
                }
            else{
                printf("Blad pobierania danych\n");
                wynik = 0;
                }
            }
        else{
            printf("Brak danych do pobrania\n");
            wynik = 0;
            }                    
        }
    else{
        wynik = 0;
        printf("Blad otwarcia portu przy pobieraniu danych\n");
        }
        
    close(fd);
}
Po wywołaniu:

Kod: Zaznacz cały

ATI(port,bufor);
otrzymuję informacje:

Kod: Zaznacz cały

Port otwarty i skonfigurowany
Wyslano dane
Port otwarty i skonfigurowany
Brak danych do pobrania
Mój program wysyła dane, bo pojawiają się na wyświetlaczu mikrokontrolera, ale nie pobiera danych.
Dlaczego mój program nie czyta danych z portu szeregowego?

Pozdrawiam.
fnmirk
Senior Member
Posty: 8321
Rejestracja: 03 grudnia 2007, 06:37

Post autor: fnmirk »

borgul
Posty: 4
Rejestracja: 03 stycznia 2012, 21:45

Post autor: borgul »

Spróbuj dodać w funkcji Open

Kod: Zaznacz cały

options.c_cflag |= (CLOCAL |CREAD);
a po write

Kod: Zaznacz cały

tcdrain(fd);
dlaczego po read zamykasz port i ponownie go otwierasz?
ODPOWIEDZ