Windows XP中的100 kHz定时器频率

有一个stream行的业余爱好水平的数控机床控制,在Windows XP中运行,它有一个定时器,在25 kHz至100 kHz范围内的用户可select的速率。

恰好我也是在build立数控机床控制器,但是我一直在使用我上层程序控制的一个Galil Motion Control公司的DMC1800系列DSP运动控制器板。 有潜在买家无法承受这种configuration,所以我写了另一个应用程序,我打算提供作为基于软件的控制包。 应用程序是完整的,除了我没有计时器。 (MS多媒体定时器是不够的。)

我一直在追求这两年没有结果,所以我决定要求帮助。 为了避免混淆,我指的是一个周期性的定时器,它能够以100kHz的频率工作,而不是秒表计时器。

我真的很感谢这个帮助,

C4C

不可能。 Windows上最快的可用定时器是1 ms(1 kHz)。 您需要一个实时操作系统或专用控制器。 即使在实时操作系统中,通常大约是20 kHz。

这个计时器到底需要做什么? 如果只需要输出25 kHz到100 kHz之间的方波,那么您将需要额外的硬件,而不是昂贵的硬件。 例如,从Data Translation看这个DT-340 。 它甚至可能比你需要的更快,我相信它甚至可以触发中断。 或者这个PCI 8255/8254 48 I / O。

如果您的预算能够支付500美元左右,则应该有很多硬件选项。 实际的可编程定时器芯片应该比这个便宜得多,所以如果你愿意把自己的电路连接到计算机上,你可能会比500美元做得更好。

我曾经围绕英特尔8253可编程间隔定时器芯片构建了一个电路,该芯片在原始IBM PC内部用于从内部扬声器发出蜂鸣声。 它被连接到一个1.193182 MHz的晶体,并有一个16位分频器。 这个芯片已经有数十年了。 如果你需要更好的话,我肯定自那以后有了改进。

当我说PC内部的8253(或8254)芯片用于驱动内部扬声器时,我并不完整。 英特尔8253在维基百科有很多。 这里说明输出0用于产生时钟中断,输出1用于DRAM刷新时序,输出2用于驱动内部扬声器。

前两个时钟输出产生中断,这是你想要的,但是上面这些输出当前做什么的描述应该给你一些暂停,以反映改变它们的行为可能会导致Windows XP注意到。 扬声器的第三个输出大多是无害的,但是如果这是你所需要的,你需要找出一些方法将信号重定向到产生和中断的地方。

可能马赫3是使用高性能事件计时器 (HPET),根据这里是最近英特尔芯片组的一部分。 定时器0和1用于8254仿真。

“ICH HPET定时器2中断可以通过TIM2_CONF寄存器路由到以下IRQ中的任何一个:11,20,21,22和23(注意:该寄存器在英特尔®ICH5中称为TIM3_CONF)。”

您可以使用QueryPerformanceCounter在当前CPU的循环中相当接近100 kHz轮询。

例如:

typedef void ( *CallbackProc )(); void PollAtKhz( int khz, CallbackProc const &Callback ) { int hz = khz * 1000; LARGE_INTEGER li; QueryPerformanceFrequency( &li ); if( li.QuadPart < hz ) return; __int64 diff = li.QuadPart / hz; LARGE_INTEGER NextStop; LARGE_INTEGER CurStop; QueryPerformanceCounter( &NextStop ); NextStop.QuadPart += diff; while( true ) { QueryPerformanceCounter( &CurStop ); if( CurStop.QuadPart >= NextStop.QuadPart ) { Callback(); QueryPerformanceCounter( &NextStop ); NextStop.QuadPart += diff; } } } 

在我的测试中,我得到了大约92-98 kHz的频率,使用这个代码来测试它:

 void TestCallBack() { static int i = 0; static time_t LastTime = time( NULL ) + 1; ++i; if( time( NULL ) >= LastTime ) { printf( "%d / sec\r\n", i ); LastTime = time( NULL ) + 1; i = 0; } } 

显然,这段代码需要最大的CPU使用率,所以为了得到这些结果, SMP机器是必须的。 此外,还可以将进程/线程优先级实时更新。

QueryPerformanceFrequency / QueryPerformanceCounter可以在Windows中进行计时。 我见过的最低频率是1.1 MHz,所以能够提供足够的频率。

但即使如此,正如其他答案所指出的那样,这也是行不通的。 Window's不是一个实时操作系统,它没有任何时间保证。 没有办法确保你的代码每1 us(100kHz)运行,因为Windows将交换到其他进程或内核代码。

你将不得不采取某种外部硬件解决方案来获得这种时机。

当你说定期计时器,我想你是指一个脉冲发生器?

你提出一个计时器,每10微秒产生一个事件? 我怀疑你应该这样做。

您可以尝试对PC的音频输出进行编程并将其连接到该工具。 当您的工具正在运行时,您将不得不静音/配置PC声音,以防止对脉冲流产生伪造的频率。

你考虑过USB脉冲发生器吗? 还是专门用于此操作的便宜的“ USB声卡 ”?

Windows XP不是一个实时系统,我不认为有一种方法可以保证10微秒范围内的定时器。 您可以在Microsoft.Ccr.Core库中查看 ,我认为这是最接近的。

编辑:我从微软找到更多的信息。 根据如何使用QueryPerformanceCounter时间码知识库文章,

 Function Units Resolution --------------------------------------------------------------------------- Now, Time, Timer seconds 1 second GetTickCount milliseconds approx. 10 ms TimeGetTime milliseconds approx. 10 ms QueryPerformanceCounter QueryPerformanceFrequency same 

这是在一篇以声明开头的文章中:

在定时代码以识别性能瓶颈时,您希望使用系统提供的最高分辨率计时器。

罗伯特·哈维是正确的,QueryPerformanceFrequency是在几十微秒的范围内,但我不认为有一种方法来使用它来精确触发事件。 我认为这使得它仅仅是一个软件解决方案的完全破产。 你看过像Arduino这样相当便宜的芯片吗? 从Arduino论坛看来,10微秒精度看起来是可能的。

也许你可以使用一些这样的:

http://www.geisswerks.com/ryan/FAQS/timing.html

查找QueryPerformanceFrequency,但也许其他解决方案可能是有用的。

虽然我怀疑meomaxy的解决方案是最好的…

如果您需要高分辨率差分时序,英特尔在这里有一些代码要求精度达到纳秒。 (关于一般差分时序的可能性也有很好的讨论)。

好吧,在阅读Mach 3文档(写得很好,内容丰富,甚至有趣)之后,我想我会看到发生了什么。 首先要认识到高频用户空间事件触发和内核中断例程之间是有区别的。 内核中断程序必须快速 ,因此不包含非常多的逻辑,所以通常我们说在程序中不可能有一个广义的回调函数来响应频率大于1 kHz的事件。 此外,操作系统使用本地计时器来确定用户程序何时可以运行,并且通常调度器速度不超过1 kHz,因此不可能编写比此更快响应的用户空间程序。

但是,在这种情况下,您不需要复杂的用户空间逻辑以这种速度响应,因为目标只是以高频率调制输出引脚以产生PWM信号。 为APIC创建一个内核中断处理程序可能是可行的,该处理程序具有高优先级,并在高频率触发,如果它只做非常简单的事情,如切换并行端口上的输出引脚。

所以,如果你想这样做,我建议你阅读内核编程和使用API​​C,你可能会得到一些有用的东西给你。 但是,有些建议的话:

  • 使用软件分发驱动程序对于您作为开发人员以及必须安装可能运行或可能不运行的驱动程序的用户来说都是一种痛苦。 (硬件是挑剔的,如果你的解决方案取决于非常具体的电脑配置,你​​的里程可能会有所不同。)
  • 有这样一个高频率中断运行会使计算机陷入困境,使事情变得非常热门。 你可能会得到摊位或蓝屏。 准备应付这种烦恼。
  • 如果您成功切换LPT引脚以响应APIC定时器,建议您连接采集卡或数字示波器,以测量频率和抖动 。 任何软件定时信号往往有更多的抖动,所以要留意这一点。 抖动有效地增加了信号中的噪声。 此外,抖动趋于保持不变,因此在低频时可能不成问题,但在高频时,抖动可能占总时间的很大比例,从而显着降低信噪比。
  • 如果您的目标确实是产生一个PWM或脉冲信号来控制步进电机,那么拥有一些板外硬件确实是最好的方法。 我会用下面的几点来说明这个问题:
    • 首先,如果您阅读了Mach 3文档,那么在出现电气问题时,它们将包含有关如何电隔离计算机并行端口的一节。 换句话说,即使使用内置的LPT端口,为了安全起见,建议使用一些外部硬件。 如果你打算这样做,你可能还包括一个2美元的定时器芯片。
    • 由于您正在生成高频信号,但只能以较低的速率控制此信号,因此无需实际生成信号本身 – 这正是计时器芯片的用途。
    • 一个5美元的低压AVR微控制器可以通过USB端口与计算机通信,并产生一个PWM信号。 这比购买100美元的主板要便宜得多,但这取决于你的需求。 (比如有多少信号等)例如,购买Teensy并将其插入计算机的USB端口,然后编写一个5行程序来控制提供的7个PWM输出。 完成,完成!
    • 如果你在线搜索“PWM并行”,你会发现很多关于如何使用并行端口产生PWM信号的教程,但是注意到其中99%实际上是关于如何控制并行外部定时器芯片的教程端口, 而不是如何直接生成实际的PWM信号。

最后,这里有一些你可能会觉得有用的文件:

  • 微秒精度计时器支持Linux内核
  • 软定时器

Windows 多媒体定时器可能会给你1毫秒。

我想说,如果不写自己的驱动程序,这是不可能的。

但是,如果你编写了自己的驱动程序,你可以抓住HPET定时器(不是在所有机器上都可用,但是大多数新机器都可用),也可能是APIC定时器(不知道是否可以给你100 kHz)千赫兹从这里..这是相当复杂的,但你必须做更多的研究。

此外,即使设置您的应用程序将消耗您的CPU使用率,应该有助于实时。

对所有的回应者来说,

我试图说清楚,我对测量时间没有兴趣,但是大部分的回答都是完全相同的。

显然我没有充分传达我的观点,所以我会再试一次。 我想创建一个事件,在1秒的时间内发生100,000次,CPU成本大约为12%。

我参考的程序Mach 3,当用户选择了10万时产生了一个108,000的频率,但频率非常稳定。 我提到,为了说明只要间隔时间的误差一致,实际时间间隔的准确性并不重要。

我将再次提到Mach 3的CPU成本在12%左右。 108,000个频率是在一个并行端口引脚上发射的,可以用一个示波器来验证,我已经完成了。

其他受访者有些明白我想完成什么,但他们的例子是在1秒的时间内测量可能发生的循环次数,同时承认CPU成本是不可接受的。

普遍的共识是,我想要做的是不可能的。 对于那些符合这个意见的人,我会鼓励你到Google Mach 3 CNC ,下载一个免费的程序副本,然后安装它。 运行该程序,使用选项卡导航到诊断页面,您将能够亲眼看到它实际上是可能的。 程序最初将以25kHz的默认频率打开。 可以通过打开菜单选项'Config'/'Ports and Pins'/然后选择新频率并重新打开程序来改变频率。

像这样的论坛有大量与这个主题有关的帖子,而且更好的部分与我收到的一样。 我提供了一个清楚地表明它是可能的例子,所以让我们来看看Mach 3是如何完成这个任务的。

C4C

我最近一直在使用一个实时Linux内核与CNC路由器一起工作,你所看到的问题是在Windows XP中缺乏实时抢占。 我不能从这里查看Mach3的东西,但它应该能够工作的唯一方法是在Windows中使用“内核级”驱动程序。 (对不起,我不是一个真正的Windows用户,所以我不知道具体情况)。 写一些驱动程序绕过Windows默认抢先模式是你的答案,但我会先学习一些关于Windows驱动程序,也许看看Linux内核的实时补丁,以供参考。

http://www.kernel.org/pub/linux/kernel/projects/rt/

在没有专用硬件的情况下使用PC进行运动控制的一个基本问题是内置于大多数PC中的各种输出的数据速率。 如果您的客户没有提到的高端运动控制器的预算,那么他们根本无法获得100 kHz的信号。

每个端口的I / O控制器都提供了某种缓冲,这样你就可以得到平滑的结果。 这在很大程度上是为了减轻软件的需求,使这些信号“砰砰”一声,并使I / O频率更加稳定。

不足之处在于缓冲可能会在系统中引入一些延迟,这可能会影响性能闭环控制电路的控制软件。 另一个缺点是这限制了你的频率选择。 PC上不能提供高端流量控制(如USB或SATA)的最快的I / O选项之一实际上是音频端口,但在大多数系统上限制为64 kHz或44 kHz。

如果音频端口是您的选择,那么您根本不需要担心时序,只要确保正确设置频率,然后按照其他方式生成信号。

如果您需要使用数字信号,并行和串行端口的工作方式类似,但速度较低。

编辑嗯…似乎并行端口比以前要快一点。 增强型并行端口(EPP)功能的机器可以为您提供高达2mb的二进制带宽,这应该在您的目标范围内。 但是,由于并行接口的工作方式,数据速度取决于外设,而不是预定义的缓冲器速度。 本质上,外设确认已经收到数据,或者已准备好发送数据。

但这并不算太坏,因为一个简单的,时钟驱动的外设很容易建立。

另外,数据不能同时在两个方向流动,来自外设的数据将导致来自主机PC的数据流被阻塞。 避免这种情况的一种可能的方式是仅安排两个并行端口可用,或者安排外设将其自己的数据传输限制到每个其他周期。

这样的端口上的I / O通常是中断驱动的。 除了一些错误状态之外,当输入或输出FIFO达到一定水平时,会产生最有用的中断。 您可以使用此中断将新数据写入(或读取)到端口。 阈值可以设置为1到16个字节。 您应该仔细测试(使用逻辑分析仪/示波器)数据是否以预期的速度以预期的速率流动。 你可以在使用QueryPerformanceCounter的软件中做到这一点。

你可以尝试使用像IntervalZero的RTX的东西。 它不是免费的,它是一个商业产品。它被写入介绍实时到Windows(XP等)它有一些非常快速的计时器。 根据这篇文章, RTX的定时器的值为1微秒(而Windows是1000微秒)

不确定什么价格\授权是。 我已经涉猎了eval版本。

听起来就像你需要一个555定时器(或晶体),一个与门和一个并行端口(或一个数字I / O USB设备)。 你也许可以伪造一个声卡DSP来做这样的事情,但我不会打赌。

任何你可以建立在W​​indows上的计时器将以CPU的速度运行。 并不是计算机CPU无法处理,而是必须考虑计算机上其他运动部件。 从软件模拟到标准硬件上的硬件I / O信号,获得可靠的100 kHz信号是一项相当重要的任务。 为了获得正确的信号模式,您将I / O绑定一个核心。

一些选项可能是为串口创建一个环回插头,然后使用位模式和信号类型来获得相当稳定的信号。 但是,如果要建造或购买一台用于控制数控铣床的数字控制板,则会更好。 如果你看,与Mach3 CNC有关的大部分齿轮是指带有USB,RS-232或LPT端口的控制板。

(哦,并告诉人们他们错了,而不是有建设性的评论…也不会赢你任何球迷)