Windows XP 中的 100 kHz 定时器频率
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1868642/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
100 kHz Timer Frequency in Windows XP
提问by user227239
There's a popular hobby level CNC machine tool control that operates in Windows XP and it has a timer that operates at a user selectable rate ranging from 25 kHz up to 100 kHz.
有一种流行的业余爱好者级别的 CNC 机床控制,它在 Windows XP 中运行,它有一个定时器,以用户可选的频率运行,范围从 25 kHz 到 100 kHz。
It just so happens that I also build CNC machine tool controllers but I have been using a Galil Motion Control Inc. DMC1800 series DSP motion controller board which I control with my upper level program. There are prospective buyers that cannot afford that configuration so I wrote another application which I plan to offer as software based control package. The application is complete with the exception that I have no timer. (MS Multi-Media Timer is NOT sufficient.)
碰巧我也构建了 CNC 机床控制器,但我一直在使用 Galil Motion Control Inc. DMC1800 系列 DSP 运动控制器板,我用我的上级程序控制它。有些潜在买家负担不起这种配置,因此我编写了另一个应用程序,我计划将其作为基于软件的控制包提供。该应用程序已完成,但我没有计时器。(MS 多媒体计时器是不够的。)
I have been pursuing this for over two years without results so I have decided to ask for HELP. To avoid any confusion I'm referring to a periodic timer that is capable of operating at a frequency of 100 kHz and not a stopwatch timer.
我一直在追求这个两年多没有结果所以我决定寻求帮助。为避免混淆,我指的是能够以 100 kHz 频率运行的周期性计时器,而不是秒表计时器。
I would really appreciate some help with this,
我真的很感激这方面的一些帮助,
C4C
C4C
回答by Steve
Not possible. The fastest available timer on Windows is 1 ms (1 kHz). You'll need a real-time operating system or a dedicated controller. Even in a real-time OS, usually about 20 kHz is your max.
不可能。Windows 上最快的可用计时器为 1 ms (1 kHz)。您将需要一个实时操作系统或专用控制器。即使在实时操作系统中,通常最大频率约为 20 kHz。
回答by user189169
What exactly does this timer need to do? If it just needs to output a square wave between 25 kHz up to 100 kHz, then you will need extra hardware, but not outrageously expensive hardware. For example, look at this DT-340from Data Translation. It can go even faster than you need, and I believe it can even trigger an interrupt. Or this PCI 8255/8254 48 I/O.
这个计时器到底需要做什么?如果它只需要输出 25 kHz 到 100 kHz 之间的方波,那么您将需要额外的硬件,但不是非常昂贵的硬件。例如,看看这个来自 Data Translation 的DT-340。它可以比你需要的更快,我相信它甚至可以触发中断。或者这个PCI 8255/8254 48 I/O。
If you can afford USD 500 or so in your budget, there should be lots of hardware options. The actual programmable timer chip ought to be much cheaper than that, so if you are willing to roll your own circuit and interface it to the computer, you can probably do a lot better than USD 500.
如果您能负担得起 500 美元左右的预算,那么应该有很多硬件选择。实际的可编程定时器芯片应该比这便宜得多,所以如果你愿意自己制作电路并将其连接到计算机,你可能会做得比 500 美元好很多。
I once build a circuit around the Intel 8253 Programmable Interval Timer chip, which was used inside the original IBM PC for generating the beeps out of the internal speaker. It was hooked up to a 1.193182 MHz crystal and has a 16 bit divider. This chip has been around for decades. If you need better, I'm sure there have been improvements since then.
我曾经围绕 Intel 8253 Programmable Interval Timer 芯片构建了一个电路,该芯片在原始 IBM PC 中用于从内部扬声器发出蜂鸣声。它连接到一个 1.193182 MHz 的晶体上,并有一个 16 位的分频器。这种芯片已经存在了几十年。如果你需要更好的,我相信从那时起已经有了改进。
When I say that the 8253 (or 8254) chip inside a PC is used for driving the internal speaker, I'm not being complete. There is a lot more about the Intel 8253in Wikipedia. There it explains that output 0 is used to generate the clock interrupt, output 1 is used for DRAM refresh timing, and output 2 is used to drive the internal speaker.
当我说 PC 内部的 8253(或 8254)芯片用于驱动内部扬声器时,我说的并不完整。维基百科中有更多关于英特尔 8253的信息。那里解释了输出 0 用于生成时钟中断,输出 1 用于 DRAM 刷新时序,输出 2 用于驱动内部扬声器。
The first two clock outputs generate interrupts, which is what you want, but the above descriptions of what these outputs currently do ought to give you some pause to reflect that changing their behavior might possibly cause Windows XP to notice. The third output to the speaker, is mostly harmless to mess around with, but you would need to figure out some way to redirect that signal to something that generates and interrupt, if that's what you need.
前两个时钟输出生成中断,这正是您想要的,但是以上对这些输出当前所做的描述应该让您稍作停顿,以反映更改它们的行为可能会引起 Windows XP 的注意。扬声器的第三个输出,乱七八糟基本上是无害的,但是如果你需要的话,你需要想办法将该信号重定向到产生和中断的东西。
Probably Mach 3 is using the High Performance Event Timer(HPET), which according to hereis part of recent Intel chipsets. Timer 0 and 1 are used for 8254 emulation.
可能 Mach 3 正在使用高性能事件计时器(HPET),根据这里,它是最近英特尔芯片组的一部分。定时器 0 和 1 用于 8254 仿真。
"The ICH HPET Timer 2 interrupt may be routed to any one of the following IRQs: 11, 20, 21, 22, and 23, via the TIM2_CONF register. (Note: this register is called TIM3_CONF in Intel? ICH5.)"
“ICH HPET 定时器 2 中断可以通过 TIM2_CONF 寄存器路由到以下 IRQ 中的任何一个:11、20、21、22 和 23。(注意:该寄存器在 Intel 中称为 TIM3_CONF?ICH5。)”
回答by Jon Benedicto
You can get fairly close to 100 kHz polling using QueryPerformanceCounter in a loop on current CPUs.
您可以在当前 CPU 的循环中使用 QueryPerformanceCounter 获得相当接近 100 kHz 的轮询。
For example:
例如:
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;
}
}
}
In my test, I got approximately 92-98 kHz frequency, using this code to test it:
在我的测试中,我得到了大约 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;
}
}
Obviously, this code requires maximum CPU usage, so to get these results, a SMPmachine is a must. Additionally, bumping the process/thread priority to real-time helps as well.
显然,这段代码需要最大的CPU使用率,所以要得到这些结果,一台SMP机器是必须的。此外,将进程/线程优先级提高到实时也有帮助。
回答by Blessed Geek
When you say periodic timer, I am supposing you meant a pulse generator?
当您说定期计时器时,我假设您是指脉冲发生器?
Are you proposing a timer that would generate an event every 10 microsecond? I doubt you should do that.
您是否建议使用一个每 10 微秒生成一个事件的计时器?我怀疑你应该这样做。
You might try to program the audio output of the PC and interface that to the tool. You would have to silence/configure away PC sounds while your tool is operating to prevent frequencies that would be spurious to the pulse stream.
您可以尝试对 PC 的音频输出进行编程并将其连接到该工具。在您的工具运行时,您必须将 PC 声音静音/配置掉,以防止对脉冲流造成干扰的频率。
Have you considered a USB pulse generator? Or a cheap "USB sound card" dedicated to this operation?
您是否考虑过 USB 脉冲发生器?还是专用于此操作的廉价“ USB 声卡”?
回答by jball
Windows XP is not a realtime system, and I don't think there's a way to guarantee timers in the 10 microsecond range. You can look around in the Microsoft.Ccr.Corelibrary, I think it's the closest you'll get.
Windows XP 不是实时系统,我认为没有办法保证计时器在 10 微秒范围内。您可以在Microsoft.Ccr.Core库中环顾四周,我认为这是最接近的。
Edit: I found more information from Microsoft. According to the How To Use QueryPerformanceCounter to Time Codeknowledge-base article,
编辑:我从 Microsoft 找到了更多信息。根据How To Use QueryPerformanceCounter to Time Code知识库文章,
Function Units Resolution
---------------------------------------------------------------------------
Now, Time, Timer seconds 1 second
GetTickCount milliseconds approx. 10 ms
TimeGetTime milliseconds approx. 10 ms
QueryPerformanceCounter QueryPerformanceFrequency same
and that's in the context of an article that starts with the statement:
这是在以以下语句开头的文章的上下文中:
When timing code to identify performance bottlenecks, you want to use the highest resolution timer the system has to offer.
在对代码进行计时以识别性能瓶颈时,您希望使用系统必须提供的最高分辨率计时器。
Robert Harvey is right, the QueryPerformanceFrequency is in the tens of microseconds range, but I don't think there is a way to use it to precisely trigger events. I think that makes it a complete bust for a software only solution. Have you looked at any chips like the Arduino that are fairly cheap? From the Arduino forums, it looks like 10 microsecond precision is possible.
Robert Harvey 是对的,QueryPerformanceFrequency 在几十微秒范围内,但我认为没有办法使用它来精确触发事件。我认为这使它成为纯软件解决方案的彻底破产。你有没有看过像 Arduino 这样相当便宜的芯片?从Arduino 论坛看来,10 微秒的精度是可能的。
回答by shf301
The best you can do for timing in Windows is QueryPerformanceFrequency/QueryPerformanceCounter. The lowest frequency I've seen those produce is 1.1 MHz, so that would give sufficient frequency.
您可以在 Windows 中为计时做的最好的事情是QueryPerformanceFrequency/ QueryPerformanceCounter。我见过的最低频率是 1.1 MHz,因此可以提供足够的频率。
But even with that it as the other answers pointed out, it won't work. Window's isn't a real time operating system, it doesn't make any timing guarantees. There is no way to make sure that your code is running every 1 us (for 100 kHz), since Windows will swap away to other processes or kernel code.
但即使像其他答案所指出的那样,它也行不通。Window 不是实时操作系统,它不提供任何时间保证。无法确保您的代码每 1 us(对于 100 kHz)运行一次,因为 Windows 将交换到其他进程或内核代码。
You'll have to go with some sort of external hardware solution to get that kind of timing.
您必须使用某种外部硬件解决方案才能获得这种计时。
回答by DaMacc
Maybe you could use some of this:
也许你可以使用其中的一些:
http://www.geisswerks.com/ryan/FAQS/timing.html
http://www.geisswerks.com/ryan/FAQS/timing.html
Look for QueryPerformanceFrequency, but maybe the other solutions might be useful.
寻找 QueryPerformanceFrequency,但也许其他解决方案可能有用。
回答by Steve
Alright, after reading the Mach 3 documentation (which is well-written, informative, and even funny), I think I see what is going on. First, realize that there is a difference between having a user-space event trigger at a high frequency and having a kernel interrupt routine. The kernel interrupt routine must be fast, and thus not contain very much logic, so normally we say that it's impossible to have a generalized call-back in your program that can respond to events at frequencies > 1 kHz. Furthermore, operating systems use the local timers for the schedule, which decides when user programs can run, and typically the scheduler speed is not more than 1 kHz, therefore it's impossible to write a user-space program that responds faster than this.
好吧,在阅读了 Mach 3 文档(它写得很好,内容丰富,甚至很有趣)之后,我想我明白了发生了什么。首先,要意识到用户空间事件以高频率触发和内核中断例程是有区别的。内核中断例程必须很快,因此不包含太多逻辑,所以通常我们说在您的程序中不可能有一个可以响应频率 > 1 kHz 的事件的通用回调。此外,操作系统使用本地计时器进行调度,这决定了用户程序何时可以运行,并且调度程序的速度通常不超过 1 kHz,因此不可能编写响应速度比这更快的用户空间程序。
However, in thiscase, you don't need to have complex user-space logic responding at that speed, since the goal is only to modulate an outputpin at a high frequency in order to produce a PWM signal. It mightbe feasible to create a kernel interrupt handler for the APICwhich has high priority and is triggered at high frequency, if it onlydoes very simple things such as toggling an output pin on the parallel port.
但是,在这种情况下,您不需要复杂的用户空间逻辑以该速度响应,因为目标只是以高频调制输出引脚以产生 PWM 信号。这可能是建立在一个内核中断处理程序可行的APIC具有高优先级,触发以高频率,如果只是做很简单的事情,如并行端口触发输出引脚。
So, if you wish to do this, I suggest you read up on kernel programming and using the APIC, and you might be achieve something useful to you. However, some words of advice:
所以,如果你想这样做,我建议你阅读内核编程和使用 APIC,你可能会得到一些对你有用的东西。但是,一些忠告:
- Distributing a driver with your software is a pain in the ass both for you as a developer and for your users who must install a driver which may or may not work. (Hardware is finicky and if your solution depends on very specific computer configurations your mileage may vary.)
- Having such a high-frequency interrupt running will bog down the computer and make things very hot. You may get stalls or blue screens. Be prepared to deal with this kind of annoyances.
- If you succeed in toggling an LPT pin in response to an APIC timer, I suggest hooking up an acquisition card or digital oscilloscope to measure not only the frequency, but also the jitter. Any software-timed signal tends to have more jitter, so watch out for this. Jitter effectively increases the noise in your signal. Additionally, jitter tends to remain constant, so at low frequencies it may not be a problem but at high frequencies the jitter may become a large percentage of your total period, significantly decreasing the signal-to-noise ratio.
- If your goal is really to just produce a PWM or pulse signal to control stepper motors, having a bit of out-board hardware is really the best way. I'll back this up with a few sub-points:
- Firstly, if you read the Mach 3 docs, they contain a section on how to electrically isolate your computer's parallel port in case of electrical issues. In other words, even if you use the built-in LPT port, some external hardware is recommended anywaysjust for safety. If you're going to do this, you may as well include a $2 timer chip.
- Since you are generating a high-frequency signal but only controllingthis signal at a lower rate, there is no need to bog down the computer with the task of actually producing the signal itself---this is what timer chips are for.
- A $5 low-cast AVR microcontroller can talk to the computer over the USB port and generate a PWM signal. This is a far less expensive solution than buying a $100 board, but it depends on your needs. (Like how many signals, etc.) For example, buy a Teensyand just plug it into your computer's USB port, and write a 5-line program to control the 7 provided PWM outputs. Done, and done!
- If you search online for "PWM parallel", you'll find lots of tutorials on how to generate PWM signals using the parallel port, but notice that 99% of them are actually tutorials on how to control an external timer chip attached to the parallel port, nothow to generate the actual PWM signal directly.
- 随您的软件分发驱动程序对于您作为开发人员和必须安装可能有效也可能无效的驱动程序的用户来说都是一件痛苦的事情。(硬件很挑剔,如果您的解决方案依赖于非常特定的计算机配置,您的里程可能会有所不同。)
- 运行如此高频率的中断会使计算机陷入困境并使事情变得很热。您可能会遇到摊位或蓝屏。准备好应对这种烦恼。
- 如果您成功切换 LPT 引脚以响应 APIC 计时器,我建议连接采集卡或数字示波器,不仅可以测量频率,还可以测量抖动。任何软件定时信号往往有更多的抖动,所以要注意这一点。抖动有效地增加了信号中的噪声。此外,抖动往往保持恒定,因此在低频下可能不是问题,但在高频下,抖动可能会占整个周期的很大一部分,从而显着降低信噪比。
- 如果您的目标真的只是产生 PWM 或脉冲信号来控制步进电机,那么使用一些外置硬件确实是最好的方法。我将用几个子点来支持这一点:
- 首先,如果您阅读 Mach 3 文档,它们包含有关如何在出现电气问题时对计算机的并行端口进行电气隔离的部分。换句话说,即使您使用内置的 LPT 端口,为了安全起见,无论如何还是推荐一些外部硬件。如果您打算这样做,您还可以包含一个 2 美元的计时器芯片。
- 由于您正在生成高频信号,但仅以较低的速率控制该信号,因此无需让计算机陷入实际生成信号本身的任务——这就是定时器芯片的用途。
- 一个 5 美元的低价 AVR 微控制器可以通过 USB 端口与计算机通信并生成 PWM 信号。这比购买 100 美元的电路板便宜得多,但这取决于您的需求。(比如多少信号等)例如,买一个Teensy,把它插到你电脑的USB端口,写一个5行程序来控制7个提供的PWM输出。大功告成,大功告成!
- 如果您在网上搜索“PWM 并行”,您会发现很多关于如何使用并行端口生成 PWM 信号的教程,但请注意,其中 99% 实际上是关于如何控制连接到并行端口的外部定时器芯片的教程端口,而不是如何直接生成实际的 PWM 信号。
Finally, here are some documents you might find useful:
最后,这里有一些您可能会觉得有用的文档:
回答by Joe Z
While I suspect meomaxy's solution is the best...
虽然我怀疑 meomaxy 的解决方案是最好的......
If you need high resolution differential timing, intel has some code herethat claims accuracy down to the nanosecond. (There's also a good discussion of general differential timing possibilities).
如果您需要高分辨率差分计时,英特尔在此处提供了一些代码,声称精度低至纳秒。(还有一个关于一般差分时序可能性的很好的讨论)。
回答by SingleNegationElimination
A basic problem with using a PC for motion control, without dedicated hardware, is the data rate of the various outputs built in to most PC's. If your customers don't have the budget for the high end motion controller you mention, then they simply aren't going to have access to 100 kHz signals.
在没有专用硬件的情况下使用 PC 进行运动控制的一个基本问题是大多数 PC 内置的各种输出的数据速率。如果您的客户没有您提到的高端运动控制器的预算,那么他们根本无法访问 100 kHz 信号。
The I/Ocontrollers for every port provides some kind of buffering so that you will get smooth results out of them. This largely serves the purpose of alleviating software from the need to 'bit-bang' those signals, and also makes I/O frequency much more stable.
每个端口的I/O控制器都提供某种缓冲,以便您从中获得平滑的结果。这在很大程度上有助于减轻软件对这些信号的“位冲击”需求,并使 I/O 频率更加稳定。
The downside is the buffering will probably introduce some latency in the system, which may impact the performance closed loop control circuit with the control in software. Another downside is this limits your frequency options. One of the fastest I/O options on a PC that doesn't provide high end flow control like USB or SATA is actually the audio port, but that is limited to 64 kHz or 44 kHz on most systems.
缺点是缓冲可能会在系统中引入一些延迟,这可能会影响具有软件控制的闭环控制电路的性能。另一个缺点是这会限制您的频率选择。不提供 USB 或 SATA 等高端流量控制的 PC 上最快的 I/O 选项之一实际上是音频端口,但在大多数系统上仅限于 64 kHz 或 44 kHz。
If the audio port is an option for you, then you don't need to worry about timing at all, Just make sure you set the frequency properly, and produce your signal as you would otherwise.
如果音频端口是您的选择,那么您根本不需要担心时间问题,只需确保正确设置频率,并像其他方式一样产生信号。
If you need to use a digital signal, the parallel and serial ports work in a similar fashion , but at a lower maximum speed.
如果您需要使用数字信号,并行端口和串行端口的工作方式类似,但最大速度较低。
EDITHmm... It seems parallelports are a bit faster than they used to be. An enhanced parallel Port (EPP) capable machine can give you up to 2mbits of of binary bandwidth, which should be well within the reach of your goal. However, due to the way the parallel interface works, data speed is dependent on the peripheral, rather than some predefined buffer speed. Essentially, the peripheral acknowledges that it has recieved data, or that it is ready to send data, for each byte transferred.
编辑嗯...似乎并行端口比以前快一点。支持增强型并行端口 (EPP) 的机器可以为您提供高达 2 兆位的二进制带宽,这应该完全可以达到您的目标。然而,由于并行接口的工作方式,数据速度取决于外设,而不是一些预定义的缓冲速度。本质上,对于传输的每个字节,外设确认它已接收到数据或准备发送数据。
This isn't too bad, though, because a simple, clock driven peripheral is easy to set up.
不过,这还不错,因为一个简单的、时钟驱动的外设很容易设置。
Additionally, data cannot flow in both directions at the same time, data coming from the peripheral will cause the stream of data from the host PC to block. A possible way to circumvent that is to just arrange to have two parallel ports available, or arrange for the peripheral to limit its own data transmissions to every other cycle.
此外,数据不能同时双向流动,来自外设的数据会导致来自主机 PC 的数据流阻塞。一种可能的规避方法是只安排两个并行端口可用,或者安排外设将其自己的数据传输限制为每隔一个周期。
I/O on a such a port is normally interrupt driven. Besides a few error states, the most useful interrupts are generated when the input or output FIFO's reach a certain level. You can use this interrupt to write (or read) new data to the port. The threshold can be set to anywhere from 1 to 16 bytes. You should carefully test (with a logic analyzer/oscilloscope) that data is actually flowing at the expected speed, with the expected rate. You could do this almost as well in software using a QueryPerformanceCounter.
此类端口上的 I/O 通常是中断驱动的。除了一些错误状态外,最有用的中断是在输入或输出 FIFO 达到某个级别时生成的。您可以使用此中断向端口写入(或读取)新数据。阈值可以设置为 1 到 16 字节之间的任何值。您应该(使用逻辑分析仪/示波器)仔细测试数据实际上以预期的速度和预期的速率流动。在使用QueryPerformanceCounter 的软件中,您几乎也可以做到这一点。