搜索
bottom↓
回复: 29

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

[复制链接]

出0入0汤圆

发表于 2014-12-2 16:42:09 | 显示全部楼层 |阅读模式
上位机与单片机之前传送的数据格式是以ACSII码格式传送的,对吧?
1、C#上位机能过以下代码可以发送数据到单片机中
        byte[] cScanCmd = new byte[14];
            cScanCmd[0] = 0xaa;     
        cScanCmd[1] = 0x80;
        cScanCmd[2] = 0x81;
        cScanCmd[3] = 0x7f;
        cScanCmd[4] = 0x04;
        cScanCmd[5] = 0x05;
        cScanCmd[6] = 0x06;
        cScanCmd[7] = 0x07;
        cScanCmd[8] = 0x08;
        cScanCmd[9] = 0x09;
        cScanCmd[10] = 0x0a;
        cScanCmd[11] = 0x0b;   
        cScanCmd[12] = 0x0c;
            cScanCmd[13] = 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这样的十六进制数据呢?

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2014-12-2 17:00:22 | 显示全部楼层
先下班,回家再看,我们再讨论;

出0入0汤圆

 楼主| 发表于 2014-12-2 19:47:37 来自手机 | 显示全部楼层
kinsno 发表于 2014-12-2 17:00
先下班,回家再看,我们再讨论;

哈哈,好的。谢谢关注。

出0入0汤圆

发表于 2014-12-2 19:59:05 | 显示全部楼层
电子小生 发表于 2014-12-2 19:47
哈哈,好的。谢谢关注。

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

出0入0汤圆

发表于 2014-12-2 21:13:51 | 显示全部楼层
szRecv = Encoding.ASCII.GetString(data);你这个转成string不是把0x7f以上的数据都转错了么?你看看data里边的数据,这个应该是没有问题的。

出0入0汤圆

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

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

出0入0汤圆

 楼主| 发表于 2014-12-3 09:19:00 | 显示全部楼层
farmerzhangdl 发表于 2014-12-2 21:13
szRecv = Encoding.ASCII.GetString(data);你这个转成string不是把0x7f以上的数据都转错了么?你看看data ...

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

出0入0汤圆

发表于 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类说明。

出0入25汤圆

发表于 2014-12-3 10:11:59 | 显示全部楼层
先读取 BytesToRead 判断,再 Read(buff,0, BytesToRead ) 不行吗?

出0入0汤圆

发表于 2014-12-3 10:41:02 | 显示全部楼层
本帖最后由 gallop020142 于 2014-12-3 10:42 编辑

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

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

出0入89汤圆

发表于 2014-12-3 10:47:34 | 显示全部楼层
不要编码,直接处理byte数组

出0入147汤圆

发表于 2014-12-3 10:49:34 | 显示全部楼层
估计你是想把byte数据转换为16进制字符串吧:

  1. string s =Convert.ToString(byte, 16);
复制代码

出0入0汤圆

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

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

出0入0汤圆

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

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

出0入0汤圆

发表于 2014-12-3 15:12:20 | 显示全部楼层
电子小生 发表于 2014-12-3 14:57
是用的.net的SerialPort类。我是想实现传HEX码的

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

  3. With cserport
  4.             .PortName = "COM1"
  5.             .BaudRate = 9600
  6.             .DataBits = 8
  7.             .StopBits = StopBits.One
  8.             .Parity = Parity.None
  9.             .ReadBufferSize = 1024
  10.             .WriteBufferSize = 1024
  11.             .WriteTimeout = 2000
  12.             .ReadTimeout = 5000
  13. End With

  14. cserport.Open()

  15. byttemp(0) = &h0
  16. ......
  17. byttemp(9) = &h9

  18. cserport.Write(byttemp, 0, 10)
复制代码







出0入0汤圆

 楼主| 发表于 2014-12-3 15:12:53 | 显示全部楼层
gallop020142 发表于 2014-12-3 10:41
我的代码是
byte[] byteArray = new byte[serialPort1.ReadBufferSize];
int len = serialPort1.Read(by ...

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

出0入0汤圆

 楼主| 发表于 2014-12-3 15:23:04 | 显示全部楼层
sunjianmax232 发表于 2014-12-3 15:12
那就简单了。只用过vb.net,下边是vb.net的写法,c#语法上要更改下。

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

出0入0汤圆

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

出0入0汤圆

发表于 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

出255入0汤圆

发表于 2014-12-4 08:01:10 | 显示全部楼层
本帖最后由 天使之翼 于 2014-12-4 08:02 编辑

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

出0入0汤圆

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

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

出0入0汤圆

 楼主| 发表于 2014-12-4 09:11:57 | 显示全部楼层
xiongh 发表于 2014-12-3 15:59
利用serialPort1.Read( Data, 0, Number),将数据读到数组 Data[]中然后再进行处理。

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

出255入0汤圆

发表于 2014-12-5 07:56:38 | 显示全部楼层
电子小生 发表于 2014-12-4 09:07
是的,在边学边做呢。还请多多指教。

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

出0入0汤圆

发表于 2014-12-5 08:26:59 | 显示全部楼层
打算用C#的SerialPort类,在此学习学习~

出0入0汤圆

发表于 2014-12-5 08:52:42 | 显示全部楼层
本帖最后由 activeleo 于 2014-12-5 08:53 编辑

给你发两个例程参考下!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-12-5 10:38:35 | 显示全部楼层
好的,C#处理串口学习下有那些好的方法

出0入0汤圆

 楼主| 发表于 2014-12-5 12:59:25 | 显示全部楼层
activeleo 发表于 2014-12-5 08:52
给你发两个例程参考下!

好的,多谢您了!

出0入0汤圆

发表于 2015-9-18 13:59:06 | 显示全部楼层
参考一下,学习了!

出0入0汤圆

发表于 2015-9-18 14:13:24 | 显示全部楼层
参考一下,学习了!

出0入0汤圆

发表于 2015-10-18 14:53:11 | 显示全部楼层
正好在学C#, 非常有用啊

回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-25 23:03

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表