Comment puis-je envoyer des caractères nuls au port série en utilisant l'API Windows?

StackOverflow https://stackoverflow.com/questions/387322

  •  23-08-2019
  •  | 
  •  

Question

Je travaille sur un programme utilitaire Windows qui communique avec un peu de matériel personnalisé à l'aide d'un port COM standard. Le protocole de communication (qui est hors de mon contrôle) me demande de transmettre et recevoir des données brutes 8 bits octets.

Je suis actuellement en utilisant la fonction API Windows suivante pour envoyer des données au port COM:

WriteFile(hFile, lpBuffer, numberOfBytesToWrite, ...)

hFile est une référence au port COM correctement ouvert, et lpBuffer est un tableau d'octets que j'ai en mémoire. Le code fonctionne parfaitement jusqu'à ce qu'un caractère nul (ASCII zéro) doit être envoyé à l'appareil. WriteFile cesse d'envoyer dès qu'il détecte le caractère nul car il suppose que celui-ci atteint la fin de la chaîne. Cela se produit même si je mets numberOfBytesToWrite correctement.

Comment puis-je envoyer des données brutes au port COM en utilisant l'API Windows? Je préfère utiliser un appel API standard semblable à WriteFile, mais je suis ouvert aux suggestions.

Je suis actuellement en utilisant RapidQ pour construire l'utilitaire, mais tout ce qu'il fait est d'appeler la fonction API Windows directement.

Modifier: Ma configuration se compose d'un PC Windows connecté via le port série du module matériel personnalisé. Le module dispose d'un petit écran sur lequel je suis en mesure d'afficher les caractères transmis. Je l'ai testé cette configuration avec un autre programme utilitaire tiers. Je suis en mesure de communiquer avec le module en utilisant ce programme tiers, et les caractères NULL sont affichées correctement. Dans mon propre programme, quand je l'utilise WriteFile, un caractère nul partout dans le flux d'émission arrête les restes du flux d'être envoyé.

Était-ce utile?

La solution

Je l'ai fait la programmation du port série Windows avant, et je suis sûr que je suis en mesure d'envoyer des caractères nuls à travers les ports série (différents protocoles de transfert de fichiers n'aurait pas fonctionné autrement). Je peux penser à deux explications possibles:

  1. recevoir appareil imprime les données qu'elle a reçu en utilisant une méthode qui arrête au niveau du premier caractère nul. Comment déterminez-vous que le dispositif de transmission se termine au premier nul? Le problème pourrait être quelque part plus loin sur la ligne?
  2. Le pilote série est cassé. Ce qui est assez peu probable, mais il est une explication possible. Si vous utilisez un tiers propriétaire dodgy partie port série et ses pilotes, ils pourraient être suspects. Si vous utilisez un standard intégré port série avec les pilotes Windows normal, cela est probablement pas un problème.

Je viens d'avoir un coup d'œil à RapidQ et il y a une troisième explication possible:

  1. Le marshaling que RapidQ peut faire dans le processus d'appel de fonctions API Win32 peut avoir des problèmes avec des caractères nuls incorporés dans les données à envoyer. Je ne sais pas quoi que ce soit au sujet RapidQ, mais est encore un autre maillon de la chaîne qui doit être pris en considération.

Autres conseils

Greg est probablement correct, mais je également vérifier vos paramètres de port COM. Assurez-vous que vos paramètres DCB sont correctement réglés. Consulter SetCommState et GetCommState pour information.

Normalement, série est 8N1, mais votre appareil est peut-être en utilisant une autre parité, ou arrêter la configuration de bits, etc.

Comme Greg, je l'ai fait beaucoup de travail sur moi-même série, et cela peut souvent être la source de problèmes ... Essayez de parler avec RS485 et une structure incorrecte DCB ... heh ..

Larry

PS: Si vous ne possédez pas déjà un, je vous recommande vous faire une bonne série boîte de break-out. J'ai une part autour de la maison, et il vous montrera ce que tous les signaux sont, sur toutes les lignes pendant toutes vos communications, et est un outil de débogage très puissant.

Je l'ai utilisé WriteFile dans le passé et il a bien fonctionné avec des octets nuls. Je fouille dans RapidQ, il pourrait être le problème.

Si rien de tout cela aide, vous pouvez toujours faire ce que je fais. Utilisez le code COMM de Greg pour tester l'appareil avec. Rappelez-vous Qmodem? :) Très bel outil pour le test / débogage des routines de série. Vous ccould même utiliser Qmodem et un simple script Qmodem pour lire le port COM sur une autre boîte (ou un autre port dans la même boîte), et imprimer la valeur hexadécimale de chaque CHAR envoyé. Oh, attendez. Qmodem a que construit. :) Utilisez l'émulation ASCII de débogage et affiche les valeurs hexagonales de chaque omble chevalier qui vient à travers le port série. Ensuite, vous pourriez au moins vérifier si votre code fonctionne correctement ou non.

Maintenant, la question. Est-ce que WriteFile retour quand il frappe la valeur NULL, ou faut-il rester assis et attendre, et ne jamais revenir?

Si elle ne retourne jamais, il peut ne pas être votre code. WriteFile retourne seulement quand il a envoyé tous dwBytesToWrite, ou s'il y a une erreur. Tout le reste, et il est en train d'écrire, mais il y a un échec à l'autre bout.

Pour envoyer un caractère NULL par série, vous pouvez utiliser la fonction SetEndOfFile (), donnant le gestionnaire du port en tant que fichier.

Si vous avez trop de données NULL pour l'envoyer est probablement pas idéal, mais il est une solution de contournement.

Fonction Détails

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top