串行通信 C++
Posted
技术标签:
【中文标题】串行通信 C++【英文标题】:Serial communication c++ 【发布时间】:2018-08-17 18:04:56 【问题描述】:我正在尝试在我的电脑和 arduino ATmega2560 之间进行一些串行通信
首先是微控制器的程序:
void setup()
Serial.begin(9600);
void loop()
Serial.write('A');
arduino 程序非常基础,他的目的是检查电脑上的下一个程序。
main.cpp:
#include <iostream>
#include "SerialPort.h"
using namespace std;
int main()
SerialPort port("com3", 9600);
while (1)
//Receive
unsigned char dataR;
port.receive(dataR, 1);
cout << dataR << endl;
return 0;
SerialPort.h:
#include <windows.h>
#include <iostream>
class SerialPort
public:
//Constructors
SerialPort();
SerialPort(const char* port, unsigned long BaudRate);
//Initialization
void Initialize(const char* port, unsigned long BaudRate);
//Serial I/O
void receive(unsigned char &data, unsigned int byteSize);
void transmit(unsigned char *data, unsigned int byteSize);
//State
void connect();
void disconnect();
bool isConnected();
//Destructor
~SerialPort();
private:
HANDLE handler;
bool isConnect;
;
还有 SerialPort.cpp:
#include "SerialPort.h"
/*Constructors*/
SerialPort::SerialPort()
: isConnect(false)
SerialPort::SerialPort(const char* port, unsigned long BaudRate)
: isConnect(false)
Initialize(port, BaudRate);
/*Initialization*/
void SerialPort::Initialize(const char* port, unsigned long BaudRate)
handler = CreateFile(port, GENERIC_READ | GENERIC_WRITE, NULL, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (handler == INVALID_HANDLE_VALUE)
std::cout << "ERROR!::Error during opening port" << port << std::endl;
return;
DCB serialParameters;
if (!GetCommState(handler, &serialParameters)) /*Get com parameters*/
std::cout << "ERROR!::failed to get current serial parameters" << std::endl;
return;
serialParameters.DCBlength = sizeof(DCB);
serialParameters.BaudRate = BaudRate;
serialParameters.ByteSize = 1; /*8 bit data format*/
serialParameters.StopBits = TWOSTOPBITS;
serialParameters.Parity = PARITY_NONE;
if (!SetCommState(handler, &serialParameters)) /*Send modified com parameters*/
std::cout << "ALERT!:Failed to set THE Serial port parameters" << std::endl;
return;
isConnect = true;
PurgeComm(handler, PURGE_RXCLEAR | PURGE_TXCLEAR);
/*Serial I/O*/
void SerialPort::receive(unsigned char &data, unsigned int byteSize)
ReadFile(handler, &data, byteSize, NULL, NULL);
void SerialPort::transmit(unsigned char *data, unsigned int byteSize)
WriteFile(handler, data, byteSize, NULL, NULL);
/*State*/
void SerialPort::connect()
isConnect = true;
void SerialPort::disconnect()
isConnect = false;
bool SerialPort::isConnected()
return isConnect;
/*Destructors*/
SerialPort::~SerialPort()
if (isConnect)
isConnect = false;
CloseHandle(handler);
我对这个程序有疑问:我没有收到正确的数据。我应该在哪里到达终端
A
A
A
...
我得到了奇怪的字符?在一个正方形中
希望你能理解我的问题 谢谢
【问题讨论】:
并且您没有检查任何错误。例如,可能是您的ReadFile
失败(在最后一个参数中同时使用 0 是错误的)
这是您评论 RbMn 之后的新接收方法:
对不起,我弄错了.... 新方法是 void SerialPort::receive(unsigned char &data, unsigned int byteSize) DWORD read; ReadFile(handler, &data, byteSize, &read, NULL); std::cout
它说读取了一个字节,我也打印了相同的字符
也许这个旧答案中的代码会有所帮助:***.com/a/6037377/179910
【参考方案1】:
DCB
ByteSize
参数在 bits 中。您指定了一个带有一个数据位的 UART 帧 - 两端的硬件都不支持。
对于常规的 N,8,1 数据帧,使用
serialParameters.ByteSize = 8 ;
serialParameters.StopBits = ONESTOPBIT ;
serialParameters.Parity = NOPARITY ;
ByteSize
可能是一个误导性名称。它定义了 UART 帧中开始位和停止位之间的位数。最常见的是 8,但对于纯 ASCII 数据传输,可能会使用 7 - 至少在历史上是这样。
Atmel AVR UART 支持具有 5 到 9 个数据位的帧。 PC 的 UART 可能是虚拟的,但通常与 16550 UART 兼容,后者支持 5 到 8 位数据帧,但是现在您更有可能使用 USB 串行适配器和 USB/串行桥上的 UART可能不支持所有 16550 模式 - 例如常见的 FTDI232R 仅支持 7 或 8 位帧,而 Prolific PL2303 支持 5 到 8 位帧。如果你想确定它,避免非常规帧并坚持使用 N、8、1 可能是值得的可以在一系列硬件上工作。
【讨论】:
【参考方案2】:从the Arduino documentation 到Serial.begin()
(强调添加):
可选的第二个参数配置数据、奇偶校验和停止 位。默认为 8 个数据位,无奇偶校验,一个停止位。
我在您的代码中看到了这一点(没有第二个参数):
Serial.begin(9600);
还有这个
serialParameters.StopBits = TWOSTOPBITS;
我认为这可能是你的问题。
【讨论】:
发送端的停止位太多通常不是问题。 期望两个停止位,但只发送一个。 你可以有 100 个停止位,它会工作得很好。虽然数据位数错误,但...... 是的,从技术上讲,这并不能解决他的问题,直到他向另一个方向发送数据。我错过了数据位!以上是关于串行通信 C++的主要内容,如果未能解决你的问题,请参考以下文章
arduino 和 Visual Studio C++,2 路串行通信
如何在 Linux 上通过 C++ 中的串行接口与 Arduino 通信?