cserialport类定时200ms发送数据,有时定时混乱,不是200ms而是420ms,选用多媒体定时器一样出现此问题。求解

冰晶之魂 2013-11-25 11:28:42
PC用cserialport类setTimer定时200ms发送数据给MCU,有时定时混乱,不是200ms而是420ms,下一个数据又间隔十几毫秒发送,导致数据接收出现乱码,选用多媒体定时器一样出现此问题。求解
...全文
1034 72 打赏 收藏 转发到动态 举报
写回复
用AI写文章
72 条回复
切换为时间正序
请发表友善的回复…
发表回复
冰晶之魂 2014-11-27
  • 打赏
  • 举报
回复
一旦卡死在writefile或GetOverlappedResult,那就是重启计算机的节奏
冰晶之魂 2014-11-27
  • 打赏
  • 举报
回复
引用 70 楼 zypinga 的回复:
楼主你好,我也在用cserialport类串口通讯,我的只要实现发送功能就可以,但是要求是25ms,请问这个类能达到么?
这个真不好说
  • 打赏
  • 举报
回复
楼主你好,我也在用cserialport类串口通讯,我的只要实现发送功能就可以,但是要求是25ms,请问这个类能达到么?
冰晶之魂 2013-12-26
  • 打赏
  • 举报
回复
引用 65 楼 woshi_hujunjun 的回复:
哎哟 ,还在考虑系统的事情啊! 肯定是自己代码的问题,别想太多了。 老老实实的把代码缕一缕,肯定能找到问题的,
我用了TRACE打印出调用写事件的时间间隔,记录到的数据显示等到写事件的时间被莫名推迟了200多ms。
引用 66 楼 allenemo 的回复:
SetTimer更不精准。用SetTimer计时,操作系统内部反复地使用的GetTickCount获取当前时间,再与上次插入WM_TIMER的时间做差值比较,要是大于等于SetTimer的时间间隔,就插入一个WM_TIMER到消息队列。更恶心的是如果插入WM_TIMER时发现消息队列还有先前的WM_TIMER没处理完,先前的WM_TIMER就会被操作系统移除。 GetTickCount的精度也就15MS(事实上还不如多媒体),再加上偶有被移除的WM_TIMER,SetTimer的精度能到30MS就不错了。
我查到的资料里说QueryPerformanceCounter较好,用这个做定时器。
冰晶之魂 2013-12-26
  • 打赏
  • 举报
回复
引用 64 楼 schlafenhamster 的回复:
“所以串口发送和接收不能同时进行” 没叫你 同时,是叫你 开个 发送线程, 提高优先度,sleep 定时。 能不能发送 ( 有没有在接受) 通过 event 控制。
一直以来用的串口类网址:http://blog.csdn.net/liquanhai/article/details/6941574。 上上个星期六我试过开个线程,具体做法是在他的串口类里面等到写事件然后打开发送线程,发送线程里面定时发数据,结果不是很理想,主要是我每一次发送的数据都不一样,但它只连续发第一条数据(代码我删了,没留下)。星期天的时候我封装了一个定时器,使用线程和QueryPerformanceCounter(我以为RDTSC指令也可以,看了下资料貌似不是很好)。然后我在串口类里面添加了几行代码。主要添加的代码有在每一次ClearCommError之后调用SetCommMask。还有就是在ReceiveChar函数执行ResetEvent,这是我在看龚建伟写的《Visrual C++/Turbo C串口通信编程实践》里113页中关于CreateEvent函数的介绍提到创建的事件如果是手工复位,那么必须在程序中调用ResetEvent。最后一点就是串口类接收到消息之后没有按它原来的sendmessage给窗口,而是给一个C++类,在C++类里面放入数组里,再由C++类提交给窗口。然后测试了一个下午,那次没出现问题。之后我有事就没进行测试了,如果有时间的话,再测试一两天,看看有没有问题。只能先这样了。谢谢您一直以来给我的帮助!
冰晶之魂 2013-12-25
  • 打赏
  • 举报
回复
这段时间有事,没能回复!
引用 62 楼 jzycode 的回复:
你的代码我们都没有看见过,其中到底什么地方写的不合理,我们无从知道,大家也都是凭借经验猜测而已,你如此询问有什么实际意义呢?学习也是要讲究技巧的,太过于纠结于某个问题,难道不是在浪费时间吗?哪怕别人的一句话就能让你拨开云雾见晴天!
好吧!过去的少年梦!这位兄弟你赢了!表示C++这方面的高人我身边没有。关于纠结,我一直相信认真纠结于某一个问题不是浪费时间!我承认我很死板!
阿先森 2013-12-15
  • 打赏
  • 举报
回复
SetTimer更不精准。用SetTimer计时,操作系统内部反复地使用的GetTickCount获取当前时间,再与上次插入WM_TIMER的时间做差值比较,要是大于等于SetTimer的时间间隔,就插入一个WM_TIMER到消息队列。更恶心的是如果插入WM_TIMER时发现消息队列还有先前的WM_TIMER没处理完,先前的WM_TIMER就会被操作系统移除。 GetTickCount的精度也就15MS(事实上还不如多媒体),再加上偶有被移除的WM_TIMER,SetTimer的精度能到30MS就不错了。
woshi_hujunjun 2013-12-11
  • 打赏
  • 举报
回复
哎哟 ,还在考虑系统的事情啊! 肯定是自己代码的问题,别想太多了。 老老实实的把代码缕一缕,肯定能找到问题的,
冰晶之魂 2013-12-10
  • 打赏
  • 举报
回复
引用 39 楼 zhuyf87 的回复:
多媒体定时器timeSetEvent()函数,定时精度为ms级。 对于精确度要求更高的定时操作,可以试试QueryPerformanceFrequency() 和 QueryPerformanceCounter()函数。
兄弟那两个函数是计时不是定时,要定时的话得开辟线程,然后使用那两个函数封装成定时器。
冰晶之魂 2013-12-10
  • 打赏
  • 举报
回复
引用 57 楼 schlafenhamster 的回复:
"开辟的串口线程既要发送又要接收" 不能分成 2个 线程 ? 为什么 ?
因为接收和发送的都是同一个串口,两个线程的话比较麻烦
schlafenhamster 2013-12-10
  • 打赏
  • 举报
回复
"开辟的串口线程既要发送又要接收" 不能分成 2个 线程 ? 为什么 ?
冰晶之魂 2013-12-10
  • 打赏
  • 举报
回复
引用 55 楼 schlafenhamster 的回复:
"试了下提升线程权限,好像没用" 操作系统 按 线程 调度 (不是 进程), 定时器在 主线程 , 而主线程是 不能 提升线程 优先度。 只能在 发送 线程 中 提升线程 优先度,Sleep(200), 是 代替 定时器, 用来 定时的。
我是提升串口处理的线程中提升优先度,如果用Sleep代替定时器的话不行,因为开辟的串口线程既要发送又要接收。

BOOL CSerialPort::StartMonitoring()
{
	if (!(m_Thread = AfxBeginThread(CommThread, this)))
		return FALSE;
	m_Thread->SetThreadPriority(THREAD_PRIORITY_TIME_CRITICAL);
	TRACE("Thread started\n");
	return TRUE;    
}
schlafenhamster 2013-12-10
  • 打赏
  • 举报
回复
“所以串口发送和接收不能同时进行” 没叫你 同时,是叫你 开个 发送线程, 提高优先度,sleep 定时。 能不能发送 ( 有没有在接受) 通过 event 控制。
冰晶之魂 2013-12-10
  • 打赏
  • 举报
回复
引用 60 楼 schlafenhamster 的回复:
"两个线程的话比较麻烦" 怕麻烦, 就没办法 了
兄弟,我使用的串口类它就只使用一个线程。我电脑没串口,使用usb转串口线,rs485通信,半双工。所以串口发送和接收不能同时进行,就创建一个线程就够了。
_船长_ 2013-12-10
  • 打赏
  • 举报
回复
引用 61 楼 bingjingzhihun 的回复:
连续第三次回复了,把前面各位兄弟给我的建议都一一回复了。 [quote=引用 43 楼 asdjy123 的回复:] 在接收完一帧报文立即使用:PurgeComm(mycom.m_hComm, PURGE_RXCLEAR);//清空接收缓冲区, 我就是这么干的
兄弟我试过像你这么干了,没用貌似。
引用 53 楼 jzycode 的回复:
代码写的有问题,就别再纠结了,找个高人给你看看代码!
兄弟,或许是我太过纠结!高人也是慢慢爬上来的,自己不学习分析研究的话那就爬不起来了啊。
引用 51 楼 allenemo 的回复:
多媒体定时,理论上精度是1MS,实际上操作系统忙不过来的,它要考虑硬件IO、消息循环、线程池。一般配置的机器精度到15MS就是极限了。
学习了,那换成settimer么?[/quote] 你的代码我们都没有看见过,其中到底什么地方写的不合理,我们无从知道,大家也都是凭借经验猜测而已,你如此询问有什么实际意义呢?学习也是要讲究技巧的,太过于纠结于某个问题,难道不是在浪费时间吗?哪怕别人的一句话就能让你拨开云雾见晴天!
冰晶之魂 2013-12-10
  • 打赏
  • 举报
回复
连续第三次回复了,把前面各位兄弟给我的建议都一一回复了。
引用 43 楼 asdjy123 的回复:
在接收完一帧报文立即使用:PurgeComm(mycom.m_hComm, PURGE_RXCLEAR);//清空接收缓冲区, 我就是这么干的
兄弟我试过像你这么干了,没用貌似。
引用 53 楼 jzycode 的回复:
代码写的有问题,就别再纠结了,找个高人给你看看代码!
兄弟,或许是我太过纠结!高人也是慢慢爬上来的,自己不学习分析研究的话那就爬不起来了啊。
引用 51 楼 allenemo 的回复:
多媒体定时,理论上精度是1MS,实际上操作系统忙不过来的,它要考虑硬件IO、消息循环、线程池。一般配置的机器精度到15MS就是极限了。
学习了,那换成settimer么?
schlafenhamster 2013-12-10
  • 打赏
  • 举报
回复
"两个线程的话比较麻烦" 怕麻烦, 就没办法 了
_船长_ 2013-12-09
  • 打赏
  • 举报
回复
代码写的有问题,就别再纠结了,找个高人给你看看代码!
冰晶之魂 2013-12-09
  • 打赏
  • 举报
回复
woshi_hujunjun兄弟你加日志的方法也行,就是太慢了。
schlafenhamster 2013-12-09
  • 打赏
  • 举报
回复
"试了下提升线程权限,好像没用" 操作系统 按 线程 调度 (不是 进程), 定时器在 主线程 , 而主线程是 不能 提升线程 优先度。 只能在 发送 线程 中 提升线程 优先度,Sleep(200), 是 代替 定时器, 用来 定时的。
加载更多回复(52)

2,640

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 硬件/系统
社区管理员
  • 硬件/系统社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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