导航:首页 > 操作系统 > 8015单片机

8015单片机

发布时间:2022-05-07 22:54:06

单片机与VB的通信

分有没多点啊?

程序在这:

VERSION 5.00
Object = "{648A5603-2C6E-101B-82B6-000000000014}#1.1#0"; "MSCOMM32.OCX"
Begin VB.Form Form1
Caption = "Form1"
ClientHeight = 5235
ClientLeft = 60
ClientTop = 465
ClientWidth = 6990
Icon = "Form1.frx":0000
LinkTopic = "Form1"
ScaleHeight = 5235
ScaleWidth = 6990
StartUpPosition = 3 '窗口缺省
Begin MSCommLib.MSComm MS
Left = 3840
Top = 4080
_ExtentX = 1005
_ExtentY = 1005
_Version = 393216
DTREnable = -1 'True
End
Begin VB.CommandButton Command5
Caption = "清除"
Height = 375
Left = 3600
TabIndex = 26
Top = 3240
Width = 615
End
Begin VB.CommandButton Command4
Caption = "清除"
Height = 375
Left = 3600
TabIndex = 25
Top = 2040
Width = 615
End
Begin VB.Frame Frame2
Height = 555
Left = 120
TabIndex = 14
Top = 0
Width = 6795
Begin VB.ComboBox Comset0
Height = 300
Index = 0
ItemData = "Form1.frx":0442
Left = 540
List = "Form1.frx":046A
Style = 2 'Dropdown List
TabIndex = 19
Top = 180
Width = 735
End
Begin VB.ComboBox Comset
Height = 300
Index = 1
ItemData = "Form1.frx":04B9
Left = 1920
List = "Form1.frx":04F0
Style = 2 'Dropdown List
TabIndex = 18
Top = 180
Width = 915
End
Begin VB.ComboBox Comset
Height = 300
Index = 2
ItemData = "Form1.frx":0561
Left = 3480
List = "Form1.frx":056E
Style = 2 'Dropdown List
TabIndex = 17
Top = 180
Width = 915
End
Begin VB.ComboBox Comset
Height = 300
Index = 3
ItemData = "Form1.frx":0589
Left = 4920
List = "Form1.frx":059C
Style = 2 'Dropdown List
TabIndex = 16
Top = 180
Width = 615
End
Begin VB.ComboBox Comset
Height = 300
Index = 4
ItemData = "Form1.frx":05AF
Left = 6120
List = "Form1.frx":05B9
Style = 2 'Dropdown List
TabIndex = 15
Top = 180
Width = 615
End
Begin VB.Label Label2
Caption = "串口"
Height = 195
Index = 5
Left = 120
TabIndex = 24
Top = 240
Width = 435
End
Begin VB.Label Label2
Caption = "波特率"
Height = 195
Index = 1
Left = 1380
TabIndex = 23
Top = 240
Width = 555
End
Begin VB.Label Label2
Caption = "数据位"
Height = 255
Index = 2
Left = 4380
TabIndex = 22
Top = 240
Width = 615
End
Begin VB.Label Label2
Caption = "奇偶位"
Height = 255
Index = 3
Left = 2880
TabIndex = 21
Top = 240
Width = 675
End
Begin VB.Label Label2
Caption = "停止位"
Height = 255
Index = 4
Left = 5580
TabIndex = 20
Top = 240
Width = 555
End
End
Begin VB.TextBox Text3
Height = 735
Left = 360
MultiLine = -1 'True
ScrollBars = 2 'Vertical
TabIndex = 12
Text = "Form1.frx":05C3
Top = 2040
Width = 3015
End
Begin VB.TextBox Text1
Height = 1215
Left = 360
MultiLine = -1 'True
TabIndex = 11
Text = "Form1.frx":05CA
Top = 720
Width = 1695
End
Begin VB.Timer Timer1
Interval = 500
Left = 4680
Top = 4440
End
Begin VB.CommandButton Command3
Caption = "DTR-ON"
Height = 375
Left = 5640
TabIndex = 6
Top = 4080
Width = 975
End
Begin VB.CommandButton Command2
Caption = "RTS-OFF"
Height = 375
Left = 5640
TabIndex = 5
Top = 3480
Width = 975
End
Begin VB.CommandButton Command1
Caption = "端口状态"
Height = 375
Left = 4920
TabIndex = 3
Top = 2400
Visible = 0 'False
Width = 255
End
Begin VB.TextBox Text2
Height = 1455
Left = 360
MultiLine = -1 'True
ScrollBars = 2 'Vertical
TabIndex = 2
Top = 3240
Width = 3060
End
Begin VB.CommandButton Send
Caption = "发送"
Height = 615
Left = 5640
TabIndex = 1
Top = 2280
Width = 975
End
Begin VB.CommandButton Opencom
Caption = "打开串口"
Height = 615
Left = 5640
TabIndex = 0
Top = 960
Width = 975
End
Begin VB.PictureBox MS2
Height = 480
Left = 5400
ScaleHeight = 420
ScaleWidth = 1140
TabIndex = 27
Top = 4680
Width = 1200
End
Begin VB.Label Label6
Caption = "接收:"
Height = 375
Left = 360
TabIndex = 13
Top = 3000
Width = 495
End
Begin VB.Label Label5
Caption = "外设状态:"
Height = 375
Left = 2160
TabIndex = 10
Top = 1320
Width = 855
End
Begin VB.Label Label4
Caption = "测试外设是否存在"
Height = 495
Left = 4680
TabIndex = 9
Top = 4080
Width = 855
End
Begin VB.Label Label3
Caption = "请求发送"
Height = 255
Left = 4680
TabIndex = 8
Top = 3600
Width = 855
End
Begin VB.Label Label2
Caption = "端口状态"
Height = 375
Index = 0
Left = 2160
TabIndex = 7
Top = 720
Width = 735
End
Begin VB.Label Label1
Height = 375
Left = 3240
TabIndex = 4
Top = 1320
Width = 1815
End
End
Attribute VB_Name = "Form1"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Private CCount As Integer
Private Hexchange As Boolean
Private RTS As Boolean
Private Sendhexdata() As Byte
Private Nosend As Boolean

Private Sub Combo1_Click()
On Error GoTo Combo1_Error
If MS.PortOpen Then
If MS.CommPort <> (Combo1.ListIndex + 1) Then
If MsgBox("端口" & MS.CommPort & "正在使用,你要停止它并使用新的端口吗?", vbYesNo + vbExclamation + vbDefaultButton2, "更改端口?") = vbYes Then
Call Opencom_Click
MS.CommPort = Combo1.ListIndex + 1
Label1 = " 端口更改为" & MS.CommPort
Else
Combo1.ListIndex = MS.CommPort - 1
Exit Sub
End If
End If
Else
MS.CommPort = Combo1.ListIndex + 1
End If

Exit Sub
Combo1_Error:
MsgBox "端口打开错误", vbInformation

End Sub

Private Sub Command1_Click()
Text1 = "CDHolding:" & MS.CDHolding & Chr(13) & " CTSHolding:" & MS.CTSHolding & Chr(13) _
& " DSRHolding:" & MS.DSRHolding & Chr(13) & " InBufferCount:" & MS.InBufferCount & Chr(13) _
& " OutBufferCount:" & MS.OutBufferCount & Chr(13) & " PortOpen:" & MS.PortOpen

End Sub

Private Sub Command2_Click()
If MS.RTSEnable Then
MS.RTSEnable = False
Command2.Caption = "RTS-OFF"
Else
MS.RTSEnable = True
Command2.Caption = "RTS-ON"
End If
Call Command1_Click
End Sub

Private Sub Command3_Click()
If MS.DTREnable Then
MS.DTREnable = False
Command3.Caption = "DTR-OFF"
Else
MS.DTREnable = True
Command3.Caption = "DTR-ON"
End If
Call Command1_Click
End Sub

Private Sub Command4_Click()
Text3 = ""
End Sub

Private Sub Command5_Click()
Text2 = ""
End Sub

Private Sub Comset_Click(Index As Integer) '端口属性值设置
On Error GoTo ComsetError
comsetd1 = Comset(2).ListIndex
comsett1 = "n"
Select Case comsetd1
Case 0
comsett1 = "n"
Case 1
comsett1 = "o"
Case 2
comsett1 = "e"
End Select

MS.Settings = Comset(1).Text & "," & comsett1 & "," & Comset(3).Text & "," & Comset(4).Text

Exit Sub
ComsetError: '错误处理
MsgBox "端口属性值无效!" & Te & Te & "将恢复为默认值(9600,N,8,1)", vbCritical
MS.Settings = "9600,n,8,1"
Comset(1).ListIndex = 9
Comset(2).ListIndex = 0
Comset(3).ListIndex = 0
Comset(4).ListIndex = 0
End Sub

Private Sub Comset0_Click(Index As Integer)
If MS.PortOpen Then Call Opencom_Click
MS.CommPort = Comset0(0).ListIndex + 1
End Sub

Private Sub Form_Load()
Comset0(0).ListIndex = 3
Comset(1).ListIndex = 9
Comset(2).ListIndex = 0
Comset(3).ListIndex = 0
Comset(4).ListIndex = 0
Call Timer1_Timer
End Sub

Private Sub MS_OnComm()
On Error GoTo OncommError
Dim Breceive() As Byte
Dim Sreceive As String
Dim intValue As Integer

Select Case MS.CommEvent

Case comEvReceive '接收数据

Sreceive = MS.Input
Text2 = Text2 & Sreceive '字符接收

' MsgBox "wate:"

'--------------------------------

Case 1001
MsgBox "收到断开信号!", vbInformation
Case 1002
MsgBox "准备发送时,CTS为低", vbInformation
Case 1003
MsgBox "准备发送时,DSR为低", vbInformation
Case 1004
MsgBox "数据帧错误!", vbCritical
Case 1006
MsgBox "端口溢出!", vbCritical
Case 1007
MsgBox "准备发送时,CD为低", vbInformation
Case 1008
MsgBox "接收缓冲区溢出!", vbCritical
Case 1009
MsgBox "奇偶校验错!", vbCritical
Case 1010
MsgBox "发送缓冲区满!", vbCritical
Case 1011
MsgBox "检取端口时,发生了没预料的错误!", vbCritical
'------------
Case 1
MsgBox "发送缓冲区字符小于设定值!", vbExclamation
Case 2
MsgBox "接收到" & MS.RThreshold & "个字符"
Case 3
'MsgBox IIf(MS.ctsRHolding, "可以发送", "不能发送")
Label1 = IIf(MS.CTSHolding, "可以发送", "不能发送")
Case 4
'MsgBox IIf(MS.dsrHolding, "外设接入", "外设移出")
Label1 = IIf(MS.DSRHolding, "外设接入", "外设移出")
Case 5
'MsgBox IIf(MS.CDHolding, "响铃", "")
Label1 = IIf(MS.CDHolding, "CD置位", "CD复位")
Case 6
Label1 = IIf(MS.CDHolding, "响铃", "不响")
Case Else
MsgBox "意外事件!代码:" & MS.CommEvent, vbCritical
End Select

Exit Sub
OncommError:
MsgBox "设备出错!代码:" & Err.Number, vbCritical

End Sub

Private Sub Opencom_Click()
On Error GoTo PortError
If Not MS.PortOpen Then
MS.PortOpen = True
Opencom.Caption = "关闭串口"
Label1 = "设备 " & MS.Object & " Id: " & MS.CommID
Else
MS.PortOpen = False
Opencom.Caption = "打开串口"
End If
Call Command1_Click
Exit Sub
PortError: '错误处理
Select Case Err.Number
Case 8002
MsgBox "串口 " & MS.CommPort & " 不存在!", vbExclamation
Case 8005
MsgBox "串口 " & MS.CommPort & " 被占用!", vbInformation
Case 380
MsgBox "无效的属性值!", vbInformation
Case 8012
MsgBox "串口 " & MS.CommPort & " 没有打开!", vbInformation
Case 8015
MsgBox "不能设置串口 " & MS.CommPort & "通信状态!", vbInformation
Case 8019
MsgBox "串口 " & MS.CommPort & " 忙!", vbInformation
Case 8020
MsgBox "串口 " & MS.CommPort & " 错误!", vbInformation
Case Else
MsgBox "其它错误:" & Err.Number, vbInformation
End Select
End Sub

Private Sub Send_Click()
Dim Send_text As String

If Not MS.PortOpen Then Call Opencom_Click
If Not MS.PortOpen Then Exit Sub

If Not MS.DSRHolding Then GoTo NoConnect
If Not MS.CTSHolding Then
'MsgBox "外设不允许发送!"
'Exit Sub
End If
Send_text = Text3
MS.Output = Send_text
Exit Sub

NoConnect:
MsgBox "外设" & MS.CommPort & "没接入"
End Sub

Private Sub Timer1_Timer()
Call Command1_Click
Form1.Caption = Now
End Sub

㈡ DSP处理器和鼠标内部的芯片是否有区别

HDNS2000光学感测芯片在运动检测中的应 用2009年02月17日 星期二 下午 10:40
摘 要:安捷伦(Agilent)公司的hdns2000芯片是一种高性能的运动检测器件,在目前的光学鼠标中应用广泛,其易用性和廉价性使其非常适合应用于中低精度的运动和位置检测中。本文介绍hdns2000的功能、特点,从硬件与软件两个方面讨论hdns2000与AVR单片机的接口设计。

关键词:hdns2000 运动检测 AVR

在机电产品设计中,有时需要检测物体间的相对运动,包括运动方向和运动距离。若采用机械式的结构,比如机械鼠标中的滚轮和轨迹球,则会由于频繁的机械运动而发生故障,导致精度下降甚至失效,维修起来也不方便。另外它需要两个物体表面相接触,靠相互间的摩擦进行工作,这在某些场合是不能允许的。解决方案之一就是采用光电器件,运用光学原理来测定运动。安捷伦公司的hdns2000就是为此而设计的,虽然它的市场是针对光学鼠标,但也可以作为一种高性能而又廉价的器件运用于工业控制领域中。
1 hdns2000芯片介绍

1.1 主要功能与特性

hdns2000是安捷伦推出的高性能的光学感测芯片,它的内部包含三个基本模块:图像拾取系统、DSP处理器、PS/2或四状态输出转换器,如图1所示。在hdns2000芯片的底部有一个感光眼,如同一个小型的摄像头,不断地对物体表面进行拍照,接着将前后两次的图像送入DSP中进行处理,以判断物体移动的方向和大小,最后将数据转化为PS/2格式或者以两通道四状态格式输出。图2中的(a)与(b)分别为芯片前后两次拾取的图像。比较图2中的(a)和(b)可以看出,物体向左下方移动了一点。
hdns2000的图像拾取系统每秒钟可以拾取1500张图像,可以精确地测量最高30.48 cm/s(12 英寸/s)的运动,分辨率为400点每英寸。

1.2 引脚介绍
hdns2000的主要引脚框图如图3所示。
PS2_C:PS/2接口的时钟端。
MODE/XA:复用引脚,接高电平时表示选择PS/2模式;否则,为XA输出。
RB/XB:复用引脚,PS/2模式时为鼠标右键输入;否则,为XA输出。
MB/YB:复用引脚,PS/2模式时为鼠标中键输入;否则,为YB输出。
LB/YA:复用引脚,PS/2模式为鼠标左键输入;否则,为YA输出。
XY_LED:激光LED控制输出,在物体长时间不移动时,hdns2000可以控制LED关闭,以节约能量。
VDD3:3.3 V直流电源输入。
REFB:内部参考引脚,通过电容与VDD3相连。
PS2_D :PS/2接口的数据端。
NRESET:低电平复位引脚。
VDD5:5 V直流电源输入。
GND:电源地。
OSC2:晶振输出。
OSC1:晶振输入,外接18.432 MHz晶振。

2 hdns2000与AVR单片机接口设计
2.1 hdns2000与AT90S8015接口

hdns2000直接提供有PS/2接口,方便了PS/2鼠标的设计;但在机电控制中,为了提高效率,宜直接采用hdns2000的另一种输出模式,即X向与Y向两通道四状态输出模式。此时XA、XB指示X向移动状态,而YA、YB指示Y向移动状态。图 4为hdns2000与AVR单片机AT90S8515的接口原理图。接口主要占用了4个引脚,其它两个是可选的,所以,即使是AVR中最低档的ATtiny系列也可以方便地与hdns2000连接。

另外在对节能要求不高的场合,可以将激光LED的一端直接与地相连接,而通过控制开关三极管2N3906来主动控制hdns2000的工作状态。本文作者在设计时正是采用的这种方式。在进行系统设计时,最好采用安捷伦公司提供的套件,其中包括hdns2000芯片、HDNS2100透镜、HDNS2200 激光LED卡件及HLMP-ED80激光LED,激光波长为639 nm。
2.2 四位状态机的工作过程

在hdns2000内部有两个状态机分别指示X、Y两个方向,每个状态机又有四个稳定的状态。图5是状态机的示意图。由图5可见,一开始系统处于状态0,每当检测到物体向正向或反向移动1个单位时就转移到下一个状态,所以只要连续监测状态机状态的变化就可以判断物体移动的方向和距离。图6(a)和(b)分别为负向移动和正向移动时状态机输出的波形。值得注意的是,每个状态的最少停留时间为133μs。

2.3 接口软件设计
由状态机输出波形图可以看出,有一种很简单自然的接口设计方法,就是将状态输出引脚接到单片机的外部中断引脚上,使其在每个波形的上下边沿都产生中断,再在中断处理程序中,检测另一对应波形的电平高低,就可以判断移动方向。比如在XA的上升沿时,若XB是低电平就是左移,若XB是高电平就是右移。这种方法需要单片机提供足够多的外部中断。若同时检测X向与Y向运动,且单片机1个引脚不能同时提供上升沿和下降沿中断的情况下,就需要占用8个中断、8条引脚;而目前许多单片机仅提供2个外部中断引脚,这种要求显然较为苛刻。

另一种方式就是降低精度要求,仅在XA与YA的上升沿进行检测,此时仅需要2个外部中断引脚。但这种方式在一种极端条件下会出错,读者可以自行分析。若只检测X一个方向,则可以同时检测上下沿中断,这样不会出错。这种方式牺牲了一点对运动换向和震颤的敏感度;但编程简单,不失为一种好方法。

本文采用的是查询方式,这种方式不占用任何中断,且能够不损精度地同时检测X向与Y向运动。前面已经提过,每个状态的最小保持时间为133 μs,所以,只要将查询的周期控制在60μs之下就可以抓住每个状态的变化。对于AT90S8515,若按晶振为8 MHz计算,则只需将查询周期汇编指令数控制在450条以下就可以了。实际上,以下给出的C语言程序经过编译后只有不大于60条汇编指令,完全能够满足系统要求。

该方法的基本思想是将状态机的前一状态与现在的状态组合在同一字节内,如表1所列,寻找其中的规律,简化程序设计。表1中以PRE开头的表示前一状态的对应值。

以X向移动为例(仅看前半字节),正向移动时对应的值为0b1000、0b1110、0b0111、0b0001,负向移动时对应的值为0b0010、0b1011、0b1101、0b0100。假设状态不变的情况已经排除,且查询周期足够短,不会出现相对周期的组合值。所以只要能将以上两组值区分开来就可以了,这也正是程序中两条条件判断语句的目的。读者可以对照程序自行验证。接口程序如下:
while(1){
state=PINA&0xcc;
state_change=state^pre_state;
combo_state=sate | (pre_state>>2);
if(state_change & 0x0c)
{
if((combo_state & 0x06) == 0x06)
{asm("INC R20");goto next;}
if((combo_state | 0x09) == 0x09)
{asm("INC R20");goto next;}
asm("DEC R20");
}
next:
if(state_change & 0xc0)
{
if((temp & 0x60) == 0x60)
{asm("INC R21");goto end;}
if((temp | 0x90) == 0x90)
{asm("INC R21");goto end;}
asm("DEC R21");
}
end:pre_state=state;}

程序已经事先定义了寄存器R20与R21分别为X、Y向的计数器,用来表示X、Y向移动的距离。以上程序段利用内嵌汇编语句优化了程序结构。实际上,还可以对编译器生成的汇编代码进行优化,这里就不再详述了。

结 语

以上软硬件接口设计虽然是以功能强大的AVR单片机作为例子,但通过仔细分析不难发现,在简单的应用场合,用普通的51单片机,甚至如AT89C2051在12 MHz晶振频率下也可以实现其功能。所以整个系统会是相当廉价的。

㈢ 用MFC怎么做串口测试程序,我要详细步聚!!!!!!!!

添加一个mscomm 控件里面有,然后设置它的波特率,波特率和下位机的波特率要一致。然后就用
Write和Read方法读写数据就行了。
推荐关于MSCOMM控件的一些说明
VB5.0/6.的MSComm通信控件提供了一系列标准通信命令的接口,它允许建立串口连接,可以连接到其他通信设备(如Modem).
还可以发送命令、进行数据交换以及监视和响应在通信过程中可能发生的各种错误和事件,从而可以用它创建全双工 、事件驱
动的、高效实用的通信程序。但在实际通信软件设计过程中,MSComm控件并非像想象中那样完美和容易控制.特别是在中文Wln
95/98下通信时更会出现问题。下面就从基础开始介绍,然后逐步讨沦MSComm控件在编程中出现的问题以及编程技巧。
一、用MSComm控件通信
1.串口通信基础知识
一般悦来,计算机都有一个或多个串行端口,它们依次为com1、Com2、…,这些串口还提供了外部设备与pC进行数据传输和
皿信的通道。这些串口在CPU和外设之间充当解释器的角色。当字符数据从CPU发送给外设时,这些字符数据将被转换成串行比特
流数据;当接收数据时,比特流数据被转换为字符数据传递给CPU,再进一步说,在操作系统方面,Windows用通信驱动程序
(COMM.DRV)调用API函数发送和接收数据,当用通信控件或声明调用API函数时,它门由COMM. DRV解释并传递给设备驱动程序,
作为一个vB程序员,要编写通信程序.只需知道通信控件提供给Windows通信AP1函数的接口即可.换句话说,只需设定和监视通
信控件的属性和事件即可。
2.使用Mscomm控件
在开始使用MSComm控件之前。需要先了解其属性、事件或错误
属性 描述
CommPort 设置或返回通信端口号
Settings 以字符串的形式设置或返回波特率、奇偶校验、数据位和停止位
PortOpen 设置或返回通信端口的状态。也可以打开和关闭端口
Input 返回和删除接收缓冲区中的字符
Output 将字符串写入发送缓冲区

CommEvent属性为通信事件或错误返回下列值之一。在该控件的对象库中也可以找到这些常量。
常量 值 描述
ComEventBreak 1001 收到了断开信号
ComEventCTSTO 1002 Clear To Send Timeout。在发送字符时,在系统指定的事1件内,CTS(Clear To Send)线是低电平
ComEventDSRTO 1003 Data Set Ready Timeout。在发送字符时,在系统指定的事件内,DSR(Data Set Ready)线是低电平
ComEventFrame 1004 数据帧错误。硬件检测到一个数据帧错误
ComEventOverrun 1006 端口溢出。硬件中的字符尚未读,下一个字符又到达,并且丢失
ComEventCDTO 1007 Carrier Detect Time。在发送字符时,在系统指定的事件内,CD(Carrier Detect)线是低电平。CD
也称为RLSD(Receive Line Singal Detect,接收线信号检测)
ComEventRxOver 1008 接收缓冲区溢出。在接收缓冲区中没有空间
ComEventRxParity 1009 奇偶校验错。硬件检测到奇偶校验错误7
ComEventTxFull 1010 发送缓冲区满。在对发送字符排队时,发送缓冲区满
ComEventDCB 1011 检取端口DCB(Device Control Blick)时发生了没有预料到的错误

通信事件包含了下面的设置:
常量 值 描述
ComEvSend 1 发送缓冲区中的字符数比Sthreshold值低
ComEvReceive 2 接收到了Rthreshold个字符。持续产生该事件,直到使用了Input属性删除了接收缓冲区中的数据
ComEvCTS 3 CTS(Clear To Send)线改变
ComEvDSR 4 DSR(Data Set Ready)线改变。当DSR从1到0改变时,该事件发生
ComEvCD 5 CD(Carrier Detect)线改变ComEvRing6检测到响铃信号。一些URAT(Universal AsynchronousReciver-
-Transmitters,通用异步收发器)不支持该事件
ComEvEOF 7 收到了EOF字符(ASCII字符26)

Error消息(MSComm控件)下表列出了MSComm控件可捕获的错误消息:
常量 值 描述
ComInvalidPropertyValue 380 无效的属性值
ComSetNotSupported 383 属性只读
ComGetNotSupported 394 属性只读
ComPortOpen 8000 端口打开时该存在无效
8001 超时设置必须比0值大
ComPortInvalid 8002 无效的端口号
8003 属性只在运行时有效
8004 属性在运行时是只读的
ComPortAleadyOpen 8005 端口已经打开
8006 设备标识符无效或不支持
8007 不支持设备的波特率
8008 指定的字节大小无效
8009 缺省参数错误
8010 硬件不可用(被其他设备锁住)
8011 函数不能分配队列
ComNoOpen 8012 设备没有打开
8013 设备已经打开
8014 不能使用通信通知
ComSetCommStateFailed 8015 不能设置通信状态
8016 不能设置通信事件屏蔽
ComPortNotOpen 8018 该存在只在端口打开是有效
8019 设备忙
ComReadError 8020 通信设备读错误
ComDCBError 8021 检取端口设备控制块时出现内部错误

搞清楚以上基本属性后,就可以开始编写通信许程序了。在VB5.0/6.0中新建一个工程文件。添加Microsoft Comm Control 5.0组
件,在简体Form1中加入Command命令按钮并取名为CmdTest,MSComm控件取名为MSComm1,加入如下程序代码。
Private Sub cmdTestClick ( ) '打开串口
MSComml.CommPort =2 '设定Com2
If MSComml.PortOpen = False Then
MSComm1.Settings = "9600,n,8,1" '9600波特率,无校验,8位数据位,1位停止位
MSComm1.PortOpen = True '打开串口
End if
MSComm1.OutBufferCount = 0 '清空发送缓冲区
MSComm1.InBufferCount = 0 '滑空接收缓冲区

'发送字符数据时注意必须用回车符(vbcr)结束
MSComm1.Output="This is a qood book ! " &vbCr

'泼打电话号码或发送AT命令
MSComm1.Output = "ATDT 05778191898 , & vbCr

'发送字符数组数据时注意ByteArray必须事先定义赋值
Dim ByteArray as byte( )

'定义动态数组
ReDim ByteArray(1)

'重定义数组大小
ByteArray ( 0 ) =0
ByteArray ( 1 ) = 1
MSComm1.Output = ByteArray
End Sub

private Sub MScommEvent( )
Select Case MSComm1.CommEvent
Case comEvReceive
Dim Buffer As Variant
MSComm1.InputLen = 0
'接收二进制数据
MSComm1.InputMode= ComInputModeBinary
Buffer=MSComm1.Input
'接收字符数据
MSComm1.InputMode=comInputModeText
Buffer = MSComml.Input
Case else
End Select
End sub
( 程序1)

二、中文Win 95/98下的通信问题与解决方法
1.接收的数据少于发送的数据
如果通过MSComm控件一次性传送较多的二进制数据,那么,很可能收到的数据不足。例如在设置为24oobps传输率的情况下,
一次性可以传输2048个字符数据 那么在大多数情况下。一次只能收到1200个字符左右,这址出为新版的MSComm32.OCX中存在一
个影响传输二进制数据的臭虫(bug).注意这不是特性。
32位Windows API函数(以下简称API)使用了几个用COMMTIMEOUTS结构表示的限时变量,WriteTotalTimeOutConstant 即是其
中的一个,它被Windows内部设定为5000(即5秒),这个常量决定了在通信驱动程序停止传输之前花费在发送缓冲区中数据的时间
的长短,5秒钟意味着通信速度为1200bps情况下仅能发送600个字符,24oobps情况下仅能发送1200个左右的字符。事实上,在一个
缓冲区内一次性发送更多的数据是非常可能的。这个bug同样也能引发问题,甚至在高速串口门通信情况下,即使系统在使用流控
制,无论丛软件流(Xon/XofI)还是硬件流(CTS/RTS)。假如数据在发送缓冲区中时,流控制停止了传输,如果停止时间超过5
秒钟.则数据就会丢失。在某些环境下,5秒钟可能相当短.不过也不必担心, VB 5.0/6.0版本的MSComm控件有一个新增的重要的
属性称为CommID, CommID指的是当串口被打开时,被API所调用的串口句柄或称标志,这也意味着能利用API接口函数去修改这个
常量。每次串口关闭后,Windows会自动将之恢复为5000,所以,每次打开串口后需要重斩设定以下API声明,其代码见下程序。
Type COMMTIMEOUTS
ReadIntervalTimeout As Long
ReadTotalTimeoutMultiplier As Long
ReadTotalTimeoutConstant As Long
WriteTotalTimeoutMultiplier As Long
WriteTotalTimeoutConstant As Long
End Type
Declare Function SetCommTimeouts Lib "Kernel32"
(BYVal hFile As Long, lpComm TimeoutsAs COMMTIMEOUTS) As Long
Declare Function GetCommTimeouts Lib "Kernel32"
(ByVal hFile As Long, lpCommTimeouts As COMMTIMEOUTS) As Long
Dim timeouts As COMMEOUTS
Dim Ret As Long
If Comm1.PortOpen = False Then
Comm1.PortOpen = True
End if
Ret=GetCommTimeouts ( Comm1.CommID , timeouts )
'Set some default timeouts
timeOuts.ReadIntervalTimeout = 1
timeouts.ReadTotalTimeoutMultiplier =1
timeouts.ReadTotalTimeoutConstant =1
timeouts.WriteTotalTimeoutMultiplier =1
timeouts.WriteTotalTimeoutConstant=
( Comm1.OutBufferSize\Val(Comm1.Settings))*10000+1000
Ret=SetCommTimeouts( Comm1.CommID , timeouts )
( 程序2)

2.如何发送大于128的字符数据
在通信程序中,以单字符方式逐个发送数据时,每一个数据范围 0-255(即十六进制的00-FF)。在单字符版本的英文Win95或
DOS版的BASIC程序中,只需要将相应的数据转换成相应的字符发送到通信端口即可。但在中文Win95/98下却行不通,假设在中文
Win95/98下运行以下程序:
Dim i
For i=0 to 255
MSComm1.Output=chr(i)
Next i

希望在接收端得到预期的0-255之间的数据,结果却是:前129个数据接收正确,为0-128,后面127个数据为126个0和一个255,
造成这种给果的原因在于中文Windows使用的是双字节字符集(DBCS)系统。DBCS系统使用0-128之间的数字表示ASCII字符,大于
128的数字仅作为前导字符,它只是显示是一个非拉丁语系的字符,而并不代表实际意义。上述程序在调用CHR()函数时用到了
DBCS字符集,冈此产生了此类错误。那么,如何发送人于128的数据呢?答案是使用字符数组,将以上程序改为:
Dim cc(255) As Byte
For i = 0 To 255
cc(i) = i
Next i
MSComm1.Output = cc
Do
DoEvents
Loop Until MSComm1.OutBufferCount = 0
'接收过程 MSComm1_OnComm()
Select Case MSComm1.CommEvent
Case comEvReceive
Dim Buffer As Variant, b1,i
MSComm1.InputMode=comInputModeBinery
MSComm1.InputLen = 0
Buffer = MSComm1.Input
For i=LBound (Buffer) To UBound (Buffer )
Debug.Print Buffer ( i ) ;
Next i
Case . . . . .

3.如何发送0字符(00H,NULL)
在VisuaI C++中使用串口控件发送0字符有些麻烦,但在VB5.0/6.0中只要注意以下两点即可:
(1)设置MSComm控件的属性 NullDiscard=False;。
(2)使用二进制接收,即用 MSComm1.InputMode=ComInputModeBinary便可以解决问题;

4.如何发送递中文字符串(DBcS字符)
VB5.0/6.0的各种参考书上均指明MSComm通信控件不能发送或接收双字节字符集系统DBCS)的二进制数据,这对于我国及亚洲一些
使用DBCS字符集的国家不能不说是一大人遗憾。但是我在实践中发现,用MSComm控件也可以发送中文字符,具体方法有以下两种:
(1)直接发送
直接发送即把中文字符等同于英文字符。如:MSComm1.Intput= " 这是一行中文数据!" ,但这种方法发送的中文数据不能太
长,发送缓冲区和接收缓冲区的大小需设定为中文字符的两倍以上,而且发送与接收系统所处的操作系统版本最好要一致,否则会
出现接收或发送缓冲区溢出之类的错误。这种方法时用于一般要求不太高的场合。
(2)间接发送
在发送端将汉字或字符转换为机器内码或区位码数据数组,然后将咏转换后的数据发送到串口,在接收端接收到数据后,按照
相反的顺序得到的数据转换为相应的汉字或字符,在转换过程中.要用到位运算,如取得汉字的内码后需要将高字节和低字节分开,
而VB5.0/6.0中并没有提供此类函数,以下是求整数高、低字节的函数。

Public Function HiByte(a As Integer )
Dim b
b= a And &HFF00
b = b / 256
If b<0 Then b = b + 256
HiByte = b
End Function

Public Function LowByte(a As Integ`er)
Dim b
b = a And &HFF
LowByte = b
End Function

5.如何用单机进行通信测试
通常在写好了通信程序后需要两台PC或一台Pc、一台单片机.将通信口连接后进行测试,但很多时侯因条件限制仅有单台PC机,
测试项目很简单,那么能否测试呢?当然可以,而且方法也很简单。对于九针的串口,找一个废弃的串口鼠标,剥外鼠标线,将连
接2、3针的线对接即可;对于25针的串口,找一枚曲别针(最好有塑料外套的)将它扯直,剥削去两头的塑料后在两头各弯一个圆
圈,中间对忻后直接套接在串口的2、3针上即可。如果但心不够安全,则可以将5针按地。
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
关于mscomm的用法,提高篇......[mgwmj]?

MSCOMM控件是个好东西,如果您能够充分了解他,他会为您衷心的效劳。

大致看了一下下午有关讨论MSCOMM的话题,觉得有必要说说我的心得,我一般只做硬件,没有系统的学过软件,只是业余时间
学学用用,多少掌握了一点,也在此拿出来玩玩,不知有错没有,我可是以为我已经做的很好了^_^

这是一个VB通用串口事件驱动接收程序。一次性接收一个数据包,数据包可以为任意字节,保证不会丢失一个数据!
Private Sub MSComm_OnComm()
Dim S() As Byte
Dim SS(1024) As Byte
Static N As Long
Static T As Variant

If (MSComm.CommEvent = comEvReceive) Then
S = MSComm.Input '只要有数据就收进来,哪怕只是一个
If (Timer - T > 0.01) Then '间隔10MS以上就认为是一个新的包
text1="" 'text1用于搜集和显示接收(HEX格式)
N = 0
End If
T = Timer
For i = 0 To UBound(S) '一个数据包可能产生若干个oncomm事件
Text1.Text = Text1.Text & Right("0" & Hex(S(i)) & "H", 3) + " "
SS(N+i)=S(i) '接收数据包缓存于SS()
N=N+UBound(S)
Next i
End If
End Sub

㈣ 8015单片机储存器结构是什么

这个简单,大家都是知道的。

㈤ 急!请教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:接收方式使用了文本方式,用二进制方式即可。

㈥ 可编程控制器原理作业题

1.PLC是在什么控制系统基础上发展起来的( A).
(A) 继电控制系统 (B) 单片机 (C)工业电脑(D)机器人
2.常见的接近开关按感应的物体来分为( A )。
( A)电感式/电容式 (B) PNP/NPN (C)常开/常闭 ( D)定时器/计数器
3.工业中控制电压一般是多少伏(A)
(A)24V (B)36V (C)110V (D)220V
4.三菱FX系列PLC普通输入点,输入响应时间大约是多少ms?(B )
(A) 100 ms (B)10ms (C)15 ms (D)30 ms
5.对于小的PLC系统,如( C )点以内的系统.一般不需要扩展.
(A)60 (B)70 (C)80 (D)90
6.PLC的输入电流是由内部的DC24V电源供给的,为了确实切断,必须取( A )以下电流。
(A)1.5mA (B)2.5mA (C)3.5mA (D)4.5mA
7.FX2N的输出继电器最多可达( C )点
(A)64 (B)128 (C)256 (D)512
8.一般要求模拟放大电路的输入电阻(A)
(A)大些好,输出电阻小些好(B)小些好,输出电阻大些好
(C)和输出电阻都大些好(D)和输出电阻都小些好
9.FX2N PLC软元件中有( C )点状态可构成状态转移图。
(A)300 (B)600 (C)900 (D)1200
10.对于所有的FX CPU ,表示1 秒时钟脉冲的是(B )
(A)M8011 (B)M8013 (C)M8014 9D)M8015
11.OUT指令对于( A )是不能使用的
(A)输入继电器 (B)输出继电器 (C)辅助继电器 (D)状态继电器
12.串联电路块并联连接时,分支的结束用( C )指令
(A)AND/ADI (B)OR/ORI (C)ORB (D)ANB
13.使用( B )指令,元件Y、M仅在驱动断开后的一个扫描周期内动作
(A)PLS (B)PLF (C)MPS (D)MRD
14.存储器是存放程序的仓库,采用电擦除的存储器使用非常方便,它是( D )
(A)RAM (B)EPROM (C)EPRAM (D)EP2ROM
15.状态的顺序可以自由选择,但在一系列的STL指令后,必须写入(C )指令
(A)MC (B)MRC (C)RET (D)END
16. ( B )是PLC每执行一遍从输入到输出所需的时间.
(A)8 (B)扫描周期 (C)设定时间 (D)32
17.对于STL指令后的状态S,OUT指令与( B )指令具有相同的功能
(A)OFF (B)SET (C)END (D)NOP
18.助记符后附的( B )表示脉冲执行
(A)(D)符号(B)(P)符号 (C)(V)符号 (D)(Z)符号

㈦ 三菱Q系列PLC中各个特殊寄存器的意义

1、通用数掘寄存器:

(1)、可用于传送和暂存数据,也可参与算术逻辑运算,并保存运算结果。除此之外,它们还各自具有一些特殊功能。

(2)、汇编语言程序员必须熟悉每个寄存器的一般用途和特殊用途,只有这样,才能在程序中做到正确、合理地使用它们。

2、断电保持数据查存器:可以利用外部设备的参数设定改变通用数据查存器与有断电保持功能数据寄存器的分配, D512-D7999的断电保持功能不能用软件改变,但可用指令清除它们的内容。


3、特殊数据寄存器:特殊数据查存器的作用是用来监控PLC的运行状态,如扫描时间、电池电压等,具体可参见用户手册。


4、变址寄存器:实际上是一种特殊用途的数据高存器,其作用相当于微机中的变址寄存器,用于改变元件的编号(变址) 。

(7)8015单片机扩展阅读:

1、三菱(Mitsubish)不是一个单独的公司,是由众多的独立公司组成的团体,其中大多数公司使用“三菱”这一名称,但不会简单地自称“三菱”。

2、三菱Kinyokai(也被称为Friday Club,直译为星期五俱乐部)的核心成员有28家,三菱的成员公司约有500家,名称中有“三菱”的公司约有400家,另有数以百计的三菱公司名称中没有“三菱”。

3、这些公司的商业活动是独立进行的,甚至在很多领域彼此竞争,

4、这些公司起源于1870年岩崎弥太郎(Yataro Iwasaki)经营的一家船运公司,随后公司开始涉足矿业、造船、银行和保险,为日后三菱公司的成长与发展奠定了坚实的基础。

5、值得注意的是,三菱铅笔株式会社(Mitsubishi Pencil)不是三菱的成员公司。

阅读全文

与8015单片机相关的资料

热点内容
成都python培训机构好不好 浏览:421
mysql查看配置命令 浏览:597
v8编译cmake 浏览:964
app品牌起步阶段需要什么营销 浏览:358
压缩机制冷剂温度 浏览:930
会日语的程序员 浏览:19
网银密码加密失败怎么回事 浏览:727
android开发音乐播放器 浏览:808
ug120阵列命令快捷键 浏览:597
气动隔膜式压缩机 浏览:470
linux如何修改主机名 浏览:104
单片机光标上下移动 浏览:528
数据加密验证 浏览:108
程序员被激怒 浏览:891
winxp找不到服务器dns地址 浏览:842
以文本文件的格式保存考生文件夹 浏览:41
编译原理文法分为几类 浏览:570
JAVA基础学python要多久 浏览:74
java流量控制 浏览:936
java实现多重继承 浏览:707