串行通信c ++

时间:2018-08-17 18:04:56

标签: c++ winapi embedded avr

我正在尝试在PC和arduino ATmega2560之间进行一些串行通讯

首先是microntroller的程序:

void setup() {
    Serial.begin(9600);
}

void loop() {
    Serial.write('A');
}

arduino程序非常基础,他的目的是检查PC上的下一个程序。

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
...

我得到的怪异字符是?在一个正方形

希望您能理解我的问题 谢谢

2 个答案:

答案 0 :(得分:2)

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,则可能需要付出一定的代价可以在多种硬件上工作。

答案 1 :(得分:0)

Serial.begin()的{​​{3}}开始(已加强调):

  

可选的第二个参数配置数据,奇偶校验和停止   位。默认值为8个数据位,无奇偶校验,一个停止位

我在您的代码中看到了这一点(没有第二个参数):

Serial.begin(9600);

还有这个

serialParameters.StopBits = TWOSTOPBITS;

我认为这可能是您的问题。