使用C函数fopen,fread和fwrite与串口进行交互?

Haz*_*zar 1 c file-io serial-port

我一直试图通过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;
}
Run Code Online (Sandbox Code Playgroud)

最新发现摘要:使用Habi建议的免费串行端口监视器,我现在知道WriteFile运行正常,COM6正在接收消息.我仍在寻找交叉电缆来仔细检查消息是否正在通过线路传输.我想,如果有人能看到这个新版本并告诉我是否有任何错误,特别是与ReadFile函数有关,我会想到这一点,我将非常感激.令我困扰的是,Free Serial Port软件只显示从我的计算机传来的数据,而不是设备的响应.= \

Hab*_*abi 5

代替

"COM6"
Run Code Online (Sandbox Code Playgroud)

尝试

"\\\\.\\COM6"
Run Code Online (Sandbox Code Playgroud)

我建议使用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
}
Run Code Online (Sandbox Code Playgroud)

似乎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;
Run Code Online (Sandbox Code Playgroud)

要最初清除COM端口,我会在开始发送和接收字节之前进行这样的重置:

FlushFileBuffers( hComDev );

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

COMSTAT     comStat;
DWORD       dwErrorFlags;
ClearCommError ( hComDev, &dwErrorFlags, &comStat );
Run Code Online (Sandbox Code Playgroud)

你要求超时吗?要配置超时,请尝试以下操作:

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);
Run Code Online (Sandbox Code Playgroud)

我的代码应该将ascii值字符串写入设备,然后读取响应,但我似乎无法获得任何响应.

你确定这些字节真的发送到了设备吗?如果您可以选择,请使用示波器并监控PC的Tx线.发送一些字节并检查波特率和开始/停止位.如果您没有硬件来监控此信号,请使用基于软件的串行监视器,例如Free Serial Port Monitor.我没有这种软件工具的经验,但他们应该向您展示至少Windows驱动程序尝试通过您选择的COM端口发送内容.

问候Habi