Léa-Linux & amis :   LinuxFR   GCU-Squad   GNU
communication par port serie
Envoyé par: Steph10200

Bonjour,

je suis entrain de developper en C 1 appli, et j'ai besoin de communiquer (avec 1 pic (ou autre)) par liaison serie.

et la j'ai qq problemes, j'ai trouvé nulle part un bon tuto la dessus.

je sais ecrire sur un port // (outb inb) mais pas sur un port serie.

j'ai +/- vu qu'il fallait ouvrir le "fichier" /dev/ttyS0, mais apres, on fait comment pour lire et ecrire ? es ce qu'un fprintf et 1 fscanf suffisent ?

merci



--- Stéphane ---

Poste le Friday 21 January 2005 15:50:47
Répondre     Citer    
Re: communication par port serie
Envoyé par: Steph10200

bon voila ce que j'ai pour le moment :

#include <sys/types.h>
#include <sys/stat.h>
#include <asm/ioctls.h>
#include <asm/termios.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

// je n'ai certainement pas besoin de toutes ces includes (g repris sur 1 autre programme)


#define COM_PORT1 "/dev/ttyS0"
# BAUDRATE B9600

int fd;
struct termios oldtio,newtio;

void Open_ComPort(char com){
int result,arg;
// ...
if (debug) printf("\ntrying to open com 1 fd=");
fd = open(COM_PORT1,O_RDWR | O_NOCTTY | O_NDELAY);
if (debug) printf("\nPort com 1 ouvert");
// ...
if (debug) printf("\nfd : %i \r\n",fd);

tcgetattr(fd,&oldtio);
bzero(&newtio, sizeof(newtio));
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;

} // fin du open

int Close_ComPort(void){
return( close(fd) );
}//close_ComPort


void main (void)
{

Open_ComPort(1);
// ????
//Comment faire ici ?

//?????

Close_ComPort();
} // fin main



Merci de m'aider





--- Stéphane ---

Poste le Friday 21 January 2005 19:02:25
Répondre     Citer    
Re: communication par port serie
Envoyé par: HortY

Désolé de te faire une fausse joie winking smiley Mais moi aussi je serais intéressé par la réponse à ton problème!

Poste le Friday 4 March 2005 10:42:50
Répondre     Citer    
Re: communication par port serie
Envoyé par: Steph10200

oui alors en fait, j'ai utilisé le "fichier" /dev/ttyS0.

voici l'extrait du programme :

// .. defines
#define COM_PORT1 "/dev/ttyS0"

// ..  main () {
struct termios termios_p;

// ouverture port
                if (debug) printf("Essaye d'ouvrir le port com 1\n");
                fd = open(COM_PORT1,O_RDWR | O_NOCTTY);
                if (debug) printf("Port com 1 ouvert\n");
// config du port
bzero(&termios_p, sizeof(termios_p));
termios_p.c_cflag = CLOCAL | CS8 | CSTOPB; // 9600,8,N,1
cfsetospeed(&termios_p, BAUDRATE);      // 9600 voir define
cfsetispeed(&termios_p, BAUDRATE);      // 9600 voir define
termios_p.c_oflag &= ~OPOST;
termios_p.c_oflag &= ~(IXON | IXOFF | IXANY); /* no flow control */

termios_p.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
termios_p.c_oflag &= ~OPOST; /* No output processing */
termios_p.c_oflag &= ~ONLCR; /* Don't convert linefeeds */
termios_p.c_cflag |= CREAD;

tcflush(fd, TCIFLUSH); // clear the line
tcsetattr(fd, TCSANOW, &termios_p);

fcntl(fd, F_SETFL, 0); // mode non bloquant
// fin config


// operations : 
ecrit=write (fd, &data,1); // ecriture de 1 caractere de data sur port
tcdrain(fd); // attente tt recu
usleep(50000); // 50000 // attente
lu=read (fd, &recu, 1); // lecture d'un caractere dans recu

ecrit et lu recoivent le nb de caracteres réélement lu ou ecrit (pour verifier)

reste plus a la fin qu'a fermer le port

close (fd);

} // fin du main

voila j'espere t'avoir aidé
si tu as des questions ou des problemes je reste dispo.
tu peux bien sur par exemple faire une fonction pour l'ouverture du port , une pour l'ecriture, une pour la lecture ...

voila




--- Stéphane ---

Poste le Friday 4 March 2005 11:04:10
Répondre     Citer    
Re: communication par port serie
Envoyé par: Steph10200

j'ai juste oublié 1 define c'est pour le baudrate


#define BAUDRATE B9600


j'ai oublié aussi de commenter les 2 lignes a la fin (si tu copie le code tel quel)

voila


--- Stéphane ---

Poste le Friday 4 March 2005 11:07:18
Répondre     Citer    
Re: communication par port serie
Envoyé par: HortY

C'est en fait juste pour un envoi de trame par liaison série afin de commander une caméra. je pense qu'en utilisant un peu de ton code (si tu me l'autorise winking smiley ) je pourrais éventuellement m'en sortir. Merci encore!

Et effectivement, trouver un tuto sur la liaison série est étrangement très difficile!!

Poste le Friday 4 March 2005 11:09:40
Répondre     Citer    
Re: communication par port serie
Envoyé par: marc ferraton

Il faut gerer les time-out sur les lectures et ecritures, mais sinon lecture et ecriture sont en gras dans le texte,
ceci n'est pas un exemple mais une appli fonctionnelle

quelque chose comme çà pour l'ecriture
/***********************************
envoi de la question a l'API
retourne -1 si defaut
 ************************************/
int comm_send_mbus(int port ,char *question, int size_q )
{
        int i = 0 ; 

        fd_set wfds;
        struct timeval tv;
        int retval;
        
        /* Set the non-blocking write */ 
        fcntl(port, F_SETFL, fcntl(port,F_GETFL)|O_NONBLOCK); */

        i = write(port,question,size_q);

        tv.tv_sec = timeout_s;
        tv.tv_usec = timeout_usec;

        /* check write end */
        FD_SET(port, &wfds);
        retval = select(port+1, NULL, &wfds, NULL, &tv);
        if (retval <= 0) {
                if DEBUG2 fprintf(stderr,"SOCK_SEND_MBUSconfused smileyerious Time-out en ecriture d'écriture, comm non-disponible\n");
                tcflush(port, TCIOFLUSH );
                return retval;
        }

        /* Set the blocking write */ 
        fcntl(port, F_SETFL, fcntl(port,F_GETFL)&~O_NONBLOCK);

        return i;
}

et pour la lecture
/***********************************
lecture de la reponse de l'API
retourne le nombre de caractere lus
 ************************************/
int comm_recv_mbus(int port, char *reponse, int size_r)
{
        int i=0;
        int j=0;
        long k=0;
        int on = 1;
        int off = 0;
        int car;
        fd_set rfds;
        struct timeval tv;
        int retval;

        if (size_r >= 261 ) {
                if DEBUG1 fprintf(stderr,"SRV_API:comm_recv_mbusconfused smileyerious Panique trop d'éléménts à lire\n");
                return -3;
        }

        /* Set the non-blocking read */ 
        fcntl(port, F_SETFL, fcntl(port,F_GETFL)|O_NONBLOCK); 
        /* Wait up to few seconds. */
        tv.tv_sec = timeout_s;
        tv.tv_usec = timeout_usec;

        /* Watch stdin (fd 0) to see when it has input. */
        FD_ZERO(&rfds);
        FD_SET(port, &rfds);
        while ( i < size_r ) {
                retval = select(port+1, &rfds, NULL, NULL, &tv);
                /* Don't rely on the value of tv now! */

                if ( retval >  0 )
                {
                        /* FD_ISSET(0, &rfds) will be true. */
                        if DEBUG2 fprintf(stderr,"SRV-API:comm_recv_mbus:Info données disponibles depuis API%d .\n",retval);

                        j = read(port,reponse+i,size_r-i);
                        if ( j > 0 ) { 
                                if DEBUG2 fprintf(stderr,"SRV-API:comm_recv_mbus:Info nb caractere a lire 0x%02x lu 0x%02x total 0x%02x\n",size_r-i,j,i+j);
                                if DEBUG2 {
                                        for ( k = 0; k<j;k++) 
                                                fprintf(stderr,"SRV-API:comm_recv_mbus:Info i=%02x caractere %02x\n",i+k,reponse[i+k]);
                                }
                                tv.tv_sec = timeout_s;
                                tv.tv_usec = timeout_usec;
                                i += j;
                        } else {
                                fprintf(stderr,"errno %d\n",errno);
                                perror("read");
                                if DEBUG2 fprintf(stderr,"SRV-API:comm_recv_mbus:Info nb caractere a lire 0x%02x lu 0x%02x total 0x%02x\n",size_r-i,j,i+j);
                        }
                        
                } else {
                        if DEBUG1 fprintf(stderr,"SRV-API:comm_recv_mbusconfused smileyerious Pas de reponse de l'esclave MODBUS\n"); 
                        /* Set the blocking read */ 
                        fcntl(port, F_SETFL, fcntl(port,F_GETFL)&~O_NONBLOCK); 

                        return -2;
                }

        }
        /* Set the blocking read */ 
        fcntl(port, F_SETFL, fcntl(port,F_GETFL)&~O_NONBLOCK); 
        return i;
}


les fonctions seront appelées comme suit
                /* ouverture du port*/
                if( !(port_serie=comm_init(port_serie)) ) 
                { 
                        fprintf(stderr,"SRV-APItongue sticking out smileyanique: ouverture port impossible\n");
                        return (-1); 
                }
                /* envoi de la demande à l'API*/
                if ( comm_send_mbus(port_serie ,question, psize_q ) == -1 ) 
                {
                        fprintf(stderr,"SRV-APItongue sticking out smileyanique: erreur d'ecriture vers l'API\n");
                        comm_close(port_serie); 
                        return (-1);
                }
                /* lecture normale du port API */
                if ( comm_recv_mbus(port_serie ,reponse, psize_r ) <= 0 ) {
                        fprintf(stderr,"SRV-APItongue sticking out smileyanique: pas de reponse de l'API\n");
                        comm_close(port_serie); 
                        return (-1);
                }
                /* fermeture port et liberation verrou */
                comm_close(port_serie); 

Poste le Friday 4 March 2005 11:30:38
Répondre     Citer    
Re: communication par port serie
Envoyé par: HortY

et bé! rapide et tout !

Merci bien!! smiling smiley
C'est fort aimable de prendre un peu de votre temps pour répondre aussi vite et clairement! J'étudie votre source et je vais voir ce que je prendrais winking smiley
Lecture du port ne m'est pas utile.

Poste le Friday 4 March 2005 11:35:57
Répondre     Citer    
Re: communication par port serie
Envoyé par: HortY

oups pardon, VOS sourceS !!! winking smiley merci encore!

Poste le Friday 4 March 2005 11:37:27
Répondre     Citer    

Veuillez vous authentifier auparavant pour commenter.

 

Ce forum !
communication par port serie
Pour poser vos questions sur les scripts shell, le Perl, le C, etc... Attention : nous ne sommes pas des spécialistes du dev, ce forum est juste pour de petites aides ponctuelles concernant le développement et les outils de développement.

Sauf mention contraire, les documentations publiées sont sous licence Creative-Commons