当前位置:编程学习 > C#/ASP.NET >>

C#串口通信问题?求解!

已知设备商提供的通信协议为:
2协议内容
2.1读取版本号
此命令用于读取读写器的版本号,接收此命令的读写器进入标签设置。
Head Addr Len Cmd  Check
0x0A 0x02 0x22 cc
   读写器接收到此命令帧后,返回应答帧表示命令已接收。应答帧如下所示:
Head Addr Len Status Response Response Check
0x0B 0x04 0x00 Major Minor cc
Major为固件程序主版本。
Minor为固件程序次版本。

我在窗体上放在serialPort1控件,并设置好属性。

在按纽事件中加代码:

  serialPort1.Open();//打开串口

           try
            {
                serialPort1.WriteLine("0x22");//发送读取设备版本号命令

            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.ToString());
            }

   textBox1.Text = serialPort1.ReadLine().ToString();//接收返回设备应答信息

但一到接收这里程序就死掉了。请问是什么原因?小弟第一次做这个,请高手们帮忙解决一下。即刻送分


--------------------编程问答-------------------- 自己顶起来 --------------------编程问答-------------------- 数据没有返回?
用串口工具试一下,有返回数据吗? --------------------编程问答-------------------- textBox1.Text = serialPort1.ReadLine().ToString();//接收返回设备应答信息
这里在没有收到数据时肯定会停在这里的,因为你使用的是同步的方式 --------------------编程问答-------------------- 那要怎么才能让他返回数据? --------------------编程问答--------------------
引用 3 楼 xuexiaodong2009 的回复:
textBox1.Text = serialPort1.ReadLine().ToString();//接收返回设备应答信息
这里在没有收到数据时肯定会停在这里的,因为你使用的是同步的方式
如何才能接收到返回数据? --------------------编程问答-------------------- 在serialport_DataReceive事件里获取信息。 --------------------编程问答--------------------
引用 4 楼 hhh8815 的回复:
那要怎么才能让他返回数据?

1、串口参数要与设备的串口参数一样(如波特率)
2、按照设备的协议向设备发送命令。
3、设备本身能返回数据。
--------------------编程问答-------------------- http://blog.csdn.net/redhaste/archive/2009/04/21/4097863.aspx

参考。


如果你接收到串口信息, 不能直接赋值给textbox, 需要用到textBox.Invoke() --------------------编程问答-------------------- string data = serialPort.ReadExisting();
--------------------编程问答-------------------- 命令参数都是对的,但返回是空值 --------------------编程问答-------------------- 无语。
告诉你命令是:0x0A 0x02 0x22 。你偏偏就属容易0x22;
另外,在serialport_DataReceive事件里获取信息。
想在DataReceive里使用textbox1.text的话,主要要使用托管。 --------------------编程问答--------------------
引用 10 楼 hhh8815 的回复:
命令参数都是对的,但返回是空值

这样的情况:
1、检查串口设置
2、设备是否启用了串口通讯功能。
3、检查发送的命令是否符合协议。 --------------------编程问答--------------------
引用 11 楼 mjp1234airen4385 的回复:
无语。
告诉你命令是:0x0A 0x02 0x22 。你偏偏就属容易0x22;
另外,在serialport_DataReceive事件里获取信息。
想在DataReceive里使用textbox1.text的话,主要要使用托管。
请楼上大哥指教具体点,我真是第一次做这个,很多不懂?发送命令那应该怎么写? --------------------编程问答-------------------- 不是告诉你了吗?0x0A 0x02 0x22 cc
--------------------编程问答-------------------- 看协议啊~~!!~!~! --------------------编程问答-------------------- 1.2.1 命令帧格式定义
命令帧是主机操作读写器的数据帧,格式如下表所示:

Head Addr Len Cmd  Parameter … Parameter Check
0x0A 1 byte n+2 1 byte Byte 1           Byte n cc
Head是帧头标志,定义为0x0A
Addr是读写器地址,一般地址从0~240,255(0xFF)为公用地址,254(0xFE)为广播地址。读写器接收自身地址、公用地址和广播地址的命令,对广播地址命令不做回复。
Len是包长域,表示Length域后帧中字节数。
Cmd是命令码域。
Parameter是命令帧中的参数域。
Check是校验和域,规定校验范围是从帧头域到参数域最后一个字节为止所有字节的校验和(相加取反加1,取最后两位)。读写器接收到命令帧后需要计算校验和来检错。

1.2.2  响应帧格式定义
响应帧是读写器返回给主机的数据帧,响应帧包含了读写器需要采集的数据,其格式定义如下表所示:

Head Addr Len Status Response  … Response Check
0x0A 1 byte n+2 1 byte Byte 1           Byte n cc
Head是包类型域,响应帧包类型固定为0xE0。
Addr是读写器自身地址。
Len是包长域,表示Length域后帧中字节数。
Status表示命令所规定的操作执行的结果,0表示正确执行,其他表示执行中发生异常。
Response是响应帧中的返回数据。
Check是校验和域,规定校验范围是从包类型域到参数域最后一个字节为止所有字节的校验和。PC机接收到命令帧后需要计算校验和来检错。


2协议内容
2.1读取版本号
此命令用于读取读写器的版本号,接收此命令的读写器进入标签设置。
Head Addr Len Cmd  Check
0x0A 0x02 0x22 cc
   读写器接收到此命令帧后,返回应答帧表示命令已接收。应答帧如下所示:
Head Addr Len Status Response Response Check
0x0B 0x04 0x00 Major            Minor cc
Major为固件程序主版本。
Minor为固件程序次版本。


这就是协议,串口和设备都是正常的,因为我在用VB的程序能读取?现在要写成C#的
--------------------编程问答--------------------
引用 14 楼 zongbao516 的回复:
不是告诉你了吗?0x0A 0x02 0x22 cc

            try
            {
                serialPort1.WriteLine("0x0A");
                serialPort1.WriteLine("4");
                serialPort1.WriteLine("0x02");
                serialPort1.WriteLine("0x22");
                serialPort1.WriteLine("cc");
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.ToString());
            }
是否是这样写? --------------------编程问答-------------------- 用串口调试工具,按照协议 0x0A 0x02 0x22 cc
看看有没有返回数据。
--------------------编程问答-------------------- zongbao516
 
能不能帮忙远程一下,调试助手上发也没反映?我的QQ463845617。不知你有没有时间麻烦你帮我看看,谢谢! --------------------编程问答--------------------
引用 19 楼 hhh8815 的回复:
zongbao516
 
能不能帮忙远程一下,调试助手上发也没反映?我的QQ463845617。不知你有没有时间麻烦你帮我看看,谢谢!

不准用聊天的
你不是有VB的程序吗?你看一下VB程序发送的命令是怎么编辑的。 --------------------编程问答-------------------- VB是用DLL的,DLL是别人写的。我现在想直接用协议用C#做 --------------------编程问答--------------------
引用 21 楼 hhh8815 的回复:
VB是用DLL的,DLL是别人写的。我现在想直接用协议用C#做

把协议书发我邮箱,我帮你看看吧。 --------------------编程问答-------------------- vpp516@163.com --------------------编程问答-------------------- 如何在B电脑上,监测A电脑上某服务是否正常启动? --------------------编程问答-------------------- 找不到你的邮箱?
--------------------编程问答--------------------
引用 24 楼 zzrxt 的回复:
如何在B电脑上,监测A电脑上某服务是否正常启动?

用过WMI --------------------编程问答-------------------- 发到你邮箱了,帮忙看一下,谢谢! --------------------编程问答-------------------- 看一下你程序里面串口的设置 --------------------编程问答-------------------- 用串口调试工具,发送这条命令 0x0A10x020x22cc
--------------------编程问答-------------------- 1.2.1 命令帧格式定义
命令帧是主机操作读写器的数据帧,格式如下表所示:

Head Addr Len Cmd Parameter … Parameter Check
0x0A 1 byte n+2 1 byte Byte 1 Byte n cc
Head是帧头标志,定义为0x0A
Addr是读写器地址,一般地址从0~240,255(0xFF)为公用地址,254(0xFE)为广播地址。读写器接收自身地址、公用地址和广播地址的命令,对广播地址命令不做回复。
Len是包长域,表示Length域后帧中字节数。
Cmd是命令码域。
Parameter是命令帧中的参数域。
Check是校验和域,规定校验范围是从帧头域到参数域最后一个字节为止所有字节的校验和(相加取反加1,取最后两位)。读写器接收到命令帧后需要计算校验和来检错。


请注意看协议,我现场编写,自己再改改吧。
byte[] bdata = new byte[5];
bdata[0] = 0x0A;
bdata[1] = 0x06;
bdata[2] = 0x02;
bdata[3] = 0x22;
bdata[4] = 0x未知;
//未知的部分就是:Check是校验和域,规定校验范围是从帧头域到参数域最后一个字节为止所有字节的校验和(相加取反加1,取最后两位)。读写器接收到命令帧后需要计算校验和来检错。
//这个校验和,是需要你写个算法,把从bdata[0]到bdata[3]这个四个字节里的数据做校验,并把校验结果赋值给bdata[4].具体的算法描述也告诉你了:规定校验范围是从帧头域到参数域最后一个字节为止所有字节的校验和(相加取反加1,取最后两位)。
try
  {
  serialPort1.WriteByte(bdata, 0, bdata.Length);
  }
  catch (Exception ee)
  {
  MessageBox.Show(ee.ToString());
  }
--------------------编程问答-------------------- 帮你顶起来 --------------------编程问答-------------------- 要不自己计算校验和域,要不问一下厂家有没有demo --------------------编程问答--------------------
引用 30 楼 mjp1234airen4385 的回复:
1.2.1 命令帧格式定义
命令帧是主机操作读写器的数据帧,格式如下表所示:

Head Addr Len Cmd Parameter … Parameter Check
0x0A 1 byte n+2 1 byte Byte 1 Byte n cc
Head是帧头标志,定义为0x0A
Addr是读写器地址,一般地址从0~240,255(0xFF)为公用地址,254(0xFE)为广播地……

bydata[1]=0x06;是什么?没这个命令。 --------------------编程问答--------------------
引用 32 楼 zongbao516 的回复:
要不自己计算校验和域,要不问一下厂家有没有demo

很想知道自己如何计算?没有这个行不行? --------------------编程问答--------------------
引用 29 楼 zongbao516 的回复:
用串口调试工具,发送这条命令 0x0A10x020x22cc

用调试工具发送没反应? --------------------编程问答-------------------- bydata[1]=0x06;是什么?没这个命令。
苍天,是我打错字了,还是你打错字了?
我打的是:
byte[] bdata = new byte[5];
bdata[0] = 0x0A;
bdata[1] = 0x06;
bdata[2] = 0x02;
bdata[3] = 0x22;
bdata[4] = 0x未知;
--------------------编程问答-------------------- 如果没有这个行的话,你说协议里还要这个干什么?
CC校验是在数据通讯里常用的手段,在设备里有同样的算法,
设备会把你传入的数据(除去校验值)进行校验,
如果和你传入的校验值一样,才处理数据,不然就返回错误了。
这是为了防止别人串改数据的。
当然,你这个协议里的校验算法简单了一点。 --------------------编程问答-------------------- 好,晚上回去试下。谢谢各位
--------------------编程问答-------------------- try
  {
  serialPort1.WriteByte(bdata, 0, bdata.Length);
  }
  catch (Exception ee)
  {
  MessageBox.Show(ee.ToString());
  }

serialPort1没有WriteByte这个属性 --------------------编程问答-------------------- http://msdn.microsoft.com/zh-cn/library/system.io.ports.serialport(v=VS.100).aspx --------------------编程问答-------------------- 各位大侠,我想问c#中怎么将串口接收到的数据赋值到我所定义的变量?新手上路,请各位高手多多指教,谢谢! --------------------编程问答-------------------- 如果你是想将串口读取的数据显示在TextBox里面,则需要在串口的DataReceived事件中托管另一个事件,如this.Invoke(new EventHandler(readData));然后在readData事件中进行显示,若是直接赋值给变量,直接赋值就可以了
补充:.NET技术 ,  C#
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,