我一直在尝试通过 RS232 串行端口与我的设备进行通信(在我的例子中是 COM6)。我的代码应该将一串 ASCII 值写入设备,然后读取响应,但是我似乎无法得到任何响应。当我让它写入和读取计算机中的文件时,该程序似乎工作得相对良好,但当我指定 COM6 时则不然。这是我的代码的最新版本:
using namespace std;
const char ASCII[ ]= "0123456789ABCDEF";
char *Checksum (char *buffer)
{
static char Hex[10];
static int a1, a2;
register unsigned int i;
int sum;
printf("%s \n", buffer);
sum = 256;
for ( i=0 ; i<strlen(buffer) ; i++ )
{
sum-=buffer[i];
if ( sum<0 )
sum+= 256;
}
a1 = (sum & 0xF0) >> 4;
a2 = sum & 0x0F;
Hex[0] = ASCII[a1];
Hex[1] = ASCII[a2];
Hex[2] = 0;
printf("the checksum is %s \n",Hex);
return(Hex);
}
int main()
{
char data[80], input[80], *data2;
char *response;
DCB dcb;
bool retVal;
DWORD dwBytesTransferred;
DWORD byteswritten;
printf("the variable response is initially: %d\n", response);
dcb.BaudRate = CBR_19200; //19200 Baud
dcb.ByteSize = 8; //8 data bits
dcb.Parity = NOPARITY; //no parity
dcb.StopBits = ONESTOPBIT; //1 stop
//New open port area
HANDLE hPort;
if ((hPort = CreateFile ( "\\\\.\\COM6",
GENERIC_READ | GENERIC_WRITE,
0, // exclusive access
NULL, // no security attrs
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL)) != INVALID_HANDLE_VALUE)
{
printf("SUCCESS opening the port\n");// success
}
//GetCommState
DCB Dcb;
GetCommState (hPort, &Dcb);
Dcb.BaudRate = CBR_19200;
Dcb.StopBits = ONESTOPBIT;
Dcb.ByteSize = 8;
Dcb.Parity = NOPARITY;
Dcb.fParity = 0;
Dcb.fOutxCtsFlow = 0;
Dcb.fOutxDsrFlow = 0;
Dcb.fDsrSensitivity = 0;
Dcb.fTXContinueOnXoff = TRUE;
Dcb.fOutX = 0;
Dcb.fInX = 0;
Dcb.fNull = 0;
Dcb.fErrorChar = 0;
Dcb.fAbortOnError = 0;
Dcb.fRtsControl = RTS_CONTROL_DISABLE;
Dcb.fDtrControl = DTR_CONTROL_DISABLE;
//Flushing
FlushFileBuffers( hPort );
PurgeComm (hPort, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
COMSTAT comStat;
DWORD dwErrorFlags;
ClearCommError ( hPort, &dwErrorFlags, &comStat );
//NEW commtimeouts area
COMMTIMEOUTS CommTimeOuts;
DWORD dwTimeout = 3000; // <- set timeout in milliseconds
if(!dwTimeout)
{ // Don't use timeout -> Read the bytes already in input buffer and return immediately
CommTimeOuts.ReadIntervalTimeout = MAXDWORD;
CommTimeOuts.ReadTotalTimeoutConstant = 0;
} else
{ // Use given timeout, wait until the requested number of bytes are read - or timeout
CommTimeOuts.ReadIntervalTimeout = 0;
CommTimeOuts.ReadTotalTimeoutConstant = dwTimeout;
}
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutConstant = 0;
SetCommTimeouts (hPort, &CommTimeOuts);
printf("insert ASCII code string you wish to send:");
scanf("%s", input);
strcpy(data, "{0x02}");
strcat(data, input);
printf("%s \n", data);
data2=Checksum(data);
strcat(data, data2);
strcat(data, "{0x03}");
printf("the final sent message will be: %s \n",data);
retVal = WriteFile(hPort,data, strlen(data), &byteswritten, NULL);
printf("Number of bytes written: %d\n", byteswritten);
printf("Write Success? %d\n", retVal);
retVal=ReadFile (hPort, &response, 20, &dwBytesTransferred, NULL);
printf("Read Success? %d\n", retVal);
printf("Port Response: %d\n", response);
free(response);
return 0;
}
最新发现摘要:使用 Habi 建议的免费串行端口监视器,我现在确信 WriteFile 正常运行,并且 COM6 正在接收消息。我仍在寻找交叉电缆来仔细检查消息是否正在跨线路传输。我想,当我试图弄清楚是否有人可以查看这个新版本并告诉我是否有任何问题,特别是与 ReadFile 函数相关的问题时,我将不胜感激。令我困扰的是,免费串行端口软件仅显示从我的计算机传递的数据,而根本不显示设备的响应。 =\
最佳答案
而不是
"COM6"
尝试
"\\\\.\\COM6"
我建议使用CreateFile()、ReadFile()、WriteFile()
。
要打开 COM 端口,请尝试以下操作:
HANDLE hComDev;
if ((hComDev = CreateFile ( "\\\\.\\COM6",
GENERIC_READ | GENERIC_WRITE,
0, // exclusive access
NULL, // no security attrs
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL)) != INVALID_HANDLE_VALUE)
{
// success
}
您的代码中似乎缺少调用GetCommState()
。尝试配置 COM 端口:
DCB Dcb;
GetCommState (hComDev, &Dcb);
Dcb.BaudRate = CBR_19200;
Dcb.StopBits = ONESTOPBIT;
Dcb.ByteSize = 8;
Dcb.Parity = NOPARITY;
Dcb.fParity = 0;
Dcb.fOutxCtsFlow = 0;
Dcb.fOutxDsrFlow = 0;
Dcb.fDsrSensitivity = 0;
Dcb.fTXContinueOnXoff = TRUE;
Dcb.fOutX = 0;
Dcb.fInX = 0;
Dcb.fNull = 0;
Dcb.fErrorChar = 0;
Dcb.fAbortOnError = 0;
Dcb.fRtsControl = RTS_CONTROL_DISABLE;
Dcb.fDtrControl = DTR_CONTROL_DISABLE;
为了最初清除 COM 端口,我会在开始发送和接收字节之前进行如下重置:
FlushFileBuffers( hComDev );
PurgeComm (hComDev, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR);
COMSTAT comStat;
DWORD dwErrorFlags;
ClearCommError ( hComDev, &dwErrorFlags, &comStat );
你要求超时吗?要配置超时,请尝试以下操作:
COMMTIMEOUTS CommTimeOuts;
DWORD dwTimeout = .... // <- set timeout in milliseconds
if(!dwTimeout)
{ // Don't use timeout -> Read the bytes already in input buffer and return immediately
CommTimeOuts.ReadIntervalTimeout = MAXDWORD;
CommTimeOuts.ReadTotalTimeoutConstant = 0;
}
else
{ // Use given timeout, wait until the requested number of bytes are read - or timeout
CommTimeOuts.ReadIntervalTimeout = 0;
CommTimeOuts.ReadTotalTimeoutConstant = dwTimeout;
}
CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
CommTimeOuts.WriteTotalTimeoutConstant = 0;
SetCommTimeouts (hComDev, &CommTimeOuts);
My code is supposed to write a string of ascii values to the device and then read the response, however I cannot seem to get any response.
您确定字节确实发送到设备了吗?如果可以的话,请使用示波器并监控 PC 的 Tx 线路。发送一些字节并检查波特率和开始/停止位。如果您没有硬件来监视该信号,请使用基于软件的串行监视器,例如Free Serial Port Monitor 。我没有使用此类软件工具的经验,但它们至少应该向您展示 Windows 驱动程序尝试通过您选择的 COM 端口发送某些内容。
问候 哈比
关于c - 使用 C 函数 fopen、fread 和 fwrite 与串行端口交互?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11765349/