本站部分文章、图片属于网络上可搜索到的公开信息,均用于学习和交流用途,不能代表睿象云的观点、立场或意见。我们接受网民的监督,如发现任何违法内容或侵犯了您的权益,请第一时间联系小编邮箱jiasou666@gmail.com 处理。
本篇文章给大家谈谈事件通知方法串口接收,以及对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
今天给各位分享事件通知方法串口接收的知识,其中也会对进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:
vb.net 怎么用事件触发的方式读取串口数据
首先:
textbox里没有显示,是因为SerialPort1和TextBox2不是同一线程创建的,需要跨线程操作。需要用到委托,这样才能显示出来。
其次:
我觉得用串口的接收数据事件更好一些。
下面代码供参考:
'----------------------
'串口接收数据事件,其实比用定时器更好,
'触发事件的条件可以自己在form_load中设置ReceivedBytesThreshold属性数值,默认为ReceivedBytesThreshold=1
Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
Dim strRecvData As String = ""
strRecvData = SerialPort1.ReadExisting
Call disPlayComData(strRecvData)
End Sub
Delegate Sub callback(ByVal strT As String) '定义委托
Sub showString(ByVal comdata As String) '显示结果
Me.TextBox1.Text = "结果:" comdata
End Sub
Sub disPlayComData(ByVal strTmp As String) '判定是否为跨线程
If Me.TextBox1.InvokeRequired Then
Dim d As New callback(AddressOf showString)
Me.Invoke(d, New Object() {strTmp})
Else
Me.TextBox1.Text = strTmp
End If
End Sub
C# serialport内datareceived事件接收串口数据,详细步骤。
//Thread.sleep(1000);//处理事件这块可以加上延时确保不定数的数据可以全部收到缓冲后,才去读缓冲内容--单位:毫秒
byte[] data = new byte[serialPort1.BytesToRead]; //定义缓冲区,因为串口事件触发时有可能收到不止一个字节
serialPort1.Read(data, 0, data.Length);//读取指定长度
foreach (byte Member in data) //遍历用法
{
string str = Convert.ToString(Member, 16).ToUpper();
textBox1.AppendText("0x" + (str.Length == 1 ? "0" + str : str) + " ");
}
读取有的string InputData = serialPort1.ReadExisting();
单字节读取(当波特率高时就会丢失数据)
byte DataReceived = (byte)(serialPort1.ReadByte());
扩展资料:
衡量通信中实际数据位的参数。当计算机发送一个信息包,实际的数据往往不会是8位的,标准的值是6、7和8位。如何设置取决于你想传送的信息。比如,标准的ASCII码是0~127(7位)。扩展的ASCII码是0~255(8位)。
如果数据使用简单的文本(标准 ASCII码),那么每个数据包使用7位数据。每个包是指一个字节,包括开始/停止位,数据位和奇偶校验位。由于实际数据位取决于通信协议的选取,术语“包”指任何通信的情况。
参考资料来源:百度百科-串口通信
急!请教RS485串口通讯的问题
你用vb还是vc?
看OnComm事件应该是vb吧。
(参照出处http://www.gjwtech.com/serialcomm.htm):
MSComm控件使用详解
摘要:本文详细介绍了MSComm控件在串口编程中使用。
目 次
MSComm控件两种处理通讯的方式
CommPort属性
RThreshold 属性
CTSHolding 属性
SThreshold 属性
CDHolding 属性
DSRHolding 属性
Settings 属性
InputLen 属性
EOFEnable 属性
Handshake 常数
OnComm 常数
InputMode 常数
错误消息
MSComm 控件通过串行端口传输和接收数据,为应用程序提供串行通讯功能。MSComm控件在串口编程时非常方便,程序员不必去花时间去了解较为复杂的API函数,而且在VC、VB、Delphi等语言中均可使用。 Microsoft Communications Control(以下简称MSComm)是Microsoft公司提供的简化Windows下串行通信编程的ActiveX控件,它为应用程序提供了通过串行接口收发数据的简便方法。具体的来说,它提供了两种处理通信问题的方法:一是事件驱动(Event-driven)方法,一是查询法。
1.MSComm控件两种处理通讯的方式
MSComm控件提供下列两种处理通讯的方式:事件驱动方式和查询方式。
1.1 事件驱动方式
事件驱动通讯是处理串行端口交互作用的一种非常有效的方法。在许多情况下,在事件发生时需要得到通知,例如,在串口接收缓冲区中有字符,或者 Carrier Detect (CD) 或 Request To Send (RTS) 线上一个字符到达或一个变化发生时。在这些情况下,可以利用 MSComm 控件的 OnComm 事件捕获并处理这些通讯事件。OnComm 事件还可以检查和处理通讯错误。所有通讯事件和通讯错误的列表,参阅 CommEvent 属性。在编程过程中,就可以在OnComm事件处理函数中加入自己的处理代码。这种方法的优点是程序响应及时,可靠性高。每个MSComm 控件对应着一个串行端口。如果应用程序需要访问多个串行端口,必须使用多个 MSComm 控件。
1.2 查询方式
查询方式实质上还是事件驱动,但在有些情况下,这种方式显得更为便捷。在程序的每个关键功能之后,可以通过检查 CommEvent 属性的值来查询事件和错误。如果应用程序较小,并且是自保持的,这种方法可能是更可取的。例如,如果写一个简单的电话拨号程序,则没有必要对每接收一个字符都产生事件,因为唯一等待接收的字符是调制解调器的“确定”响应。
2.MSComm 控件的常用属性
MSComm 控件有很多重要的属性,但首先必须熟悉几个属性。
CommPort 设置并返回通讯端口号。
Settings 以字符串的形式设置并返回波特率、奇偶校验、数据位、停止位。
PortOpen 设置并返回通讯端口的状态。也可以打开和关闭端口。
Input 从接收缓冲区返回和删除字符。
Output 向传输缓冲区写一个字符串。
下面分别描述:
CommPort属性 设置并返回通讯端口号。
语法 object.CommPort[value ] (value 一整型值,说明端口号。)
说明 在设计时,value 可以设置成从 1 到 16 的任何数(缺省值为 1)。但是如果用 PortOpen 属性打开一个并不存在的端口时,MSComm 控件会产生错误 68(设备无效)。
注意:必须在打开端口之前设置 CommPort 属性。
RThreshold 属性:在 MSComm 控件设置 CommEvent 属性为 comEvReceive 并产生 OnComm 之前,设置并返回的要接收的字符数。
语法 object.Rthreshold [ = value ](value 整型表达式,说明在产生 OnComm 事件之前要接收的字符数。 )
说明 当接收字符后,若 Rthreshold 属性设置为 0(缺省值)则不产生 OnComm 事件。例如,设置 Rthreshold 为 1,接收缓冲区收到每一个字符都会使 MSComm 控件产生 OnComm 事件。
CTSHolding 属性:确定是否可通过查询 Clear To Send (CTS) 线的状态发送数据。Clear To Send 是调制解调器发送到相联计算机的信号,指示传输可以进行。该属性在设计时无效,在运行时为只读。
语法: object.CTSHolding(Boolean)
Mscomm 控件的 CTSHolding 属性设置值:
True Clear To Send 线为高电平。
False Clear To Send 线为低电平。
说明:如果 Clear To Send 线为低电平 (CTSHolding = False) 并且超时时,MSComm 控件设置 CommEvent 属性为 comEventCTSTO (Clear To Send Timeout) 并产生 OnComm 事件。
Clear To Send 线用于 RTS/CTS (Request To Send/Clear To Send) 硬件握手。如果需要确定 Clear To Send 线的状态,CTSHolding 属性给出一种手工查询的方法。
详细信息 有关握手协议,请参阅 Handshaking 属性。
SThreshold 属性: MSComm 控件设置 CommEvent 属性为 comEvSend 并产生 OnComm 事件之前,设置并返回传输缓冲区中允许的最小字符数。
语法 object.SThreshold [ = value ]
value 整形表达式,代表在 OnComm 事件产生之前在传输缓冲区中的最小字符数。
说明:若设置 Sthreshold 属性为 0(缺省值),数据传输事件不会产生 OnComm 事件。若设置 Sthreshold 属性为 1,当传输缓冲区完全空时,MSComm 控件产生 OnComm 事件。如果在传输缓冲区中的字符数小于 value,CommEvent 属性设置为 comEvSend,并产生 OnComm 事件。comEvSend 事件仅当字符数与 Sthreshold 交叉时被激活一次。例如,如果 Sthreshold 等于 5,仅当在输出队列中字符数从 5 降到 4 时,comEvSend 才发生。如果在输出队列中从没有比 Sthreshold 多的字符,comEvSend 事件将绝不会发生。
Handshake 常数
常数 值 描述
comNone 0 无握手。
comXonXoff 1 XOn/Xoff 握手。
comRTS 2 Request-to-send/clear-to-send 握手。
comRTSXOnXOff 3 Request-to-send 和 clear-to-send 握手皆可。
OnComm 常数
常数 值 描述
comEvSend 1 发送事件。
comEvReceive 2 接收事件。
comEvCTS 3 clear-to-send 线变化。
comEvDSR 4 data-set ready 线变化。
comEvCD 5 carrier detect 线变化。
comEvRing 6 振铃检测。
comEvEOF 7 文件结束。
Error 常数
常数 值 描述
comEventBreak 1001 接收到中断信号
comEventCTSTO 1002 Clear-to-send 超时
comEventDSRTO 1003 Data-set ready 超时
comEventFrame 1004 帧错误
comEventOverrun 1006 端口超速
comEventCDTO 1007 Carrier detect 超时
comEventRxOver 1008 接收缓冲区溢出
comEventRxParity 1009 Parity 错误
comEventTxFull 1010 传输缓冲区满
comEventDCB 1011 检索端口 设备控制块 (DCB) 时的意外错误
InputMode 常数
常数 值 描述
comInputModeText 0 (缺省)通过 Input 属性以文本方式取回数据。
comInputModeBinary 1 通过 Input 属性以二进制方式检取回数据。
CDHolding 属性:通过查询 Carrier Detect (CD) 线的状态确定当前是否有传输。Carrier Detect 是从调制解调器发送到相联计算机的一个信号,指示调制解调器正在联机。该属性在设计时无效,在运行时为只读。
语法 object.CDHolding
设置值:CDHolding 属性的设置值为:
设置 描述
True Carrier Detect 线为高电平
False Carrier Detect 线为低电平
说明:注意当 Carrier Detect 线为高电平 (CDHolding = True) 且超时时,MSComm 控件设置CommEvent 属性为 comEventCDTO(Carrier Detect 超时错误),并产生 OnComm 事件。
注意 在主机应用程序中捕获一个丢失的传输是特别重要的,例如一个公告板,因为呼叫者可以随时挂起(放弃传输)。
Carrier Detect 也被称为 Receive Line Signal Detect (RLSD)。
数据类型 Boolean
DSRHolding 属性:确定 Data Set Ready (DSR) 线的状态。Data Set Ready 信号由调制解调器发送到相连计算机,指示作好操作准备。该属性在设计时无效,在运行时为只读。
语法:object.DSRHolding
object 所在处表示对象表达式,其值是“应用于”列表中的对象。
DSRHolding 属性返回以下值:
值 描述
True Data Set Ready 线高
False Data Set Ready 线低
说明:当 Data Set Ready 线为高电平 (DSRHolding = True) 且超时时,MSComm 控件设置 CommEvent 属性为 comEventDSRTO(数据准备超时)并产生 OnComm 事件。
当为 Data Terminal Equipment (DTE) 机器写 Data Set Ready/Data Terminal Ready 握手例程时该属性是十分有用的。
数据类型:Boolean
Settings 属性: 设置并返回波特率、奇偶校验、数据位、停止位参数。
语法: object.Settings[ = value]
说明:当端口打开时,如果 value 非法,则 MSComm 控件产生错误 380(非法属性值)。
Value 由四个设置值组成,有如下的格式:
"BBBB,P,D,S"
BBBB 为波特率,P 为奇偶校验,D 为数据位数,S 为停止位数。value 的缺省值是:
"9600,N,8,1"
InputLen 属性:设置并返回 Input 属性从接收缓冲区读取的字符数。
语法 object.InputLen [ = value]
InputLen 属性语法包括下列部分:
value 整型表达式,说明 Input 属性从接收缓冲区中读取的字符数。
说明:InputLen 属性的缺省值是 0。设置 InputLen 为 0 时,使用 Input 将使 MSComm 控件读取接收缓冲区中全部的内容。
若接收缓冲区中 InputLen 字符无效,Input 属性返回一个零长度字符串 ("")。在使用 Input 前,用户可以选择检查 InBufferCount 属性来确定缓冲区中是否已有需要数目的字符。该属性在从输出格式为定长数据的机器读取数据时非常有用。
EOFEnable 属性:确定在输入过程中 MSComm 控件是否寻找文件结尾 (EOF) 字符。如果找到 EOF 字符,将停止输入并激活 OnComm 事件,此时 CommEvent 属性设置为 comEvEOF,
语法:object.EOFEnable [ = value ]
EOFEnable 属性语法包括下列部分:
value 布尔表达式,确定当找到 EOF 字符时,OnComm 事件是否被激活,如“设置值”中所描述。
value 的设置值:
True 当 EOF 字符找到时 OnComm 事件被激活。
False (缺省)当 EOF 字符找到时 OnComm 事件不被激活。
说明:当 EOFEnable 属性设置为 False,OnComm 控件将不在输入流中寻找 EOF 字符。
错误消息(MS Comm 控件)
下表列出 MSComm 控件可以捕获的错误:
值 描述
380 无效属性值 comInvalidPropertyValue
383 属性为只读 comSetNotSupported
394 属性为只读 comGetNotSupported
8000 端口打开时操作不合法 comPortOpen
8001 超时值必须大于 0
8002 无效端口号 comPortInvalid
8003 属性只在运行时有效
8004 属性在运行时为只读
8005 端口已经打开 comPortAlreadyOpen
8006 设备标识符无效或不支持该标识符
8007 不支持设备的波特率
8008 指定的字节大小无效
8009 缺省参数错误
8010 硬件不可用(被其它设备锁定)
8011 函数不能分配队列
8012 设备没有打开 comNoOpen
8013 设备已经打开
8014 不能使用 comm 通知
8015 不能设置 comm 状态 comSetCommStateFailed
8016 不能设置 comm 事件屏蔽
8018 仅当端口打开时操作才有效 comPortNotOpen
8019 设备忙
8020 读 comm 设备错误 comReadError
8021 为该端口检索设备控制块时的内部错误 comDCBError
///-----------------------------------------------------
串口数据接收方式
1、 在OnComm 事件中接收数据:
这种方式能充分MSCOMM控件的特性。OnComm 事件还可以检查和处理通讯错误;可以通过检查 CommEvent 属性的值来查询事件和错误;对于不定长数据以及对数据进行处理比较复杂的情况,此法不是很方便。
Private Sub MSComm_OnComm ()
Select Case MSComm1.CommEvent
' 错误
Case comEventBreak ' 收到 Break。
Case comEventCDTO ' CD (RLSD) 超时。
Case comEventCTSTO ' CTS Timeout。
Case comEventDSRTO ' DSR Timeout。
Case comEventFrame ' Framing Error
Case comEventOverrun '数据丢失。
Case comEventRxOver'接收缓冲区溢出。
Case comEventRxParity' Parity 错误。
Case comEventTxFull '传输缓冲区已满。
Case comEventDCB '获取 DCB] 时意外错误
' 事件
Case comEvCD ' CD 线状态变化。
Case comEvCTS ' CTS 线状态变化。
Case comEvDSR ' DSR 线状态变化。
Case comEvRing ' Ring Indicator 变化。
Case comEvReceive ' 收到 RThreshold # of chars.
Case comEvSend ' 传输缓冲区有 Sthreshold 个字符 '
Case comEvEof ' 输入数据流中发现 EOF 字符
End Select
End Sub
2.轮循法采集数据:
A、定时器轮循法
对于数据包方式收发数据以及不需即时响应情况,用轮循法更好些。实际上轮循法最大的好处在于集中处理数据而且不太占用CPU。轮循法要注意定时采集的时间片段大小;这里用二进制收发模式;使属性RThreshold、SThreshold为0,屏蔽ONCOMM事件。
InputMode = comInputModeBinary
RThreshold = 0
SThreshold = 0
Private Sub TmrComm_Timer()
'采用轮循法采集数据
Dim Rx_buff() As Byte
Dim okstring As String
Dim ReceivedLen As Integer
On Error GoTo ErrorHandler
TmrComm.Enabled = False '关闭定时器
If commport.InBufferCount 0 Then
ReceivedLen = commport.InBufferCount
Rx_buff = commport.Input
okstring = StrConv(tempbyte, vbUnicode)
If ReceivedLen = 6 Then
If Chr(tempbyte(0)) = ":" And tempbyte(3) = h0a Then
....
End If
If Instr(okstring ,":@END*",vbBinaryCompare) Then
....
End If
End If
TmrComm.Enabled = True '打开定时器
End Sub
B、直接轮循法
此法用于接收少量控制命令字;
' 保存输入子串的缓冲区
Dim Instring As String
' 使用 COM1。
MSComm1.CommPort = 1
' 9600 波特,无奇偶校验,8 位数据,一个停止位。
MSComm1.Settings = "9600,N,8,1"
' 当输入占用时,
' 告诉控件读入整个缓冲区。
MSComm1.InputLen = 0
' 打开端口。
MSComm1.PortOpen = True
' 将 attention 命令送到调制解调器。
MSComm1.Output = "ATV1Q0" Chr$(13)
' 确保
' 调制解调器以"OK"响应。
' 等待数据返回到串行端口。
Do
DoEvents
Buffer$ = Buffer$ MSComm1.Input
Loop Until InStr(Buffer$, "OK" vbCRLF)
' 从串行端口读 "OK" 响应。
' 关闭串行端口。
MSComm1.PortOpen = False
如何处理不定长数据的接收
在处理串口通讯时,经常会遇到不定长数据的接收。由于通讯任务不同及编程要求的差异所以采用的方法也有所不同。本文就此问题进行探讨。不定长数据从数据格式上分,可分为有格式和无格式。
一、无格式不定长数据的接收
这种格式在实际串口通讯中用得不多,一般只用传送字符串数据。问题在于怎么判断接收结束。一般用时间延迟的方法解决。
A、对于非握手式通讯,可用一个定时器定时轮循接收,并假定每个轮循接收完成。用ONCOMM事件接收也可,只是不如定时器定时轮循接收简便。
B、对于握手方式通讯,可用直接轮循法提高接收的准确性。下面是实现此法的函数:
Function sComm(sCommand As String, comReceive As MSComm) As String
Dim nReceiveCount As Integer
If comReceive.PortOpen = False Then
comReceive.PortOpen = True
End If
comReceive.Output = sCommand
Do
nReceiveCount = comReceive.InBufferCount
sleep (2) 'API 函数,挂起当前进程一段时间
Loop Until comReceive.InBufferCount = nReceiveCount
If comReceive.PortOpen = True Then
sComm = comReceive.Input
End If
End Function
注:此函数参照了xth一文。
此法一般是能确保数据接收的正确,但由于WINDOWS是多任务操作系统,当有耗时的进程运行时会丢失数据。如果系统会出现这种情况,可增大函数sleep()的参数值。
二、不定长格式数据的接收
对于不定长数据接收最好的方法是制定通讯协议,比如定义开始字符和结束字符。由于单片机系统通讯一般不太复杂,没必要去制定一套象通用计算机间通讯的协议,而根据单片机系统的大小和性能要求制定通讯协议。实际上为便于交流、维护以及一致性,可制定一套可伸缩的通讯协议。定义了开始字符和结束字符就容易实现不定长格式数据通讯,但在实际通讯编程还是容易出现一些比较隐蔽的通讯错误。下面就常用方法分别进行分析。
A、定时器轮循法。
假定每个轮循期数据接收完毕,并在每个轮循期处理数据,由于有开始字符和结束字符很容易确定接收数据的完整性。好象合理设定轮循时间值就万无一失了,但被动接收数据时无论如何也找不合适的轮循时间值,因为启动定时器和数据到来基本不同步,这就会出现一次发送的数据被分在两个轮循期接收,所以被动接收数据时不能假定每个轮循期数据接收完毕。在接收到结束字符后才确定一次数据接收完毕就可解决此问题。
B、OnComm事件法。
方法和定时器轮循法基本相同,因为每次OnCommg事件也只能接收到一部分数据。在VB的在线帮助中这样注解“设置 Rthreshold 为 1,接收缓冲区收到每一个字符都会使 MSComm 控件产生 OnComm 事件。”。但实际上OnComm事件并不是每收到一个字符便触发一次 OnComm 事件。OnComm事件是在缓冲区收到几个甚至几十个字节数据后才被触发的。版主认为这是WINDOWS多任务使操作系统不能实时响应造成的。如果要在每次OnComm事件接收一个字符似乎可设INPUTLEN属性为1,但实际行不通。VB在线帮助中“有该属性在从输出格式为定长数据的机器读取数据时非常有用”的注解,好象在说对定长字符有效,但版主发现INPUTLEN设为16,接收16个字符定长数据时却被当作两次接收了,一次12个,一次4个。建议在OnComm事件中接收数据要定义通讯协议并检测数据的完整性。 对于不定长格式数据的接收程序员更喜欢定时器轮循法,也许OnComm事件不好控制吧。
对于不定长数据的接收,最佳方法可能是在OnComm事件中启动定时器轮循接收,并同时停止OnComm事件的触发,接收完毕后或超时开启OnComm事件。
用字符方式收发码值大于127的字符数据
VB的通讯控件友好、功能强大,编程速度快是众人皆知的。加上VB的易学、易用,快速开发等特点,数据通讯量不是很大时,在单片机通讯领域广泛地使用VB开发PC上层通讯软件。实际开发时会有不少问题,这里就用字符方式收发码值大127的字符数据进行讨论。
在实际开发中经常遇到通讯只是用来发送一些控制字符命令和少量数据。在VB的中文在线帮助中有“若数据只用 ANSI 字符集,则用 comInputModeText”的表述。 ANSI字符集是0-127这容易使人误解为h88也可用“INPUTMIDE=comInputModeText”方式收发。我刚开始用VB编通讯模块时就为此迷惑过,网上不少网友也时常问及这种问题。实际上在VB中0-127是可以正常收发的,大于127即H7F的只有H80和HFF能够收发,其余ANSI字符都被过滤为0。由于串口通讯是以字节收发的,数据如以comInputModeText模式收发则非字符串数据会被过滤。在VB中用“INPUTMIDE = comInputModeBinary” 就可以解决这个问题,只是收发都必须用动态数组来完成。用comInputModeBinary模式编程稍有点复杂,调试也不直观,对于初学者不易掌握。另外软件完成后,在实际应用时会增加工程维护难度,因为对于二进制代码不是易于理解的。比如下端机发送现场统计数据233,comInputModeBinary模式下串口监测到“:A H233",它代表A探针的温度。一般串口监测软件要么用ASCII方式显示,要么用二进制方式显示。用ASCII方式则不能看到H233,而二进制方式则示不好理解,如果显示58 65 233 59,我想没有人喜欢这种方式(如果有更好的方式的话)。但如果显示“:A 2 3 3 ;”不就解决问题了!用comInputModeText方式就可完成任务了,只是多了一段数据分离程序。对于一般通讯要求这种方法不为是一种好方法。由于通讯任务是多种多样的,有时候这种方法就有点力不从心了,如传送较多的的数据时,这会显著地增加通讯量,通讯变得复杂了,对于单片机系统就不太合适了;还有一些特殊要求,如数据包的识别符也不适此法,但能确定传送数据码值范围也可用此法。下面介绍另一种方法,此法适用比较广,传送二进制数据通讯量增加也不大。
这种方法实际上很简单,实际运用中有不少采用此法。原理是一码分为二码。如设7E为临界字符,对于7E则分为7E和0两个ASCII码,依此类推,8F分为7E和11。接收合并时遇到7E则将7E和后一个ASCII码相加为下字符。下面给出C语言函数,VB转换一下便可。
由于C语言不能返回两个参数,所以用数组指针。
void Filt(char code[],char c)
{
if(c=='F')
{
if(code[0]=0X7E)
{
code[1]=code[0]-0X7E;
code[0]=0X7E;
}
else
{
code[1]=0XFF; /*0XFF作为标记code[1]不可能产生0XFF*/
}
}
else if(c=='H')
{
if(code[0]!=0X7E)
{
code[1]=0xFE; /*转换完成标记*/
}
else
{
if(code[1]==0XFE)
{
code[1]=0XFF; /*接收下一个码的标记*/
}
else
{
code[0]=code[0]+code[1];
code[1]=0XFE;
}
}
}
发送时:
char SendChar[2]; /*存储发送的值*/
....
SendChar[0]=c; /*c为待发ASCII码*/
Filt(SendChar,'F');
if(SendChar(1)==0XFF)
{
..... /*发送SendChar[0]*/
}
else
{
...... /*发送SendChar[0],SendChar[1]*/
}
接收时:
char ReceiveChar[2]; /*存储接收的值*/
.....
ReceiveChar[0]=c0; /*c0接收的ASCII码*/
Filt(ReceiveChar,'H');
if(ReceiveChar[1]==0xFF)
{
ReceiveChar[1]=c1; /*c1为下一个*/
Filt(ReceiveChar,'H);
}
else if(ReceiveChar[1]==0xFE)
{
...... /*存储转换后的ReceiveChar[0]*/
}
以上代码仅提供一种思路,实际情况视编程需要而定。
串口通讯问答录
1、Q:各位vb高手:我有一个问题想请教一下。我从COM口用BIN方式接收到数据(一串汉字),存入一BYTE数组,但无法还原为一串汉字,我认为是ANSI和UNICODE的转换,请问如何转换。
例:字符串“我”,按BIN方式接收成一BYTE数组,其值为“206,210”,如用“CHR(206)+CHR(210)”却无法得到“我”,实际上“我”=CHR(-12860)请问如何能实现BYTE数组(206,210)与字符串“我”之间的转换?万分感谢!!!
JY
1999.10
A:经CHR(206)+CHR(210)转换后实际上变成了两个UNICODE字符,四个字节了。汉字的收发必须用BINARY方式。下面的程序能实现汉字收发。
发:
Dim ytemp() As Byte
Dim stemp As String
stemp = "你好!"
ytemp = StrConv(stemp, vbFromUnicode)
Debug.Print UBound(ytemp)
MSComm1.Output = ytemp
收:
Private Sub mscTest_OnComm()
'中文收发
Dim yTemp() As Byte
Dim stemp As String
Dim i As Integer
If mscTest.InBufferCount 0 Then
i = mscTest.InBufferCount
yTemp = mscTest.Input
stemp = StrConv(yTemp, vbUnicode)
txtTest1.Text = stemp
End If
End Sub
Deson
1999-10-16
--------------------------------------------------------------------------------
2、Q:各位大侠,在下被两个问题困扰多时,实在无法找到答案,请各位多多指教。
1、在用MSCOMM控件设计通讯程序时,我始终无法将ASC码大于127的值发送出去,查阅了VB论坛以前的文章,按部就班也不行,部分 VB 程序如下,请指教:
Private Sub OkBtn_Click()
Dim Data() as byte
Dim Temp as variant
redim data(10)
For i = 0 to 10
Data(i) = int(rnd()*256)
next
temp = data
mscomm.output = temp
end Sub
A:接收方式使用了文本方式,用二进制方式即可。
MFC串口接收数据
使用MSComm控件串口接收数据,一般设置成SetRThreshold(1);
//参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件
并且串口每次接收到的数据个数是不确定的,如果
事件通知方法串口接收你自己确定需要接收到多少个数据的话,就好办
事件通知方法串口接收了。
//全局变量
BYTE Comm_Packet_Len; //需要接收到的数据个数
BYTE Comm_DataBuffer[20]; //依次存放串口接收到的数据
long Comm_Packet_Index; //每次收到数据个数,并标志数据应放在全局数组位置的索引
//每次处理完数据后清空,为下一次接收做准备
void CEOLDlg::OnMscomm()
{
// TODO: Add your control notification handler code here
VARIANT variant_inp;
COleSafeArray safearray_inp;
long len=0, k=0; //转换为数组时使用的变量
BYTE rxdata[204]; //设置BYTE数组 An 8-bit integerthat is not signed.
CString strtemp; //字符型变量
int temp = 0; //临时变量
unsigned char ecuchecksum = 0; //ecu回传校验码
if(m_ctrlComm.GetCommEvent() == 2) //事件值为2表示接收缓冲区内有字符
{ //以下
事件通知方法串口接收你可以根据自己的通信协议加入处理代码
variant_inp = m_ctrlComm.GetInput();//读缓冲区
safearray_inp = variant_inp; //VARIANT型变量转换为ColeSafeArray型变量
len = safearray_inp.GetOneDimSize(); //得到有效数据长度
for(k = 0; k < len; k++) //将ColeSafeArray型变量转换为BYTE型数组
{
safearray_inp.GetElement(k, rxdata + k);//转换为BYTE型数组
}
for(temp = 0; temp < len; temp++)
{
Comm_DataBuffer[Comm_Packet_Index + temp] = rxdata[temp];
}
Comm_Packet_Index += len;
if(Comm_Packet_Index == Comm_Packet_Len)//接收到的数据个数等于
{
//处理接收到的数据
}
}
}
串口接收比较好的处理方式
串口接收比较好的处理方式如下。
1.设定好通讯协议,如包头+长度+数据+校验+包尾,那么中断中每收到一个字节就判断,直到收到包尾为止。这是51时代用得比较多的状态机接收流程。
但如果由于接收中断被嵌套,或干扰等原因导致一帧数据的后部分丢失,就是说接收不到包尾,那么这个状态机如何能自动复位以便接收下一帧?
2.串口空闲中断也是用得比较多的一种方法,但是波特率较高的时候,空闲中断的触发时间相应变短,使得接收中断不被打断的要求变高,如果接收中断被耽误了,从而触发空闲中断,也是收不到完整数据。
3.定时器中断代替串口空闲中断,这个可以避免串口空闲中断时间不够的问题,因为这个定时器中断可以自己设置。但是一个串口需要搭配一个定时器使用,不爽。
4.串口接收只把数据放到缓存,此外不做任何事情。然后在另一个线程不断parse这个缓存,从头开始找其中有没有符合一帧的数据,如果有就是解析,同时将这一帧从缓存中删掉,如果没有就什么也不做。这样的程序就不用管一帧是否结束,可以较好的适应各种收不全、丢数据的问题。
关于事件通知方法串口接收和的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。
事件通知方法串口接收的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于、事件通知方法串口接收的信息别忘了在本站进行查找喔。
暂时没有评论,来抢沙发吧~