我遇到串口连接时最不寻常的问题。
我正在尝试从rs-232设备解析一些数据,但如果我用我的程序打开串口,数据总是会出现乱码。
我发送了一个示例,当我嗅探程序打开的连接时,我看到了什么:
我在Realterm打开连接时看到的内容:
我在两种情况下都使用完全相同的配置打开串行连接:baud = 9600,8个数据位,无奇偶校验,1个停止位。所有相同的,并由嗅探器认证。
我已经关注了有关串行连接的MSDN文章,确定了重叠连接,查找了串行事件以及所有...我在这里发布了我使用的代码:
#include <windows.h>
#include <stdio.h>
#include "serial.h"
Serconfig serconfig;
int seropen()
{
serconfig.hserial = CreateFile( serconfig.port,
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0); //abre
if (serconfig.hserial == INVALID_HANDLE_VALUE) //se der erro, sai fora
{
printf("erro ao abrir %s\r\n", serconfig.port);
return -1;
}
FillMemory(&(serconfig.dcbSerialParams), sizeof(DCB), 0);
serconfig.dcbSerialParams.DCBlength = sizeof(DCB);
/*
if (!BuildCommDCB(serconfig.dcbstring, &(serconfig.dcbSerialParams))) {
printf("%s não está pronta\r\n", serconfig.port);
serclose();
return -1;
}
*/
if( !GetCommState(serconfig.hserial, &(serconfig.dcbSerialParams)) ) // Obtém a configuração atual da Porta Serial.
return false; // Erro na leitura de DCB.
//Define novos parâmetros
serconfig.dcbSerialParams.BaudRate = CBR_9600;
serconfig.dcbSerialParams.ByteSize = 8;
serconfig.dcbSerialParams.Parity = NOPARITY;
serconfig.dcbSerialParams.StopBits = ONESTOPBIT;
if (!SetCommState(serconfig.hserial, &serconfig.dcbSerialParams))
{
int error = GetLastError();
printf("configuração de %s invalida. Erro %d\r\n", serconfig.port, error);
serclose();
return -1;
}
/*
COMMTIMEOUTS timeouts;
timeouts.ReadIntervalTimeout = 20;
timeouts.ReadTotalTimeoutMultiplier = 10;
timeouts.ReadTotalTimeoutConstant = 100;
timeouts.WriteTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 100;
if (!SetCommTimeouts(serconfig.hserial, &timeouts)){
printf("erro ao configurar os timeouts de %s", serconfig.port);
return -1;
}
*/
serconfig.osReader = {0};
PurgeComm(serconfig.hserial, PURGE_RXCLEAR|PURGE_RXABORT);
printf("%s aberta e configurada\r\n", serconfig.port);
return 0;
}
int serclose()
{
CloseHandle(serconfig.hserial); // se der erro,sai fora
CloseHandle(serconfig.osReader.hEvent); // se der erro,sai fora
}
void serread(char * buffer, long long unsigned int * result, int read) // fiz deste jeito para ter compatibilidade com a macro SERIAL_INPUT
{
DWORD dwRead;
// Create the overlapped event. Must be closed before exiting
// to avoid a handle leak.
if (!serconfig.fWaitingOnRead)
{
serconfig.osReader.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (serconfig.osReader.hEvent == NULL)
{
printf("erro criando evento\r\n");
CloseHandle(serconfig.osReader.hEvent); // se der erro,sai fora
*result = 0;
return;
// Error creating overlapped event; abort.
}
// Issue read operation.
//printf("tentando ler %d bytes\r\n", read);
if (!ReadFile(serconfig.hserial, buffer, read, &dwRead, &serconfig.osReader))
{
if (GetLastError() != ERROR_IO_PENDING) // read not delayed?
{
printf("erro de comunicação\r\n");
CloseHandle(serconfig.osReader.hEvent); // se der erro,sai fora
*result = 0 ;
}
else
{
//printf("leitura incompleta\r\n", dwRead);
serconfig.fWaitingOnRead = TRUE;
*result = 0 ;
return;
}
}
else
{ //printf("lidos %d bytes\r\n", dwRead);
// read completed immediately
//HandleASuccessfulRead(lpBuf, dwRead);
//PurgeComm(serconfig.hserial, PURGE_RXCLEAR|PURGE_RXABORT);
*result = dwRead;
serconfig.lastread = dwRead;
CloseHandle(serconfig.osReader.hEvent);
PurgeComm(serconfig.hserial, PURGE_RXCLEAR|PURGE_RXABORT);
return;
}
}
if (serconfig.fWaitingOnRead) {
//printf("aguardando evento\r\n");
DWORD dwRes = WaitForSingleObject(serconfig.osReader.hEvent, READ_TIMEOUT);
switch(dwRes)
{
// Read completed.
//printf("leitura completa ");
case WAIT_OBJECT_0:
if (!GetOverlappedResult(serconfig.hserial, &serconfig.osReader, &dwRead, FALSE))
{
// Error in communications; report it.
CloseHandle(serconfig.osReader.hEvent); // se der erro,sai fora
printf("erro de comunicação\r\n");
serconfig.fWaitingOnRead = FALSE;
*result = 0;
}
else
// Read completed successfully.
//HandleASuccessfulRead(lpBuf, dwRead);
*result = dwRead;
serconfig.fWaitingOnRead = FALSE;
serconfig.lastread = dwRead;
//printf("lidos %d bytes\r\n", dwRead);
CloseHandle(serconfig.osReader.hEvent);
PurgeComm(serconfig.hserial, PURGE_RXCLEAR|PURGE_RXABORT);
return;
// Reset flag so that another opertion can be issued.
break;
case WAIT_TIMEOUT:
//printf("timeout\r\n");
// Operation isn't complete yet. fWaitingOnRead flag isn't
// changed since I'll loop back around, and I don't want
// to issue another read until the first one finishes.
//
// This is a good time to do some background work.
*result = 0;
break;
default:
// Error in the WaitForSingleObject; abort.
// This indicates a problem with the OVERLAPPED structure's
// event handle.
*result = 0;
serconfig.fWaitingOnRead = FALSE;
printf("erro na comunicação\r\n");
break;
}
}
}