C#串口通信 serialport类 本帖最后由 hlxk11hlxk11 于 2011-12-07 22:05:13 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 serialPort.Write(BSendTemp, 0, 10);//发送命令 Thread.Sleep(4000);你既要发送数据,又要主线程休眠4秒,可能是你的数据还没有发送完,主线程就休眠了,造成后来从缓存区读出来的数据不全.其实你可以搞个定时器,设定时间为4000,然后在定时器触发时间中读串口的缓存.注意把电脑的DB9针的RS232口的2和3脚用短路块短起来. 不用 Thread.Sleep(4000)的话就读不到数据,定时器我没用过,我查下资料 晕不是有个DataReceived事件嘛?在这个事件中使用SerialPort.ReadExisting 方法。 serialPort.ReceivedBytesThreshold可能跟这个属性有关,我以前也遇到过你这种问题,我是7位的,你要是50位的话把这个值改到50应该就行了,它就会自动触发DataReceived事件 private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { int bytes = 0; String strMoney = String.Empty;//钱数 String strNumber = String.Empty;//币数 String strMoneyAndNumber = String.Empty;//钱数+币数 bytes = serialPort.BytesToRead;//读取串口中的数据 byte[] buffer = new byte[bytes];//转换成数组 for (int i = 0; i < bytes; i++) { buffer[i] = (byte)(serialPort.ReadByte());//循环遍历每个元素 } if (bytes != 0)//判断数组是否为0 {.......} 串口是一位一位地传输的,当你正在读的时候可能数据还没有完全传到接收缓冲区,所以你只能读到部位数据。因此需要足够长的延时来等待数据全部传输完成。你上面延时4秒再读的话可以把时间调长一点,这样不好估算时间,而且传输不同数量的字节延时长度如果长了是浪费,如果短了又无法接收完成,所以不建议直接用很长的延时。你上面发送命令后应该是等待一定时间,设备会回传数据给你,而设备响应的时间应该是可以估算的,然后再读取数据。帮你改了一下程序。 Byte[] BSendTemp = { 0x00, 0xff, 0xff, 0xcc, 0x01, 0x01, 0x02, 0x40, 0x00, 0x44 }; //建立临时字节数组对象 serialPort.Write(BSendTemp, 0, 10);//发送命令 Thread.Sleep(4000); // 等待设备响应。 int count; do { count = serialPort.BytesToRead; // 读取缓冲区数据长度 Thread.Sleep(10); // 延时10毫秒 } while (count != serialPort.BytesToRead); // 判断刚才读取的长度与缓冲区长度相同表示已经接收完成,如果不同则将缓冲区长度赋给cout再延时10毫秒判断 serialPort.Read(BReceived, 0, count); MessageBox.Show(count.ToString()); 关键是count = serialPort.BytesToRead; // 读取缓冲区数据长度这个值还是9,您的这个方法可以确定每次都将缓存区的数据都读到!还是没有办法解决无法接受50个字节的问题 初始化(自行在构造函数中注册serialPort_DataReceived事件): System.IO.MemoryStream ms = new System.IO.MemoryStream(100); void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) { byte[] bytes = new byte[100]; int count = serialPort.Read(bytes, 0, 100); ms.Write(bytes, 0, count); }使用: Byte[] BSendTemp = { 0x00, 0xff, 0xff, 0xcc, 0x01, 0x01, 0x02, 0x40, 0x00, 0x44 }; //建立临时字节数组对象 ms.Position = 0; --将内存流重置 serialPort.Write(BSendTemp, 0, 10);//发送命令 查看(添加一个按钮,点击查看,防止线程阻塞):MessageBox.Show(ms.Position.ToString());--内存流当前位置就是接收到的字节数 这个我试过了,改到50,就是说缓冲区中有50个字节才出发DataReceived事件,改了之后的效果就是出现了重复多次出现相同的9个字节! 串口精灵可以收到59个字节,自己写的只能收到9个,要不是有这个串口精灵,我会以为是下位机只发回了9个字节,可是事实上有59个之多,而我只能收到9个。ReceivedBytesThreshold属性设置大点没有效果,改了之后的效果就是出现了重复多次出现相同的9个字节! 非常感谢,可是调试了下 int count = serialPort.Read(bytes, 0, 100);此时的count就只有9,所以···要不是有串口精灵,我会以为是下位机只发回了9个字节,可是事实上有59个之多,而我只能收到9个。ReceivedBytesThreshold属性设置大点没有效果,改了之后的效果就是出现了重复多次出现相同的9个字节! 你的9字节到底是你发送的数据的前面9字节还是后面9字节或者是中间9字节Thread.Sleep(4000);可以适当地调试一个这个Sleep的参数看看有什么变化。 SOS:C# Sokcet udp winform通信软件到其它没有装VS的机上通信不了 C# DataGrideView 的CurrentCellChanged事件加载时,只执行一次,如何实现? UTF16如何转换成UTF8? 100分跪求 VS .net下载地址 C#调用DLL的问题 VS2005在VMWARE下能编译发布安装包,稳定性是否会有问题? 问大家一个简单的问题??? 客户端软件发布后,怎么记录新版本与旧版本的不同,方便后续做更新 请问我错在哪里? 请教.net中Crystal报表运用的问题 C#编写触发程序 winform中DataGridView应该在什么事件里进行数据验证
Thread.Sleep(4000);
你既要发送数据,又要主线程休眠4秒,可能是你的数据还没有发送完,主线程就休眠了,造成后来从缓存区读出来的数据不全.其实你可以搞个定时器,设定时间为4000,然后在定时器触发时间中读串口的缓存.注意把电脑的DB9针的RS232口的2和3脚用短路块短起来.
在这个事件中使用SerialPort.ReadExisting 方法。
private void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
int bytes = 0;
String strMoney = String.Empty;//钱数
String strNumber = String.Empty;//币数
String strMoneyAndNumber = String.Empty;//钱数+币数
bytes = serialPort.BytesToRead;//读取串口中的数据 byte[] buffer = new byte[bytes];//转换成数组 for (int i = 0; i < bytes; i++)
{
buffer[i] = (byte)(serialPort.ReadByte());//循环遍历每个元素
}
if (bytes != 0)//判断数组是否为0
{.......}
Byte[] BSendTemp = { 0x00, 0xff, 0xff, 0xcc, 0x01, 0x01, 0x02, 0x40, 0x00, 0x44 }; //建立临时字节数组对象
serialPort.Write(BSendTemp, 0, 10);//发送命令
Thread.Sleep(4000); // 等待设备响应。
int count;
do
{
count = serialPort.BytesToRead; // 读取缓冲区数据长度
Thread.Sleep(10); // 延时10毫秒 } while (count != serialPort.BytesToRead); // 判断刚才读取的长度与缓冲区长度相同表示已经接收完成,如果不同则将缓冲区长度赋给cout再延时10毫秒判断 serialPort.Read(BReceived, 0, count);
MessageBox.Show(count.ToString());
这个值还是9,
您的这个方法可以确定每次都将缓存区的数据都读到!还是没有办法解决无法接受50个字节的问题
void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
byte[] bytes = new byte[100];
int count = serialPort.Read(bytes, 0, 100);
ms.Write(bytes, 0, count);
}
使用:
Byte[] BSendTemp = { 0x00, 0xff, 0xff, 0xcc, 0x01, 0x01, 0x02, 0x40, 0x00, 0x44 }; //建立临时字节数组对象
ms.Position = 0; --将内存流重置
serialPort.Write(BSendTemp, 0, 10);//发送命令 查看(添加一个按钮,点击查看,防止线程阻塞):
MessageBox.Show(ms.Position.ToString());--内存流当前位置就是接收到的字节数
int count = serialPort.Read(bytes, 0, 100);
此时的count就只有9,所以···
要不是有串口精灵,我会以为是下位机只发回了9个字节,可是事实上有59个之多,而我只能收到9个。ReceivedBytesThreshold属性设置大点没有效果,改了之后的效果就是出现了重复多次出现相同的9个字节!
Thread.Sleep(4000);
可以适当地调试一个这个Sleep的参数看看有什么变化。