Windows XP中的100 kHz定时器频率

use*_*239 6 windows winapi

有一个流行的业余爱好级数控机床控制在Windows XP中运行,它有一个定时器,用户可选择的速率范围从25 kHz到100 kHz.

碰巧我也建造了数控机床控制器,但我一直在使用我用上层程序控制的Galil Motion Control Inc. DMC1800系列DSP运动控制器板.有些潜在的买家无法承受这种配置,所以我写了另一个我打算作为基于软件的控制包提供的应用程序.应用程序完成,但我没有计时器.(MS多媒体定时器是不够的.)

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

我真的很感激这方面的帮助,

C4C

Ste*_*eve 10

不可能.Windows上最快的可用计时器是1毫秒(1千赫).您需要一个实时操作系统或专用控制器.即使在实时操作系统中,通常大约20 kHz也是最大值.


use*_*169 9

这个计时器究竟需要做什么?如果它只需要输出25 kHz到100 kHz之间的方波,那么您将需要额外的硬件,但不需要非常昂贵的硬件.例如,从数据转换中查看此DT-340.它可以比你需要的更快,我相信它甚至可以触发中断.还是这个PCI8254分之825548个I/O.

如果您的预算可以支付500美元左右,那么应该有很多硬件选择.实际的可编程定时器芯片应该比它便宜得多,所以如果你愿意自己编写电路并将其连接到电脑上,你可能会比500美元做得更好.

我曾经在英特尔8253可编程间隔定时器芯片周围构建一个电路,该芯片在原始IBM PC中用于产生内部扬声器的蜂鸣声.它连接到1.193182 MHz晶振并具有16位分频器.这款芯片已经存在了几十年.如果你需要更好,我相信从那时起就有了改进.

当我说PC内部的8253(或8254)芯片用于驱动内置扬声器时,我并不完整.关于维基百科中的英特尔8253还有很多其他内容.在那里它解释了输出0用于产生时钟中断,输出1用于DRAM刷新定时,输出2用于驱动内部扬声器.

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

可能Mach 3正在使用高性能事件定时器(HPET),根据这里的最新英特尔芯片组.定时器0和1用于8254仿真.

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

  • 那么实际劫持PC的内部扬声器输出并通过"嘟嘟"它们来创建所需的信号呢? (2认同)

Jon*_*cto 7

您可以在当前CPU的循环中使用QueryPerformanceCounter进行相当接近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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的测试中,我的频率大约为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;
    }
}
Run Code Online (Sandbox Code Playgroud)

显然,这段代码需要最大的CPU使用率,因此要获得这些结果,必须使用SMP机器.此外,将进程/线程优先级提升为实时也有帮助.