重启后读取 - 使用串行库的 RS232 串行通信 - C++
Read after restart - RS232 Serial communication using Serial Library - C++
我正在尝试通过使用 C++ 的串行库和在以下位置找到的一些示例,通过串行连接从 RS-232 读取数据:
http://www.codeproject.com/Articles/992/Serial-library-for-C
有没有信号检测方法或事件让我知道。
我仅使用串口转 USB 连接器将 Rx 和 Neutral 连接到电路板,并在 Visual studio 2013 中使用串口库并编写C++ 中的代码。
我想在手动重启时将从我的板传输的 ASCII 数据写入文本文件,这样我就可以很容易地从文本文件中解析数据。
我的板子只有在重启时才会发送发送数据。
我是串行连接的新手,我无法弄清楚如何让我的程序理解在电路板重置时读取数据。
我正在使用监听程序:
#define STRICT
#include <tchar.h>
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include "Serial.h"
//C++ headers
#include <iostream>
#include <fstream>
#include <string>
enum { EOF_Char = 27 };
int ShowError (LONG lError, LPCTSTR lptszMessage)
{
// Generate a message text
TCHAR tszMessage[256];
wsprintf(tszMessage,_T("%s\n(error code %d)"), lptszMessage, lError);
// Display message-box and return with an error-code
::MessageBox(0,tszMessage,_T("Listener"), MB_ICONSTOP|MB_OK);
return 1;
}
//int __cdecl _tmain (int /*argc*/, char** /*argv*/)
int WINAPI _tWinMain(HINSTANCE /*hInst*/, HINSTANCE /*hInstPrev*/, LPTSTR /*lptszCmdLine*/, int /*nCmdShow*/)
{
CSerial serial;
LONG lLastError = ERROR_SUCCESS;
const char* Port_name = "COM3";
// Attempt to open the serial port (COM1)
lLastError = serial.Open(_T(Port_name),0,0,false);
if (lLastError != ERROR_SUCCESS)
return ::ShowError(serial.GetLastError(), _T("Unable to open COM-port"));
// Setup the serial port (9600,8N1, which is the default setting)
lLastError = serial.Setup(CSerial::EBaud9600,CSerial::EData8,CSerial::EParNone,CSerial::EStop1);
if (lLastError != ERROR_SUCCESS)
return ::ShowError(serial.GetLastError(), _T("Unable to set COM-port setting"));
// Register only for the receive event
lLastError = serial.SetMask(CSerial::EEventBreak |
CSerial::EEventCTS |
CSerial::EEventDSR |
CSerial::EEventError |
CSerial::EEventRing |
CSerial::EEventRLSD |
CSerial::EEventRecv);
if (lLastError != ERROR_SUCCESS)
return ::ShowError(serial.GetLastError(), _T("Unable to set COM-port event mask"));
// Use 'non-blocking' reads, because we don't know how many bytes
// will be received. This is normally the most convenient mode
// (and also the default mode for reading data).
lLastError = serial.SetupReadTimeouts(CSerial::EReadTimeoutNonblocking);
if (lLastError != ERROR_SUCCESS)
return ::ShowError(serial.GetLastError(), _T("Unable to set COM-port read timeout."));
// Keep reading data, until an EOF (CTRL-Z) has been received
bool fContinue = true;
do
{
// Wait for an event
lLastError = serial.WaitEvent();
if (lLastError != ERROR_SUCCESS)
return ::ShowError(serial.GetLastError(), _T("Unable to wait for a COM-port event."));
else
return ::ShowError(serial.GetLastError(), _T("Waiting for a COM-port event."));
// Save event
const CSerial::EEvent eEvent = serial.GetEventType();
// Handle break event
if (eEvent & CSerial::EEventBreak)
{
printf("\n### BREAK received ###\n");
}
// Handle CTS event
if (eEvent & CSerial::EEventCTS)
{
printf("\n### Clear to send %s ###\n", serial.GetCTS()?"on":"off");
}
// Handle DSR event
if (eEvent & CSerial::EEventDSR)
{
printf("\n### Data set ready %s ###\n", serial.GetDSR()?"on":"off");
}
// Handle error event
if (eEvent & CSerial::EEventError)
{
printf("\n### ERROR: ");
switch (serial.GetError())
{
case CSerial::EErrorBreak: printf("Break condition"); break;
case CSerial::EErrorFrame: printf("Framing error"); break;
case CSerial::EErrorIOE: printf("IO device error"); break;
case CSerial::EErrorMode: printf("Unsupported mode"); break;
case CSerial::EErrorOverrun: printf("Buffer overrun"); break;
case CSerial::EErrorRxOver: printf("Input buffer overflow"); break;
case CSerial::EErrorParity: printf("Input parity error"); break;
case CSerial::EErrorTxFull: printf("Output buffer full"); break;
default: printf("Unknown"); break;
}
printf(" ###\n");
}
// Handle ring event
if (eEvent & CSerial::EEventRing)
{
printf("\n### RING ###\n");
}
// Handle RLSD/CD event
if (eEvent & CSerial::EEventRLSD)
{
printf("\n### RLSD/CD %s ###\n", serial.GetRLSD()?"on":"off");
}
// Handle data receive event
if (eEvent & CSerial::EEventRecv)
{
// Read data, until there is nothing left
DWORD dwBytesRead = 0;
char szBuffer[101];
do
{
// Read data from the COM-port
lLastError = serial.Read(szBuffer,sizeof(szBuffer)-1,&dwBytesRead);
if (lLastError != ERROR_SUCCESS)
return ::ShowError(serial.GetLastError(), _T("Unable to read from COM-port."));
if (dwBytesRead > 0)
{
// Finalize the data, so it is a valid string
szBuffer[dwBytesRead] = '[=10=]';
//writing data to text file
std::ofstream o("save.txt");
o << "Data: " << szBuffer << std::endl << "BytesRead: " <<dwBytesRead <<std::endl;
// Display the data
printf("%s", szBuffer);
// Check if EOF (CTRL+'[') has been specified
if (strchr(szBuffer,EOF_Char))
fContinue = false;
}
}
while (dwBytesRead == sizeof(szBuffer)-1);
}
}
while (fContinue);
// Close the port again
serial.Close();
return 0;
}
我确实在我的 while 语句中设置了一些断点,并试图重新启动电路板。然后我像这样将数据写入我的文本文件。
线索 1:
Data: "H¢˜A,B™žX
BytesRead: 100
线索 2:
Data: x]Ãßÿ$¢œŒ2Y¶SIeó1ñ\@ó8¬!)þ
BytesRead: 30
我知道这个数据不正确,我应该得到 ASCII 数据。
是否有任何库支持解决我的问题?
我需要在UART重启后读取数据,一旦它停止接收数据,它应该将所有数据写入一个文本文件。
请帮帮我,非常感谢。
在设置函数中设置错误的波特率会给出错误的输出。
lLastError = serial.Setup(CSerial::EBaud115200,CSerial::EData8,CSerial::EParNone,CSerial::EStop1);
还有
std::ofstream output_file;
//Creating a text file
output_file.open("save_test.txt", std::ios_base::app);
//writing data to text file
output_file /*<< "Data: "*/ << szBuffer;
而不是下面的代码(每次都会覆盖文本文件并且看不到任何数据)
//writing data to text file
std::ofstream o("save.txt");
o << "Data: " << szBuffer << std::endl << "BytesRead: " <<dwBytesRead <<std::endl;
将数据追加到文本文件中,在文本文件中可以看到RS232传输的完整数据。
我正在尝试通过使用 C++ 的串行库和在以下位置找到的一些示例,通过串行连接从 RS-232 读取数据: http://www.codeproject.com/Articles/992/Serial-library-for-C
有没有信号检测方法或事件让我知道。 我仅使用串口转 USB 连接器将 Rx 和 Neutral 连接到电路板,并在 Visual studio 2013 中使用串口库并编写C++ 中的代码。
我想在手动重启时将从我的板传输的 ASCII 数据写入文本文件,这样我就可以很容易地从文本文件中解析数据。
我的板子只有在重启时才会发送发送数据。 我是串行连接的新手,我无法弄清楚如何让我的程序理解在电路板重置时读取数据。
我正在使用监听程序:
#define STRICT
#include <tchar.h>
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include "Serial.h"
//C++ headers
#include <iostream>
#include <fstream>
#include <string>
enum { EOF_Char = 27 };
int ShowError (LONG lError, LPCTSTR lptszMessage)
{
// Generate a message text
TCHAR tszMessage[256];
wsprintf(tszMessage,_T("%s\n(error code %d)"), lptszMessage, lError);
// Display message-box and return with an error-code
::MessageBox(0,tszMessage,_T("Listener"), MB_ICONSTOP|MB_OK);
return 1;
}
//int __cdecl _tmain (int /*argc*/, char** /*argv*/)
int WINAPI _tWinMain(HINSTANCE /*hInst*/, HINSTANCE /*hInstPrev*/, LPTSTR /*lptszCmdLine*/, int /*nCmdShow*/)
{
CSerial serial;
LONG lLastError = ERROR_SUCCESS;
const char* Port_name = "COM3";
// Attempt to open the serial port (COM1)
lLastError = serial.Open(_T(Port_name),0,0,false);
if (lLastError != ERROR_SUCCESS)
return ::ShowError(serial.GetLastError(), _T("Unable to open COM-port"));
// Setup the serial port (9600,8N1, which is the default setting)
lLastError = serial.Setup(CSerial::EBaud9600,CSerial::EData8,CSerial::EParNone,CSerial::EStop1);
if (lLastError != ERROR_SUCCESS)
return ::ShowError(serial.GetLastError(), _T("Unable to set COM-port setting"));
// Register only for the receive event
lLastError = serial.SetMask(CSerial::EEventBreak |
CSerial::EEventCTS |
CSerial::EEventDSR |
CSerial::EEventError |
CSerial::EEventRing |
CSerial::EEventRLSD |
CSerial::EEventRecv);
if (lLastError != ERROR_SUCCESS)
return ::ShowError(serial.GetLastError(), _T("Unable to set COM-port event mask"));
// Use 'non-blocking' reads, because we don't know how many bytes
// will be received. This is normally the most convenient mode
// (and also the default mode for reading data).
lLastError = serial.SetupReadTimeouts(CSerial::EReadTimeoutNonblocking);
if (lLastError != ERROR_SUCCESS)
return ::ShowError(serial.GetLastError(), _T("Unable to set COM-port read timeout."));
// Keep reading data, until an EOF (CTRL-Z) has been received
bool fContinue = true;
do
{
// Wait for an event
lLastError = serial.WaitEvent();
if (lLastError != ERROR_SUCCESS)
return ::ShowError(serial.GetLastError(), _T("Unable to wait for a COM-port event."));
else
return ::ShowError(serial.GetLastError(), _T("Waiting for a COM-port event."));
// Save event
const CSerial::EEvent eEvent = serial.GetEventType();
// Handle break event
if (eEvent & CSerial::EEventBreak)
{
printf("\n### BREAK received ###\n");
}
// Handle CTS event
if (eEvent & CSerial::EEventCTS)
{
printf("\n### Clear to send %s ###\n", serial.GetCTS()?"on":"off");
}
// Handle DSR event
if (eEvent & CSerial::EEventDSR)
{
printf("\n### Data set ready %s ###\n", serial.GetDSR()?"on":"off");
}
// Handle error event
if (eEvent & CSerial::EEventError)
{
printf("\n### ERROR: ");
switch (serial.GetError())
{
case CSerial::EErrorBreak: printf("Break condition"); break;
case CSerial::EErrorFrame: printf("Framing error"); break;
case CSerial::EErrorIOE: printf("IO device error"); break;
case CSerial::EErrorMode: printf("Unsupported mode"); break;
case CSerial::EErrorOverrun: printf("Buffer overrun"); break;
case CSerial::EErrorRxOver: printf("Input buffer overflow"); break;
case CSerial::EErrorParity: printf("Input parity error"); break;
case CSerial::EErrorTxFull: printf("Output buffer full"); break;
default: printf("Unknown"); break;
}
printf(" ###\n");
}
// Handle ring event
if (eEvent & CSerial::EEventRing)
{
printf("\n### RING ###\n");
}
// Handle RLSD/CD event
if (eEvent & CSerial::EEventRLSD)
{
printf("\n### RLSD/CD %s ###\n", serial.GetRLSD()?"on":"off");
}
// Handle data receive event
if (eEvent & CSerial::EEventRecv)
{
// Read data, until there is nothing left
DWORD dwBytesRead = 0;
char szBuffer[101];
do
{
// Read data from the COM-port
lLastError = serial.Read(szBuffer,sizeof(szBuffer)-1,&dwBytesRead);
if (lLastError != ERROR_SUCCESS)
return ::ShowError(serial.GetLastError(), _T("Unable to read from COM-port."));
if (dwBytesRead > 0)
{
// Finalize the data, so it is a valid string
szBuffer[dwBytesRead] = '[=10=]';
//writing data to text file
std::ofstream o("save.txt");
o << "Data: " << szBuffer << std::endl << "BytesRead: " <<dwBytesRead <<std::endl;
// Display the data
printf("%s", szBuffer);
// Check if EOF (CTRL+'[') has been specified
if (strchr(szBuffer,EOF_Char))
fContinue = false;
}
}
while (dwBytesRead == sizeof(szBuffer)-1);
}
}
while (fContinue);
// Close the port again
serial.Close();
return 0;
}
我确实在我的 while 语句中设置了一些断点,并试图重新启动电路板。然后我像这样将数据写入我的文本文件。
线索 1:
Data: "H¢˜A,B™žX
BytesRead: 100
线索 2:
Data: x]Ãßÿ$¢œŒ2Y¶SIeó1ñ\@ó8¬!)þ
BytesRead: 30
我知道这个数据不正确,我应该得到 ASCII 数据。 是否有任何库支持解决我的问题?
我需要在UART重启后读取数据,一旦它停止接收数据,它应该将所有数据写入一个文本文件。
请帮帮我,非常感谢。
在设置函数中设置错误的波特率会给出错误的输出。
lLastError = serial.Setup(CSerial::EBaud115200,CSerial::EData8,CSerial::EParNone,CSerial::EStop1);
还有
std::ofstream output_file;
//Creating a text file
output_file.open("save_test.txt", std::ios_base::app);
//writing data to text file
output_file /*<< "Data: "*/ << szBuffer;
而不是下面的代码(每次都会覆盖文本文件并且看不到任何数据)
//writing data to text file
std::ofstream o("save.txt");
o << "Data: " << szBuffer << std::endl << "BytesRead: " <<dwBytesRead <<std::endl;
将数据追加到文本文件中,在文本文件中可以看到RS232传输的完整数据。