C#串口通信 serialport类
--------------------编程问答-------------------- serialPort.Write(BSendTemp, 0, 10);//发送命令Thread.Sleep(4000);
你既要发送数据,又要主线程休眠4秒,可能是你的数据还没有发送完,主线程就休眠了,造成后来从缓存区读出来的数据不全.其实你可以搞个定时器,设定时间为4000,然后在定时器触发时间中读串口的缓存.注意把电脑的DB9针的RS232口的2和3脚用短路块短起来. --------------------编程问答-------------------- 接下来你如果再读,能读回更多? --------------------编程问答--------------------
不用 Thread.Sleep(4000)的话就读不到数据,定时器我没用过,我查下资料
--------------------编程问答-------------------- 哦。延迟4秒,因为串口是流设备,数据没发送完成或是你设备没发送完成,延迟是一种比较简单的方式,至于延迟多少。这个你试试,不一定要4秒。如果设备就是很慢,那延迟4秒也必须的。 --------------------编程问答-------------------- 不延时的话根本就得不到数据,所以才加了4s的延时,好纠结 --------------------编程问答--------------------
再读的话,还是只读到前9个字节 --------------------编程问答--------------------
如果不延时的话,就读不到数据了。因为发送命令,下位机需要进行数据处理,才能传回数据 --------------------编程问答-------------------- 晕不是有个DataReceived事件嘛?
在这个事件中使用SerialPort.ReadExisting 方法。 --------------------编程问答-------------------- serialPort.ReceivedBytesThreshold可能跟这个属性有关,我以前也遇到过你这种问题,我是7位的,你要是50位的话把这个值改到50应该就行了,它就会自动触发DataReceived事件 --------------------编程问答--------------------
--------------------编程问答-------------------- 8楼+1 --------------------编程问答--------------------
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个字节的问题 --------------------编程问答--------------------
你看一下是不是你的串口控件把接收缓冲区大小设置成9字节了,如果不是可以先用串口调试助手看一下能接收到多少数据 --------------------编程问答-------------------- 初始化(自行在构造函数中注册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的参数看看有什么变化。 --------------------编程问答-------------------- 通讯线程要与界面线程分开,我做串口通讯的时候就遇到这个问题 --------------------编程问答--------------------
ding
补充:.NET技术 , C#