”,也就是十六进制的零,你却用byte类型,末尾还不加竖罩零(缓冲区长度还差一个字节呢),是否报错,需要听天由命——因为COMM1的那发送函数"og:type" content="webpage">”,也就是十六进制的零,你却用byte类型,末尾还不加竖罩零(缓冲区长度还差一个字节呢),是否报错,需要听天由命——因为COMM1的那发送函数" /> ”,也就是十六进制的零,你却用byte类型,末尾还不加竖罩零(缓冲区长度还差一个字节呢),是否报错,需要听天由命——因为COMM1的那发送函数"> 关于Delphi串口发送数据软件报错_软件运维_内存溢出

阅读 11

关于Delphi串口发送数据软件报错,第1张

COMM1是什么东西,微软的那个控件

?记得它好像是用char数组做发送缓冲的,要求结尾必须是“\0”,也就是十六进制的零,你却用byte类型,末尾还不加竖罩零(缓冲区长度还差一个字节呢),是否报错,需要听天由命——因为COMM1的那发送函数会拼命访问你缓冲区后的字节(那里不属于你的缓冲区范围之内),期待找到一个“0”来结束。Delphi的语法对数据

类型限制很严,需要你很仔细才行,许多数据类型不是简单类型强制转换就能解决问题的。

========================

抱歉前面没注意看参数,WriteCommData()内第二参数是数据长度,应该不是问题。

估计你的问题很可能是与你余乱闹关闭串口的时机和方式关。

串口控件,一般内置一个线程,主要负责监视接收数据,以及从(控件内部的)发送队列里取数据去执行发送行为。在你程序关闭前,你应该先可靠中止这线程,然后再退出程序,这依靠成员方法StopComm()来实现,如果你没做好,在释放Comm控件后线程还在运行(控件被释放与线程是否存在和执行无关!),那么陪让线程内还在访问控件已经被释放的某资源(一般是指针指向的某内存),那就产生你这样的问题。

请这样仔细检查:释放控件的代码有几处,在什么时候做;调用StopComm()的代码有几处,在什么时候做;二者是否遵循先关闭再释放的严格逻辑。如果没显式调用StopComm(),那也很可能引起你的问题——StopComm()内部是必须等待线程结束才返回的,因此安全,而程序退出控件直接被自动释放是不行的。

1、 mscomm控件安装。

Mscomm控件默认存在于delphi的ActiveX面板上,如果不存在,需要先导入该控件,步骤 :通过菜单 component---Import Activex component 打开Import Acitvex对话框。如下图:

如果列表中找不到该Microsoft Comm Control,那么点Add按钮找到Mscomm32.ocx,最后点Install..即可。2、 需要了解的属性

需要了解的几个属性:

CommPort:设置通信端口号,用该串口与外界通信。

Setting:以字符串的形式设置数据传输速率、奇偶校验、数据比特、停止比特;

PortOpen:设置并返回通信端口的状态,用来可以打开和关闭端口;

Input:从接收缓冲区返回和删除字符;

Output:向传输缓冲区定一个字符串)

RThreshold:设置接收几个字符触发控件响应函数。

CTSHolding:该属性确定是否可通过查询CTS线的状态发送数据。CTS是调制解调器发送到相连计算机的信号,指示传输可以进行。该属性在设计时无效,在运行时为只读。

如果CTS线为低电平(CTSHolding = FALSE)并且超时时,MSComm控件设置CommEvent属性为comEventCTSTO(Clear To Send Timeout)并产生OnComm事伯。CTS线用于RTS/CTS硬件握手。如果需要确定CTS线的状态,CTSHolding属性给出一种手工查询方法。

SThreshold:设置发送缓冲区中有几个字符时候触发oncomm

InputMode:用于设置或者返回传输数据的类型。

ComInputModeText(缺省) 0 通过Input属性以文本方式取回数据

ComInputModeBinary 1 通过Input属性以二进制方式取回数据

InputLen:该属性用于设置并返回Input属性从接收缓冲区读取的字符数。

InBuffersize:设置输入缓冲区的大小,默认值为1024字节。

InBufferCount: InBufferCount属性用于返回输入缓冲区内的等待读取的字节个数,可以通过该属性值为0来清除接收缓冲区。

Output:void SetOutput(const VARIANT &newValue)

Output属性用于向发送缓冲区写数据流。注意:Output属性可以发送文本数据或二进制数据。传输文本数据时,应该将字符型 数据放入VARIANT变量中;传行迅锋输二进制数据(即按字节传送)时,应将字节型数据放入VARIANT型变量中。如果通常给应用程序发送ANSI字符串,可以以文本方式发送。如果数据包含了内嵌控制字符、NULL字符等,必须将其作为二进制传递过去。

DTREnable:确定在通信时是否使用DTR线有效,DTR是计算机发送到调制解调器的信号,表明计算机在等待数据传输。

RTSEnable:确定是否使用RTS线有效。一般情况下,由计算机发送RTS信号到连接的调制解调器,请求允许发送数据。

EOFEnable:确定在输昌滚入过程中MSComm控件是否寻找文件结尾(EOF)字符。如果找到EOF字符,将停止输入并激活OnComm事件,此时CommEvent属性设置为comEvEOF,这里bNewValue为布尔表达式,确定当找到EOF字符时,OnComm事件是否被激活。当bNewValue的设置值TRUE时,EOF字符找到时OnComm事件被激活。否则当VALUE值设为FALSE(默认)时,EOF字符找到时OnComm事件不被激活。

注意:当EOFEnable属性设置为FALSE时,OnComm控件将不在输入流中寻找EOF字符。

CDHolding:通过查询CD线的状态确定当前是否有传输。CD是从调制解调器发送到相连计算机的一个信号,指示调制解调器正在联机。该属性在设计时无效,在运行时为档晌只读。属性的设置值为:当bNewValue为TRUE时,CD线为高电平;当bNewValue为FALSE时,CD线为低电平。注意当CD线为高电平(CDHolding=TRUE)且超时时,MSComm控件设置CommEvent属性为comEventCDTO(CD超时错误),并产生OnComm事件。

注意:在主机应用程序中捕获一个丢失的传输是特别重要的,例如一个公告板,因为呼叫者可以随时挂起(放弃传输)。CD也被称为Receive Line Signal Detect(RLSD)。

DSRHolding:确定DSR线的状态。DSR信号由调制解调器发送到相连计算机,指示作好 *** 作准备。该属性在设计时无效,在运行时为只读。DSRHolding属性返回为TRUE时,表示DSR线高,返回FALSE时,表示DSR线低。当DSR线为高电平时(DSRHolding=TRUE)超时时,MSComm控件设置CommEvent属性为comEventDSRTO(数据准备超时)并产生OnComm事件。当为DTE(Data Terminal Equipment)机器写DSR/DTR握手例程时该属性是分有用的。

3、 控件安装后,在AcitveX面板上可以看到一个电话机样式的图标,把它拖到delphi工程窗体上设置属性后就可以使用了

打开串口: mscomm1.portopen:=true

关闭串口: mscomm1.portopen:=false

处理接收的数据,在oncomm事件中,下面给出点提示例子(只是一个函数,缺乏桩函数不能运行,只是用来说明使用)

procedure TF_Com.MSCommComm(Sender: TObject)

var

i,j,itemp:integer

pcurDeviceSer:pdevicepro

begin

if mscomm.CommEvent = 2 then

begin

inBuf:=F_Com.MSComm.Input

for i:=0 to vararrayhighbound(inBuf,1) do

begin

if m_sourceLen >500 then

m_sourceLen := 0

m_pSourceBuf[m_sourceLen]:=inBuf[i]

m_sourceLen:=m_sourceLen+1

end

if(CommDataAnalysis()) then //如果分帧成功

begin

m_ReSendTimes := 0 //重发次数为0

for j:=0 to m_nRecDataLength-1 do

showstr:=showstr + inttohex(inBuf[j],2)+' '// _GetByte(inBuf[i])

if not bPauseFlag then

showframe(showstr,true)

else

begin

if length(showstr)>5000 then

showstr:=''

end

pcurDeviceSer:=nil

if(m_nRecDataLength = 5) then//固定帧处理

begin

for itemp:=0 to numberofdec do // numberofdec//装置个数 ,遍历,查找需要的装置

begin

if BDeviceSer[itemp].addr=RecBuf[2] then

begin

pcurDeviceSer:=@BDeviceSer[itemp] //指针指向被召唤的装置的结构体

break

end

end

if pcurDeviceSer=nil then //所召唤的装置不存在

else

FrameFix(pcurDeviceSer)

end

else //可变帧处理

begin

for itemp:=0 to numberofdec do // numberofdec//装置个数 ,遍历,查找需要的装置

begin

if BDeviceSer[itemp].addr=RecBuf[4] then

begin

pcurDeviceSer:=@BDeviceSer[itemp]

break

end

end

if pcurDeviceSer=nil then //所召唤的装置不存在

else

FrameUnFix(pcurDeviceSer)

end

end

end

// end

end

发送串口数据:

procedure SendComData()

var

i,j:integer

begin //Main_Form.dqc.ConvertStr2Hex(tempstr,SendBuf,m_nSendDataLength)

if (SendBuf[0]=$10) then

m_nSendDataLength:=5

else

m_nSendDataLength:=((SendBuf[1] and $ff)+6) //+号比&(按位与运算符)优先级高.

outBuf := VarArrayCreate([0,m_nSendDataLength-1], varByte)

for i:=0 to m_nSendDataLength-1 do

outBuf[i]:=SendBuf[i]

F_Com.MSComm.Output:=outBuf

上面的例子只是为了说明使用方法,并不可运行。

你需要知道以下内容:雀雀铅

1. 如何开启仪器的RS232通讯。可能是通过仪器上的岁亩按钮或者触摸屏,或者默认自动开启。

2.开启RS232通讯之后仪器的通讯设置,包括波特率,数据位,停止位和奇偶校验位,根据这些信息设置Delphi上RS232通讯的参数,例如9600,n,8,1

3.仪器连接在电脑上的RS232端口,通常是COM1.但是有些仪器可能有特殊的驱顷好动,或者通过USB模拟的端口,要通过设备管理器来查看具体是COM几。

4.与仪器通讯的具体命令格式。例如Topcon的色度测试仪开始测试的命令是“ASFS + 回车换行”。那么你就通过Delphi程序发送相应的命令,例如通过TMSComm控件可以这样写:

MSComm.Output = "ASFS" + sLineBreak


希望上述解答对你有帮助。

欢迎分享,转载请注明来源:

内存溢出

原文地址:

https://outofmemory.cn/yw/12276810.html
字符
(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
谷歌浏览器Chrome的扩展程序安装目录是什么?安装在哪里?
上一篇
2023-05-24
求教,php 如何获取文件的下载路径?
2023-05-24

发表评论
请登录后评论... 登录
提交

    评论列表(0条)
保存
{label} {label}