串口读取数据显示问题(100)

  • 主题发起人 主题发起人 rogerxu
  • 开始时间 开始时间
R

rogerxu

Unregistered / Unconfirmed
GUEST, unregistred user!
本人急于编写电子秤串口读取程序难点在于,如何分字节的得到每一个字节的内容电子秤的说明书上写明,一次发送6个帧,每个帧10位,第一位是起始位,最后一位是结束位,中间8位为数据我只需要第3,4,5帧的内容,这三帧的内容是BCD1,BCD2,BCD3这样的BCD1 显示电子秤的数值的最低字节BCD2 显示电子秤的数值的中间字节BCD3 显示电子秤的数值的最高字节我怎么才能做到获取每一帧的内容,然后把它展出到窗体上面我在MSCOMM的事件里的代码为procedure TMainForm.ShowChange;var ReceiveData : oleVariant; StrBuffer : string; BufferCount,I : Integer; DataBuffer : Variant; BByte : array of Byte;begin case MSComm.CommEvent of comEvReceive: begin StrBuffer := ''; BufferCount := MSComm.InBufferCount; if BufferCount>0 then begin ReceiveData := MSComm.Input; SetLength(BByte,4096); BByte := ReceiveData; for I := 0 to BufferCount - 1 do begin StrBuffer := StrBuffer + IntToStr(BByte); end; Memo1.Lines.Add(StrBuffer); end; end; 1001: begin MessageBox(Handle,'信号中断','串口通讯错误',MB_OK+MB_ICONERROR); end; 1002: begin MessageBox(Handle,'ClearToSend超时','串口错误',MB_OK+MB_ICONERROR); end; end; StPnlStatus.Caption := '正在接受串口数据......';窗体启动的时候就已经打开了串口,我的串口设置 MSComm.InputLen := 6; //因为要接收6帧 MSComm.InBufferSize := 512; Mscomm.DTREnable := True; // 数据终端准备好 Mscomm.RTSEnable := True; // 请求发送 MSComm.RThreshold := 6; // 接收的数据最少为6个 MSComm.SThreshold := 0; // 发送的数据最少为0个,因为不需要发送数据
 
对于串口数据的接收最好采用定时器轮询的方式接收,接收到的数据放到一个缓冲中在接收后进行解析处理,如果采用oncomm事件方式处理的话一旦数据传送很快难免会丢数据的
 
一段用过的代码,希望有用:var //errmessage:string; recvlen:Integer; i: integer; reData:array of Variant; restr: string; StrSend: string; TxBuff: OleVariant;if mscomm.InBufferCount > 0 then begin redata := mscomm.Input; // 接收数据 for i := 0 to vararrayhighbound(redata,1) do begin ApduRecvDataBuff := Integer(redata); restr := restr + IntToHex(Integer(redata), 2) + ' '; end; WriteLog('接收数据:' + restr); end else begin WriteLog('接收数据:' + restr); Result := 0; Exit; end;接收完了,显示还不是个小问题嘛。
 
他的6个帧是连续发送?如果是,你就在接收串口数据的时候判断结束位不就行了取第2帧结束位开始第5帧结束位终止之间的数据,然后再按帧格式取数据串口每次收到的数据不一定是帧的全数据,所以你一定要用个变量累加读取每次读取的数据,根据起始位和结束位得到数据
 
不对呀,我用了你的办法ApduRecvDataBuff这个是怎么来的是声明的一个字节数组? array of byte?我使用的时候报错,各位就算我把这个读取过程另外放在事件器事件上面,一样的要报错我觉得就是这个的错ApduRecvDataBuff := Integer(redata);
 
第一帧是起始位说明书上写的是0FFH第二帧 D0-D2 小数点位置(0-5) D3-D4 当前的工作模式 00-计算重量 01-计算数量 10-百分比模式 D5 1表示负数,0表示正数 D6 1表示重量稳定,0表示不稳定 D7 1表示溢出,0表示未溢出第三帧 D0-D7 显示BCD1电子秤的数值的最低字节第四帧 D0-D7 显示BCD2电子秤的数值的中间字节第五帧 D0-D7 显示BCD3电子秤的数值的最高字节
 
可以考滤换个读串口的库MSCOMM控件用着不是很爽如果6帧是连续的可以先读出你用的数据然后再循环读空缓冲区
 
ApduSendDataBuff:array[0..255] of byte; ApduRecvDataBuff:array[0..255] of byte;
 
ApduRecvDataBuff所有的值都在这里面了但是其实只需要定义ApduRecvDataBuff【0..6】就行了撒因为发送一次只有6帧得嘛那么取某一帧的话就ApduRecvDataBuff【2】,ApduRecvDataBuff【3】,ApduRecvDataBuff【4】就可以取到重量了不但是要转成BCD码得嘛,不知道怎么根据这叁帧来计算重量
 
苍天,你就不能自己做点工作吗?都要让人帮你搞定呀?我不甩你了。拜拜。
 
不是的,我测试了很久可老是得不到正确的值 if BufferByte[0] = $FF then begin BufferByte[1] := TempBuffer[I+1]; BufferByte[2] := TempBuffer[I+2]; BufferByte[3] := TempBuffer[I+3]; BufferByte[4] := TempBuffer[I+4]; end; end; if BufferCount>0 then begin TempBuffer := MSComm.Input; BufferByte[2] := TempBuffer[2]; BufferByte[3] := TempBuffer[3]; BufferByte[4] := TempBuffer[4]; Weight1 := bcd2bin(BufferByte[2]); (16进制转换成整数) Weight2 := bcd2bin(BufferByte[3]); Weight3 := bcd2bin(BufferByte[4]); Memo.Lines.Add(IntToStr(Weight1 + Weight2*100 + Weight3*10000));显示的这个数量不对得嘛
 
呵呵,到是我误会你了。这样吧。你找个 串口调试助手 ,这个软件可以接收 从串口传来的数据,你把接收到的数据和你的软件接收到的数据比较一下,在用BCD码的格式转换一下,看看对不对。
 
我得到了16进制的数据FF 43 21 00 00但是根据这个怎么计算第叁帧,第四帧,第五帧的数据还有根据这么数据怎么计算得到重量第一帧是起始位说明书上写的是0FFH第二帧 D0-D2 小数点位置(0-5) D3-D4 当前的工作模式 00-计算重量 01-计算数量 10-百分比模式 D5 1表示负数,0表示正数 D6 1表示重量稳定,0表示不稳定 D7 1表示溢出,0表示未溢出第三帧 D0-D7 显示BCD1电子秤的数值的最低字节第四帧 D0-D7 显示BCD2电子秤的数值的中间字节第五帧 D0-D7 显示BCD3电子秤的数值的最高字节
 
第二帧: 一共八位,你把 43(16进制)转换成2进制(8位的)就可以了。转换后是01000011 小时候位数D0-D2:010 转换成10进制为2说明有小数点2位。 D3-D4 :是00 所以00-计算重量 D5: 0 表示正数 D6: 1 表示重量稳定 D7 :1 表示溢出第三、四、五帧: 高位、低位对调后为:000021 转换成 10 进制 为:33 根据前面得到的有两个小数 所以 应该除以100 得到 该电子称的读数0.33
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
1K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
900
SUNSTONE的Delphi笔记
S
后退
顶部