日期:2014-05-17  浏览次数:21036 次

SerialPort接收函数正确完全接收的问题
刚刚那个帖子我说的不清楚,现在我新开一个帖子,把我的问题说清楚了,希望大侠们能够很详细的回答我的问题,谢谢;

问题一:
问题如下:
我想把从SerialPort接收到的数放入Textbox中,但总是收不全(比如共10个字节,却总是收了5、6个,后面的就丢了)
我是这么写的(抄了修改的):
void comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
  {
int n = comm.BytesToRead;
  byte[] buf = new byte[n];//声明一个临时数组存储当前来的串口数据
  comm.Read(buf, 0, n);//读取缓冲数据
  builder.Length = 0;//清除字符串构造器的内容
  //因为要访问ui资源,所以需要使用invoke方式同步ui。
  this.Invoke((EventHandler)(delegate
  {
  //判断是否是显示为16禁止
  if (checkBoxhexreceive.Checked)
  {
  //依次的拼接出16进制字符串
  foreach (byte b in buf)
  {
  builder.Append(b.ToString("X2") + " ");
  }
  }
  else
  {
  //直接按ASCII规则转换成字符串
  builder.Append(Encoding.ASCII.GetString(buf));
  }
//追加的形式添加到文本框末端,并滚动到最后。
  textBoxreceive.Text += builder.ToString() + "\r\n";
}
}

采用RS485自发自收,每次发送相同的命令,收到在textBoxreceive中的值却不一样,(假如说全的时候是10个字节),有些时候收全了,有些时候只收了8个字节,有些时候只收了6个字节等等等等。。。。

我敢肯定是由于代码的第一行“int n = comm.BytesToRead;”在作怪,应为这里的n就决定了我要读多少字节数。

于是乎我请教了一个人,他告诉我一个方法:
采用ModBUS协议的通讯,可以这样做(比如说收到的数据将是12 34 01 78 90 AB CD):先收第一个数据(判断其是不是12),在收第二个数据(判断其是不是34),在收第三个数据(此处为01);
重点来了:根据ModBus协议来讲,第三位(此处为01)即代表了将要收到的数据时多少位(01:代表了数据为2个字节“78 90”,CRC为2个字节“AB CD”),这样我就知道了在收了第三个数据后还要再收多少个字节了,这样我就不可能丢数据了,这样问题就解决了

上面的思想是好的,但是用代码我根本不会写啊,如果用代码来实现,应该怎么写呢(上面的“先收到第三个数据,判断还要收多少位,从而保证收到的数据是完整的”),应该怎么写呢?

请尽量给代码,谢谢,如果有更好的方法,请指出,谢谢
我已经想了2天了,没有答案;


问题二:
我定义了一个串口接收函数  
void comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
。。。。。。
}

我想在别的地方调用它,怎么做呢?

比如是在一个控件触发的时候调用它:
private void button1_Click_1(object sender, EventArgs e)
        {
“调用DataReceived”函数
}

怎么做啊??
或者说这个不行,换成DataRead(串口读函数),怎么做呢??

请教了!


请高手们不要一笔带过,我是个新手,尽量将详细一点,尽量给代码

谢谢了

------解决方案--------------------
那你把参数类型改为SerialDataReceivedEventArgs不就完了吗
或者直接comm_DataReceived(null,null)试试
serialport 有个属性ReceivedBytesThreshold = 1;就是串口有1个字节
就触发接收事件进行数据读取,可以根据你的需要设置