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;
}



 主要用于自己记录,当然也希望能帮组有需要的同学。

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