串口发送的数据的格式 有格式的 长度(2)+数据+0x03+lrc #include <windows.h> #include <stdlib.h> #include <stdio.h> HANDLE gComHandle; #define SI 0xf #define SO 0xe #define STX 0x02 #define ETX 0x03 void LogToFile(char *fmt,...) { va_list pvar; char buffer[2048]; char log[2048]; // char filename[40]; // FILE *fp; // memset(filename,0,sizeof(filename)); // sprintf(filename,"%08d.txt",GetDate()); // fp=fopen(filename,"a"); memset(buffer,0,sizeof(buffer)); memset(log,0,sizeof(log)); va_start(pvar,fmt); vsprintf(buffer,fmt,pvar); va_end(pvar); sprintf(log,"%s",buffer); printf("%s\n",log); // fprintf(fp,"%s\n",log); fflush(stdout); // fflush(fp); // fclose(fp); } unsigned char GenLrc(unsigned char *Data,size_t DataLen) { unsigned int i; unsigned char lrc = 0; for (i = 0; i < DataLen; i++) { lrc ^= Data[i]; } return lrc; } int InitCom(void) { COMMTIMEOUTS TimeOuts; DCB dcb; gComHandle=CreateFile("COM2",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL); if(gComHandle==(HANDLE)-1) { LogToFile("打开COM失败!"); return -1; } SetupComm(gComHandle,1024,1024); //输入缓冲区和输出缓冲区的大小都是1024 // 设定读超时 TimeOuts.ReadIntervalTimeout=MAXDWORD; TimeOuts.ReadTotalTimeoutMultiplier=MAXDWORD; TimeOuts.ReadTotalTimeoutConstant=10000; TimeOuts.WriteTotalTimeoutMultiplier=MAXDWORD; TimeOuts.WriteTotalTimeoutConstant=10000; SetCommTimeouts(gComHandle,&TimeOuts); //设置超时 GetCommState(gComHandle,&dcb); dcb.BaudRate=115200; //波特率为115200 dcb.ByteSize=8; //每个字节有8位 dcb.Parity=NOPARITY; //无奇偶校验位 dcb.StopBits=ONESTOPBIT; // SetCommState(gComHandle,&dcb); return TRUE; } int ComSent(char * packet,int len) { char buf[6]; BOOL result; size_t lens; size_t sendlen; int i; buf[0] = STX; buf[1] = (unsigned char)(((((len / 1000) % 10) << 4) & 0xf0) | (((len / 100) % 10) & 0x0f)); buf[2] = (unsigned char)(((((len / 10) % 10) << 4) & 0xf0) | ((len % 10) & 0x0f)); buf[3] = ETX; buf[4] = ETX; buf[5] = '\r'; for(i = 0; i < len; i++) buf[4] ^= packet[i]; buf[4] ^= buf[1]; buf[4] ^= buf[2]; result=WriteFile(gComHandle,buf,3,&sendlen,NULL); //FlushFileBuffers(gComHandle); if(result==0) { LogToFile("发送数据失败1"); return -1; } else { if(sendlen != 3) return -1; } result=WriteFile(gComHandle,packet,len,&sendlen,NULL); FlushFileBuffers(gComHandle); if(result==0) { LogToFile("发送数据失败2"); return -1; } else { if(sendlen != len) return -1; } result=WriteFile(gComHandle,buf+3,2,&sendlen,NULL); // PurgeComm(gComHandle, PURGE_RXCLEAR | PURGE_RXABORT | PURGE_TXABORT | PURGE_TXCLEAR ); //FlushFileBuffers(gComHandle); if(result==0) { LogToFile("发送数据失败1"); return -1; } else { if(sendlen != 2) return -1; } return len; } int ComRecv(unsigned char *recvbuf,size_t *recvlen) { size_t len; size_t offset; BOOL result; DWORD recivedlen; unsigned char buffer[1024]; START: *recvlen=0; offset=0; memset(buffer,0,sizeof(buffer)); //LogToFile("%s ", "接收STX"); len=1; while(1) //接收STX { recivedlen=0; result=ReadFile(gComHandle,buffer+offset,len,&recivedlen,NULL); if(result==0) { LogToFile("接收串口报文失败1"); return -1; } else { if(buffer[0]==0x02) { len=len-recivedlen; offset+=recivedlen; if(len==0) break; } else { if(buffer[0]!=0x00) { LogToFile("%02x",buffer[0]); } continue; } } } //LogToFile("%s ", "接收串口报文2"); len=2; while(1) { recivedlen=0; result=ReadFile(gComHandle,buffer+offset,len,&recivedlen,NULL); if(result==0) { LogToFile("接收串口报文失败2"); return -1; } else { len=len-recivedlen; offset+=recivedlen; if(len==0) break; } } //HexLogToFile(&buffer[1], 2); //LogToFile("%s ", "接收data"); len=buffer[1]/16*1000+buffer[1]%16*100+buffer[2]/16*10+buffer[2]%16; while(1) { recivedlen=0; result=ReadFile(gComHandle,buffer+offset,len,&recivedlen,NULL); if(result==0) { LogToFile("接收串口报文失败3"); return -1; } else { len=len-recivedlen; offset+=recivedlen; if(len==0) break; } } //HexLogToFile(&buffer[3], offset-3); //LogToFile("%s ", "接收ETX"); len=1; while(1) { recivedlen=0; result=ReadFile(gComHandle,buffer+offset,len,&recivedlen,NULL); if(result==0) { LogToFile("接收ETX失败"); return -1; } else { if(recivedlen==1) { len=len-recivedlen; if(buffer[offset]!=0x03) { LogToFile("校验ETX失败"); // return -1; } offset+=recivedlen; if(len==0) break; } else { len=len-recivedlen; offset+=recivedlen; if(len==0) break; } } } //HexLogToFile(&buffer[3], 1); //LogToFile("%s ", "接收LRC"); len=1; while(1) { recivedlen=0; result=ReadFile(gComHandle,buffer+offset,len,&recivedlen,NULL); if(result==0) { LogToFile("接收LRC失败"); return -1; } else { if(recivedlen==1) { len=len-recivedlen; if(buffer[offset]!=GenLrc(buffer+1,offset-1)) { LogToFile("校验LRC失败"); // return -1; } offset+=recivedlen; if(len==0) break; } else { len=len-recivedlen; offset+=recivedlen; if(len==0) break; } } } // WriteHexLog(buffer+3, offset-5); if(memcmp(buffer+3,"\x60\x00\x06\x00\x00",5)!=0 && memcmp(buffer+3,"\x60\x00\x00\x00\x06",5)!=0) { buffer[offset-1]=0x00; buffer[offset-2]=0x00; // WriteHexLog(buffer+3, offset-5); LogToFile("%s", buffer+3); goto START; } // LogToFile("%s", "hexbuf"); // WriteHexLog(buffer, offset); len=offset-5; memcpy(recvbuf,buffer+3,offset-5); *recvlen=len; return 0; } int main(int argc, char * argv[]) { size_t recvlen; char hostname[20]; char port[10]; BYTE TPDU[5]; BYTE com_recvbuf[1024]; BYTE buffer[1024]; int buffer_len; int result; char str[1024]; int len; char ch; if(InitCom()<0) exit(0); printf("请输入工作方式\n发送(s).接收(r)\n"); scanf("%c",&ch); if(ch == 's') { while(1) { recvlen=0; memset(com_recvbuf,0,sizeof(com_recvbuf)); memset(buffer,0,sizeof(buffer)); LogToFile("等待串口上送报文"); printf("请输入发送的数据\n"); scanf("%s",str); len =ComSent(str,strlen(str)); LogToFile("数据发送成功"); printf("len = %d\n",len); } } else if(ch == 'r') { while(1) { LogToFile("等待串口上送报文"); ComRecv(com_recvbuf, &recvlen); } } CloseHandle(gComHandle); return 0; }