OVH Cloud OVH Cloud

Déblocage port série

17 réponses
Avatar
SLO
Bonjour,

J'ai réalisé un petit programme en C pour communiquer par le port série avec
un montage à micro-controleur.

Mon problème est que lors d'un démarrage de session XP, il faut que je lance
un logiciel communicant avec le port série (Hyperterminal) pour débloquer le
port série.
En effet, sinon mon programme n'arrive pas à communiquer avec mon montage.

Après avoir lancé Hyper terminal et ouvert une connexion avec le port Com1,
j'arrête Hyperterminal et la je peux lancer mon prog autant de fois que je
veux et tout marche bien.

Comment faire pour débloquer le port série par mon programme ?

Merci d'avance
--
Nicolas

7 réponses

1 2
Avatar
halfwolf
SLO wrote in message news:...
Merci et désolé pour la réponse tardive.
j'ai fait des modifications en tenant compte de ton dernier post, mais
ça ne marche toujours pas.
Cependant il faut que je regarde ça plus en détail ce week-end pour voir
si ça ne vient pas de mon code.



Tu as testé juste le code que je te propose ? Sans autre fonction ?
(créer un nouveau projet qu'avec un fichier et mettre le code).
C'est important car ça permet de s'assurer que le reste de ton code
n'interfère pas.

HalfWolf
Avatar
SLO
Bonjour,

Désolé pour le temps de réaction...

J'ai testé ton code et il marche très bien.
Si je lance ton programme, que je l'arrete puis que je lance mon programme
alors mon programme marche bien.

Ton programme débloque le port comme Hyperterminal.

Par contre je ne vois pas comment modifier mon code en conséquence, je ne
comprends pas bien la différence entre nos 2 programmes qui fait que l'un
marche et pas l'autre...

Un méthode "bourrin" serait de copier ton code au début de mon programme,
mais ce n'est pas très élégant ;-)
Pourrais-tu m'expliquer s'il te plait ?

Je joins mon listing complet.

D'autre part j'ai testé mon programme sur un PC sous Windows 98 SE et là
rien ne marche, même en lançant un terminal avant mon programme.
Il faudrait que mon programme fonctionne au moins sous Windows 98, et XP.
S'il pouvait fonctionner sur Windows 2000 et Millenium ce serait pas mal.

D'où peut venir ce nouveau problème ?
Je suis près à réécrire mon programme en utilisant d'autres bibliothèques,
éventuellement en C++ si nécessaire et si ça permet de ne pas compliquer
exagérément mon programme.

Merci d'avance.
--
Nicolas.

LISTING :
----------------------------------------------------------------------------
--------------------------------------------------------
// FICHIERS D'INCLUSION
//--------------------------------------------------------------------------
----
#include <windows.h>
#include <winbase.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>

// CONSTANTES
//--------------------------------------------------------------------------
-----
// Définition du code d'erreurs
typedef enum
{
e_ErrCom_None, // Pas d'erreur
e_ErrCom_Creation, // Erreur lors de la création du flux
e_ErrCom_Utilise, // Le port com est déjà utilisé
e_ErrCom_Inexistant, // Le port com n'existe pas
e_ErrCom_Timeout, // Timeout lors d'une émission-réception
e_ErrCom_Emission, // Erreur lors de l'émission
e_ErrCom_Reception, // Erreur lors de la réception
e_ErrCom_Definition_Trame, // Erreur de définition de la trame
e_ErrCom_Nack, // Demande non prise en coompte
e_ErrCom_Checksum // Erreur de checksum
} e_ErrCom;

// Nom du port série
#define PORT1 "COM1"
#define PORT2 "COM2"

// Définition des vitesses de communication
#define V1200 1200
#define V2400 2400
#define V4800 4800
#define V9600 9600

// Définition du nombre de bits
#define BITS_7 7
#define BITS_8 8

// Définition du nombre de bits de stop
#define BIT_DE_STOP_1 1
#define BIT_DE_STOP_2 2

// Définition de la parité
#define PAS_DE_PARITE 'N'
#define PARITE_IMPAIRE 'O'
#define PARITE_PAIRE 'E'

// Codes de retour génériques
#define OK 1
#define KO 0

// Longueur max réservée pour une trame
#define LG_TRAME 100

// PROTOTYPES
//--------------------------------------------------------------------------
--
e_ErrCom OuvreCom(char *strPort,long BaudRate,int BitsSize,int Parity,int
StopBits);
e_ErrCom EmissionCom(const void *lpBuf, unsigned int nCount);
e_ErrCom ReceptionCom(void *lpBuf, unsigned int nCountMax, unsigned int
*pCountRead);
void FermeCom();
void CharReadWrite(FILE *fichier, char *cCaractere, unsigned int nNbCaract);
void TensecReadWrite(char cNom_Fichier1[],char cNom_Fichier2[]);
void TensecConvWrite (FILE *fichier, unsigned int cOctet1, unsigned int
cOctet2, unsigned int cOctet3);

// VARIABLES GLOBALES
//--------------------------------------------------------------------------
---
DCB g_DCB; // structure dcb du port
e_ErrCom g_ErrCom= e_ErrCom_None; // Variable des erreurs de com
HANDLE g_hCom = 0; // handle de la com
unsigned int nCompteur=0, nCompteur_Total=0;
char cCaractere[10];
int i=0;
FILE *fichier1, *fichier2;
char cNom_Fichier1[]="tensec1.txt";
char cNom_Fichier2[]="tensec2.txt";
const float TENSION_MAX=5.02;
const float TEMPE_MAX=2.48;

void main (void)
{
//On ouvre le fichier
fichier1=fopen(cNom_Fichier1,"w");
fichier2=fopen(cNom_Fichier2,"w");

//Exemple de configuration du port serie :
g_ErrCom=OuvreCom(PORT1,V9600,BITS_8,PAS_DE_PARITE,BIT_DE_STOP_1);

//On emet "s" correspondant à 0x73 pour "Start"
g_ErrCom=EmissionCom("s",sizeof("s"));

//On lit la réponse du PIC
while ( (nCompteur_Total <= 8189) && (i < 4000) ){
g_ErrCom=ReceptionCom(cCaractere,9,&nCompteur);

if (nCompteur!=3){
//On emet "r" correspondant à 0x72 pour
"Recommencer"
g_ErrCom=EmissionCom("r",sizeof("r"));
}
else {
//On emet "s" correspondant à 0x73 pour
"Start"
g_ErrCom=EmissionCom("s",sizeof("s"));
nCompteur_Total = nCompteur_Total +
nCompteur;

CharReadWrite(fichier1,cCaractere,nCompteur);

TensecConvWrite(fichier2,cCaractere[0],cCaractere[1],cCaractere[2]);
}
//printf("caractere=%s compteur=%d i=%d
CompteurTotal=%dn",cCaractere,nCompteur,i,nCompteur_Total);
i++;
}

//On emet "s" correspondant à 0x73 pour "Start"
g_ErrCom=EmissionCom("s",sizeof("s"));

//On ferme le port
FermeCom();
//On ferme le fichier
fclose(fichier1);
fclose(fichier2);

//TensecReadWrite(cNom_Fichier1,cNom_Fichier2);

}


//--------------------------------------------------------------------------
----
// FONCTION : OuvreCom
//--------------------------------------------------------------------------
----
// DESCRIPTION :
// Initialise et ouvre un port série
//
//--------------------------------------------------------------------------
----
// PARAMETRES :
// - strPort Nom du port "COM1", "COM2"
// - BaudRate Vitesse
// - BitsSize Taille de l'info
// - Parity Parité
// - StopBits Nombre de bits de stop
//
// RETOUR :Code d'erreur
//--------------------------------------------------------------------------
----
e_ErrCom OuvreCom(char *strPort,long BaudRate,int BitsSize,int Parity,int
StopBits)
{
g_ErrCom = e_ErrCom_None;

// On ouvre le port série
g_hCom = CreateFile(strPort,GENERIC_READ |
GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_WRITE_THROUGH |
FILE_FLAG_NO_BUFFERING,NULL);

if(g_hCom == INVALID_HANDLE_VALUE)
{
// Echec
g_ErrCom=e_ErrCom_Creation;
}
else
{
// On vide les buffers

PurgeComm(g_hCom,PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);

// On paramètre le port série
g_DCB.DCBlength = sizeof(DCB);
//Configuration actuelle
GetCommState(g_hCom, &g_DCB);
//Modification du DCB
g_DCB.BaudRateºudRate;
g_DCB.ByteSize=BitsSize;
g_DCB.Parity=Parity;
g_DCB.StopBits=StopBits;
g_DCB.fDtrControl=DTR_CONTROL_DISABLE;
//Configuration de la liaison serie
SetCommState(g_hCom,&g_DCB);
}
return g_ErrCom;
}



//--------------------------------------------------------------------------
--
// FONCTION : EmissionCom
//--------------------------------------------------------------------------
--
// DESCRIPTION :
// Emission d'octets sur la liaison série
//
//--------------------------------------------------------------------------
--
// PARAMETRES :
// -lpBuf Pointeur sur les octets a emettre
// -nCount Nombre d'octet a emettre
//
//--------------------------------------------------------------------------
--
// RETOUR :Code d'erreur
//--------------------------------------------------------------------------
--
e_ErrCom EmissionCom(const void* lpBuf,unsigned int nCount)
{

DWORD NumBytes=0;

if(g_hCom!=NULL)
{
// On pari sur pas d'erreur
g_ErrCom=e_ErrCom_None;

//Emission du buffer
if(WriteFile(g_hCom,lpBuf,nCount,&NumBytes,NULL)==0)
{
g_ErrCom=e_ErrCom_Emission;
}
}
else
//Le port n'a pas été ouvert
g_ErrCom=e_ErrCom_Creation;

return g_ErrCom;

}

//--------------------------------------------------------------------------
-
// FONCTION : ReceptionCom
//--------------------------------------------------------------------------
-
// DESCRIPTION :
// Reception de caractères sur la liaison série
//
//--------------------------------------------------------------------------
-
// PARAMETRES :
// -lpBuf Pointeur sur le buffer de caractère a lire
// -nCountMax Nombre maxi de caractère a lire
// -pCountRead Pointeur sur le nombre de caractères lus
//--------------------------------------------------------------------------
-
// RETOUR :Code d'erreur
//--------------------------------------------------------------------------
-
e_ErrCom ReceptionCom(void *lpBuf,unsigned int nCountMax, unsigned int*
pCountRead)
{
COMSTAT Stat;
DWORD Errors;
unsigned int nCarALire;
unsigned long NCarLus=0;

if(g_hCom!=NULL)
{
//on pari sur pas d'erreur
g_ErrCom=e_ErrCom_None;

//Pour éviter de gérer un time out Sleep(7)
Sleep(7);

//Pour connaitre le nombre d'octets dans le buffer d'entrée
ClearCommError(g_hCom,&Errors,&Stat);
nCarALire=Stat.cbInQue;

//On effectue la lecture si il y a des caractères présents
if( (nCarALire>0)&&(nCarALire<=nCountMax) )
{
if(ReadFile(g_hCom,lpBuf,nCarALire,&NCarLus,NULL)==0)
{
g_ErrCom=e_ErrCom_Reception;
}

}
*pCountRead=NCarLus;
}
else
//Le port n a pas été ouvert
g_ErrCom=e_ErrCom_Creation;

//Compte rendu de l'exécution
return g_ErrCom;

}

//-----------------------------------------------------------------------
// FONCTION : FermeCom
//-----------------------------------------------------------------------
// DESCRIPTION :
// Ferme le port série préalablement ouvert avec OuvreCom
//
//-----------------------------------------------------------------------
// PARAMETRES :
// Néant
//-----------------------------------------------------------------------
// RETOUR :Néant
//-----------------------------------------------------------------------
void FermeCom()
{
if(g_hCom!=NULL)
{
CloseHandle(g_hCom);
}
}

//--------------------------------------------------------------------------
--
// FONCTION : CharReadWrite
//--------------------------------------------------------------------------
--
// DESCRIPTION :
// Ajoute un caractère à un fichier texte
//
//--------------------------------------------------------------------------
--
// PARAMETRES :
// -fichier Fichier dans lequel on écrit
// -cCaractere Caractère à écrire
// -nNbCaract nb de caractères à écrire d'un coup
//
//--------------------------------------------------------------------------
--
// RETOUR :
//--------------------------------------------------------------------------
--
void CharReadWrite(FILE *fichier, char *cCaractere, unsigned int nNbCaract)
{
int i;

for (i=0 ; i<nNbCaract ; i++){
fputc( (int)cCaractere[i] , fichier );
}
}
//--------------------------------------------------------------------------
--
// FONCTION : TensecReadWrite
//--------------------------------------------------------------------------
--
// DESCRIPTION :
// Ajoute les valeurs dans un fichier texte
//
//--------------------------------------------------------------------------
--
// PARAMETRES :
// -fichier : Fichier dans lequel on écrit
// -cOctet1 : premier octet
// -cOctet2 : 2eme octet
// -cOctet3 : 3eme octet
//
//--------------------------------------------------------------------------
--
// RETOUR :
//--------------------------------------------------------------------------
--
void TensecReadWrite(char cNom_Fichier1[],char cNom_Fichier2[])
{
FILE *fichier1, *fichier2;
int nOctet1, nOctet2, nOctet2bk, nOctet3, nTension, nTempe, i, car1,
car2, car3;

fichier1=fopen(cNom_Fichier1,"r");
fichier2=fopen(cNom_Fichier2,"w");

for ( i=0 ; i<'29 ; i++){

nOctet1 = fgetc(fichier1);
nOctet2 = fgetc(fichier1);
nOctet3 = fgetc(fichier1);

car1=nOctet1;
car2=nOctet2;
car3=nOctet3;

nOctet2bk = nOctet2 & 3;
nOctet2 = nOctet2 & 192;
nOctet1 = nOctet1 << 2;
nOctet2 = nOctet2 >> 6;
nOctet2bk = nOctet2bk << 8;

nTension = nOctet1 + nOctet2;
nTension = nTension & 1023;
nTempe = nOctet2bk + nOctet3;
nTempe = nTempe & 1023;

printf("Tension = %d Temperature = %d nnOctet1 = %d nOctet2 = %d
nOctet2bk = %d nOctet3 = %dnn",nTension, nTempe, nOctet1, nOctet2,
nOctet2bk, nOctet3);
fprintf(fichier2,"car1=%d car2=%d car3=%dnTension = %d Temperature
= %d nnOctet1 = %d nOctet2 = %d nOctet2bk = %d nOctet3 %dnn",car1,car2,car3,nTension, nTempe, nOctet1, nOctet2, nOctet2bk,
nOctet3);

}

fclose(fichier1);
fclose(fichier2);

}
//--------------------------------------------------------------------------
--
// FONCTION : TensecConvWrite
//--------------------------------------------------------------------------
--
// DESCRIPTION :
// Lit 3 octets, en déduit Tension et Température et les écrit dans un
fichier
//
//--------------------------------------------------------------------------
--
// PARAMETRES :
// -fichier : Fichier dans lequel on écrit
// -cOctet1 : premier octet
// -cOctet2 : 2eme octet
// -cOctet3 : 3eme octet
//
//--------------------------------------------------------------------------
--
// RETOUR :
//--------------------------------------------------------------------------
--
void TensecConvWrite (FILE *fichier, unsigned int nOctet1, unsigned int
nOctet2, unsigned int nOctet3)
{
unsigned int nOctet2bk, nTension, nTempe;
float dTension, dTempe;

nOctet2bk = nOctet2 & 3;
nOctet2 = nOctet2 & 192;
nOctet1 = nOctet1 << 2;
nOctet2 = nOctet2 >> 6;
nOctet2bk = nOctet2bk << 8;

nTension = nOctet1 + nOctet2;
nTension = nTension & 1023;
nTempe = nOctet2bk + nOctet3;
nTempe = nTempe & 1023;

dTension = (TENSION_MAX/1024.)*nTension;
dTempe = ((TEMPE_MAX/1024.)*nTempe - 1.235) * 100;

//printf("Tension = %d Temperature = %d nnOctet1 = %d nOctet2 = %d
nOctet2bk = %d nOctet3 = %dnn",nTension, nTempe, nOctet1, nOctet2,
nOctet2bk, nOctet3);
//fprintf(fichier,"car1=%d car2=%d car3=%dnTension = %d
Temperature = %d nnOctet1 = %d nOctet2 = %d nOctet2bk = %d nOctet3 %dnn",car1,car2,car3,nTension, nTempe, nOctet1, nOctet2, nOctet2bk,
nOctet3);
fprintf(fichier,"Tension = %f V Température = %f °Cn",dTension,
dTempe);
}

----------------------------------------------------------------------------
-------------------------------------------
Fin du listing


"HalfWolf" a écrit dans le message de news:

Tu as testé juste le code que je te propose ? Sans autre fonction ?
(créer un nouveau projet qu'avec un fichier et mettre le code).
C'est important car ça permet de s'assurer que le reste de ton code
n'interfère pas.

HalfWolf


Avatar
halfwolf
Ok, je vais te dire comment marche (pas) le programme pour l'instant :
- on ouvre COM1
- on envoie 2 caractères au PIC : 0x73 ('s') et 0x00
- on va essayer 4000 fois de lire le COM1 et on va stocker dans la
limite de 8189 octets les valeurs lues dans un fichier.
- on envoie 2 caractères au PIC : 0x73 ('s') et 0x00

Pour lire dans le COM1 :
- on attend 7 ms (on essaie, car avec un Sleep, ça va dépendre de
l'OS)
- on regarde le nombre de caractères reçus pendant ce temps
- si on n'a rien ou trop, on ne lit pas les caractères
- sinon on lit les caractères reçus pendant ce temps
- si on a exactement 3 caractères on les écrits dans un fichier
et on envoie 2 caractères au PIC : 0x73 ('s') et 0x00
- si on n'a pas exactement 3 caractères on envoie 2 caractères
au PIC : 0x72 ('r') et 0x00


Plusieurs choses me choquent dans ce code :
- L'envoi des 2 caractères me paraît suspect je pense que le but et de
n'en envoyer qu'un ('s' ou 'r') et que le codeur n'a pas compris
qu'une chaîne avait toujours un 0 terminal à sa fin. L'utilisation de
sizeof tient compte de la taille de la chaîne O terminal compris,
alors que strlen retourne le nombre de caractères avant d'atteindre un
0 terminal : sizeof("s") = 2, strlen("s") = 1.
- La boucle d'attente avec un Sleep de 7 ms : un Sleep ne peut pas
valoir moins du tick de l'OS : avec une valeur aussi faible on peut
avoir un effet de bord entre 9x et NT (ou XP).
- Comme est fait le code, si on ne reçoit rien, on réémet toutes les 7
ms, ça me paraît un peu rapide. Cette gestion peut en plus être faite
à l'aide de la gestion des timeouts sur le port.
- Les timeouts sur le port ne sont pas initialisés (problème que tu
avais avec l'hyperterminal)
- Des variables globales qui n'aident pas à la compréhension du code
(point de vue personnel)

Ce que je propose :
- Envoyer un seul caractère ('s' ou 'r'), je me trompe peut être : je
ne connaîs pas le protocole du PIC.
- Virer la gestion avec le Sleep et utiliser les timeouts : on devrait
avoir un code portable sur les différents OS sans effet de bord.
- Lorsqu'on reçoit un caractère on retourne si on n'en a pas reçu
d'autre dans les 10 ms (fonctionnement proche du précédent).
- Si on ne reçoit pas de caractère on retourne après 100 ms (au lieu
de 7 ms) pour éviter de matraquer le PIC.

J'ai modifié les fonctions :
- OuvreCom
- ReceptionCom
- main

Fais un essai en remplaçant le code des anciennes fonctions avec le
mien et tiens moi au courant.

voici ces nouvelles fonctions :

e_ErrCom OuvreCom(char *strPort,long BaudRate,int BitsSize,int
Parity,int StopBits)
{
COMMTIMEOUTS timeouts;

g_ErrCom = e_ErrCom_None;

// On ouvre le port série
g_hCom = CreateFile(
strPort,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING,
NULL);
if( g_hCom == INVALID_HANDLE_VALUE )
{
// Echec
g_ErrCom = e_ErrCom_Creation;
}
else
{
// On vide les buffers
PurgeComm(
g_hCom,
PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR |
PURGE_RXCLEAR);

// On paramètre le port série
g_DCB.DCBlength = sizeof(DCB);

// Modification du DCB
GetCommState(g_hCom, &g_DCB);

g_DCB.BaudRate = BaudRate;
g_DCB.ByteSize = BitsSize;
g_DCB.Parity = Parity;
g_DCB.StopBits = StopBits;
g_DCB.fDtrControl = DTR_CONTROL_DISABLE;

SetCommState(g_hCom, &g_DCB);

// Modification des timeouts :
// - on attend toujours la fin de l'émission.
// - la fin de la réception est provoquée après avoir attendu
// plus de 10 ms après le dernier caractère reçu. Si on n'a
// rien reçu après 100 ms on sort.
GetCommTimeouts(g_hCom, &timeouts);

timeouts.ReadIntervalTimeout = 10;
timeouts.ReadTotalTimeoutConstant = 100;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 0;
timeouts.WriteTotalTimeoutMultiplier = 0;

SetCommTimeouts(g_hCom, &timeouts);
}

return g_ErrCom;
}

e_ErrCom ReceptionCom(void *lpBuf,unsigned int nCountMax, unsigned
int* pCountRead)
{
DWORD NCarLus;

NCarLus = 0;

if( g_hCom != NULL )
{
//on pari sur pas d'erreur
g_ErrCom=e_ErrCom_None;

// on lit le port
if( ReadFile(g_hCom, lpBuf, nCountMax, &NCarLus, NULL) == 0 )
{
g_ErrCom = e_ErrCom_Reception;
}
}
else
{
//Le port n a pas été ouvert
g_ErrCom = e_ErrCom_Creation;
}

*pCountRead = NCarLus;

//Compte rendu de l'exécution
return g_ErrCom;
}

void main (void)
{
CHAR cCarAEnvoyer;

//On ouvre le fichier
fichier1 = fopen(cNom_Fichier1, "w");
fichier2 = fopen(cNom_Fichier2, "w");

//Exemple de configuration du port serie :
g_ErrCom = OuvreCom(
PORT1,
V9600,
BITS_8,
PAS_DE_PARITE,
BIT_DE_STOP_1);

//On emet "s" correspondant à 0x73 pour "Start"
cCarAEnvoyer = 's';
// On emet le caractère vers le PIC
g_ErrCom = EmissionCom(cCarAEnvoyer, sizeof(cCarAEnvoyer));

//On lit la réponse du PIC
for( i = 0; (nCompteur_Total <= 8189) && (i < 4000); i++ )
{
g_ErrCom = ReceptionCom(cCaractere, sizeof(cCaractere),
&nCompteur);

if( nCompteur == 3 )
{
nCompteur_Total = nCompteur_Total + nCompteur;

CharReadWrite(fichier1, cCaractere, nCompteur);

TensecConvWrite(
fichier2,
cCaractere[0],
cCaractere[1],
cCaractere[2]);

//On emet 's' correspondant à 0x73 pour "Start"
cCarAEnvoyer = 's';
}
else
{
//On emet 'r' correspondant à 0x72 pour "Recommencer"
cCarAEnvoyer = 'r';
}

// On emet le caractère vers le PIC
g_ErrCom = EmissionCom(cCarAEnvoyer, sizeof(cCarAEnvoyer));

//printf("caractere=%s compteur=%d i=%d
CompteurTotal=%dn",cCaractere,nCompteur,i,nCompteur_Total);
}

//On emet "s" correspondant à 0x73 pour "Start"
cCarAEnvoyer = 's';
// On emet le caractère vers le PIC
g_ErrCom = EmissionCom(cCarAEnvoyer, sizeof(cCarAEnvoyer));

//On ferme le port
FermeCom();

//On ferme le fichier
fclose(fichier1);
fclose(fichier2);

//TensecReadWrite(cNom_Fichier1,cNom_Fichier2);
}
Avatar
SLO
Bonjour,

Tout d'abord merci beaucoup pour ton aide.
J'ai testé ton code et malheureusement le problème est toujours le même :

Ca ne marche que si je lance ton programme précédent ou bien hyperterminal
avant.

Suite à une erreur de compilation j'ai dû passer cCarAEnvoyer par adresse
dans chaque appelle de la fonction Emmission (j'ai passé &cCarAEnvoyer au
lieu de cCarAEnvoyer).

Mon montage reçoit bien le charactère 's' du PC, mais le problème est quand
le PC doit recevoir des octets du montage.

Je t'explique comment marche le montage :

-1. Le montage attend la réception d'un caractère (pas grave s'il y en a
plusieurs car il ne lit que le premier).
-2. Si c'est un 's' il envoie 3 octets vers le PC, sinon il attend de
nouveau la transmission d'un caractère jusqu'à recevoir un 's'
-3. Ensuite le montage attend de recevoir un caractère d'acquittement du PC
: si c'est un 's' le PC a bien reçu 3 octets et demande les 3 suivants
si ce n'est pas un 's', le PC redemande les mêmes octets
-4. le montage envoie 3 octets (les 3 précédents ou 3 nouveaux suivant
l'acquittement)
-5. on boucle au point 3. et quand le montage a envoyé ses 8192 octets il
arrête

Donc je pense que le PC ne reçoit jamais les 3 premiers octets.

Mais je ne comprends pas pourquoi ça marche après avoir lancé ton programme
et pas avant puisqu'à présent on initialise les timeouts.
Que fait ton programme précédent que ne fait pas celui que tu viens de
poster ?

Merci d'avance.

--
Nicolas
Avatar
halfwolf
"SLO" wrote in message news:<3fb90654$0$27048$...
Ca ne marche que si je lance ton programme précédent ou bien hyperterminal
avant.



Ca y est j'ai trouvé le problème : voir plus bas.

Suite à une erreur de compilation j'ai dû passer cCarAEnvoyer par adresse
dans chaque appelle de la fonction Emmission (j'ai passé &cCarAEnvoyer au
lieu de cCarAEnvoyer).



Oui mea culpa, il faut effectivement mettre &cCarAEnvoyer.

Mon montage reçoit bien le charactère 's' du PC, mais le problème est quand
le PC doit recevoir des octets du montage.



Non, voir plus bas ;)

Je t'explique comment marche le montage :



Compris.


Donc je te disais, j'ai trouvé le problème.
Je l'ai trouvé grace à un utilitaire gratuit bien sympa qui permet
d'espionner les ports alors qu'ils sont en cours d'utilisation :
PORTMON, à télécharger sur http://www.sysinternals.com .

Le problème est que le SetCommState dans OuvreCom retourne une erreur
: la configuration n'est donc pas changée. Sur mon PC sous 2000, le
port était ouvert à 1200 bauds au lieu de 9600. Le montage ne reçoit
donc pas le caractère 's', mais des caractères parasites.
Lorsqu'on a ouvert l'hyperterminal avant, le port a déjà été
initialisé aux paramètres qui nous intéressent et donc le programme
marche correctement.

Pourquoi SetCommState retourne-t'il une erreur ?
Le problème n'est pas dans OuvreCom, car le programme de test que
j'avais posté marche et pas le tien.
Dans ton programme, OuvreCom est appelé de la façon suivante :

OuvreCom(PORT1, V9600, BITS_8, PAS_DE_PARITE, BIT_DE_STOP_1);

et dans le mien de la façon suivante :

OuvreCom("COM5", 19200, 8, NOPARITY, ONESTOPBIT);

Or plus haut dans ton fichier on a :

#define PAS_DE_PARITE 'N'

et la constante windows NOPARITY ne vaut pas 'N' (mais 0), d'où
l'erreur dans SetCommState.

De plus on a aussi dans ton fichier :

#define BIT_DE_STOP_1 1

alors que la constante windows ONESTOPBIT vaut 0.

Pour résoudre le problème, il suffit donc de remplacer :

// Définition du nombre de bits de stop
#define BIT_DE_STOP_1 1
#define BIT_DE_STOP_2 2

// Définition de la parité
#define PAS_DE_PARITE 'N'
#define PARITE_IMPAIRE 'O'
#define PARITE_PAIRE 'E'

par

// Définition du nombre de bits de stop
#define BIT_DE_STOP_1 ONESTOPBIT
#define BIT_DE_STOP_2 TWOSTOPBITS

// Définition de la parité
#define PAS_DE_PARITE NOPARITY
#define PARITE_IMPAIRE ODDPARITY
#define PARITE_PAIRE EVENPARITY

et là chez moi tout marche bien :)

Moralité : ce sont souvent les bugs les plus cons qui sont les plus
durs à trouver.

HalfWolf (tout content)
Avatar
SLO
Bonjour,

Tout d'abord un grand merci !
J'ai testé la modif avec mon montage et ça marche impeccable !

Pour ton simulateur, ça a l'air très bien,mais je ne comprends pas bien
comment l'utiliser...
J'espère que ça ne t'a pas demandé trop de travail.
J'ai ouvert le projet et je l'ai compilé.
J'obtient un fichier PIC.exe et lorsque je le lance j'obtiens une erreur
"impossible d'ouvrir COM5".

D'autre part merci pour le lien, je vais tester ce logiciel.

Il me reste à tester la modif sous Win98, mais avant il faut que je créé une
partition pour l'installer sur ce PC...

Encore merci, j'espère pouvoir te rendre la pareille à l'occasion ;-)

--
Nicolas
Avatar
SLO
J'ai testé le programme sous Win 98 et ça marche impeccable aussi !
Ca devait bien venir de l'absence de gestion des timeouts...

Encore merci !

--
Nicolas.
1 2