首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

串口接收时,拼数据到数组遇到的有关问题

2012-08-03 
串口接收时,拼数据到数组遇到的问题。我单步调试时:界面textbox上显示ARM饭回来的数据:F0037E018E700117010

串口接收时,拼数据到数组遇到的问题。
我单步调试时:
 界面textbox上显示ARM饭回来的数据:
F0037E018E70011701060000FFFF014444444444444444444444444270011
701060000FFFF01666666666666666666666666AA
70011701060000FFFF0155555555555555555555555576F0037E048B
(上面在文本框显示是没有换行的)

取掉断点,全速跑时的,textBox上显示的数据:

F0037E018E70011701060000FF
FF01666666666666666666666666AA70011701060000FFFF01555555555555
5555555555557670011701060000FFFF0144444444444444444444444442
F0037E048B
(上面是换行产生的效果)


断点调试和全速跑,都收全了数据
不同的是
断点时, 数据是拼到一个临时数组里,是全的,,即本次所有数据都收齐了

而全速跑时,,从界面上显示的情况看,拼数据到数组里有错了,4次才完成

因为我在向界面显示时,每次都加一个换行
 如代码:
 

C# code
this.txGet.AppendText(str+"\r\n");



如何才能保证,全速跑时,能像断点那样,,将数据拼接对呢?

接受的全部代码如下:

C# code
 int n = comm.BytesToRead;            byte[] buf = new byte[n];//声明一个临时数组存储当前来的串口数据            bool data_1_catched = false;            string str = "";            received_count += n;//增加接收计数            temp_Counter += n;            comm.Read(buf, 0, n);//读取缓冲数据            if (n > 0)            {                Array.ConstrainedCopy(buf, 0, binary_data_1, temp_Counter - n, n);                if (temp_Counter - n > 0)                    data_1_catched = true;                //正确分析一条数据,从缓存中移除数据。               // Array.Clear(buf, 0, buf.Length);            }            if (data_1_catched)            {                this.Invoke((EventHandler)(delegate                {                    for (int i = 0; i < temp_Counter; i++)                    {                        str += binary_data_1[i].ToString("X2");                    }                    this.txGet.AppendText(str+"\r\n");                    temp_Counter = 0;                    data_1_catched = false;                    Array.Clear(binary_data_1, 0, binary_data_1.Length);                    //修改接收计数                    labelGetCount.Text = "Get:" + received_count.ToString();                }));                


[解决办法]
0、你的分还真多啊,一开一个贴,都是100分
1、把接收数组设置成全局变量,且能扩充大小的List<byte>类型
2、再开一个线程去解析List<byte>里面的数据
3、在串口接收事件和线程解析中注意对List<byte>的同步
[解决办法]
用两个队列 
在同一时间 一个队列接收 另一个处理,处理完了切换队列 处理完的队列开始接收 接收的队列开始处理 

我的串口是这样做的 第一次使用队列 还是觉得很方便
[解决办法]
可能你使用了DataReceived事件,如果使用了那么根源就在这里,这个事件是SerialPort类循环调用 WaitCommEvent时,当串口每收到一个字节,就会在一个新的线程上调用DataReceived事件所指向的方法,所以导致了乱序。
可以改成这样来处理,假如串口设置了超时(如果没设置超时根本就没必要用DataReceived事件):
C# code
       int isread = 0;       byte[] buffer = new byte[64];//长度根据你的协议需要定义        void comm_DataReceived(object sender, SerialDataReceivedEventArgs e)        {            if (Interlocked.CompareExchange(ref isread, 1, 0) != 0)                return;            while (true)            {                try                {                    int recvlen = comm.Read(buffer, 0, buffer.Length);                    //程序对接收到的buffer的处理过程,实际接收长度为recvlen                }                catch                {                    break;                }            }            Interlocked.CompareExchange(ref isread, 0, 1);        } 

热点排行