串行通信 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】:

DCBByteSize 参数在 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 路串行通信

使用 Qt 的 C++ 中的线程串行端口通信

如何在 Linux 上通过 C++ 中的串行接口与 Arduino 通信?

Microsoft Visual C++ 2010 和 Arduino UNO 之间通过 USB 进行串行通信

PC和Arduino之间通过USB的串行通信

什么叫串行通信和并行通信?异步通信和同步通信有何区别?