C程序没有在Arduino Mega上打开Serial



我有一个C程序(win32api(,它通过串行(USB(与我的Arduino Mega通信。

我可以通过IDE的串行监视器与Arduino fine进行通信。

如果我插入Arduino并运行C程序,端口似乎没有正确打开,也没有通信。在这种情况下,如果我从Arduino的IDE(或另一个串行程序(打开串行监视器,然后再次关闭它,那么C程序就可以完美地工作了。

这是我从C程序中得到的端口代码(在这个例子中,它被传递了5,因为这是Arduino正在使用的端口(:

CSerialPort.h:

#pragma once
#include <Windows.h>
#define CP_BAUD_RATE_1200 CBR_1200
#define CP_BAUD_RATE_9600 CBR_9600
#define CP_BAUD_RATE_1155 CBR_1155
#define CP_BAUD_RATE_4800 CBR_4800
#define CP_BAUD_RATE_19200 CBR_19200
#define CP_DATA_BITS_5 5
#define CP_DATA_BITS_6 6
#define CP_DATA_BITS_7 7
#define CP_DATA_BITS_8 8
#define CP_STOP_BITS_ONE ONESTOPBIT
#define CP_STOP_BITS_TWO TWOSTOPBITS
#define CP_STOP_BITS_ONE_AND_HALF ONE5STOPBITS
#define CP_PARITY_NOPARITY NOPARITY
#define CP_PARITY_ODD ODDPARITY
#define CP_PARITY_EVEN EVENPARITY
#define CP_PARITY_MARK MARKPARITY
#define CP_PARITY_SPACE SPACEPARITY
typedef HANDLE PORT;
PORT OpenPort(int idx);
void ClosePort(PORT com_port);
int SetPortBaudRate(PORT com_port, int rate);
int SetPortDataBits(PORT com_port, int databits);
int SetPortStopBits(PORT com_port, int stopbits);
int SetPortParity(PORT com_port, int parity);
int GetPortBaudRate(PORT com_port);
int GetPortDataBits(PORT com_port);
int GetPortStopBits(PORT com_port);
int GetPortParity(PORT com_port);
int SendData(PORT com_port,const char * data);
int ReciveData(PORT com_port, char * databuffer,int bufferlen);

CSerialPort.c

#include "CSerialPort.h"
#include <time.h>
PORT OpenPort(int idx)
{
HANDLE hComm;
TCHAR comname[100];
wsprintf(comname, TEXT("\\.\COM%d"), idx);
hComm = CreateFile(comname,            //port name
GENERIC_READ | GENERIC_WRITE, //Read/Write
0,            // No Sharing
NULL,         // No Security
OPEN_EXISTING,// Open existing port only
0,            // Non Overlapped I/O
NULL);        // Null for Comm Devices
if (hComm == INVALID_HANDLE_VALUE)
return NULL;
COMMTIMEOUTS timeouts = { 0 };
timeouts.ReadIntervalTimeout = 50;
timeouts.ReadTotalTimeoutConstant = 50;
timeouts.ReadTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 50;
timeouts.WriteTotalTimeoutMultiplier = 10;
if (SetCommTimeouts(hComm, &timeouts) == FALSE)
return NULL;
if (SetCommMask(hComm, EV_RXCHAR) == FALSE)
return NULL;
return hComm;
}
void ClosePort(PORT com_port)
{
CloseHandle(com_port);
}
int SetPortBaudRate(PORT com_port, int rate)
{
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
printf("FALSE BAUD STATE");
return FALSE;
dcbSerialParams.BaudRate = rate;
Status = SetCommState(com_port, &dcbSerialParams);
return Status;
}
int SetPortDataBits(PORT com_port, int bits)
{
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
printf("FALSE DATABITS STATE");
return FALSE;
dcbSerialParams.ByteSize = bits;
Status = SetCommState(com_port, &dcbSerialParams);
return Status;
}
int SetPortStopBits(PORT com_port, int bits)
{
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
printf("FALSE STOP STATE");
return FALSE;
dcbSerialParams.StopBits = bits;
Status = SetCommState(com_port, &dcbSerialParams);
return Status;
}
int SetPortParity(PORT com_port, int parity)
{
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
printf("FALSE PARITY STATE");
return FALSE;
dcbSerialParams.Parity = parity;
Status = SetCommState(com_port, &dcbSerialParams);
return Status;
}
int GetPortBaudRate(PORT com_port)
{
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
return -1;
return dcbSerialParams.BaudRate;
}
int GetPortDataBits(PORT com_port) {
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
return -1;
return dcbSerialParams.ByteSize;
}
int GetPortStopBits(PORT com_port) {
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
return -1;
return dcbSerialParams.StopBits;
}
int GetPortParity(PORT com_port) {
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
return -1;
return dcbSerialParams.Parity;
}
int SendData(PORT com_port, const char * data)
{
DWORD  dNoOFBytestoWrite = strlen(data);
DWORD  dNoOfBytesWritten;
BOOL Status = WriteFile(com_port,
data,
dNoOFBytestoWrite,
&dNoOfBytesWritten,
NULL);
if (Status == FALSE)
return -1;
return dNoOfBytesWritten;
}
int ReciveData(PORT com_port, char * data, int len)
{
DWORD dwEventMask;
DWORD NoBytesRead;
BOOL Status = WaitCommEvent(com_port, &dwEventMask, NULL);
if (Status == FALSE) {
return FALSE;
}
Status = ReadFile(com_port, data, len, &NoBytesRead, NULL);
data[NoBytesRead] = 0;
if (Status == FALSE) {
return FALSE;
}
return TRUE;
}

测试代码:

#include "CSerialPort.h"
#include <stdio.h>
#include <windows.h>
#include <stdlib.h>
bool sendComms(char * msgSndPtr, int portNum)
{
auto p1 = OpenPort(portNum);
SetPortBaudRate(p1, CP_BAUD_RATE_9600);
SetPortDataBits(p1, CP_DATA_BITS_8);
SetPortStopBits(p1, CP_STOP_BITS_ONE);
SetPortParity(p1, CP_PARITY_NOPARITY);
SendData(p1, msgSndPtr);
ClosePort(p1);
printf("%s sent.n", msgSndPtr); //debug
//strcpy(msgSndPtr,"");
return 1;
}

bool receiveComms(char * msgRecPtr, int portNum)
{
bool status = 0;
strcpy(msgRecPtr,"");
SetPortBaudRate(portNum, CP_BAUD_RATE_9600);
SetPortDataBits(portNum, CP_DATA_BITS_8);
SetPortStopBits(portNum, CP_STOP_BITS_ONE);
SetPortParity(portNum, CP_PARITY_NOPARITY);
auto p1 = OpenPort(portNum);
status = ReciveData(p1, msgRecPtr, 50);
ClosePort(p1);
if (!status) //if nothing is received, cancel out and show error
{
return 0;
}
else
{
printf("%s received.n", msgRecPtr); //debug
return 1;
}
}
void main()
{
char msgRec[50];
char * msgRecPtr = msgRec;
char msgSnd[50];
char * msgSndPtr = msgSnd;
while (!(strcmp("end",msgRecPtr)))
{
sendComms(msgSndPtr,  5);
receiveComms(msgRecPtr,  5);
printf("sent: %sn, msgSndPtr);
printf("received: %sn, msgRecPtr);
}
}

arduino代码:

int i = 0;
void setup() 
{
// Initiate Serial
Serial.begin(9600);
while (!Serial) ; // wait for serial port to connect. Needed for native USB
Serial.println("serial ready");
}
void loop() 
{
Serial.println("testing comms");
i++
delay (150);
if (i == 10) {
Serial.println("end");
}
}

如果有人在使用win32时遇到过这个问题,或者知道串行监视器是如何打开它的端口的,那将非常有帮助。

编辑:只是为了澄清一下,一旦端口成功打开一次(除了我的C程序之外的任何程序(,我的C程就会正常工作,并且可以成功打开/关闭端口,直到下一次电源循环。

感谢

我已经修复了您的代码!

主要错误是:

Incorrect use of COM port number where a handle was required
Closing the port after sending data and before receiving response which flush input buffer
Almost no error check which prohibed to know what was wrong

在测试代码中,主循环不正确。没有发送任何数据,并且当";结束";收到的是错误的。

打开端口后,我移动了COM端口参数化一次(也可能在OpenPort内部(。

处理接收的方式与您定义的通信协议有关。我还没碰那部分。如果是我的软件,我会将协议设计为面向线路的协议,即发送和接收的每条消息都将以CRLF对终止的线路的形式。然后,接收可以是一个循环,累积所有字符,直到找到行的末尾。

下面是固定的源代码。仍然有大量的romm可供增强。

测试代码:

#include "CSerialPort.h"
#include <stdio.h>     
#include <windows.h>
#include <stdlib.h>
bool SetComParameters(PORT comPort, int rate, int dataBits, int stopBits, int parity)
{
if (!SetPortBaudRate(comPort, CP_BAUD_RATE_9600)) {
fprintf(stderr, "Unable to set baudraten");
return 0;
}
if (!SetPortDataBits(comPort, CP_DATA_BITS_8)) {
fprintf(stderr, "Unable to set data bitsn");
return 0;
}
if (!SetPortStopBits(comPort, CP_STOP_BITS_ONE)) {
fprintf(stderr, "Unable to set stop bitsn");
return 0;
}
if (!SetPortParity(comPort, CP_PARITY_NOPARITY)) {
fprintf(stderr, "Unable to set parityn");
return 0;
}
return 1;
}
bool sendComms(char* msgSndPtr, PORT comPort)
{
SendData(comPort, msgSndPtr);
return 1;
}
bool receiveComms(char* msgRecPtr, PORT comPort)
{
bool status = 0;
strcpy(msgRecPtr, "");
status = ReceiveData(comPort, msgRecPtr, 50);
return status;
}
void main()
{
char msgRec[50];
char* msgRecPtr = msgRec;
char msgSnd[50];
char* msgSndPtr = msgSnd;
int portNum = 1;
PORT com_port = OpenPort(portNum);                            
if (com_port == NULL) {
fprintf(stderr, "Unable to open COM%dn", portNum);
return;
}
if (!SetComParameters(com_port, CP_BAUD_RATE_9600, CP_DATA_BITS_8, CP_STOP_BITS_ONE, CP_PARITY_NOPARITY)) {
fprintf(stderr, "Error setting parametersn");
return;
}
do {   // FPiette use of do/while instead of while loop
strcpy(msgSnd, "Hellorn");
if (!sendComms(msgSndPtr, com_port)) {  
fprintf(stderr, "sendComs failedn");
break;
}
printf("sent: %sn", msgSndPtr);
if (!receiveComms(msgRecPtr, com_port)) {
fprintf(stderr, "receiveComms failedn");
break;
}
printf("received: %sn", msgRecPtr);
} while (strcmp("end", msgRecPtr));
ClosePort(&com_port);
printf("Done.n");
}

CSerialPort.c:

#include <stdio.h>
#include "CSerialPort.h"
#include <time.h>
PORT OpenPort(int idx)
{
HANDLE hComm;
TCHAR comname[100];
wsprintf(comname, TEXT("\\.\COM%d"), idx);
hComm = CreateFile(comname,            //port name
GENERIC_READ | GENERIC_WRITE, //Read/Write
0,            // No Sharing
NULL,         // No Security
OPEN_EXISTING,// Open existing port only
0,            // Non Overlapped I/O
NULL);        // Null for Comm Devices
if (hComm == INVALID_HANDLE_VALUE)
return NULL;
COMMTIMEOUTS timeouts = { 0 };
timeouts.ReadIntervalTimeout = 50;
timeouts.ReadTotalTimeoutConstant = 50;
timeouts.ReadTotalTimeoutMultiplier = 10;
timeouts.WriteTotalTimeoutConstant = 50;
timeouts.WriteTotalTimeoutMultiplier = 10;
if (SetCommTimeouts(hComm, &timeouts) == FALSE)
return NULL;
if (SetCommMask(hComm, EV_RXCHAR) == FALSE)
return NULL;
return hComm;
}
void ClosePort(PORT* com_port)
{
if (com_port && *com_port) {
CloseHandle(*com_port);
*com_port = NULL;
}
}
int SetPortBaudRate(PORT com_port, int rate)
{
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
return FALSE;
dcbSerialParams.BaudRate = rate;
Status = SetCommState(com_port, &dcbSerialParams);
return Status;
}
int SetPortDataBits(PORT com_port, int bits)
{
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
return FALSE;
dcbSerialParams.ByteSize = bits;
Status = SetCommState(com_port, &dcbSerialParams);
return Status;
}
int SetPortStopBits(PORT com_port, int bits)
{
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
return FALSE;
dcbSerialParams.StopBits = bits;
Status = SetCommState(com_port, &dcbSerialParams);
return Status;
}
int SetPortParity(PORT com_port, int parity)
{
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
return FALSE;  
dcbSerialParams.Parity = parity;
Status = SetCommState(com_port, &dcbSerialParams);
return Status;
}
int GetPortBaudRate(PORT com_port)
{
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
return -1;
return dcbSerialParams.BaudRate;
}
int GetPortDataBits(PORT com_port) {
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
return -1;
return dcbSerialParams.ByteSize;
}
int GetPortStopBits(PORT com_port) {
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
return -1;
return dcbSerialParams.StopBits;
}
int GetPortParity(PORT com_port) {
DCB dcbSerialParams = { 0 };
BOOL Status;
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(com_port, &dcbSerialParams);
if (Status == FALSE)
return -1;
return dcbSerialParams.Parity;
}
int SendData(PORT com_port, const char* data)
{
DWORD  dNoOFBytestoWrite = strlen(data);
DWORD  dNoOfBytesWritten;
BOOL Status = WriteFile(com_port,
data,
dNoOFBytestoWrite,
&dNoOfBytesWritten,
NULL);
if (Status == FALSE)
return -1;
return dNoOfBytesWritten;
}
int ReceiveData(PORT com_port, char* data, int len)
{
DWORD dwEventMask = 0;
DWORD NoBytesRead = 0;
BOOL Status = WaitCommEvent(com_port, &dwEventMask, NULL);
if (Status == FALSE)
return FALSE;
Status = ReadFile(com_port, data, len, &NoBytesRead, NULL);
if (Status == FALSE)
return FALSE;
data[NoBytesRead] = 0;
return TRUE;
}

CSerialPort.h:

#pragma once
#include <Windows.h>
#define CP_BAUD_RATE_1200 CBR_1200
#define CP_BAUD_RATE_9600 CBR_9600
#define CP_BAUD_RATE_1155 CBR_1155
#define CP_BAUD_RATE_4800 CBR_4800
#define CP_BAUD_RATE_19200 CBR_19200
#define CP_DATA_BITS_5 5
#define CP_DATA_BITS_6 6
#define CP_DATA_BITS_7 7
#define CP_DATA_BITS_8 8
#define CP_STOP_BITS_ONE ONESTOPBIT
#define CP_STOP_BITS_TWO TWOSTOPBITS
#define CP_STOP_BITS_ONE_AND_HALF ONE5STOPBITS
#define CP_PARITY_NOPARITY NOPARITY
#define CP_PARITY_ODD ODDPARITY
#define CP_PARITY_EVEN EVENPARITY
#define CP_PARITY_MARK MARKPARITY
#define CP_PARITY_SPACE SPACEPARITY
#define bool BOOL
typedef HANDLE PORT;
PORT OpenPort(int idx);
void ClosePort(PORT* com_port);
int SetPortBaudRate(PORT com_port, int rate);
int SetPortDataBits(PORT com_port, int databits);
int SetPortStopBits(PORT com_port, int stopbits);
int SetPortParity(PORT com_port, int parity);
int GetPortBaudRate(PORT com_port);
int GetPortDataBits(PORT com_port);
int GetPortStopBits(PORT com_port);
int GetPortParity(PORT com_port);
int SendData(PORT com_port, const char* data);
int ReceiveData(PORT com_port, char* databuffer, int bufferlen);

最新更新