【问题标题】:access serial port by visual C++通过visual C++访问串口
【发布时间】:2012-12-24 03:33:32
【问题描述】:

我想通过visual c++访问串口 我从互联网上获取程序,但是当我运行程序时,端口似乎无法打开

这里是我的程序serialClass.cpp

#ifndef SERIALCLASS_H_INCLUDED
#define SERIALCLASS_H_INCLUDED
#define ARDUINO_WAIT_TIME 2000
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

class Serial
{
private:
    HANDLE hSerial;
    bool connected;
    COMSTAT status;
    DWORD errors;

public:
    Serial(char *portName);
    //Serial();
    ~Serial();
    int ReadData(char *buffer, unsigned int nbChar);
    bool WriteData(char *buffer, unsigned int nbChar);
    bool IsConnected();
};
#endif // SERIALCLASS_H_INCLUDED

还有我的 Serial.cpp

#include "SerialClass.h"
 Serial::Serial(char *portName)
 //Serial::Serial()
{
//We're not yet connected
this->connected = false;

//Try to connect to the given port throuh CreateFile
this->hSerial = CreateFile((LPCWSTR) portName,
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL,
        0);

//Check if the connection was successfull
if(this->hSerial==INVALID_HANDLE_VALUE)
{
    //If not success full display an Error
    if(GetLastError()==ERROR_FILE_NOT_FOUND){

     printf("ERROR: Handle was not attached. Reason: COM1 not available.\n");
    }
    else
    {
        printf("ERROR!!!");
    }
}
else
{
    //If connected we try to set the comm parameters
    DCB dcbSerialParams = {0};

    //Try to get the current
    if (!GetCommState(this->hSerial, &dcbSerialParams))
    {
        //If impossible, show an error
        printf("failed to get current serial parameters!");
    }
    else
    {
        //Define serial connection parameters for the arduino board
        dcbSerialParams.BaudRate=CBR_19200;
        dcbSerialParams.ByteSize=8;
        dcbSerialParams.StopBits=ONESTOPBIT;
        dcbSerialParams.Parity=NOPARITY;
        dcbSerialParams.fOutX=TRUE;
        dcbSerialParams.fInX=TRUE;


         //Set the parameters and check for their proper application
         if(!SetCommState(hSerial, &dcbSerialParams))
         {
            printf("ALERT: Could not set Serial Port parameters");
         }
         else
         {
             //If everything went fine we're connected
             this->connected = true;
             //We wait 2s as the arduino board will be reseting
             //Sleep(ARDUINO_WAIT_TIME);
             printf("Current Settings\n Baud Rate %d\n Parity %d\n Byte Size %d\n Stop Bits %d", dcbSerialParams.BaudRate, 
    dcbSerialParams.Parity, dcbSerialParams.ByteSize, dcbSerialParams.StopBits);
         }
    }
}
}

Serial::~Serial()
{
//Check if we are connected before trying to disconnect
if(this->connected)
{
    //We're no longer connected
    this->connected = false;
    //Close the serial handler
    CloseHandle(this->hSerial);
}
}

 int Serial::ReadData(char *buffer, unsigned int nbChar)
 {
//Number of bytes we'll have read
DWORD bytesRead;
//Number of bytes we'll really ask to read
unsigned int toRead;

//Use the ClearCommError function to get status info on the Serial port
ClearCommError(this->hSerial, &this->errors, &this->status);

//Check if there is something to read
if(this->status.cbInQue>0)
{
    //If there is we check if there is enough data to read the required number
    //of characters, if not we'll read only the available characters to prevent
    //locking of the application.
    if(this->status.cbInQue>nbChar)
    {
        toRead = nbChar;
    }
    else
    {
        toRead = this->status.cbInQue;
    }

    //Try to read the require number of chars, and return the number of read bytes on success
    if(ReadFile(this->hSerial, buffer, toRead, &bytesRead, NULL) && bytesRead != 0)
    {
        return bytesRead;
    }
}
//If nothing has been read, or that an error was detected return -1
return -1;
}

bool Serial::WriteData(char *buffer, unsigned int nbChar)
{
DWORD bytesSend;

//Try to write the buffer on the Serial port
if(!WriteFile(this->hSerial, (void *)buffer, nbChar, &bytesSend, 0))
{
    //In case it don't work get comm error and return false
    ClearCommError(this->hSerial, &this->errors, &this->status);

    return false;
}
else
    return true;
}

bool Serial::IsConnected()
{
     //Simply return the connection status
return this->connected;
 }

结果总是

错误:未连接手柄。原因:COM1 不可用。

任何机构都可以提供帮助?

【问题讨论】:

  • 你如何使用这个Serial类?请说明您如何声明它的实例。
  • serial::serial(); buf=(abc);serial::readdata(buf,100);
  • 您正在调用构造函数和readdata,因为它们是类中的静态方法。他们不是,这让我想知道它是如何编译的?请发帖Short, Self Contained, Correct (Compilable), Example。
  • 我是课堂编程的新手,您能提出一些建议吗?
  • 我的建议是回到基础,什么是类,如何使用,成员函数和非成员函数的区别,什么是静态成员函数。你必须先学会走路,然后才能学会跑步。

标签: c++ winapi serial-port


【解决方案1】:

问题在于转换为宽字符串而不是转换,我用以下代码替换了打开端口的那部分代码并且它起作用了:

wchar_t wcPort[64];
size_t convertedChars = 0;
mbstowcs_s(&convertedChars, wcPort, strlen(portName), portName, _TRUNCATE);

this->hSerial = CreateFile(wcPort,
    GENERIC_READ | GENERIC_WRITE,
    0,
    NULL,
    OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL,
    0);

或者正如Ben Voigt 在评论中指出的那样,您也可以调用 CreateFileA 变体,以便 Windows 为您执行转换。

【讨论】:

  • 我使用的是 COM3,我禁用了 COM1,因为它在我的主板上不起作用,所以使用了 Serial port("COM3:");
  • 您可以调用CreateFileA,因为您有一个 ASCII 文件名,并让 Windows 负责转换。
  • 只是想知道 "COM1"、"COM1:"、L("COM1")、_T("COM1")、\\\\.\\COM1 之间有什么区别?
  • L() 使它成为一个 unicode 字符串,而 _T 取决于编译器设置,因此它更通用,请参阅msdn.microsoft.com/en-us/library/se784sk6.aspx。我不认为各种形式的端口名称有实际区别,我只是习惯于使用 COM1: 等,因此端口不存在会产生错误并且不会尝试引用文件。我似乎记得有些 API 调用可能需要最后一种形式,但从记忆中,我在需要它的时候做过一次相当模糊的事情。
猜你喜欢
  • 1970-01-01
  • 2013-06-01
  • 2013-06-10
  • 1970-01-01
  • 2012-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多