C串口通信 - 數據傳送到遠程機器

1 應用到com0com,com0com是一個易於使用的內核模式虛擬串行端口驅動程序,以幫助您的工作需要。

命令:install PortNum=COM3 PortNum=COM4

表示建立一個COM3發送數據到COM4的連接。執行命令後會在設備管理器中看到這兩個虛擬的串口。


2 分爲兩個代碼文件

 A -- client -- com.c : A機器將讀取串口數據,然後用TCP連接發送到B機器

 B -- remote_machine.c:  B機器接收A傳送來的數據,就好像B機器能直接讀取A機器的串口一樣。


3 串口通信

 COM3:用串口調試工具 發送數據

 COM4:用C程序監聽此串口,讀取數據


4 TCP

 A機器:作爲client端,連接遠程機器B

 B機器:作爲server端


5 附上源代碼

  A -- client -- com.c :


#include<stdio.h>
#include<windows.h>
#include<stdlib.h>
#include<WINSOCK2.H>
struct COMMTIMEOUTS {    
    DWORD ReadIntervalTimeout;   
    DWORD ReadTotalTimeoutMultiplier;   
    DWORD ReadTotalTimeoutConstant;   
    DWORD WriteTotalTimeoutMultiplier;   
    DWORD WriteTotalTimeoutConstant;
};
HANDLE m_hIDComDev;///////////////打開串口 句柄
int delay = 5;
/***********************************************************************************************
initialSerial
功能:串口初始化
***********************************************************************************************/
void initialSerial()   //串口初始化
{
    char szComParams[50];
    DCB dcb;
    char *m_com; char *m_baud; char *m_jiaoyan;
    m_com="Com4";
    m_baud="1200";
    m_jiaoyan="E";
                      
    COMMTIMEOUTS CommTimeOuts;
    m_hIDComDev = NULL;
    m_hIDComDev = CreateFile(m_com, GENERIC_READ|GENERIC_WRITE, 0, NULL,
        OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);  //打開串口
                     
    if(m_hIDComDev==INVALID_HANDLE_VALUE)
    {
        printf("打開串口錯誤0,請檢查!");
        goto endd;
    }
    if(m_hIDComDev ==(HANDLE) -1)
    {
        printf("打開串口錯誤,請檢查!");
        goto endd;
    }
                     
    SetCommTimeouts(m_hIDComDev, &CommTimeOuts);  //串口超時配置
    CommTimeOuts. ReadIntervalTimeout= 0xFFFFFFFF;//"0xFFFFFFFF";
    CommTimeOuts. ReadTotalTimeoutMultiplier = 0;
    CommTimeOuts. ReadTotalTimeoutConstant =5000;
    CommTimeOuts. WriteTotalTimeoutMultiplier = 0;
    CommTimeOuts. WriteTotalTimeoutConstant = 5000;
    PurgeComm(m_hIDComDev, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR ) ;
    m_com="Com4:38400,E,8,1";
    wsprintf(szComParams, m_com);   //設置串口參數
                     
    dcb. DCBlength = sizeof(DCB);
    GetCommState(m_hIDComDev, &dcb);//
                    
    int baud;
    baud = atoi(m_baud);
    dcb. BaudRate = baud;   //設置波特率
    dcb. ByteSize= 8; //設置校驗字節
                     
                     
                     
    if ((!SetCommState(m_hIDComDev, &dcb))||(!SetupComm(m_hIDComDev,10000,10000)))//設置串口和收發緩衝器的大小
    {
        DWORD dwError = GetLastError();
        CloseHandle(m_hIDComDev);
    }
    PurgeComm(m_hIDComDev,PURGE_RXCLEAR|PURGE_TXCLEAR|PURGE_TXABORT|PURGE_RXABORT);//清收發緩衝器
endd:
    ;
}
/************************************************************************************************
SendData
功能:發送數據給串口
************************************************************************************************/
DWORD SendData( unsigned char buff[],int send_length)    //發送數據
{ 
    int t;
    DWORD dwBytesWritten;
    if(!WriteFile(m_hIDComDev,buff,send_length,&dwBytesWritten,NULL))
    {
        return 0;
    }
    for (t=0;t<send_length;t++)
        fprintf(stdout," %2X ",buff[t]);
    printf("\n");
    PurgeComm(m_hIDComDev,PURGE_TXCLEAR); //清發送緩衝區
    return 1;
}
/***********************************************************************************************
ReadData
功能:從串口讀取數據
參數:rebuff  收到的數據  dwBytesRead   要收到的長度    delay   延時
***********************************************************************************************/
DWORD ReadData(unsigned char rebuff [],DWORD dwBytesRead )  //讀取數據
{
    DWORD dwErrorFlags;
    COMSTAT stat;
    if(delay>0)                                                                                 
        ClearCommError(m_hIDComDev,&dwErrorFlags,&stat);
    if(stat.cbInQue <= 0)  //"stat.cbInQue" is  bytes in input buffer
        return 0;
    dwBytesRead = min(dwBytesRead,(DWORD)stat.cbInQue); //獲取字符個數
                     
    if(!ReadFile(m_hIDComDev,rebuff,dwBytesRead,&dwBytesRead,NULL))  //整體讀入
    {
        return 0;
    }
    return dwBytesRead;
}
void tcpSend(unsigned char ch[])
{
    int err;
    char receiveBuf[100]={"0"};
    char ip_addr[16];
    WORD versionRequired;
    WSADATA wsaData;
    versionRequired=MAKEWORD(1,1);
    err=WSAStartup(versionRequired,&wsaData);
    SOCKET clientSocket;
    SOCKADDR_IN clientsock_in;
    if (err)
    {
        return;
    }
    clientSocket=socket(AF_INET,SOCK_STREAM,0);
                     
    clientsock_in.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
    clientsock_in.sin_family=AF_INET;
    clientsock_in.sin_port=htons(6000);
    connect(clientSocket,(SOCKADDR*)&clientsock_in,sizeof(SOCKADDR));
                     
                     
                     
    recv(clientSocket,receiveBuf,101,0);
    //printf("%s\n",ch);
    send(clientSocket,ch,101,0);//應用TCP連接發送串口數據
}
void comRead(unsigned char ch1[])
{
    int send_length  = 100;  // 接收的長度
    printf("begin\n");
    initialSerial();
    printf("init end.\n");
    printf("begin send.\n");
    /*r = SendData(ch,send_length);
    if(r)
       printf("send end.\n");
       else
    printf("error\n");*/
    DWORD x ;
    while(1)
    {  
        x = ReadData(ch1,send_length);
        sleep(1);
        printf("waiting for data...\n");
        if(x)
              break;
    }
}
main()
{
    int i,r;
    unsigned char ch[10] = "hello";
    unsigned char ch1[100] = "\0";
                     
    comRead(ch1);//讀取 串口數據  到 ch1 數組
                     
    printf("\n\n\n\n");
    printf("Machine A...\n\n接收本機串口數據中...\n");
    printf("接收數據顯示:%s\n",ch1);
    printf("發送至MachineB中...\n");
    tcpSend(ch1); // 將串口數據發送到 遠程機器
    printf("end.\n");
    system("pause");
}

B -- remote_machine.c:

#include<stdio.h>
#include<windows.h>
#include<stdlib.h>
#include <WINSOCK2.H>
int main()
{
   SOCKADDR_IN clientsocket;
   SOCKET serConn;
   WORD myVersionRequest;
   WSADATA wsaData;
   myVersionRequest=MAKEWORD(1,1);
   int err;
   int len=sizeof(SOCKADDR);
   err=WSAStartup(myVersionRequest,&wsaData);
   if (err)
   {
       return -1;
   }
   SOCKET serSocket=socket(AF_INET,SOCK_STREAM,0);
   SOCKADDR_IN addr;
   addr.sin_family=AF_INET;
   addr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
   addr.sin_port=htons(6000);
               
   bind(serSocket,(SOCKADDR*)&addr,sizeof(SOCKADDR));
   listen(serSocket,5);
               
               
   printf("Machine B...\n識別Machine A機器的串口...\n接收數據中...\n");
              
   char sendBuf[50];
   serConn=accept(serSocket,(SOCKADDR*)&clientsocket,&len);
   sprintf(sendBuf,"welcome!",inet_ntoa(clientsocket.sin_addr));
   send(serConn,sendBuf,strlen(sendBuf)+1,0);
               
   char recvBuf[100];
   recv(serConn,recvBuf,101,0);
   printf("接收成功\n\n數據顯示:%s\n",recvBuf);
                
   system("pause");
   return 0;
}



 主要用於自己記錄,當然也希望能幫組有需要的同學。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章