VC++关于串口通讯的问题 http://www.vckbase.com/document/viewdoc.asp?id=191 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 如果不要用到中断,很简单。用outp和inp函数封装一个类就行了。不必用到vc带的控件。如果牵扯到中断,可以编一个vxd来解决。另:也有用调用api来解决的。这方面的资料很多,可以搜一下 hcomm =(HANDLE) CreateFile("com1", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); GetCommState(hcomm, &dcb) ; dcb.BaudRate =9600; dcb.ByteSize =8; dcb.StopBits=ONESTOPBIT; dcb.Parity =MARKPARITY; dcb.fBinary = TRUE ; dcb.fParity = TRUE; SetCommState(hcomm, &dcb) ; //串口参数配置 GetCommState(hcomm , &dcb ) ; SetCommState(hcomm, &dcb ) ; //send address dcb.Parity = MARKPARITY; //设为发送地址信息 SetCommState(hcomm, &dcb) ; //串口参数配置 WriteFile(hcomm ,data,1,&len,0);// send data dcb.Parity = SPACEPARITY; //设为发送数据信息 SetCommState(hcomm, &dcb) ; //串口参数配置 WriteFile(hcomm ,data,1,&len,0); 串口通讯的主要问题是数据的安全性,尽管RS232或RS422A提供什么起始位,校验位,停止位的,但是硬件设备(串口,调制解调器)接收的认为正确的数据软件并不一定认为正确,这是由于它的不抗干扰性所决定的。所以自定义协议是必不可少的。比如要发送一帧完整的数据,格式定义如下:帧头--长度:4bytes,数据:4个0X7E;有效数据长度--长度:2bytes,数据:高位 有效数据长度/256,低位:有效数据长度%256;有效数据区--长度:有效数据长度,数据:有效数据;校验区(CRC校验)--长度:4bytes,数据:CRC校验和;帧尾-- 长度:1bytes,数据:0XE7;按照以上的方式打包解包,若发现错误包,可立即申请重发,也可记录下来待传输完毕以后,重发所有错误数据包。 帧头0x01,接着帧长度Len,跟着编码的数据包(长度为Len个字节),结尾0x0D;0x0D等于'\r',而'\r'是Modem AT命令集的结束符,使用该字符作为帧结束符,有利于AT命令集的接收。使用PCOMM.DLL(你可以以该字符串搜索,可以搜到一堆关于它的资料)作为操作串口的接口(不要用API,一堆问题);而PCOMM有一个回调函数,用于监测收缓冲区的某个字符,如果出现该字符,便会响应该回调函数,从而去读数据;这下你该知道定义帧结束符的重要性了吧,定义0x0D即可整包整包的接收一帧一帧的数据,也可整包整包的接收AT命令集(免得帧拼接或命令拼接);但上述方法有问题:一旦数据帧中出现结束符即0x0D,将把整帧数据拦腰截断,怎么办?包拼接?如果数据帧中出现一万多0x0D呢?拼接一万多道?不好!所以我在开头处写着编码的数据包,关键不能让数据包中出现结束符,这儿当然是0x0D了;怎么编码该包数据,我谈谈自己的思路供大家参考(不能简单的出现0x0D就加一什么的,不行的):0x0D二进制就是00001101,要使包中不出现该字节,只要该字节的第一位,第三位或第四位不为一,则怎么组合也不可能出现0x0D了,我得思路就是实现一个Bitset的函数,该函数实现一串字节的每一个字节的指定位进行设置1和设置0的操作;实现了上面的Bitset函数,要编码刚才我们的数据就再简单不过了,指定一个字节中的某一位不用(比如第三位),将指定的数据位一一写入新的Buffer中(注意一旦遇到每一个字节的指定位需要跳过该位);当然这种做法增加了传输的数据量,如果长度位N的数据包,最坏情况下需要N+N/8+1个字节来存储,最好也要N+N/8个字节。当然编码后的数据长度不能等于0x0D,否则长度Len就是0x0D,还编码个屁呀,不过这一点并不成问题,你可以增加一个无效的字节就可以了(就当作增加一个Reserve字节);重要的是数据的内容你是无法控制它不出现0x0D的,而且有可能每个字节都出现0x0D的情况,这并不是不可能(举个实际例子,如果你的每个字节的每一位都存储一种状态信息,即以位来存储信息而不是字节,你就无法控制每一个字节都不出现0x0D)。 关于桌面的 COM中ADO的_RecordsetPtr指向的数据集如何与DBGrid绑定? RTP包长度 菜鸟问题:ODBC 求助:关于向视窗中写入信息! 请问那里能找到FAT的详细资料啊! 怎么样才能动态添加一个子菜单呢? 3. 可不可以控制拒绝收发包含某种类型附件的邮件 急??? .NET出现了,Delphi还有用处么? 有一次我在一个练习上看到一个问题,我不知道它应填什么? CSocket类的问题?急,
这方面的资料很多,可以搜一下
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
0,
NULL); GetCommState(hcomm, &dcb) ;
dcb.BaudRate =9600;
dcb.ByteSize =8;
dcb.StopBits=ONESTOPBIT;
dcb.Parity =MARKPARITY;
dcb.fBinary = TRUE ;
dcb.fParity = TRUE;
SetCommState(hcomm, &dcb) ; //串口参数配置 GetCommState(hcomm , &dcb ) ;
SetCommState(hcomm, &dcb ) ;
//send address
dcb.Parity = MARKPARITY; //设为发送地址信息
SetCommState(hcomm, &dcb) ; //串口参数配置
WriteFile(hcomm ,data,1,&len,0);// send data
dcb.Parity = SPACEPARITY; //设为发送数据信息
SetCommState(hcomm, &dcb) ; //串口参数配置
WriteFile(hcomm ,data,1,&len,0);
软件并不一定认为正确,这是由于它的不抗干扰性所决定的。所以自定义协议是必不可少的。比如要发送一帧完整的数据,格式定义如下:
帧头--长度:4bytes,数据:4个0X7E;
有效数据长度--长度:2bytes,数据:高位 有效数据长度/256,低位:有效数据长度%256;
有效数据区--长度:有效数据长度,数据:有效数据;
校验区(CRC校验)--长度:4bytes,数据:CRC校验和;
帧尾-- 长度:1bytes,数据:0XE7;
按照以上的方式打包解包,若发现错误包,可立即申请重发,也可记录下来待
传输完毕以后,重发所有错误数据包。
有利于AT命令集的接收。
使用PCOMM.DLL(你可以以该字符串搜索,可以搜到一堆关于它的资料)作为操作串口的接口(不要用API,一堆问题);而PCOMM有一个回调函数,用于监测收缓冲区的某个字符,如果出现该字符,便会响应该回调函数,从而去读数据;这下你该知道定义帧结束符的重要性了吧,定义0x0D即可整包整包的接收一帧一帧的数据,也可整包整包的接收AT命令集(免得帧拼接或命令拼接);
但上述方法有问题:一旦数据帧中出现结束符即0x0D,将把整帧数据拦腰截断,怎么办?包拼接?如果数据帧中出现一万多0x0D呢?拼接一万多道?不好!所以我在开头处写着编码的数据包,关键不能让数据包中出现结束符,这儿当然是0x0D了;
怎么编码该包数据,我谈谈自己的思路供大家参考(不能简单的出现0x0D就加一什么的,不行的):
0x0D二进制就是00001101,要使包中不出现该字节,只要该字节的第一位,第三位或第四位不为一,则怎么组合也不可能出现0x0D了,我得思路就是实现一个Bitset的函数,该函数实现一串字节的每一个字节的指定位进行设置1和设置0的操作;
实现了上面的Bitset函数,要编码刚才我们的数据就再简单不过了,指定一个字节中的某一位不用(比如第三位),将指定的数据位一一写入新的Buffer中(注意一旦遇到每一个字节的指定位需要跳过该位);
当然这种做法增加了传输的数据量,如果长度位N的数据包,最坏情况下需要N+N/8+1个字节来存储,最好也要N+N/8个字节。
当然编码后的数据长度不能等于0x0D,否则长度Len就是0x0D,还编码个屁呀,不过这一点并不成问题,你可以增加一个无效的字节就可以了(就当作增加一个Reserve字节);重要的是数据的内容你是无法控制它不出现0x0D的,而且有可能每个字节都出现0x0D的情况,这并不是不可能(举个实际例子,如果你的每个字节的每一位都存储一种状态信息,即以位来存储信息而不是字节,你就无法控制每一个字节都不出现0x0D)。