IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Réseau C Discussion :

Probleme programme d'une Liaison RS232 Série en C


Sujet :

Réseau C

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 4
    Points : 2
    Points
    2
    Par défaut Probleme programme d'une Liaison RS232 Série en C
    Bonjour,

    J'ai un compte rendu de TP a rendre sur une liaison serie RS232 et je seche un peu. voici le sujet (en gros)
    - Écrire en langage C une fonction initialiser_interface() qui effectue l'initialisation de l'UART 8250, Rapidité de modulation : 9600 bauds.
    - Écrire une fonction qui envoie un caractère sur la liaison série.
    Répéter :
    interroger l'interface (lire LSR);
    Tant que pas prêt à émettre (bit 5 de LSR == 0);
    Envoyer l'octet (l'écrire dans THR).
    - Écrire une fonction qui attend l'arrivée d'un caractère, le lit et le retourne.
    Lorsque j'execute mon programme j'ai une permission refusée. le voici:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    void initialiser_interface(void)
    {
    	int LCR = 0x3FB; //initialisation adresse LCR
    	int DLM = 0x3F8; //initialisation adresse DLM
    	int DLL = 0x3F9; //initialisation adresse DLL
     
     
    	int erreur=ioperm(LCR,10,666);
    	if(erreur==-1) // test permission acces aux couches basses des systemes
    		{
    			printf("permission refusee\n");
     
    		}
    	outb(inb(LCR)|0x80,LCR); // force le DLAB a 1 pour programmer la vitesse avec un Masque
    	outb(0x00, DLM);	//programation vitesse 9600 bauds
    	outb(0x0C, DLL);
    }
     
    void envoi_octet(unsigned char car)
    {
    	int LSR = 0x3FD; //initialisation adresse LSR
    	int THR = 0x3F8; //initialisation adresse THR
    	int LCR = 0x3FB; //initialisation adresse LCR
     
    	int erreur=ioperm(LCR,10,666);
    	if(erreur==-1) // test permission acces aux couches basses des systemes
    		{
    			printf("permission refusee\n");
     
    		}
     
    	do
    	{
    		wait();				// Attendre 
    	}while((inb(LSR) & 0x20)==0);		// tant que le registre d 'emission est plein (test bit 5 si egale 0 ou1)
    	outb(inb(LCR) & 0x7F,THR);
    	outb(car,THR);	
    }
     
    unsigned char lecture(void)
    {
     
    	int LSR = 0x3FD; //initialisation adresse LSR
    	int RHR = 0x3F8; //initialisation adresse RHR
    	int LCR = 0x3FB; //initialisation adresse LCR
     
    	char car;
     
    	int erreur=ioperm(LCR,10,666);
    	if(erreur==-1) // test permission acces aux couches basses des systemes
    		{
    			printf("permission refusee\n");
     
    		}
    	do
    	{
    		wait();			//Attente d'un caractere 
    	}while((inb(LSR) & 0X01)==0);		// tant que bit de poids faible ==0 / pas de reception
     
    	outb(inb(LCR) & 0x7F,RHR);		//lecture registre RHR, insere valeur dans variable car
    	outb(car,RHR);
                 return(RHR);	
     
    }
    Pouvez vous m'aider, et me signaler des erreurs si vous vous en apercevez?
    Merci d'avance c'est urgent!

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Points : 50 367
    Points
    50 367
    Par défaut
    A quel endroit tu as un problème de permission (je voie 3 endroits où "permission refusée" s'affichent) ?

    Quelle est la valeur de errno en cas d'erreur ?
    ioperm renvoie 0 s'il réussit, ou -1 s'il échoue, auquel cas errno contient le code d'erreur.
    Je suppose que ton OS, c'est Linux car sinon, cela ne marche pas commùe cela.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Bonjour ram-0000 merci pour ton retour rapide

    Citation Envoyé par ram-0000 Voir le message
    A quel endroit tu as un problème de permission (je voie 3 endroits où "permission refusée" s'affichent) ?

    le problème de permission arrive dès l'initialisation.

    Quelle est la valeur de errno en cas d'erreur ?

    Je n'ai pas relever la valeur de errno car il fallait que j'ajoute la ligne de code "exit (errno)" a la fin des tests ioperm.je te fait un retour des que possible merci.

    Je suppose que ton OS, c'est Linux car sinon, cela ne marche pas commùe cela.

    Oui mon OS c'est Linux

  4. #4
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par dawud Voir le message
    Bonjour,

    J'ai un compte rendu de TP a rendre sur une liaison serie RS232 et je seche un peu. voici le sujet (en gros)
    - Écrire en langage C une fonction initialiser_interface() qui effectue l'initialisation de l'UART 8250, Rapidité de modulation : 9600 bauds.
    - Écrire une fonction qui envoie un caractère sur la liaison série.
    Répéter :
    interroger l'interface (lire LSR);
    Tant que pas prêt à émettre (bit 5 de LSR == 0);
    Envoyer l'octet (l'écrire dans THR).
    - Écrire une fonction qui attend l'arrivée d'un caractère, le lit et le retourne.
    Lorsque j'execute mon programme j'ai une permission refusée. le voici:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    void initialiser_interface(void)
    {
    	int LCR = 0x3FB; //initialisation adresse LCR
    	int DLM = 0x3F8; //initialisation adresse DLM
    	int DLL = 0x3F9; //initialisation adresse DLL
     
     
    	int erreur=ioperm(LCR,10,666);
    	if(erreur==-1) // test permission acces aux couches basses des systemes
    		{
    			printf("permission refusee\n");
     
    		}
    	outb(inb(LCR)|0x80,LCR); // force le DLAB a 1 pour programmer la vitesse avec un Masque
    	outb(0x00, DLM);	//programation vitesse 9600 bauds
    	outb(0x0C, DLL);
    }
    Pouvez vous m'aider, et me signaler des erreurs si vous vous en apercevez?
    Merci d'avance c'est urgent!
    Tu es certain que l'ordre des paramètres du outb() de Linux est (valeur, adresse I/O) ?
    Citation Envoyé par man
    outb() and friends are hardware specific. The value argument is passed first and the port argument is passed second, which is the opposite order from most DOS implementations.
    OK.

    Et j'ai pas vu quand tu remets le bit 7 de LCR à 0 ?

    Et tu n'as pas non plus autorisé l'accès aux registres DLL et DLM...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    void envoi_octet(unsigned char car)
    {
    	int LSR = 0x3FD; //initialisation adresse LSR
    	int THR = 0x3F8; //initialisation adresse THR
    	int LCR = 0x3FB; //initialisation adresse LCR
     
    	int erreur=ioperm(LCR,10,666);
    	if(erreur==-1) // test permission acces aux couches basses des systemes
    		{
    			printf("permission refusee\n");
     
    		}
     
    	do
    	{
    		wait();				// Attendre 
    	}while((inb(LSR) & 0x20)==0);		// tant que le registre d 'emission est plein (test bit 5 si egale 0 ou1)
    	outb(inb(LCR) & 0x7F,THR);
    	outb(car,THR);	
    }
    Idem, tu n'as pas autorisé l'accès à THR. Sinon, il est absurde de modifier le bit 7 de LCR maintenant. Son état normal est 0. On ne le met à 1 que lors de la modification du registre 16-bit de vitesse. (DL*). On le remet à 0 dès que cette opération est terminée.

    Ton code suppose que l'adresse I/O de base de l'UART est 3F8, ce qui n'est pas forcément vrai (c'est une donnée de configuration). Tu devrais séparer l'adresse de base de l'adresse des registres, au moins statiquement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    #define BASE 0x3F8
     
    #define DLL (base + 0)
    #define DLH (base + 1)
     
    #define TXD (base + 0)
    #define RXD (base + 0)
    #define IER (base + 1)
    #define IIR (base + 2)
    #define LCR (base + 3)
    #define LSR (base + 4)
    #define MCR (base + 5)
    #define MSR (base + 6)
    Pas de Wi-Fi à la maison : CPL

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2009
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 4
    Points : 2
    Points
    2
    Par défaut
    Bonjour Emmanuel et merci pour ta réponse.

    J'ai effectué des recherches de mon coté et j'avais deja fait des modifs avec #define, tu a donc m'a confirmé mes erreurs.

    Voici mon nouveau code pour l'envoi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
     
    #include <stdio.h>
    #include <sys/io.h>
    #include <errno.h>
     
    #define COM1 0X3F8 //adresse port COM1
     
    //adresses des registres (relatifs a l'adresse de base du port utilisé)
     
    #define PORT1 COM1
    #define THR PORT1
    #define RBR PORT1
    #define DLL PORT1
    #define DLM (PORT1+1) //adresse DLM 0x3F9
    #define LCR (PORT1+3) //adresse LCR 0x3FB
    #define LSR (PORT1+5) //adresse LSR 0x3FD
     
     
    void initialiser_interface(void);
    void envoi_octet(unsigned char car);
    unsigned char recoi_octet(void);
     
    void main(void) {
      char c;
      printf( "caractere a envoyer ?\n" );
      scanf( "%c", &c );
      initialiser_interface();
      envoi_octet( c );
    }
     
     
    void initialiser_interface(void)
    {
     
    	int erreur=ioperm(LCR,10,666);
    	if(erreur==-1) // test permission acces aux couches basses des systemes
    		{
    			printf("permission refusee\n");
    			exit(errno);
     
    		}
    	outb(inb(LCR)|0x80,LCR); // force le DLAB a 1 pour programmer la vitesse avec un Masque
    	outb(0x00, DLM);	//programation vitesse 9600 bauds
    	outb(0x0C, DLL);
    	outb(0x07,LCR); /programmation de la liaison DLAB = 0 Pas de parité 8 bits de données 2 bits de stop 
    }
     
     
     
    void envoi_octet(unsigned char car)
    {
     
    	int erreur=ioperm(LCR,10,666);
    	if(erreur==-1) // test permission acces aux couches basses des systemes
    		{
    			printf("permission refusee\n");
    			exit(errno);
     
    		}
     
    	do
    	{
    		wait();				// Attendre 
    	}while((inb(LSR) & 0x20)==0);		// tant que le registre d 'emission est plein (test bit 5 si egale 0 ou1)
    	outb(car,THR);	
    }
    Maintenant et celui pour la reception

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
     
    #include <stdio.h>
    #include <sys/io.h>
    #include <errno.h>
    #define COM1 0X3F8 //adresse port COM1
     
    //adresses des registres (relatifs a l'adresse de base du port utilisé)
     
    #define PORT1 COM1
    #define THR PORT1
    #define RBR PORT1
    #define DLL PORT1
    #define DLM (PORT1+1) //adresse DLM 0x3F9
    #define LCR (PORT1+3) //adresse LCR 0x3FB
    #define LSR (PORT1+5) //adresse LSR 0x3FD
     
     
    void initialiser_interface(void);
    void envoi_octet(unsigned char car);
    unsigned char recoi_octet(void);
     
    void main(void) {
       char c;
       initialiser_interface();
       printf( "Attente d'un caractere...\n" );
       c = recoi_octet();
       printf( "caractere recu = %c\n", c );
    }
     
     
    void initialiser_interface(void)
    {
     
    	int erreur=ioperm(LCR,10,666);
    	if(erreur==-1) // test permission acces aux couches basses des systemes
    		{
    			printf("permission refusee\n");
    			exit(errno);
     
    		}
    	outb(inb(LCR)|0x80,LCR); // force le DLAB a 1 pour programmer la vitesse avec un Masque
    	outb(0x00, DLM);	//programation vitesse 9600 bauds
    	outb(0x0C, DLL);
    	outb(0x07,LCR); /programmation de la liaison DLAB = 0 Pas de parité 8 bits de données 2 bits de stop 
    }
     
     
     
    void envoi_octet(unsigned char car)
    {
     
    	int erreur=ioperm(LCR,10,666);
    	if(erreur==-1) // test permission acces aux couches basses des systemes
    		{
    			printf("permission refusee\n");
    			exit(errno);
     
    		}
     
    	do
    	{
    		wait();				// Attendre 
    	}while((inb(LSR) & 0x20)==0);		// tant que le registre d 'emission est plein (test bit 5 si egale 0 ou1)
    	outb(car,THR);	// envoi caractere sur port
    }
     
     
     
    unsigned char recoi_octet(void)
    {
     
     
    	char car;
     
    	int erreur=ioperm(LCR,10,666);
    	if(erreur==-1) // test permission acces aux couches basses des systemes
    		{
    			printf("permission refusee\n");
                            exit(errno);
     
    		}
    	do
    	{
    		wait();			//Attente d'un caractere 
    	}while((inb(LSR) & 0x01)==0);		// tant que bit de poids faible ==0 / pas de reception
    	return(inb(RBR)); //retourne caractere
    }
    Sous Linux outb() est bien définit de cette facon.
    Je vais essayer de le tester dans une salle TP cette semaine. Que pense tu de mes modifications?

    Merci pour ton retour

Discussions similaires

  1. [WD17] remplacer une liaison RS232 par une liaison Bluetooth
    Par davcaz dans le forum WinDev
    Réponses: 0
    Dernier message: 16/12/2013, 17h57
  2. [Débutant] Recuperer une trame sur une liaison RS232 (CommPortDriver)
    Par coxycross dans le forum C++Builder
    Réponses: 3
    Dernier message: 23/05/2012, 13h02
  3. Recueillir les informations d'une liaison RS232
    Par tibo7 dans le forum LabVIEW
    Réponses: 6
    Dernier message: 21/09/2008, 12h25
  4. Réponses: 1
    Dernier message: 26/04/2007, 15h23
  5. Réponses: 2
    Dernier message: 20/06/2006, 17h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo