请教 vb mscoom 通讯为题

时间:2021-08-07 20:56:18
当上位机(电脑软件)与下位机(单片机)通讯时,上位机总不能将下位机发送的数据(十六进制)全部接受,每次通讯数据量在10万以下,vb的 mscoom控件的InBufferSize属性的最大值为32767,大于此值可能会溢出,但奇怪的是当小于此值时也会丢,请问丢哪里了,期待赐教!!!
以下是电脑软件程序的部分代码:

Private Sub Comm_OnComm()
   Dim IntR  as integer
   Static Resv As Variant '接收数据
   Static DataC As Long '串口数据字节数
   Static CTestData() As Byte'用于存放接受的字符
   Static FactCount As Long '累计实际接收的数据
   static TestFlag  Boolean'实验结束标志
   TestFlag = false
   Comm.RThreshold = 0 
   FactCount = 0
   DataC = Comm.InBufferCount: Resv = Comm.Input  
   ReDim CTestData(100000)
   For IntR = 0 To DataC - 1
          CTestData(IntR) = Resv(IntR)
          FactCount = FactCount + 1
   Next IntR
   
   Static CurrTime As Long '等待时间
   CurrTime = GetTickCount
   '一直接受数据,直到接受完成为止 
   do                        
           If Comm.InBufferCount >= 1000 Or Abs(GetTickCount - CurrTime) >= 100 Then
                CurrTime = GetTickCount 
                DataC = Comm.InBufferCount: Resv = Comm.Input
                For IntR = 0 To DataC - 1
                     CTestData(FactCount) = Resv(IntR)
                     FactCount = FactCount + 1                    
                     DoEvents
                     Next IntR
                End If
                DoEvents
            Endif
            Do While  Comm.InBufferCount = 0 '无数据则测试结束
              debug.print "实验结束"
              TestFlag = ture
              Exit Do
           Loop
           if TestFlag  then Exit do
        
Exit Sub




18 个解决方案

#1


接收到数据就进行处理,定义那么大数组干嘛,论坛很多串口通信的帖子,看看吧,把数据处理改改

#2


嘿嘿 的确是发重了
对于通信质量要求高或者数据量偏大的应用,不建议用 Comm_OnComm()
建议:
用双Timer实现。一个管收数据,一个管发数据。建立自己的缓冲区,不间断的接收所有的数据,知道发送端发送完毕。

#3


留一个邮箱,给你发我的基于Comm_OnComm()
的测试源码。
双Timer的涉及公司版权,恕不能相赠

#4


标题都能写错

#5


试一试这个,看看有没有丢失信息的情况,如果没有,依照这个代码写自己的程序即可。
http://download.csdn.net/source/1262066

#6


tianliang03@126.com
thinks

#7


初学串口通讯,望大家多多指教,请问用多线程解决会不会好些?

#8


不会好些
引用 7 楼 tianliang007 的回复:
初学串口通讯,望大家多多指教,请问用多线程解决会不会好些?

#9


引用 3 楼 ybh37 的回复:
留一个邮箱,给你发我的基于Comm_OnComm()
的测试源码。
双Timer的涉及公司版权,恕不能相赠

我的信箱是tianliang03@126.com
双Timer会好些吗?我尽量试试,谢谢

#10


引用 8 楼 dbcontrols 的回复:
不会好些

引用 7 楼 tianliang007 的回复:
初学串口通讯,望大家多多指教,请问用多线程解决会不会好些?

有没有别的办法?我查找了些资料,觉得多线程加缓冲池能够稳定些,还不知道会怎样。谢谢!

#11


引用楼主 tianliang09 的回复:
当上位机(电脑软件)与下位机(单片机)通讯时,...

那你知道单片机是怎么工作的吗?那么小的内存单片机既然都可以跑,PC你还怕内存不够会溢出?
不用看你的程序都知道肯定是你的程序方法上就问题。即使是能运行,也是不可取的。

#12


能说的具体点吗?请教了!

#13


具体点?那就给你看一段简单的单片机串口通讯时的处理过程吧

void COM_Event () interrupt 4 
{   
unsigned char dat = 0;
unsigned char NXorData = 0;
if(RI == 1){
//接收数据 SBUF 为单片机的接收发送缓冲寄存器
dat = SBUF;
RI = 0;
// 这里分析你收到的信息,同事可做出反应
switch(CApproach){
case 0: // 数据包头
if(dat==0xB2){
 CApproach = 1;
}
break;
case 1: // 机号
if(dat==MyNumber){
 CApproach = 2;
}else{
 CApproach = 0;
}
break;
case 2: // 命令
if(dat>=1&&dat<=7){
 CCommand = dat;
 CApproach = 3;
}else{
 CApproach = 0;
}
break;
case 3: // 命令参数
switch(CApproach){
case 1: // 探测设备命令,无参数
CXorCount = dat;
CApproach = 255;
break;
case 2: // 开启通讯监视,无参数
CXorCount = dat;
CApproach = 255;
break;
case 3: // 关闭通讯监视,无参数
CXorCount = dat;
CApproach = 255;
break;
default:
CApproach = 0;
break;
}
break;
case 255: // 接收包尾
if(dat==0xB3){
switch(CCommand){
case 1: // 探测设备命令需要进行异或校验
NXorData = 0xB2;
NXorData = NXorData^MyNumber;
NXorData = NXorData ^ CCommand;
if(NXorData==CXorCount){
SendBufToPort("LTC-20100409A",13);
}else{
CApproach = 0;
}
break;
case 2: // 开启通讯监视命令需要进行异或校验
NXorData = 0xB2;
NXorData = NXorData^MyNumber;
NXorData = NXorData ^ CCommand;
if(NXorData==CXorCount){
AddMinute = 0;
AddSecond = 0;
AddMillisecond = 0;
AddMicrosecond = 0;
Approach = 1;

SendBufToPort("Open stakeout.",14);
}else{
CApproach = 0;
}
break;
case 3: // 关闭通讯监视命令需要进行异或校验
NXorData = 0xB2;
NXorData = NXorData^MyNumber;
NXorData = NXorData ^ CCommand;
if(NXorData==CXorCount){
Approach = 0;
AddMinute = 0;
AddSecond = 0;
AddMillisecond = 0;
AddMicrosecond = 0;
SendBufToPort("Close stakeout.",14);
}else{
CApproach = 0;
}
break;
default:
CApproach = 0;
break;
}
}else{
CApproach = 0;
}
break;
}
}else{
TI = 0;
}

}

#14


再给你看一段PC处理串口通讯的过程,VC代码,该程序的完整过程可以在我的资源里找到

//============================================================================================================
//                                          关 键 部 分 代 码
//============================================================================================================
void CDemoDlg::OnOK() 
{
BOOL OpenState;
DWORD NowTickCount;
DWORD SaveTickCount;
char * SendText;
// 这里很关键,因为 Send 是通过 GlobalSize 来取得指针大小的,所以需要这样分配控件大小
SendText = (char *)GlobalAlloc(GMEM_ZEROINIT, 4);

ReturnValue = 0; //设置默认返回为失败
Approach = 0; //设置接收步骤参数

COMM1.EventRead = OnComm; //设置处理函数
COMM1.ObjClassAddress = (DWORD)this; //设置类地址,确保在OnComm过程中可以调用本类中的一些过程或变量
COMM1.Port = 1; //设置端口
COMM1.BaudRate = CBR_57600; //设置波特率
COMM1.ByteSize = 8; //设置数据位
COMM1.Parity = 0; //设置校检
COMM1.StopBits = 1; //设置停止位
OpenState = COMM1.Open(); //打开串口,这时候便开始了 OnComm 事件的侦听
if(OpenState==TRUE){
sprintf(SendText,"AT\r\n"); //设置要发送的文本内容(当然也可以发送字节流)
COMM1.Send((BYTE*)SendText); //发送文本到串口

//=========== 以下做超时处理 ===========
//超时处理总共有两个全局变量控制
//ExecOver 和 ReturnValue
ExecOver = FALSE;
SaveTickCount = GetTickCount();
while(ExecOver==FALSE){
Sleep(5);
NowTickCount = GetTickCount();
if(NowTickCount-SaveTickCount>=1000){
//超过1秒钟还未正常返回结果就自动退出循环
ReturnValue = 0;
ExecOver=TRUE;
}
}
COMM1.Close();
}
if(ReturnValue==1){
MessageBox("串口1接入的设备支持AT命令。","执行结果",64);
}else{
MessageBox("没有检测到串口1接入支持AT命令的设备。","执行结果",64);
}
}

void CDemoDlg::OnComm(DWORD pClassAddress, BYTE *ReadBuffers, DWORD ReadCount)
{
// pClassAddress 类地址,由用户自行设置 ObjClassAddress 而来
// ReadBuffers 从串口缓冲区读到的数据指针
// ReadCount 从川口缓冲区读到的数据大小
//=============== 还原类的方法,以下是范例 ===============
//CDemoDlg * DlgObj;
//DlgObj = (CDemoDlg *)pClassAddress;
//DlgObj->COMM1.Send((BYTE *)"AAA");
//========================================================
// 下面做个简单的信息识别处理

// 还原类事例对象,因为要用到类中的变量
CDemoDlg * DlgObj;
DlgObj = (CDemoDlg *)pClassAddress;

DWORD i;
if(ReadCount>0){
for(i=0;i<ReadCount;i++){
switch(DlgObj->Approach){
case 0:
if((BYTE)ReadBuffers[i]==0x0D||(BYTE)ReadBuffers[i]==0x0A){ //有可能先发换行符号
DlgObj->Approach = 1;
}else if((BYTE)ReadBuffers[i]==0x4F||(BYTE)ReadBuffers[i]==0x62){ //有可能直接发 OK 信息
DlgObj->Approach = 2;
}
break;
case 1:
if((BYTE)ReadBuffers[i]==0x4F||(BYTE)ReadBuffers[i]==0x6F){
DlgObj->Approach = 2;
}else if((BYTE)ReadBuffers[i]==0x0D||(BYTE)ReadBuffers[i]==0x0A){
DlgObj->Approach = 1;
}else{
DlgObj->Approach = 0;
}
break;
case 2:
if((BYTE)ReadBuffers[i]==0x4B||(BYTE)ReadBuffers[i]==0x6B){
DlgObj->Approach = 3;
}else{
DlgObj->Approach = 0;
}
break;
case 3:
if((BYTE)ReadBuffers[i]==0x0D||(BYTE)ReadBuffers[i]==0x0A){
DlgObj->ReturnValue = 1;
DlgObj->ExecOver = TRUE;
}
DlgObj->Approach = 0;
break;
}

}
}
}

#15


找了一下,这里还有一段VB的过程

Private Sub MSComm1_OnComm()
   Dim TempBytes() As Byte, TempBytesCount As Long
   Dim X As Long, nowxor As Long, RetEventStr As String
   On Error Resume Next
   '通过 CommEvent 属性判断是发生什么事件
   If MSComm1.CommEvent = comEvReceive Then
      JJ = JJ + 1
      ReadBytes = MSComm1.Input

      ReadCount = UBound(ReadBytes)
      'ReDim ReadBytes(ReadCount)
      'CopyMemory ReadBytes(0), TempBytes(0), ReadCount + 1

      For X = 0 To ReadCount
         Select Case Approach
         Case 201: '判断是否是结束符号
                  If ReadBytes(X) = &HB3 Then
                     '开始运算数据是否正确
                     Select Case NowCommand
                     Case &HFF:  '机器型号命令
                                 nowxor = &HB2
                                 nowxor = nowxor Xor m_ENumber
                                 nowxor = nowxor Xor NowCommand
                                 nowxor = nowxor Xor Parameter1
                                 For Y = 0 To Parameter1 - 1
                                    nowxor = nowxor Xor ReadByteArray(Y)
                                 Next Y
                                 If xorvalue = nowxor Then
                                    ReturnString = StrConv(ReadByteArray, vbUnicode)
                                 Else
                                    ReturnString = ""
                                 End If
                                 Timer1.Enabled = False
                                 WaitTime = 0
                     End Select
                  End If
                  Approach = 0               '完成处理,将步骤设置为初始阶段
         
         Case 200: '接收异或校检码准备对数据的完整性和正确性进行核对
                  xorvalue = ReadBytes(X)       '将异或校检码存入公共变量中,等就收到包尾信息后再进行处理
                  Approach = 201                '因为异或校检码属于不定值,所以无法判断是否正确,直接进入下一步等下一步进行判断
         
         
         Case 8:  '机器型号返回信息
                  ReadByteArray(ReadByteCount) = ReadBytes(X)
                  ReadByteCount = ReadByteCount + 1
                  If ReadByteCount >= Parameter1 Then
                     Approach = 200          '去接收异或校检码准备和对数据的正确性
                  End If

         Case 6:  '机器型号返回信息
                  ReturnString = ""
                  Parameter1 = ReadBytes(X)     '接收返回字符串数量
                  ReadByteCount = 0
                  ReDim ReadByteArray(Parameter1 - 1)
                  Approach = 8                  '无法验证数据的正确性,将接收步骤调整为下一步
                  
         Case 2:  '识别命令,若数据不在可识别的命令数值范围内,作弃包处理
                  Select Case ReadBytes(X)
                  Case &HFF:  '机器型号命令
                              NowCommand = &HFF
                              Approach = 6      '数据符合要求,将接收步骤调整为下一步
                  Case Else
                     Approach = 0   '数据不符合接收步骤和相关的规定,放弃该数据(弃包处理)
                  End Select
                  
         Case 1:  '识别机号,判断数据是否应该发送到本机的,若不是就不必继续处理了
                  If m_ENumber = 0 Then
                     '初始化时没有机号标准,所以直接读取信息成为机号
                     m_ENumber = ReadBytes(X)
                     Approach = 2   '数据符合要求,将接收步骤调整为下一步
                  Else
                     If ReadBytes(X) = m_ENumber Then
                        Approach = 2   '数据符合要求,将接收步骤调整为下一步
                     Else
                        Approach = 0   '数据不符合接收步骤和相关的规定,放弃该数据(弃包处理)
                     End If
                  End If
                  
         Case 0:  '根据步骤,等待包头的出现,若不是包头数据就继续等待包头
                  If ReadBytes(X) = &HB2 Then
                     Approach = 1   '数据符合要求,将接收步骤调整为下一步
                  End If
                  
         End Select
      Next X
   End If
   Exit Sub
错误处理:
   Approach = 0
End Sub

#16


引用 15 楼 supermanking 的回复:
找了一下,这里还有一段VB的过程

VB code

Private Sub MSComm1_OnComm()
   Dim TempBytes() As Byte, TempBytesCount As Long
   Dim X As Long, nowxor As Long, RetEventStr As String
   On Error Resume Next
   '通……



谢谢您!现在的问题是,想用多线程处理通信,但关于线程的安全退出一直存在问题,请问有何高见,谢谢!!!

#17


引用 16 楼 tianliang09 的回复:
谢谢您!现在的问题是,想用多线程处理通信,但关于线程的安全退出一直存在问题,请问有何高见,谢谢!!!

VB的多线程要编译P代码才好用,而且调试最好是编译EXE后运行看看,直接调试弄不好会有问题的。
VB做多线程本来就很多要注意的地方,个人感觉VC在这方面要简单和稳定很多。

#18


其实你可以参考一下我资源里的一个串口通讯的VC代码,用起来也很简单的。
http://download.csdn.net/source/2690778

#1


接收到数据就进行处理,定义那么大数组干嘛,论坛很多串口通信的帖子,看看吧,把数据处理改改

#2


嘿嘿 的确是发重了
对于通信质量要求高或者数据量偏大的应用,不建议用 Comm_OnComm()
建议:
用双Timer实现。一个管收数据,一个管发数据。建立自己的缓冲区,不间断的接收所有的数据,知道发送端发送完毕。

#3


留一个邮箱,给你发我的基于Comm_OnComm()
的测试源码。
双Timer的涉及公司版权,恕不能相赠

#4


标题都能写错

#5


试一试这个,看看有没有丢失信息的情况,如果没有,依照这个代码写自己的程序即可。
http://download.csdn.net/source/1262066

#6


tianliang03@126.com
thinks

#7


初学串口通讯,望大家多多指教,请问用多线程解决会不会好些?

#8


不会好些
引用 7 楼 tianliang007 的回复:
初学串口通讯,望大家多多指教,请问用多线程解决会不会好些?

#9


引用 3 楼 ybh37 的回复:
留一个邮箱,给你发我的基于Comm_OnComm()
的测试源码。
双Timer的涉及公司版权,恕不能相赠

我的信箱是tianliang03@126.com
双Timer会好些吗?我尽量试试,谢谢

#10


引用 8 楼 dbcontrols 的回复:
不会好些

引用 7 楼 tianliang007 的回复:
初学串口通讯,望大家多多指教,请问用多线程解决会不会好些?

有没有别的办法?我查找了些资料,觉得多线程加缓冲池能够稳定些,还不知道会怎样。谢谢!

#11


引用楼主 tianliang09 的回复:
当上位机(电脑软件)与下位机(单片机)通讯时,...

那你知道单片机是怎么工作的吗?那么小的内存单片机既然都可以跑,PC你还怕内存不够会溢出?
不用看你的程序都知道肯定是你的程序方法上就问题。即使是能运行,也是不可取的。

#12


能说的具体点吗?请教了!

#13


具体点?那就给你看一段简单的单片机串口通讯时的处理过程吧

void COM_Event () interrupt 4 
{   
unsigned char dat = 0;
unsigned char NXorData = 0;
if(RI == 1){
//接收数据 SBUF 为单片机的接收发送缓冲寄存器
dat = SBUF;
RI = 0;
// 这里分析你收到的信息,同事可做出反应
switch(CApproach){
case 0: // 数据包头
if(dat==0xB2){
 CApproach = 1;
}
break;
case 1: // 机号
if(dat==MyNumber){
 CApproach = 2;
}else{
 CApproach = 0;
}
break;
case 2: // 命令
if(dat>=1&&dat<=7){
 CCommand = dat;
 CApproach = 3;
}else{
 CApproach = 0;
}
break;
case 3: // 命令参数
switch(CApproach){
case 1: // 探测设备命令,无参数
CXorCount = dat;
CApproach = 255;
break;
case 2: // 开启通讯监视,无参数
CXorCount = dat;
CApproach = 255;
break;
case 3: // 关闭通讯监视,无参数
CXorCount = dat;
CApproach = 255;
break;
default:
CApproach = 0;
break;
}
break;
case 255: // 接收包尾
if(dat==0xB3){
switch(CCommand){
case 1: // 探测设备命令需要进行异或校验
NXorData = 0xB2;
NXorData = NXorData^MyNumber;
NXorData = NXorData ^ CCommand;
if(NXorData==CXorCount){
SendBufToPort("LTC-20100409A",13);
}else{
CApproach = 0;
}
break;
case 2: // 开启通讯监视命令需要进行异或校验
NXorData = 0xB2;
NXorData = NXorData^MyNumber;
NXorData = NXorData ^ CCommand;
if(NXorData==CXorCount){
AddMinute = 0;
AddSecond = 0;
AddMillisecond = 0;
AddMicrosecond = 0;
Approach = 1;

SendBufToPort("Open stakeout.",14);
}else{
CApproach = 0;
}
break;
case 3: // 关闭通讯监视命令需要进行异或校验
NXorData = 0xB2;
NXorData = NXorData^MyNumber;
NXorData = NXorData ^ CCommand;
if(NXorData==CXorCount){
Approach = 0;
AddMinute = 0;
AddSecond = 0;
AddMillisecond = 0;
AddMicrosecond = 0;
SendBufToPort("Close stakeout.",14);
}else{
CApproach = 0;
}
break;
default:
CApproach = 0;
break;
}
}else{
CApproach = 0;
}
break;
}
}else{
TI = 0;
}

}

#14


再给你看一段PC处理串口通讯的过程,VC代码,该程序的完整过程可以在我的资源里找到

//============================================================================================================
//                                          关 键 部 分 代 码
//============================================================================================================
void CDemoDlg::OnOK() 
{
BOOL OpenState;
DWORD NowTickCount;
DWORD SaveTickCount;
char * SendText;
// 这里很关键,因为 Send 是通过 GlobalSize 来取得指针大小的,所以需要这样分配控件大小
SendText = (char *)GlobalAlloc(GMEM_ZEROINIT, 4);

ReturnValue = 0; //设置默认返回为失败
Approach = 0; //设置接收步骤参数

COMM1.EventRead = OnComm; //设置处理函数
COMM1.ObjClassAddress = (DWORD)this; //设置类地址,确保在OnComm过程中可以调用本类中的一些过程或变量
COMM1.Port = 1; //设置端口
COMM1.BaudRate = CBR_57600; //设置波特率
COMM1.ByteSize = 8; //设置数据位
COMM1.Parity = 0; //设置校检
COMM1.StopBits = 1; //设置停止位
OpenState = COMM1.Open(); //打开串口,这时候便开始了 OnComm 事件的侦听
if(OpenState==TRUE){
sprintf(SendText,"AT\r\n"); //设置要发送的文本内容(当然也可以发送字节流)
COMM1.Send((BYTE*)SendText); //发送文本到串口

//=========== 以下做超时处理 ===========
//超时处理总共有两个全局变量控制
//ExecOver 和 ReturnValue
ExecOver = FALSE;
SaveTickCount = GetTickCount();
while(ExecOver==FALSE){
Sleep(5);
NowTickCount = GetTickCount();
if(NowTickCount-SaveTickCount>=1000){
//超过1秒钟还未正常返回结果就自动退出循环
ReturnValue = 0;
ExecOver=TRUE;
}
}
COMM1.Close();
}
if(ReturnValue==1){
MessageBox("串口1接入的设备支持AT命令。","执行结果",64);
}else{
MessageBox("没有检测到串口1接入支持AT命令的设备。","执行结果",64);
}
}

void CDemoDlg::OnComm(DWORD pClassAddress, BYTE *ReadBuffers, DWORD ReadCount)
{
// pClassAddress 类地址,由用户自行设置 ObjClassAddress 而来
// ReadBuffers 从串口缓冲区读到的数据指针
// ReadCount 从川口缓冲区读到的数据大小
//=============== 还原类的方法,以下是范例 ===============
//CDemoDlg * DlgObj;
//DlgObj = (CDemoDlg *)pClassAddress;
//DlgObj->COMM1.Send((BYTE *)"AAA");
//========================================================
// 下面做个简单的信息识别处理

// 还原类事例对象,因为要用到类中的变量
CDemoDlg * DlgObj;
DlgObj = (CDemoDlg *)pClassAddress;

DWORD i;
if(ReadCount>0){
for(i=0;i<ReadCount;i++){
switch(DlgObj->Approach){
case 0:
if((BYTE)ReadBuffers[i]==0x0D||(BYTE)ReadBuffers[i]==0x0A){ //有可能先发换行符号
DlgObj->Approach = 1;
}else if((BYTE)ReadBuffers[i]==0x4F||(BYTE)ReadBuffers[i]==0x62){ //有可能直接发 OK 信息
DlgObj->Approach = 2;
}
break;
case 1:
if((BYTE)ReadBuffers[i]==0x4F||(BYTE)ReadBuffers[i]==0x6F){
DlgObj->Approach = 2;
}else if((BYTE)ReadBuffers[i]==0x0D||(BYTE)ReadBuffers[i]==0x0A){
DlgObj->Approach = 1;
}else{
DlgObj->Approach = 0;
}
break;
case 2:
if((BYTE)ReadBuffers[i]==0x4B||(BYTE)ReadBuffers[i]==0x6B){
DlgObj->Approach = 3;
}else{
DlgObj->Approach = 0;
}
break;
case 3:
if((BYTE)ReadBuffers[i]==0x0D||(BYTE)ReadBuffers[i]==0x0A){
DlgObj->ReturnValue = 1;
DlgObj->ExecOver = TRUE;
}
DlgObj->Approach = 0;
break;
}

}
}
}

#15


找了一下,这里还有一段VB的过程

Private Sub MSComm1_OnComm()
   Dim TempBytes() As Byte, TempBytesCount As Long
   Dim X As Long, nowxor As Long, RetEventStr As String
   On Error Resume Next
   '通过 CommEvent 属性判断是发生什么事件
   If MSComm1.CommEvent = comEvReceive Then
      JJ = JJ + 1
      ReadBytes = MSComm1.Input

      ReadCount = UBound(ReadBytes)
      'ReDim ReadBytes(ReadCount)
      'CopyMemory ReadBytes(0), TempBytes(0), ReadCount + 1

      For X = 0 To ReadCount
         Select Case Approach
         Case 201: '判断是否是结束符号
                  If ReadBytes(X) = &HB3 Then
                     '开始运算数据是否正确
                     Select Case NowCommand
                     Case &HFF:  '机器型号命令
                                 nowxor = &HB2
                                 nowxor = nowxor Xor m_ENumber
                                 nowxor = nowxor Xor NowCommand
                                 nowxor = nowxor Xor Parameter1
                                 For Y = 0 To Parameter1 - 1
                                    nowxor = nowxor Xor ReadByteArray(Y)
                                 Next Y
                                 If xorvalue = nowxor Then
                                    ReturnString = StrConv(ReadByteArray, vbUnicode)
                                 Else
                                    ReturnString = ""
                                 End If
                                 Timer1.Enabled = False
                                 WaitTime = 0
                     End Select
                  End If
                  Approach = 0               '完成处理,将步骤设置为初始阶段
         
         Case 200: '接收异或校检码准备对数据的完整性和正确性进行核对
                  xorvalue = ReadBytes(X)       '将异或校检码存入公共变量中,等就收到包尾信息后再进行处理
                  Approach = 201                '因为异或校检码属于不定值,所以无法判断是否正确,直接进入下一步等下一步进行判断
         
         
         Case 8:  '机器型号返回信息
                  ReadByteArray(ReadByteCount) = ReadBytes(X)
                  ReadByteCount = ReadByteCount + 1
                  If ReadByteCount >= Parameter1 Then
                     Approach = 200          '去接收异或校检码准备和对数据的正确性
                  End If

         Case 6:  '机器型号返回信息
                  ReturnString = ""
                  Parameter1 = ReadBytes(X)     '接收返回字符串数量
                  ReadByteCount = 0
                  ReDim ReadByteArray(Parameter1 - 1)
                  Approach = 8                  '无法验证数据的正确性,将接收步骤调整为下一步
                  
         Case 2:  '识别命令,若数据不在可识别的命令数值范围内,作弃包处理
                  Select Case ReadBytes(X)
                  Case &HFF:  '机器型号命令
                              NowCommand = &HFF
                              Approach = 6      '数据符合要求,将接收步骤调整为下一步
                  Case Else
                     Approach = 0   '数据不符合接收步骤和相关的规定,放弃该数据(弃包处理)
                  End Select
                  
         Case 1:  '识别机号,判断数据是否应该发送到本机的,若不是就不必继续处理了
                  If m_ENumber = 0 Then
                     '初始化时没有机号标准,所以直接读取信息成为机号
                     m_ENumber = ReadBytes(X)
                     Approach = 2   '数据符合要求,将接收步骤调整为下一步
                  Else
                     If ReadBytes(X) = m_ENumber Then
                        Approach = 2   '数据符合要求,将接收步骤调整为下一步
                     Else
                        Approach = 0   '数据不符合接收步骤和相关的规定,放弃该数据(弃包处理)
                     End If
                  End If
                  
         Case 0:  '根据步骤,等待包头的出现,若不是包头数据就继续等待包头
                  If ReadBytes(X) = &HB2 Then
                     Approach = 1   '数据符合要求,将接收步骤调整为下一步
                  End If
                  
         End Select
      Next X
   End If
   Exit Sub
错误处理:
   Approach = 0
End Sub

#16


引用 15 楼 supermanking 的回复:
找了一下,这里还有一段VB的过程

VB code

Private Sub MSComm1_OnComm()
   Dim TempBytes() As Byte, TempBytesCount As Long
   Dim X As Long, nowxor As Long, RetEventStr As String
   On Error Resume Next
   '通……



谢谢您!现在的问题是,想用多线程处理通信,但关于线程的安全退出一直存在问题,请问有何高见,谢谢!!!

#17


引用 16 楼 tianliang09 的回复:
谢谢您!现在的问题是,想用多线程处理通信,但关于线程的安全退出一直存在问题,请问有何高见,谢谢!!!

VB的多线程要编译P代码才好用,而且调试最好是编译EXE后运行看看,直接调试弄不好会有问题的。
VB做多线程本来就很多要注意的地方,个人感觉VC在这方面要简单和稳定很多。

#18


其实你可以参考一下我资源里的一个串口通讯的VC代码,用起来也很简单的。
http://download.csdn.net/source/2690778