c#串口指令发送周期的问题

xiemeilin 2010-04-15 10:46:19
我要给个仪器发送指令,但是呢这个仪器不太好使,需要满足它的周期才能返回好的数据,不然就会出现乱码,我用早先用LabVIEW做的一个串口程序,指令发送周期是1500ms收到的数据是很好的,没有乱码。
但是我现在用c#来做,却老是收到乱码数据,我设置timer的周期也是1500ms啊,为什么会出现截然不同的结果呢?

private void Device_Load(object sender, EventArgs e)
{
Creatlabel();
Iniform();
timersend.Enabled = false;
if (conf.Openport(serialPort, Comname, boudrate, parity, databit, stopbit))
{
MessageBox.Show("通讯成功");
timersend.Enabled = true;
}

else
{
MessageBox.Show("通讯失败,请检查串口是否被占用?");
}
timersend.Interval = 2000;
}
private void SendCommand()
{
int i;
string sendstr;
for (i = 0; i < Equiment.Length; i++)
{
// RRSTSB0000ZU
sendstr = "RRSTSB" + Equiment[i].PadLeft(4, '0') + "ZU";
serialPort.WriteLine(sendstr);

Delay(2000);
}
}
private void Delay(int mm)
{
DateTime current = DateTime.Now;

while (current.AddMilliseconds(mm) > DateTime.Now)
{
Application.DoEvents();
}
return;
}

我把timer的周期从1000设到2000可是好像一点改善都没有,希望大家帮忙解决下。
难道LabVIEW的时间跟c#的时间概念不一样?
...全文
408 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
soulsteal 2010-04-16
  • 打赏
  • 举报
回复
接收到数据,启动线程,处理数据,同时关闭采集功能,同时开启计时线程
计时时间到,开启采集功能
风中一匹狼 2010-04-16
  • 打赏
  • 举报
回复
乱码是不是 你接收回来的数据没有转换数据类型,应该转换为16进制的啊
xiemeilin 2010-04-16
  • 打赏
  • 举报
回复
[Quote=引用 11 楼 leafold 的回复:]

收发数据放在线程中做。
[/Quote]
我想请教下怎么做?我现在就是用sleep来做停顿1s然后再发数据,这样数据也接收完了,出现乱码的现象就少了,基本正常。
soulsteal 2010-04-15
  • 打赏
  • 举报
回复
你第一条返回是正确的么?
你接收到的是什么类型数据,显示的是什么类型数据,这两个类型对了么?
你的波特率设对了么?
xiemeilin 2010-04-15
  • 打赏
  • 举报
回复
就没人回复一下?
suners 2010-04-15
  • 打赏
  • 举报
回复
ooo
xiemeilin 2010-04-15
  • 打赏
  • 举报
回复
乱码就是出现 RRSTSB 0147 0000 0002 C0999 -0000 -0000 0000 0000 0002 C0999 -0000 -0000 0000 0000 0002 C0??-0000 -0000 0000 0000 0004 C0999 -0000 -0000 0000 0000 0005 0002 ZU
一些问号,我用indeof('?')好像不能识别这个?难道这个?是中文状态下的问号
doubleu2005 2010-04-15
  • 打赏
  • 举报
回复
接受数据的code在哪?
leafold 2010-04-15
  • 打赏
  • 举报
回复
收发数据放在线程中做。
xiemeilin 2010-04-15
  • 打赏
  • 举报
回复
现在的问题是,我在发送下一条指令之前停顿1s,然后再发第二条指令,这样就能收到正确的数据,但是这个延时函数占用很大的系统资源。cpu占有50%,但是用System.Threading.Thread.Sleep(1000);的话程序感觉像是给卡住了一样,点其他地方很久才反应过来。
        private void Delay(int mm)
{
DateTime current = DateTime.Now;

while (current.AddMilliseconds(mm) > DateTime.Now)
{
Application.DoEvents();
}
return;
}

这个延时函数效率不太高。
tfzdh 2010-04-15
  • 打赏
  • 举报
回复
关注。
Joe-xXx 2010-04-15
  • 打赏
  • 举报
回复
"需要满足它的周期才能返回好的数据",这句话你经过认真思考了么?

出现乱码的可能是:
1.通讯串口设置不对,一般都是波特率不匹配;
2.接收数据编码不一致;
3.设备发送过来的数据就是乱码的.
xiemeilin 2010-04-15
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 leafold 的回复:]

1、查看十六进制的值。
2、一般不用定时接收的方法,可以用定长指令或设定特定的指令头和尾字节。
[/Quote]
那有什么好办法呢?我每天指令之间的间隔是1000ms.
xiemeilin 2010-04-15
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 soulsteal 的回复:]

你第一条返回是正确的么?
你接收到的是什么类型数据,显示的是什么类型数据,这两个类型对了么?
你的波特率设对了么?
[/Quote]
每次第一条返回是正确的没有乱码,我的波特率设置的是9600。从第二次开始就会出现乱码,然后我发现加了延时也就是上面那个delay之后cpu占用达到50%。
都是字符类型的数据。
leafold 2010-04-15
  • 打赏
  • 举报
回复
1、查看十六进制的值。
2、一般不用定时接收的方法,可以用定长指令或设定特定的指令头和尾字节。
为了解决在测试模块通信距离中出现的误差大,每个人的测试条件都不一样,没有标准, 没有数据(数据最能说明问题),数据手动记录容易丢失,手动计算的误差大等情况.在经理的 指导下,特此开发了一款自动测试模块通信软件。 1。智能计算丢包个数,丢包率,增加误码判断,计算误码率,增加丢字节数,丢字节率判断。 2。测试记录,智能保存,点击保存可以将结果自动保存到txt文本中,便于查看和记录!让你在测试过程中更省心 更给力! 在测试过程中,只需要每次填写两个模块之间的距离即可,然后点击开始测试。该软件将自动计算所有的丢包率 丢字节个数 误码个数,误码率等,点击保存,将测试结果智能保存,并 打开,便于测试人员查看测试结果! 最后该软件得到的测试结果 为100m的情况误码率的情况,400m(需要用户自己设定)丢包率的情况 1000m的丢包率 误码率情况等所有信息,如下图所示。 3.增加ESC,自动退出功能。当用户想退出此程序,只需要按一下ESC键,便可关闭此程序(测试记录保存在d:\桑锐电子测试报告.txt不会丢失) 4.增加右键菜单功能。 5.串口设置信息以及发送区信息智能保存。(让测试过程设置信息更简单,更快速,更智能) 例如上次我们打开了串口5,波特率为9600 ,校验位:偶校验,发送的数据为11 22 33 44 55 。 我们下次打开此工具默认串口串口5,波特率为9600 ,校验位:偶校验,发送的数据为11 22 33 44 55 6.操作起来更简单。 点击开始测试,将自动打开串口,然后自动按照设定的发送包个数(例如我们设定总共发送500包) 发送周期为1000ms,模块之间的距离为100m,点击开始测试,自动打开串口,自动开始发送设定的字符。 发送到例如100包(您设定总共发送100包),就停止发送。 7.程序指令集重新优化,整体程序大小仅44kb.更加便于存储和便于传输!(需安装.net2.0)
* * MODBUS协议 * * * 介绍: * 此modbus上位机 协议类 具有较强的通用性 * 本协议类最主要的思想是 把所有向下位机发送指令 先存放在缓冲区中(命名为管道) * 再将管道中的指令逐个发送出去。 * 管道遵守FIFO的模式。管道中所存放指令的个数 在全局变量中定义。 * 管道内主要分为两部分:1,定时循环发送指令。2,一次性发送指令。 * 定时循环发送指令:周期性间隔时间发送指令,一般针对“输入寄存器”或“输入线圈”等实时更新的变量。 * 这两部分的长度由用户所添加指令个数决定(所以自由性强)。 * 指令的最大发送次数,及管道中最大存放指令的个数在常量定义中 可进行设定。 * * 使用说明: * 1,首先对所定义的寄存器或线圈进行分组定义,并定义首地址。 * 2,在MBDataTable数组中添加寄存器或线圈所对应的地址。 注意 寄存器:ob = new UInt16()。线圈:ob = new byte()。 * 3,对所定义的地址 用属性进行定义 以方便在类外进行访问及了解所对应地址的含义。 * 4,GetAddressValueLength函数中 对使用说明的"第一步"分组 的元素个数进行指定。 * 5,在主程序中调用MBConfig进行协议初始化(初始化内容参考函数)。 * 6,在串口中断函数中调用MBDataReceive()。 * 7,定时器调用MBRefresh()。(10ms以下) * 指令发送间隔时间等于实时器乘以10。 例:定时器5ms调用一次 指令发送间隔为50ms。 * 8,在主程序初始化中添加固定实时发送指令操作 用MBAddRepeatCmd函数。 * 9,在主程序运行过程中 根据需要添加 单个的指令操作(非固定重复发送指令)用MBAddCmd函数。

110,566

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧