Wait(ms)内置函数的探讨(1)——基本功能 12/22/2009
Wait(ms)内置函数,在LabVIEW开发环境下,选择程序框图中的函数选板,在编程〉定时〉中就可以找到该内置函数。参见图1-1,右边是该内置函数的图标。 Wait(ms)内置函数在中文版的LabVIEW中被译为:等待(ms)。 1、等待(ms)内置函数的功能等待指定长度的毫秒数,并返回毫秒计时器的值。等待时间指定要等待时间,以毫秒为单位。函数的等待时间不超过0x7ffffff,即2147483647毫秒。如需等待更长的时间,可再次执行函数。 将0连接到毫秒计时值输入,可迫使当前线程放弃对CPU的控制。 该函数作出异步系统调用,但是函数节点却是同步操作的。所以,直到指定时间结束,函数才停止执行。 该内置函数在程序中通常被用来做定时器或延迟器使用。它的输入端为所期待的定时数值(以ms为单位),它的输出返回毫秒计时器的值。 由于等待(ms)是一个LabVIEW的内置函数,所以我们根本无法了解其程序内部的执行的方式或运行方法。但是我们可以通过不同的编程形式运行的结果来间接的认识和了解它。 先看下面的例子,参见图1-2: 在图1-2中,我们为等待(ms)内置函数设定一个1000ms的定时值,程序运行后它的输出“毫秒计时值”则显示出一组无法确定的数据,并且每次程序运行后该输出值都是不一样的,但趋势是不断增加的。这里显然是等待(ms)定时器的起始时间是一个不断改变的数值,这究竟是为什么呢? 下面我们对图1-2所示的程序进行一下改动,看看改动后的运行结果。 图1-3的运行结果显示,此时我们可以获得与输入设定值一样的“毫秒计时值”。很显然等待(ms)内置函数中包含了一个类似于“时间计数器”的内置函数,他们在某一时刻同步开始操作,这样我们就可以在等待(ms)的输出端获得稳定的“毫秒计时值”。 关于时间计数器内置函数的介绍,这里不想多谈了。Csxcs366在本站的“csxcs366手记”专栏的“LV深入探索(30)——谈谈LabVIEW中的几种定时器”有专门的描述。我们这里仅借用他的结论。 “基准参考时间(0 毫秒)未定义的说法比较模糊,难道会是个随机数?这显然是不可能,如果是随机数,那两次调用TICK COUNT取得差值就不可能表示经过的毫秒数。无论如何,必须有个时间的起点。 API函数中也有一个类似的函数:GetTickCount,该函数返回计算机启动以来经过的毫秒数。在9X中,它读取的是BIOS中保存的系统时钟的滴答数,早期PC的ROM初始化Intel8259定时器芯片来产生硬件中断08H。这个中断有时称为“定时器滴答”中断。中断08H每隔54.925毫秒产生一次,或大约每18.2次。BIOS使用中断08H更新存于BIOS数据区的“时间”值。这就是常说的55ms的由来。对于NT操作系统,常规的说法是能精确到10ms,也就是说精度在1ms时是不精确的。 经过实际测试,LabVIEW的TICK COUNT的返回值和API的返回值是一致的,也就是计算机启动以来经过的毫秒数”。(这里得感谢csxcs366用他的智慧为我们做出了这样的结论,这样的工作绝对是我力所不能及的——labview7i) 现在可以说是清楚了,等待(ms)内置函数和时间计数器内置函数的起始工作时刻是来自计算机启动以来所经过的毫秒数,所以我们才会看到图1-2程序运行后,它的输出“毫秒计时值”则显示出一组无法确定的数据,并且每次运行后该输出值都是不一样的,但趋势是不断增加的现象。而图1-3所显示的输出确实是定时器定时的毫秒计时值。 通过这样的分析,显然下面的这两个程序应该是完全等价的!(请注意:此时用等待下一个整倍数毫秒内置函数也会得到同样的结果) 这种情况下,结论果真如此吗?是的,在通常的情况下这个结论是正确的。可是csxcs366却在文中展示出了另外的实验结果。 是这样的,当无数次叠代发生时,图1-6要比图1-5花费更多地时间来处理程序运行。因为它的程序内部多了一些可执行的节点,每次叠代必将常数0送到等待(ms)的输入端,而等待(ms)内置函数则在判断输入为零后,会通知系统关闭等待(ms)的线程,所以将消耗更多地时间。 而为什么等待下一个整倍数毫秒内置函数的第一次总是不对的,这涉及到该内置函数的运行机理。对于等待下一个整倍数毫秒内置函数而言,LabVIEW通过一个毫秒计数器来监测等待的时间量,等待会一直持续,直到您所指定的整数倍毫秒时间量。由于毫秒计时器一直在工作,所以首次进入毫秒计数器会得不到所期待的计时时间,参见图1-3的说明,但是它可以实现图1-4的效果。 但是无论怎样说,它们都是基于软件定时的,在定时精度要求高的地方不要使用它们,应该使用实时系统中的硬件定时。相比较而言,等待下一个整倍数毫秒内置函数的定时精度要高于等待(ms)内置函数。我们用下图中的程序验证了这个结论。 定时大于10ms时,按上图分别使用等待下一个整倍数毫秒内置函数和等待(ms)内置函数进行测试,结果前者大概比后者的定时精度高一个数量级。即便是定时小于10ms,定时精度也是前者要优于后者。 下面是来自NI网站上的一则问题解答。 问题: 在LabVIEW中,等待(ms)和等待下一个整倍数毫秒两个内置函数有什么区别? 解答: 等待(ms)函数等待的是您指定的时间量。而对等待下一个整倍数毫秒函数而言,LabVIEW通过一个毫秒计数器来监测等待的时间量,等待会一直持续,直到您所指定的整数倍毫秒时间量。可以考虑这样一种情况,以方便您来理解这两个函数的区别。假设您需要某个特殊任务每小时执行一次,您有两种方法供选择: 1).获取当前时间,并决定在60分钟后执行任务。 2).您可以决定在每小时的开始执行任务(12:00, 1:00, 等等)。 例如,如果完成该任务需要5分钟,而您使用第一种方法,在12:00开始这个任务,并在12:05结束。那么您接下来需要等待60分钟直到1:05,才开始再次执行并于1:10完成。然后您又需要再等60分钟,以此类推。随着时间的推移,您每次开始任务的时间也将随之变化,从小时的开始,慢慢变化到结束,并再次循环。这就是在LabVIEW中关于等待(ms)函数的类推。另一方面,如果您使用第二种方法,它不会关心任务是花5分钟还是15 分钟来完成,任务开始的时间总是在每个小时的开始。需要注意的是,取决于您开始的时间,第一次的等待时间也许会相当短,这是因为系统时钟在您开始等待前已经开始计时了。所以,如果您于12:50开始您的第一个任务,那么很快,您将在1:00开始您的下一个任务。这就是在LabVIEW中关于等待下一个整倍数毫秒函数的类推。 其实上面的解答中,对于“使用第一种方法”的说法未必很准确,通过下面对数据流的分析将会看清这一点(除非你使用的是顺序结构,参见下图1-9)。 尊重别人就是尊重自己 | 写着玩! 外行当然说的就是我自己,内行是指NI的那些AE,因为他们更清楚LV的内涵和机理。就LV学习和使用而言,我的确就是个外行。但是,我想通过“看热闹”使自己尽可能的接近于内行。这肯定是一个可望而又不可及的目标。 历史纪录十一月 2011 分类
All |










RSS Feed