使用COM端口与硬币兑换商交互

Cra*_*ker 7 c# delphi serial-port delphi-6 multidrop-bus

我有一个硬币兑换器MEI Cashflow E7900和一个MDB适配器,用于将设备连接到串行端口.向我销售适配器的商店还提供了一个测试应用程序,用Delphi编写,用Borland Delphi v6.0编译.它工作得很好,但我的代码由于某种原因没有.
使用MDB时,必须POLL每200ms 发送一次命令.如果一切正常,硬币转换器发送ACK.当我使用Delphi应用程序发送它时,会话看起来像这样:

=> 0x0B*0x0B(星号表示奇偶校验设置为Mark.默认奇偶校验为空格)
<= 0x00

所以一切都很好,这就是我所期待的.当我POLL使用C#应用程序发送时,它就像:

=> 0x0B*0x0B
<= 0x3F 0x00

有时硬币兑换商发送给我0x3F 0x11之后POLL没有任何意义,没有任何有效的回应.当我得到这样的响应时,我运行Delphi应用程序,它得到一个有效的ACK响应.我使用的是COM端口嗅探器,以确保发送的数据没有任何差别,包括端口配置本身,我不断得到不同的响应.
这里是测试应用程序(Delphi)的源代码:

<...>
//The component used it called BComPort
form1.BComPort1.BaudRate:=br9600;
form1.BComPort1.Parity:=paSpace;
form1.BComPort1.Port:="%port name goes here%";
form1.BComPort1.Open;
<...>

procedure SetModeBit(modebit:boolean);
begin
if modebit then begin
   form1.BComPort1.BeginUpdate;
   form1.BComPort1.Parity:=paMark;
   form1.BComPort1.EndUpdate;
end else begin
   form1.BComPort1.BeginUpdate;
   form1.BComPort1.Parity:=paSpace;
   form1.BComPort1.EndUpdate;
 end;

procedure TForm1.PollTimer(Sender: TObject);
var
    s,buf,buf2:string;
    i,len:integer;
    x,adr,dat1,ack,chk:byte;
    crc:integer;
<...>
adr:=$08 or $0B;
SetModeBit(true);
form1.BComPort1.Write(adr,1);
dat1:=0;
crc:=adr + dat1;
try
  s:=inttohex(crc,10);
  s:=s[length(s)-1]+s[length(s)];
  chk:=strtoint('$'+s);
except
end;
SetModeBit(false);
form1.BComPort1.Write(chk,1);
Run Code Online (Sandbox Code Playgroud)

此处提供完整的代码清单,但此处提供的代码应该足够了.

我的代码(C#):

 private const byte P_ADDRESS = 0x8;
 static void Main(string[] args)
 {
        <...> 
        port = new SerialPort(ports[index]);
        port.BaudRate = 9600;
        port.StopBits = StopBits.One;
        port.DataBits = 8;
        port.DtrEnable = true;
        port.RtsEnable = true;
        port.Parity = Parity.Space;
        <...>
 }

 private static void onDataReceived(object sender, SerialDataReceivedEventArgs e)
 {
        byte[] dataReceived = new byte[port.BytesToRead];
        SetModeBit(false);
        port.Read(dataReceived, 0, dataReceived.Length);
        Console.WriteLine("Data received:");
        foreach (Byte b in dataReceived)
        {
            Console.Write(b.ToString("X") + " ");
        }
        Console.WriteLine();
 }

 private static void SetModeBit(Boolean mode)
 {
        port.Parity = mode ? Parity.Mark : Parity.Space;
 }


 private static void SendData(Byte cmd, Byte[] data)
 {
        byte adr = (byte)(P_ADDRESS | cmd);
        byte crc = adr;
        foreach (var b in data)
            crc += b;
        SetModeBit(true);
        port.Write(new byte[] { adr }, 0, 1);
        SetModeBit(false);
        if (data.Length > 0)
            port.Write(data, 0, data.Length);
        port.Write(new byte[] { crc }, 0, 1);
 }
Run Code Online (Sandbox Code Playgroud)

Delphi应用程序的轮询命令:

17.08.2012 18:05:18 COM8 Capture Started
17.08.2012 18:05:38 COM8 Opened By Process ID=2872
17.08.2012 18:05:38 Baud Rate =9600
17.08.2012 18:05:38 RTS Signal = True
17.08.2012 18:05:38 DTR Signal = True
17.08.2012 18:05:38 Line Control Change: SPACE-8-1
17.08.2012 18:05:38 Baud Rate =9600
17.08.2012 18:05:38 RTS Signal = True
17.08.2012 18:05:38 DTR Signal = True
17.08.2012 18:05:38 Line Control Change: MARK-8-1
17.08.2012 18:05:38 Write 1 Bytes:

 0B                                              ; .               

17.08.2012 18:05:38 Baud Rate =9600
17.08.2012 18:05:38 RTS Signal = True
17.08.2012 18:05:38 DTR Signal = True
17.08.2012 18:05:38 Line Control Change: SPACE-8-1
17.08.2012 18:05:38 Write 1 Bytes:

 0B                                              ; .               

17.08.2012 18:05:38 GetCommStatus Result:16
17.08.2012 18:05:38 Parity Error = True
17.08.2012 18:05:38 Baud Rate =9600
17.08.2012 18:05:38 RTS Signal = True
17.08.2012 18:05:38 DTR Signal = True
17.08.2012 18:05:38 Line Control Change: SPACE-8-1
17.08.2012 18:05:38 Read 1 Bytes:

00                                              ; .
Run Code Online (Sandbox Code Playgroud)

使用我的应用程序轮询命令:

17.08.2012 18:12:08 COM8 Capture Started
17.08.2012 18:12:11 COM8 Opened By Process ID=3164
17.08.2012 18:12:11 Baud Rate =9600
17.08.2012 18:12:11 RTS Signal = True
17.08.2012 18:12:11 DTR Signal = False
17.08.2012 18:12:11 Line Control Change: SPACE-8-1
17.08.2012 18:12:11 Baud Rate =9600
17.08.2012 18:12:11 RTS Signal = True
17.08.2012 18:12:11 DTR Signal = True
17.08.2012 18:12:11 Line Control Change: SPACE-8-1
17.08.2012 18:12:11 DTR Signal = True
17.08.2012 18:12:11 Baud Rate =9600
17.08.2012 18:12:11 RTS Signal = True
17.08.2012 18:12:11 DTR Signal = True
17.08.2012 18:12:11 Line Control Change: MARK-8-1
17.08.2012 18:12:11 Write 1 Bytes:

 0B                                              ; .               

17.08.2012 18:12:11 Baud Rate =9600
17.08.2012 18:12:11 RTS Signal = True
17.08.2012 18:12:11 DTR Signal = True
17.08.2012 18:12:11 Line Control Change: SPACE-8-1
17.08.2012 18:12:11 Write 1 Bytes:

 0B                                              ; .               

17.08.2012 18:12:11 GetCommStatus Result:16
17.08.2012 18:12:11 Parity Error = True
17.08.2012 18:12:11 Read 1 Bytes:

3F                                              ; ?               

17.08.2012 18:12:11 Read 1 Bytes:

00                                              ; .
Run Code Online (Sandbox Code Playgroud)

收到的数据似乎几乎相同,除了0x3F一开始.但该设备的行为也不同,它似乎并没有被连接到PC,它说:"用机器已禁用",当我使用C#应用程序,和"状态OK"当我使用Delphi应用程序.可能因为.NET Framework而发生这种情况?用于COM端口交互的任何库名都是有意义的.

我知道,为什么我得到不同的回应.我希望有人能帮助我.提前致谢.还要感谢阅读这个大问题.