电子小生 发表于 2014-12-2 16:42:09

请教关于C#做的上位机与单片机之间的通信数据格式问题

上位机与单片机之前传送的数据格式是以ACSII码格式传送的,对吧?
1、C#上位机能过以下代码可以发送数据到单片机中
      byte[] cScanCmd = new byte;
            cScanCmd = 0xaa;   
      cScanCmd = 0x80;
      cScanCmd = 0x81;
      cScanCmd = 0x7f;
      cScanCmd = 0x04;
      cScanCmd = 0x05;
      cScanCmd = 0x06;
      cScanCmd = 0x07;
      cScanCmd = 0x08;
      cScanCmd = 0x09;
      cScanCmd = 0x0a;
      cScanCmd = 0x0b;   
      cScanCmd = 0x0c;
            cScanCmd = 0x55;
            string sScanMasterMachineCmd = System.Text.Encoding.Default.GetString(cScanCmd);
            serialPort1.Write(sScanMasterMachineCmd);
在上位机程序中以十六进制数据,再通过转换便可以发送十六进制数据到单片机中。其中超过127的数据(0x80)都可以正常发送并显示。
2、单片机发送数据到C#上位机中,C#上位机接收数据部分的代码如下
      String szRecv = string.Empty;
            System.IO.Ports.SerialPort comPort = (System.IO.Ports.SerialPort)sender;
            try
            {
                serialPort1.ReceivedBytesThreshold = serialPort1.ReadBufferSize;
                while (true)
                {
                  byte[] data = System.Text.Encoding.ASCII.GetBytes(serialPort1.ReadExisting());
                  szRecv = Encoding.ASCII.GetString(data);
                  if (string.Equals(szRecv, string.Empty))
                  {
                        break;
                  }
                  strCollect += szRecv;
                  Application.DoEvents();
                  System.Threading.Thread.Sleep(100);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, ex.ToString(), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            我想实现直接能接收到单片机发送过来的十六进制如0XAA 0X80等超过0x7f的数据,但这个程序实现不了,超过0x7f的数据,data显示为0x3f。有什么办法能实现直接接收到像0xaa这样的十六进制数据呢?

kinsno 发表于 2014-12-2 17:00:22

先下班,回家再看,我们再讨论;

电子小生 发表于 2014-12-2 19:47:37

kinsno 发表于 2014-12-2 17:00
先下班,回家再看,我们再讨论;

哈哈,好的。谢谢关注。

kinsno 发表于 2014-12-2 19:59:05

电子小生 发表于 2014-12-2 19:47
哈哈,好的。谢谢关注。

晕,我以为我能搞定,看了一下,没发现啥毛病,搞不定啊;
我的通信协议本来就是ASCII码,和你这个不兼容啊,我也是个二把刀;
建议:你在坛子里搜索一些串口助手的代码,然后学习参考下,特别是HEX模式下收数据;

farmerzhangdl 发表于 2014-12-2 21:13:51

szRecv = Encoding.ASCII.GetString(data);你这个转成string不是把0x7f以上的数据都转错了么?你看看data里边的数据,这个应该是没有问题的。

电子小生 发表于 2014-12-3 09:17:37

kinsno 发表于 2014-12-2 19:59
晕,我以为我能搞定,看了一下,没发现啥毛病,搞不定啊;
我的通信协议本来就是ASCII码,和你这个不兼容 ...

嗯,通信协议做成ascii码也行。我只是看到C#的发送数据转换很简单。不知道它是怎么实现的。

电子小生 发表于 2014-12-3 09:19:00

farmerzhangdl 发表于 2014-12-2 21:13
szRecv = Encoding.ASCII.GetString(data);你这个转成string不是把0x7f以上的数据都转错了么?你看看data ...

是的,我发送0xaa结果接收到的是0x3f。只有发送0x7f以下的数据才是正确的。不知道是怎么回事

sunjianmax232 发表于 2014-12-3 09:28:24

楼主用的是.net的SerialPort类吧?
上位机与单片机之前传送的数据格式是以ACSII码格式还是以HEX码传送由你自已决定,可以直接传hex码,也可以转换后以ascii码传送,我一般是直接传HEX,方便MCU直接处理。
写数据VB.NET:Public Sub Write (buffer As Byte(), offset As Integer, count As Integer)
读数据VB.NET:Public Function Read (buffer As Byte(), offset As Integer, count As Integer) As Integer
更详细的参考MSDN中的SerialPort类说明。

墨非 发表于 2014-12-3 10:11:59

先读取 BytesToRead 判断,再 Read(buff,0, BytesToRead ) 不行吗?

gallop020142 发表于 2014-12-3 10:41:02

本帖最后由 gallop020142 于 2014-12-3 10:42 编辑

我的代码是
byte[] byteArray = new byte;
int len = serialPort1.Read(byteArray, 0, byteArray.Length);

for (int i = 0; i < len; i++)
{
   receiveByteQueue.Enqueue(byteArray);
}
                         
楼主这样试试,看行不行

youkebing 发表于 2014-12-3 10:47:34

不要编码,直接处理byte数组

leafstamen 发表于 2014-12-3 10:49:34

估计你是想把byte数据转换为16进制字符串吧:

string s =Convert.ToString(byte, 16);

farmerzhangdl 发表于 2014-12-3 11:44:43

电子小生 发表于 2014-12-3 09:19
是的,我发送0xaa结果接收到的是0x3f。只有发送0x7f以下的数据才是正确的。不知道是怎么回事 ...

我已经说了啊,就是GetString的事情,0x7f以上的没法转成string,要么你直接把byte数组做6进制变换,要么你直接处理byte

电子小生 发表于 2014-12-3 14:57:59

sunjianmax232 发表于 2014-12-3 09:28
楼主用的是.net的SerialPort类吧?
上位机与单片机之前传送的数据格式是以ACSII码格式还是以HEX码传送由你 ...

是用的.net的SerialPort类。我是想实现传HEX码的

sunjianmax232 发表于 2014-12-3 15:12:20

电子小生 发表于 2014-12-3 14:57
是用的.net的SerialPort类。我是想实现传HEX码的

那就简单了。只用过vb.net,下边是vb.net的写法,c#语法上要更改下。
dim cserport As SerialPort
Dim byttemp(9) As Byte

With cserport
            .PortName = "COM1"
            .BaudRate = 9600
            .DataBits = 8
            .StopBits = StopBits.One
            .Parity = Parity.None
            .ReadBufferSize = 1024
            .WriteBufferSize = 1024
            .WriteTimeout = 2000
            .ReadTimeout = 5000
End With

cserport.Open()

byttemp(0) = &h0
......
byttemp(9) = &h9

cserport.Write(byttemp, 0, 10)







电子小生 发表于 2014-12-3 15:12:53

gallop020142 发表于 2014-12-3 10:41
我的代码是
byte[] byteArray = new byte;
int len = serialPort1.Read(by ...

可以的,多谢你了。顺便问一下———receiveByteQueue.Enqueue(byteArray);您这句放是在做啥处理,其中receiveByteQueue是如何定义的呢?

电子小生 发表于 2014-12-3 15:23:04

sunjianmax232 发表于 2014-12-3 15:12
那就简单了。只用过vb.net,下边是vb.net的写法,c#语法上要更改下。




嗯好,谢谢。我发送是可以的。主要是接收处理问题,是我的处理代码有问题。应该是10楼的处理方式,直接读过来就可以了。

xiongh 发表于 2014-12-3 15:59:00

利用serialPort1.Read( Data, 0, Number),将数据读到数组 Data[]中然后再进行处理。

gallop020142 发表于 2014-12-3 17:19:14

电子小生 发表于 2014-12-3 15:12
可以的,多谢你了。顺便问一下———receiveByteQueue.Enqueue(byteArray);您这句放是在做啥处理,其中re ...

Queue<byte>我的接收队列是放在一个线程,信息的parse是在另一个线程里面。
这个程序的所有文件在http://www.amobbs.com/thread-5588053-1-1.html

天使之翼 发表于 2014-12-4 08:01:10

本帖最后由 天使之翼 于 2014-12-4 08:02 编辑

你应该是第一次做上位机,上位机的串口控件里有个设置传输方式,一般我们传输的是数据(0~255),所以你要把他设置成2进制传输。2进制也可以解析成ascii

电子小生 发表于 2014-12-4 09:07:02

天使之翼 发表于 2014-12-4 08:01
你应该是第一次做上位机,上位机的串口控件里有个设置传输方式,一般我们传输的是数据(0~255),所以你要把 ...

是的,在边学边做呢。还请多多指教。

电子小生 发表于 2014-12-4 09:11:57

xiongh 发表于 2014-12-3 15:59
利用serialPort1.Read( Data, 0, Number),将数据读到数组 Data[]中然后再进行处理。

嗯,是这样处理的。多谢了

天使之翼 发表于 2014-12-5 07:56:38

电子小生 发表于 2014-12-4 09:07
是的,在边学边做呢。还请多多指教。

上位机一般都有传输方式控制。一般上位机都会只用2进制方式通信(0~255)。这样也能包含ascii

Stargazer-1986 发表于 2014-12-5 08:26:59

打算用C#的SerialPort类,在此学习学习~

activeleo 发表于 2014-12-5 08:52:42

本帖最后由 activeleo 于 2014-12-5 08:53 编辑

给你发两个例程参考下!

lee345 发表于 2014-12-5 10:38:35

好的,C#处理串口学习下有那些好的方法

电子小生 发表于 2014-12-5 12:59:25

activeleo 发表于 2014-12-5 08:52
给你发两个例程参考下!

好的,多谢您了!

wjshw123 发表于 2015-9-18 13:59:06

参考一下,学习了!

wjshw123 发表于 2015-9-18 14:13:24

参考一下,学习了!

wgj_fly 发表于 2015-10-18 14:53:11

正好在学C#, 非常有用啊

页: [1]
查看完整版本: 请教关于C#做的上位机与单片机之间的通信数据格式问题