【求助】关于C#窗体中串口接收
究竟怎样才能实时性好,我的做法:1. 使用Timer控件,每200msTick一次
2. 在Tick事件中向串口发送数据(MODBUS RTU)
3. serialPort_DataReceived 事件中,先休眠线程5ms(网上的大神好像都有这句,我也不知道为啥),再处理回复的数据。再跨线程调用控件,把串口的数据解析出来,放到TextBox里。发现几秒才变一次
大侠们快来看看吧,小弟先谢过了
PS:串口接收数据,每次都是11个字节,所以触发事件的阀值也写的11. 本帖最后由 alitasoft 于 2015-3-30 09:52 编辑
楼上的方法太慢了,不用定时器,第三点说的实际上很清楚:
DataReceived事件会阻塞当前线程,如果没有数据就一直阻塞,当有数据到达时就可以从缓冲区中读取数据
——这一点和中断机制非常类似:串口读取线程和主任务线程分离,当有数据到达时,系统(来源于底层硬件)会产生数据到达中断,然后由OS通知你的程序
这里sleep(5ms)没必要,反而会影响实时性。
这是08年写的一个通讯组件的调度模型,1个线程用于数据读取和发送,多个线程用于数据处理,中间通过适配器进行数据/指令调度
双缓冲可以做到基本无延迟
定时器模式相当于你每间隔XXXms去询问一下,总体上而言和使用循环去检测有无没啥区别,不过定时器可以避免阻塞当前进程,不会出现页面刷新、无法操作这样的问题
至于“放到TextBox里。发现几秒才变一次”这个还取决于对Received缓冲区的使用方式
其中有这么一句话由于 SerialPort 类会缓冲数据,而 BaseStream 属性内包含的流则不缓冲数据,因此二者在可读字节数量上可能会不一致。 BytesToRead 属性可以指示有要读取的字节,但 BaseStream 属性中包含的流可能无法访问这些字节,原因是它们已缓冲到 SerialPort 类中
alitasoft 发表于 2015-3-30 09:56
定时器模式相当于你每间隔XXXms去询问一下,总体上而言和使用循环去检测有无没啥区别,不过定时器可以避免 ...
谢谢你,我突然发现我的下位机是出厂设置的1.38s更新一次,改为50ms后情况大为改善 休眠哪个线程5ms? sbk100 发表于 2015-3-30 11:28
休眠哪个线程5ms?
this.thread.sleep(5); 百里屠苏 发表于 2015-3-30 12:22
this.thread.sleep(5);
这句话是不是相当于单片机里的delay_ms(5)? sbk100 发表于 2015-3-30 12:46
这句话是不是相当于单片机里的delay_ms(5)?
不是的,除非你的单片机上了操作系统 百里屠苏 发表于 2015-3-30 12:54
不是的,除非你的单片机上了操作系统
那为啥要休眠5ms呢? 本帖最后由 error_dan 于 2015-3-30 14:42 编辑
----------------------------
图文混排好麻烦啊。。。 error_dan 发表于 2015-3-30 14:39
----------------------------
图文混排好麻烦啊。。。
谢谢你的讲解 但是我理解的是只要串口收到数据就会触发serialPort_DataReceived 事件,如果serialPort_DataReceived是一个线程的话,cpu也不会因为执行这个线程而不去执行其他线程啊
线程间的切换不是一直是CPU自己调度的吗,即使不休眠这5ms,CPU也应该可以去干其他的事情吧? error_dan 发表于 2015-3-30 14:39
----------------------------
图文混排好麻烦啊。。。
果然阻塞线程了,我在主界面上放了checkBox,点好几次才点到。郁闷
页:
[1]