问题描述
我正在使用here中找到的代码来将数据从ATmega微控制器接收到我的PC。代码“ USB2SERIAL_Read_W32.c”处理Windows COM端口并接收串行数据,然后将其打印到控制台。
我试图修改代码以使其连续运行,即等待数据,在收到字符时打印它们,然后返回等待新数据。
#include <Windows.h>
#include <stdio.h>
void main(void)
{
HANDLE hComm; // Handle to the Serial port
char ComPortName[] = "\\\\.\\COM9"; // Name of the Serial port(May Change) to be opened,BOOL Status; // Status of the varIoUs operations
DWORD dwEventMask; // Event mask to trigger
char TempChar; // Temperory Character
char SerialBuffer[256]; // Buffer Containing Rxed Data
DWORD NoBytesRead; // Bytes read by ReadFile()
int i = 0;
int counter=0;
printf("\n\n +==========================================+");
printf("\n | Serial Port Reception (Win32 API) |");
printf("\n +==========================================+\n");
/*---------------------------------- opening the Serial Port -------------------------------------------*/
hComm = CreateFile( ComPortName,// Name of the Port to be Opened
GENERIC_READ | GENERIC_WRITE,// Read/Write Access
0,// No Sharing,ports cant be shared
NULL,// No Security
OPEN_EXISTING,// Open existing port only
0,// Non Overlapped I/O
NULL); // Null for Comm Devices
if (hComm == INVALID_HANDLE_VALUE)
printf("\n Error! - Port %s can't be opened\n",ComPortName);
else
printf("\n Port %s Opened\n ",ComPortName);
/*------------------------------- Setting the Parameters for the SerialPort ------------------------------*/
DCB dcbSerialParams = { 0 }; // Initializing DCB structure
dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
Status = GetCommState(hComm,&dcbSerialParams); //retreives the current settings
if (Status == FALSE)
printf("\n Error! in GetCommState()");
dcbSerialParams.Baudrate = CBR_9600; // Setting Baudrate = 9600
dcbSerialParams.ByteSize = 8; // Setting ByteSize = 8
dcbSerialParams.StopBits = OnesTOPBIT; // Setting StopBits = 1
dcbSerialParams.Parity = nopARITY; // Setting Parity = None
Status = SetCommState(hComm,&dcbSerialParams); //Configuring the port according to settings in DCB
if (Status == FALSE)
{
printf("\n Error! in Setting DCB Structure");
}
else //If Successfull display the contents of the DCB Structure
{
printf("\n\n Setting DCB Structure Successfull\n");
printf("\n Baudrate = %d",dcbSerialParams.Baudrate);
printf("\n ByteSize = %d",dcbSerialParams.ByteSize);
printf("\n StopBits = %d",dcbSerialParams.StopBits);
printf("\n Parity = %d",dcbSerialParams.Parity);
}
/*------------------------------------ Setting Timeouts --------------------------------------------------*/
COMMTIMEOUTS timeouts = { 0 };
timeouts.ReadIntervalTimeout = MAXDWORD;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.WritetotalTimeoutConstant = 0;
timeouts.WritetotalTimeoutMultiplier = 0;
if (SetCommTimeouts(hComm,&timeouts) == FALSE)
printf("\n\n Error! in Setting Time Outs");
else
printf("\n\n Setting Serial Port Timeouts Successfull");
/*------------------------------------ Setting Receive Mask ----------------------------------------------*/
dwEventMask=EV_RXCHAR;
Status = SetCommMask(hComm,dwEventMask); //Configure Windows to Monitor the serial device for Character Reception
if (Status == FALSE)
printf("\n\n Error! in Setting CommMask");
else
printf("\n\n Setting CommMask successfull");
/*------------------------------------ Setting WaitComm() Event ----------------------------------------*/
while(1){
int j =0;
i=0;
for(j=0;j<sizeof(SerialBuffer);j++){ //Clear SerialBuffer
SerialBuffer[j]=0;
}
printf("\n\n Waiting for Data Reception");
Status = WaitCommEvent(hComm,&dwEventMask,NULL); //Wait for the character to be received
/*-------------------------- Program will Wait here till a Character is received ------------------------*/
if (Status == FALSE){
printf("\n Error! in Setting WaitCommEvent()");
}
else //If WaitCommEvent()==True Read the RXed data using ReadFile();
{
printf("\n\n Characters Received");
do{
Status = ReadFile(hComm,&TempChar,sizeof(TempChar),&NoBytesRead,NULL);
if(Status==TRUE){
if(NoBytesRead>0){
SerialBuffer[i] = TempChar;
}
i++;
}
else
printf("\n Error! in Setting ReadFile()");
}while (NoBytesRead);
/*------------Printing the RXed String to Console----------------------*/
printf("\n\n ");
for (j = 0; j < strlen(SerialBuffer); j++)
printf("%c",SerialBuffer[j]);
}
//CloseHandle(hComm);//Closing the Serial Port
printf("\n +==========================================+\n");
}
}//End of Main()
我所做的更改是添加while(1)循环,在每个循环的开始处清除缓冲区,注释掉端口处理程序的关闭,更改超时,如{{ 3}},并进行一些其他小的调整和修饰。
问题是由于某种原因,每当我收到字符串“ 1234”时,首先触发预期事件,打印接收到的字符,然后由于某种原因触发另一个事件,没有字符等待,如下图所示:
总而言之,为什么会触发意外事件,我该如何解决?
编辑:我还没有找到解决方案,但是我发布了一个发现的解决方法(也许它可以帮助某人发现最初的问题)。如果我将Comm Mask设置为零,并在每次循环迭代中将其重置为EV_RXCHAR,它似乎可以正常工作;也就是说,当我第二次到达WaitCommEvent行时,它不会像以前那样自动触发。不好的是,我无法解释为什么它现在可以工作,而且我认为它也应该首先正确地工作。因此,任何帮助将不胜感激。这是具有变通方法的代码,该代码将CommMask设置为零并返回到EV_RXCHAR:
#include <Windows.h>
#include <stdio.h>
void main(void){
printf("Hello!\n");
DWORD dwCommEvent;
DWORD dwRead;
DWORD lpEvtMask;
char chRead;
char ComPortName[] = "\\\\.\\COM9"; // Name of the Serial port(May Change) to be opened,int i=0;
HANDLE hComm;
hComm = CreateFile( ComPortName,GENERIC_READ | GENERIC_WRITE,OPEN_EXISTING,0);
if (hComm == INVALID_HANDLE_VALUE)
printf("Error opening port.\n");
//////////////////////////////////////////////////////
DCB dcb;
FillMemory(&dcb,sizeof(dcb),0);
if (!GetCommState(hComm,&dcb)) // get current DCB
printf("Error GetCommState.\n");
// Update DCB rate.
dcb.Baudrate = CBR_9600 ;
dcb.ByteSize = 8; // Setting ByteSize = 8
dcb.StopBits = OnesTOPBIT; // Setting StopBits = 1
dcb.Parity = nopARITY; // Setting Parity = None
dcb.DCBlength = sizeof(dcb);
// Set new state.
if (!SetCommState(hComm,&dcb))
printf("Error SetCommState.\n");
// Error in SetCommState. Possibly a problem with the communications
// port handle or a problem with the DCB structure itself.
/////////////////////////////////////////////////////////////////////
COMMTIMEOUTS timeouts;
timeouts.ReadIntervalTimeout = MAXDWORD;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.WritetotalTimeoutMultiplier = 0;
timeouts.WritetotalTimeoutConstant = 0;
if (!SetCommTimeouts(hComm,&timeouts))
printf("Error timeouts.\n");
if(!PurgeComm(hComm,PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT))
printf("Error PurgeComm.\n");
////////////////////////////////////////
for ( ; ; ) {
if (!SetCommMask(hComm,0))
printf("Error CommMask.\n");
if (!SetCommMask(hComm,EV_RXCHAR))
printf("Error CommMask.\n");
printf("Waiting for characters.. \n\n");
if (WaitCommEvent(hComm,&dwCommEvent,NULL)) {
do {
if (ReadFile(hComm,&chRead,1,&dwRead,NULL)){
if(dwRead!=0)
printf("Character Received: %c\n",chRead);
}
else{
printf("ErrorReadFile.\n");
break;
}
}while (dwRead);
}
else{
printf("Error WaitCommEvent.\n");
break;
}
printf("=========================\n");
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)