一种较好的软件延时方法

类别:公司新闻 时间:2018-02-06 点击:92 次

工控软件中经常需要对控制的电机进行延时动作,本文对几种常用延时方 法的优缺点进行比较后,推荐一种既能达到延时效果,又可以少占用系统资源的方法。此方 法在〈〈数字汽车衡称重管理软件》中得到了良好的应用。
在工控软件中,经常需要对各种开关进行延 时打开、闭合;对电机进行延时通电、断电等操 作。
常用的延时方法有以下两种。
一种方法是调用Sleep()函数。这个函数使 用比较方便,但是它的缺点是冻结主线程,阻止 用户在程序界面进行其他的操作。函数的原型是 VOID Sleep(
DWORD dwMilliseconds // 要延时的毫秒时间);
如果想延时1秒的话,这样调用Sleep(1000)。 另一种常用的方法是调用GetTickCount(),
在循环中检测两次时间差值,来达到延时目的。 实际应用时,先设定一个延时值DT,并在循环中 检测时间差是否大于此值(即大于DD,如果不 满足,则循环一直进行,直到达到设定时间值 DT,才进行开关动作,典型代码如下:
void DelayTime(DWORD DT)
{
long tt;
tt=GetTickCount();
while (GetTickCount()- tt<DT)
{
Application- >ProcessMessages(); if ((GetTickCount()- tt)<=0) tt=GetTickCount();
}
}
这个函数可以代替Sleep,也不会冻结主界面, 但是 CPU 的使用率达 100%。GetTickcount ()
函数记录的是从机器开机时到当前的时间,返回 值为DWORD类型。单位是毫秒(ms)。此函数在机 器运行49.7天就会复位,即复位再次从零开始。 而工控软件是长时间运行的,甚至启动之后,非 特殊情况,不会关机,因此当时间到达49.7天时,程序运行会有问题,此刻延时可能会出错。
笔者在工作中,也遇到过软件的延时问题, 那么有没有一种既能延时,又能减少CPU资源的 占用的方法呢?笔者查找了一些资料,通过实践 检验,找到一种符合上述要求的方法,为了调用 方便,将其封装成C函数。具体代码如下:
int CreateTestTimer(long e) // 参数为延时秒数 int CreateTestTimer(long e)
{
HANDLE hTimer=NULL;
HANDLE hT[1];
LARGE_INTEGER liDueTime ; liDueTime .QuadPart=e *(- 100000000)/10; hTimer=CreateWaitableTimer(NULL,TRUE, "TestWaitableTimer");// 创建定时器对象hT[0]=hTimer; if (!hTlmer)
{
return 1;
}
if (!SetWaitableTimer (hTimer, &liDueTime, 0,NULL,NULL,false))//设置定时器激发条件 {
CloseHandle(hTimer); return 2;
}
DWORD lBusy; do
{
lBusy=MsgWaitF orMultipleObj ects(1 ,hT,F alse,
0xfiff,QSLLINPUT);//等待定时器的复位信号 Application- >ProcessMessages();
}
while(lBusy==(WAIT_OBJECT_0+1)); CloseHandle(hTimer); return 0;
}
上述函数CreateTestTimer(long e)在调用时,其
参数e即为要延时的秒数,这个函数最大延时时 间是25秒,这是由操作系统的线程时间片分配机 制决定的。如果要延时更长可以多次调用此函数。 在控制系统的两个动作之间调用这个函数,即可 实现动作之间的延时。
笔者在开发《数字汽车衡称重管理软件》时,常要用到USB串口转换器。因为USB转换器 质量良莠不齐,不能以统一的时间片来读取所有 传感器,否则在遇到某些质量不好转换器时会出 错。因此在读每个传感器内码时,插时一定的延 时加以解决,延时值由用户设定。
如图1所示,时间值n由用户设定。如果使 用的是计算机主板上自带的串口,n值可设为0。 软件中有时间值设定窗口,如图2所示。

上述的各种延时方法,延时精度是以秒为单 位。在工控软件中,开关的闭合,电机启停,常 常以秒为单位,因此使用此函数延时是合适的。

中国领先的称重软件技术提供商

The Leading Provider of Geomatic Solutions in China

展开收起网站地图