win32 串口通信 同步方式 和异步方法 比较

参考网址:

https://blog.csdn.net/zhuyonghao123/article/details/8162250

并作了修改,可以与TC35 模块通信。

1. 同步模式

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>

HANDLE Open_driver_T(TCHAR *name)
{
       //打开串口
       HANDLE m_hCom = CreateFile(name,
                                  GENERIC_READ | GENERIC_WRITE, 
                                  0, 
                                  NULL,
                                  OPEN_EXISTING, 
                                  0, 
                                  NULL
                                  );

       if(m_hCom == INVALID_HANDLE_VALUE)
       {
            printf("Create File faile\n");          
            return NULL;
       }

       //设置缓冲区大小

       if(!SetupComm(m_hCom,1024,1024))
      {
             printf("SetupComm fail!\n");
             CloseHandle(m_hCom);
             return NULL;
       }

       //设置超时
       COMMTIMEOUTS TimeOuts;
       memset(&TimeOuts,0,sizeof(TimeOuts));
       TimeOuts.ReadIntervalTimeout = 100;
       TimeOuts.ReadTotalTimeoutConstant = 1000;
       TimeOuts.ReadTotalTimeoutMultiplier = 100;
       TimeOuts.WriteTotalTimeoutConstant = 2000;
       TimeOuts.WriteTotalTimeoutMultiplier = 50;
       SetCommTimeouts(m_hCom,&TimeOuts);

       PurgeComm(m_hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);

       //设置串口参数
       DCB dcb = {0};

       if (!GetCommState(m_hCom,&dcb))
       {
            printf("GetCommState fail\n");
            return NULL;
       }

       dcb.DCBlength = sizeof(dcb);

       if (!BuildCommDCB(TEXT("9600,n,8,1"),&dcb))//填充DCB的数据传输率、奇偶校验类型、数据位、停止位
       {
            printf("BuileCOmmDCB fail\n");
            CloseHandle(m_hCom);
            return NULL;
       }

       if(SetCommState(m_hCom,&dcb))
       {
            printf("SetCommState OK!\n");

       }

       return m_hCom;

}


unsigned char Send_driver_T(HANDLE fd, BYTE *data,DWORD dwDataLen)
{
       DWORD dwError;
       DWORD dwExpectSend = dwDataLen;
       DWORD dwRealSend = 0;
       BYTE *pSendBuffer;

       pSendBuffer = data;

       if(ClearCommError(fd,&dwError,NULL))
       {
            PurgeComm(fd,PURGE_TXABORT | PURGE_TXCLEAR);
       }

       if(!WriteFile(fd,pSendBuffer,dwExpectSend ,&dwRealSend,NULL))
       {    
            //写串口失败
            printf("发送失败!\n");
            return 1;
       }

       return 0;
}



unsigned char Receive_driver_T(HANDLE fd, BYTE *data)
{
       DWORD dwError;
       DWORD dwWantRead = 20;
       DWORD dwRealRead = 0;
       BYTE* pReadBuf;

       int i;


       pReadBuf = data;

       if (ClearCommError(fd,&dwError,NULL))
       {
            PurgeComm(fd,PURGE_TXABORT | PURGE_TXCLEAR);
       }

       if(!ReadFile(fd,pReadBuf,dwWantRead ,&dwRealRead,NULL))    //成功返回非0 //失败返回0
       {
            return 1;

       }

       if(dwRealRead>0){
            printf("recv_len = %d\n",dwRealRead);
       }

       printf("接收数据: ");

       for(i=0; i<dwRealRead; i++)
       {
            printf("%.2x ",data[i]);
       }

       printf("\n");

       return 0;

}

int Close_driver(void *fd)
{
       CloseHandle(fd);
       return 0;
}

void _tmain(int argc, _TCHAR* argv[])
{
       HANDLE hCom;
       BYTE SendData[20] = "AT\r\n";
       BYTE RecvData[100] = {0};

       unsigned int SendCnt=0;
       unsigned int RecvCnt=0;


       hCom = Open_driver_T(TEXT("COM6"));

       if(!hCom)
       {
            printf("串口端口打开失败\n");
            return ;
       }
       else
       {
            printf("串口端口打开成功!\n");   
       }

       SendCnt=0;

        if(Send_driver_T(hCom, SendData,4))
        {
                printf("send fail\n");
        }
        else
        {
                printf("send success!\n");
        }

        //Sleep(1000);

        printf("\n");

        if(Receive_driver_T(hCom, RecvData))
        {
                printf("recv fail!\n");
        }
        else
        {

                printf("recv success!\n");
        }

        Sleep(1000);

}

2. 异步模式

#include "stdafx.h"
#include <windows.h>
#include <stdio.h>


OVERLAPPED wrOverlapped;


HANDLE Open_driver_Y(TCHAR *name)
{
    //打开串口

    HANDLE m_hCom = CreateFile(name,
                               GENERIC_READ | GENERIC_WRITE, 
                               0, 
                               NULL,
                               OPEN_EXISTING, 
                               FILE_FLAG_OVERLAPPED, 
                               NULL);
    if(m_hCom == INVALID_HANDLE_VALUE)
    {
        printf("Create File faile\n");
        return NULL;
    }

    //设置缓冲区大小
    if(!SetupComm(m_hCom,1024,1024))
    {
        printf("SetupComm fail!\n");
        CloseHandle(m_hCom);
        return NULL;
    }

    //设置超时
    COMMTIMEOUTS TimeOuts;

    memset(&TimeOuts,0,sizeof(TimeOuts));
    TimeOuts.ReadIntervalTimeout = 100;
    TimeOuts.ReadTotalTimeoutConstant = 1000;
    TimeOuts.ReadTotalTimeoutMultiplier = 100;
    TimeOuts.WriteTotalTimeoutConstant = 2000;
    TimeOuts.WriteTotalTimeoutMultiplier = 50;
    SetCommTimeouts(m_hCom,&TimeOuts);

    PurgeComm(m_hCom,PURGE_TXCLEAR|PURGE_RXCLEAR);

    //设置串口参数
    DCB dcb = {0};

    if (!GetCommState(m_hCom,&dcb))
    {
            printf("GetCommState fail\n");
            return NULL;
    }

    dcb.DCBlength = sizeof(dcb);

    if (!BuildCommDCB(TEXT("9600,n,8,1"),&dcb))//填充DCB的数据传输率、奇偶校验类型、数据位、停止位
    {
        printf("BuileCOmmDCB fail\n");
        CloseHandle(m_hCom);
        return NULL;
    }

    if(SetCommState(m_hCom,&dcb))
    {
        printf("SetCommState OK!\n");
    }

    //建立并初始化重叠结构
    ZeroMemory(&wrOverlapped,sizeof(wrOverlapped));

    if (wrOverlapped.hEvent != NULL)
    {
        ResetEvent(wrOverlapped.hEvent);

        wrOverlapped.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
    }

    return m_hCom;

}


unsigned char Send_driver_Y(HANDLE fd, BYTE *data,DWORD dwDataLen)
{
    DWORD dwError;
    DWORD dwExpectSend = dwDataLen;
    DWORD dwRealSend = 0;
    BYTE *pSendBuffer;

    pSendBuffer = data;

    if(ClearCommError(fd,&dwError,NULL))
    {
            PurgeComm(fd,PURGE_TXABORT | PURGE_TXCLEAR);
    }

    if(!WriteFile(fd,pSendBuffer,dwExpectSend ,&dwRealSend,&wrOverlapped))
    {    
        if(GetLastError() == ERROR_IO_PENDING)
        {
            while(!GetOverlappedResult(fd,&wrOverlapped,&dwRealSend,FALSE))  
            //成功返回非0,失败返回0
            {
                if(GetLastError() == ERROR_IO_INCOMPLETE)
                {
                    continue;
                }
                else
                {
                    printf("send Fail!\n");
                    ClearCommError(fd,&dwError,NULL);
                    return 1;

                }

            }

        }

    }

    return 0;

}


unsigned char Receive_driver_Y(HANDLE fd, BYTE *data)
{

    DWORD dwError;
    DWORD dwWantRead = 20;
    DWORD dwRealRead = 0;
    BYTE* pReadBuf;
    int i;
    BYTE crc;
    pReadBuf = data;

    if (ClearCommError(fd,&dwError,NULL))
    {
        PurgeComm(fd,PURGE_TXABORT | PURGE_TXCLEAR);
    }

    if(!ReadFile(fd,pReadBuf,dwWantRead,&dwRealRead,&wrOverlapped))
    {
        dwError=GetLastError();

        if(dwError == ERROR_IO_PENDING)
        {
            while(!GetOverlappedResult(fd,&wrOverlapped,&dwRealRead,TRUE))   
            //成功返回非0, 失败返回0
            {
                return 1;
            }
        }
    }

    if(dwRealRead>0){
        printf("recv_len = %d\n",dwRealRead);     
    }

    printf("接收数据\n");

    for(i=0; i<dwRealRead; i++)
    {
        printf("%.2x ",data[i]);
    }
    printf("\r\n");

    return 0;

}


int Close_driver(void *fd)
{
    CloseHandle(fd);
    return 0;
}


void _tmain(int argc, _TCHAR* argv[])
{

    HANDLE hCom;
    BYTE SendData[20] = "AT\r\n";
    BYTE RecvData[100] = {0};
    unsigned int SendCnt=0;
    unsigned int RecvCnt=0;
    int i;

    hCom = Open_driver_Y(TEXT("COM6"));
    if(!hCom)
    {
        printf("串口端口打开失败\n");
        return ;
    }
    else
    {
        printf("串口端口打开成功!\n");
    }


    if(Send_driver_Y(hCom, SendData,4))
    {
        printf("Send Fail \n");
    }

    else
    {
        printf("Send Success \n");
    }

    printf("\n");


    if(Receive_driver_Y(hCom, RecvData))
    {
        printf("Recv Fail \n");
    }
    else
    {
        printf("Recv Success \n");
    }

    Sleep(1000);

}

运行结果:

SetCommState OK!
串口端口打开成功!
Send Success

recv_len = 9
接收数据
41 54 0d 0d 0a 4f 4b 0d 0a
Recv Success
请按任意键继续. . .

猜你喜欢

转载自blog.csdn.net/wowocpp/article/details/80594445