📄 serialio.cpp
字号:
else
{
memcpy(Getmsg, "FALSE!", 6);
return Getmsg;
}
}
char* Tc35SMSC(char* str)
{
msg[0] = 0;
strcat(msg,SMSCMsgs);
if(!ReadWriteTc35t(1, (BYTE*) msg, inBuffer))
{
memcpy(Getmsg, "FALSE!", 6);
return Getmsg;
}
// ReadWriteTc35t(1, (BYTE*) msg, inBuffer);
int p = SearchStr((char*)inBuffer,": ");
if(p > 0)
{
int p1 = SearchStr((char*)(inBuffer + p + 2), ",");
inBuffer[p+p1+2] = 0;
memcpy(str,(char*)&inBuffer[p+2], p1+1);
return str;
}
else
{
memcpy(Getmsg, "FALSE!", 6);
return Getmsg;
}
}
BOOL ReadWriteTc35t(long dt, BYTE* cmdstr, BYTE* rslstr)
{
if(!WriteCOMM(cmdstr, _mbstrlen((char*)cmdstr)))
return FALSE;
Delay(800);
if(!ReadCOMM(rslstr))
return FALSE;
return TRUE;
}
//////////////////////////Internal Functions/////////////////////////.
//返回非-1时,为串内相对地址
int SearchStr(char* sstr, char* dstr)
{
char *sp, *temp;
int len = 1000;
sp = NULL;
temp = sstr;
len = InputLength;
while((sp + strlen(dstr)) <= (sstr + len))
{
sp = (char*)memchr(sstr, *dstr, len);
if(sp == 0)
return -1;
if(memcmp(dstr,sp,strlen(dstr)) == 0)
{
return sp - temp;
}
else
{
len = len - (sp -sstr);
sstr = (sp + 1);
}
}
return -1; //搜索不到指定的字符串
}
void EmptyBuffer(BYTE* str, int bufflen)
{
for(int i = 0; i < bufflen; i++)
{
*str++ = 0;
}
}
void TestString(BYTE * test)
{
//////测试16个字节传送///////////////////
//格式:标志(0)+ 错误(1)+次数(2)+表号(3,4)+报警量(5)+累计L(6,7)
// +标志(8)+剩余(9,10)+累计H(11)+新购(12,13)+透支(14)+校验(15)
/* test[0] = 0x5U;
test[1] = 0x83;
test[2] = 0x0a;
test[3] = 0x12;
test[4] = 0x34;
test[5] = 0x0e;
test[6] = 0x00;
test[7] = 0x00;
test[8] = 0x5U;
test[9] = 0xff;
test[10] = 0xff;
test[11] = 0x04;
test[12] = 0x00;
test[13] = 0x0a;
test[14] = 0xf6;
test[15] = MakeCheckCode(test,15);
*/
//读测试用模拟数据,????为剩余量(-1),设InputLength = 52, 不做校验检查
memcpy(test,"0000,\"13507134096\",,\"12345678#12345678#123\"\r\n OK!\0", 52);
}
//////////////////////// RS232串口通讯函数 ////////////////////////////
//
BOOL CheckRS232(char* str)
{
WORD dwSize;
BOOL rv = TRUE;
//打开端口
my_hCommFile = CreateFile(str, GENERIC_READ | GENERIC_WRITE,
0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if(my_hCommFile == INVALID_HANDLE_VALUE)
{
// strcpy(display,"不能打开串口!");
return FALSE;
}
//获取端口全部性能
LPCOMMPROP lpCommProp = (LPCOMMPROP)malloc(sizeof(COMMPROP));
lpCommProp->wPacketLength = sizeof(COMMPROP);
GetCommProperties(my_hCommFile, lpCommProp);
dwSize = lpCommProp->wPacketLength;
free(lpCommProp);
lpCommProp = (LPCOMMPROP)malloc(dwSize);
lpCommProp->wPacketLength = dwSize;
GetCommProperties(my_hCommFile, lpCommProp);
//检查端口RS232/WINDOWS性能
if(!Capabilities(lpCommProp -> dwProvCapabilities))
rv = FALSE;
//常用属性设置允许检查
if(!SettaleParams(lpCommProp -> dwSettableParams))
rv = FALSE;
free(lpCommProp);
return rv;
}
//检查端口RS232/WINDOWS性能
//返回TRUE=符合RS232/WINDOWS标准
BOOL Capabilities(DWORD CAPS)
{
BOOL rv = TRUE;
if(!(CAPS & PCF_DTRDSR))
{
// strcpy(display,"端口不支持DTR/DSR握手");
rv = FALSE;
}
else if(!(CAPS & PCF_RTSCTS))
{
// strcpy(display,"端口不支持RTS/CTS握手");
rv = FALSE;
}
else if(!(CAPS & PCF_RLSD))
{
// strcpy(display,"端口不支持RLSD");
rv = FALSE;
}
else if(!(CAPS & PCF_PARITY_CHECK))
{
// strcpy(display,"端口不支持奇偶校验");
rv = FALSE;
}
else if(!(CAPS & PCF_XONXOFF))
{
// strcpy(display,"端口不支持XON/XOFF握手");
rv = FALSE;
}
else if(!(CAPS & PCF_SETXCHAR))
{
// strcpy(display,"端口不支持可设置的XON/XOFF字符");
rv = FALSE;
}
else if(!(CAPS & PCF_TOTALTIMEOUTS))
{
// strcpy(display,"端口不支持总超时设置");
rv = FALSE;
}
else if(!(CAPS & PCF_INTTIMEOUTS))
{
// strcpy(display,"端口不支持区间超时设置");
rv = FALSE;
}
// else if(!(CAPS & PCF_16BITMODE))
// {
// strcpy(display,"端口不支持16位模式");
// rv = FALSE;
// }
return rv;
}
//端口属性设置允许检查
//返回TRUE=符合RS232/WINDOWS标准
BOOL SettaleParams(DWORD PARAMS)
{
BOOL rv = TRUE;
if(!(PARAMS & SP_PARITY))
{
// strcpy(display,"不允许设置奇偶校验方式");
rv = FALSE;
}
else if(!(PARAMS & SP_BAUD))
{
// strcpy(display,"不允许设置波特速率");
rv = FALSE;
}
else if(!(PARAMS & SP_DATABITS))
{
// strcpy(display,"不允许设置数据位个数");
rv = FALSE;
}
else if(!(PARAMS & SP_STOPBITS))
{
// strcpy(display,"不允许设置停止位");
rv = FALSE;
}
else if(!(PARAMS & SP_HANDSHAKING))
{
// strcpy(display,"不允许设置握手方式");
rv = FALSE;
}
else if(!(PARAMS & SP_PARITY_CHECK))
{
// strcpy(display,"不允许设置奇偶校验允许/禁止");
rv = FALSE;
}
else if(!(PARAMS & SP_RLSD))
{
// strcpy(display,"不允许设置RLSD");
rv = FALSE;
}
return rv;
}
BOOL ReadCOMM(BYTE *InBuffer)
{
DWORD dwLastError;
DWORD nNumberOfBytesRead;
OVERLAPPED OverlappedRead = {0, 0, 0, 0, NULL};
DWORD endtime;
OverlappedRead.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
DWORD dwErrorMask;
COMSTAT comstat;
DWORD len = -1,Temlen = 0;
// EmptyBuffer(inBuffer, 4096);
EmptyBuffer((BYTE*)Getmsg, 200);
InputLength = Temlen = 0;
ClearCommError(my_hCommFile,&dwErrorMask, &comstat);
while(comstat.cbInQue == 0) //如果输入缓冲区空,则等待500ms
{
endtime = GetTickCount() + 500; //waiting For 500ms
while(GetTickCount() < endtime);
ClearCommError(my_hCommFile,&dwErrorMask, &comstat);
if(++Temlen >= 11)
{
// MessageBox(NULL, "10秒内无接收的数据\n","读数据错误", MB_ICONERROR);
return -3;
}
}
Temlen = 0;
if(comstat.cbInQue > 4000)
len = 4000;
else
len = comstat.cbInQue;
InputLength = len; //搜索长度
EmptyBuffer(InBuffer, 256);
do
{
if (!ReadFile(my_hCommFile, InBuffer + Temlen, len,
&nNumberOfBytesRead, &OverlappedRead))
{
nNumberOfBytesRead = 0;
dwLastError = GetLastError();
// LastError was ERROR_IO_PENDING, as expected.
if (dwLastError == ERROR_IO_PENDING)
{
endtime = GetTickCount() + 5000; //waiting For 5s
while(!GetOverlappedResult(my_hCommFile,&OverlappedRead, &nNumberOfBytesRead, FALSE))
{
if(GetTickCount() > endtime)
{
// MessageBox(NULL, "超时1,读不到数据\n","读数据错误", MB_ICONERROR);
return -1;
}
}
}
else
{
//Handle Errors
if (dwLastError == ERROR_INVALID_HANDLE)
{
// MessageBox(NULL, "ERROR_INVALID_HANDLE \n\n 端口可能已关闭",
// "读数据错误", MB_ICONERROR);
}
else
{
// MessageBox(NULL, "发生GetOverlappedResult错误\n","读数据错误",
// MB_ICONERROR);
}
return -2;
}
}
//搜索结束标志“OK”
if(SearchStr((char*)inBuffer,"OK") < 0)
{
Delay(1000);
ClearCommError(my_hCommFile,&dwErrorMask, &comstat);
if(comstat.cbInQue > 1000)
{
Temlen = len;
len = comstat.cbInQue;
nNumberOfBytesRead = 0;
}
else
{
Temlen = len;
len = comstat.cbInQue;
nNumberOfBytesRead = 0;
}
InputLength = InputLength + len; //搜索长度
}
}while(nNumberOfBytesRead < (DWORD)len);
ResetEvent(OverlappedRead.hEvent);
PurgeComm(my_hCommFile, PURGE_RXCLEAR); //clear receive buffer
InBuffer[Temlen+len] = '\0'; //add a String end
return TRUE;
}
BOOL WriteCOMM(BYTE *OutBuffer, int len)
{
DWORD dwLastError;
DWORD dwNumberOfBytesWritten = 0;
DWORD dwNumberOfBytesToWrite = 0;
OVERLAPPED OverlappedWrite = {0, 0, 0, 0, NULL};
DWORD endtime;
OverlappedWrite.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
dwNumberOfBytesToWrite = len;
PurgeComm(my_hCommFile, PURGE_TXCLEAR); //clear send buffer
do
{
if (!WriteFile(my_hCommFile, OutBuffer,
dwNumberOfBytesToWrite, &dwNumberOfBytesWritten,
&OverlappedWrite))
{
dwNumberOfBytesWritten = 0;
dwLastError = GetLastError();
// LastError was ERROR_IO_PENDING, as expected.
if (dwLastError == ERROR_IO_PENDING)
{
endtime = GetTickCount() + 5000; //waiting For 5s
while(!GetOverlappedResult(my_hCommFile,&OverlappedWrite,
&dwNumberOfBytesWritten, FALSE))
{
if(GetTickCount() > endtime)
{
// MessageBox(NULL, "超时,不能写数据\n","写数据错误", MB_ICONERROR);
return -1;
}
}
}
else
{
//Handle Errors
if (dwLastError == ERROR_INVALID_HANDLE)
{
// MessageBox(NULL, "ERROR_INVALID_HANDLE \n\n 端口可能已关闭",
// "写数据错误", MB_ICONERROR);
}
else
{
// MessageBox(NULL, "发生GetOverlappedResult错误\n","写数据错误",
// MB_ICONERROR);
}
return -2;
}
}
}while(dwNumberOfBytesWritten < dwNumberOfBytesToWrite);
ResetEvent(OverlappedWrite.hEvent);
PurgeComm(my_hCommFile, PURGE_TXCLEAR); //clear send buffer
return TRUE;
}
BOOL SetupCOMM(int port)
{
char* PN[] = {"COM1", "COM2", "COM3", "COM4"};
COMMTIMEOUTS commtimeouts;
DCB dcb;
DWORD fdwEvtMask;
//如果port已经打开,返回
if(IniFlag == port)
{
PurgeComm(my_hCommFile, PURGE_TXCLEAR); //clear send buffer
PurgeComm(my_hCommFile, PURGE_RXCLEAR); //clear receive buffer
return TRUE;
}
//如果已经打开了另一个串口,关闭它。打开port。
//如果没有打开任何串口(iniflag= -1),打开port。
else if(IniFlag != -1)
{
CloseHandle(my_hCommFile);
}
//检查端口
if(!CheckRS232(PN[port]))
{
// MessageBox(NULL, display, "RS232端口初始化错误", MB_ICONERROR);
CloseHandle(my_hCommFile);
return FALSE;
}
GetCommState(my_hCommFile, &dcb);
GetCommMask(my_hCommFile, &fdwEvtMask);
GetCommTimeouts(my_hCommFile, &commtimeouts);
//超时设置
commtimeouts.ReadIntervalTimeout = 250;
commtimeouts.ReadTotalTimeoutMultiplier = 0;
commtimeouts.ReadTotalTimeoutConstant = 0;
commtimeouts.WriteTotalTimeoutMultiplier = 0;
commtimeouts.WriteTotalTimeoutConstant = 0;
if(!SetCommTimeouts(my_hCommFile, &commtimeouts))
return FALSE;
//设置常用属性
//波特速率:9600-115200; 数据长度:8; 停止位:1; 校验方式:无
dcb.BaudRate = CBR_9600; // CBR_9600,CBR_19200,CBR_115200;
dcb.ByteSize = 8;
dcb.StopBits = ONESTOPBIT;
dcb.Parity = None;
//设置流控制(三线接法R-T-G)
dcb.fAbortOnError = FALSE;
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fDtrControl = FALSE;
dcb.fDsrSensitivity = FALSE;
dcb.fRtsControl = FALSE;
/*
dcb.fTXContinueOnXoff=TRUE;
dcb.XonLim = 0x100;
dcb.XonChar= 0x11;
dcb.XoffChar = 0x13;
dcb.fInX = FALSE;
dcb.EofChar = 'K';
*/
/*//设置流控制(调制解调器)
dcb.fAbortOnError = FALSE;
dcb.fOutxCtsFlow = TRUE;
dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
dcb.fOutxDsrFlow = FALSE;
dcb.fDtrControl = FALSE;
dcb.fDsrSensitivity = FALSE;
*/
if(!SetCommState(my_hCommFile,&dcb))
return FALSE;
//完成设置
IniFlag = port;
PurgeComm(my_hCommFile, PURGE_TXCLEAR); //clear send buffer
PurgeComm(my_hCommFile, PURGE_RXCLEAR); //clear receive buffer
return TRUE;
}
void Delay(unsigned long tc)
{
DWORD delaytime;
delaytime = GetTickCount() + tc;
while(GetTickCount() < delaytime){};
}
// 发送不要求格式的字符串
int WriteMSG(char* str)
{
char *cp;
msg[0] = 0;
if(toupper(*str) != 'P') //检查标志P和@
{
// MessageBox(NULL, "标志P错!\n","发送数据错误", MB_ICONERROR);
return -1;
}
cp = (char*)memchr(str, '@', 15);
int l = strlen((cp+1));
if(cp == 0)
{
// MessageBox(NULL, "标志@错!\n","发送数据错误", MB_ICONERROR);
return -1; //标志错
}
else if(l > 100) //检查数据长度
{
// MessageBox(NULL, "数据长度超范围!\n","发送数据错误", MB_ICONERROR);
return -1; //长度错
}
////生成拨号命令
strcat(msg,SendMsg);
memcpy(&msg[8], (str+1), (cp - str) - 1);
msg[(cp - str) + strlen(SendMsg) - 1] = 0;
strcat(msg,"\r\n");
if(!ReadWriteTc35t(1, (BYTE*) msg, inBuffer))
return FALSE; //读写TC35T错
////检查TC35T回应,生成传送数据"*nnnnnnnn*CCCCCCCC"
if(SearchStr((char*)inBuffer,"> ") > 0)
{
/* msg[0] = 0x12;
msg[1] = 0x34;
msg[2] = 0x56;
msg[3] = 0x78;
msg[4] = 0x90;
msg[5] = 0xab;
msg[6] = 0xcd;
msg[7] = 0xef;
msg[8] = 0x1a;
msg[9] = 0x0d;
msg[10] = 0x0a;
msg[11] = 0x0;
*/
memcpy(&msg[0], (cp+1), l);
memcpy((msg + l), "\x1a\r\n\0", 4);
WriteCOMM((BYTE*)msg, _mbstrlen(msg));
Delay(10000);
ReadCOMM(inBuffer);
if(SearchStr((char*)inBuffer,"OK") < 0)
{
// MessageBox(NULL, "发送无回应\n","发送数据错误", MB_ICONERROR);
return -1; //TC35T无回应
}
}
else
{
// MessageBox(NULL, "TC35T无回应\n","发送数据错误", MB_ICONERROR);
return -1; //TC35T无回应
}
return 0;
}
// 读短信不做格式检查
char* ReadMSG(int id)
{
char *str,ch[3];
int cp1,cp2,endflag;
void *r1;
str = Getmsg;
msg[0] = 0;
////生成读命令
strcat(msg,ReadMsg);
if(id == 0) //非法ID
{
// MessageBox(NULL, "非法ID\n","接收数据错误", MB_ICONERROR);
return "非法ID";
}
strcat(msg,itoa(id,ch,10));
strcat(msg,"\r");
if(!ReadWriteTc35t(5, (BYTE*) msg, inBuffer))
return "FALSE!"; //读写TC35T错
////搜索标志r1=短信正文起始地址;endflag=短信正文长度
r1 = (char*)memchr(&inBuffer[2],'\n',70) + 1;
if(r1 <= &inBuffer[2])
return "FALSE!";
endflag = SearchStr((char*)r1,"OK");
if(endflag > 2 )
{
////////提取地址,cp1+2指向地址起始点,cp2指向地址终止点
cp1 = SearchStr((char*)inBuffer,",\"");
cp2 = SearchStr((char*)(inBuffer+cp1),"\",");
*str++ = 'p';
memcpy(str, (inBuffer+cp1+2), cp2-2);
memcpy(str+cp2-2, "@\0", 2);
////////提取有效数据,cp1+1指向数据起始点,cp2指向数据终止点
memcpy(outstring, r1, endflag - 4);
ID--;
memcpy((str+cp2 - 1), outstring, endflag-4);
memcpy((str + cp2 - 1 + endflag - 4), "\0",1);
return --str;
}
else
{
return "EMPTY!"; //读写TC35T错
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -