seant
驱动牛犊
驱动牛犊
  • 注册日期2001-07-05
  • 最后登录2005-05-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:3256回复:5

Windows下对中断的实时处理?

楼主#
更多 发布于:2001-07-27 11:14
我正在做一个红外图象采集卡的软件,要求在中断到来后,连续均匀得采集256个数据。我想请教如何从软件上控制采样时间间隔,使其均匀(时间间隔约50us~80us)?
我现在是用的空循环方式,但效果很差。
dazzy
驱动中牛
驱动中牛
  • 注册日期2001-03-23
  • 最后登录2008-08-12
  • 粉丝1
  • 关注0
  • 积分0分
  • 威望10点
  • 贡献值1点
  • 好评度10点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2001-07-27 14:02
有两种方法比较精确的实现延时:
1.用KeQueryPerformanceCounter
     LARGE_INTEGER tics1,tics2,freq;
     unsigned int n_delay=0;//微秒
     tics1 =KeQueryPerformanceCounter(&freq);
   do{
     tics2 = KeQueryPerformanceCounter(&freq);
     n_delay =
(tics2.QuadPart - tics1.QuadPart)*1000000/freq.QuadPart;  
    }while(n_delay<80);
定时精度高(对于较短的延时(比如延时为2微秒),效果不佳)
2.用rdtsc指令//用于奔腾机
#define RDTSC __asm _emit 0x0f __asm _emit 0x31
unsigned int tsc1,tsc2,tsc3,tsc4,n_delay;
n_delay= 0;

_asm RDTSC;
_asm mov tsc1,eax;
_asm mov tsc2,edx;

do{
_asm RDTSC;
_asm mov tsc3,eax;
_asm mov tsc4,edx;

_asm mov eax,tsc3;
_asm sub eax,tsc1;              
_asm mov tsc3,eax;

_asm mov eax,tsc4;              
_asm sbb eax,tsc2;
_asm mov tsc4,eax;

_asm mov eax,tsc3;
_asm mov edx,tsc4;

_asm mov ecx,freq;//freq为计算机时钟
_asm div ecx;
_asm mov n_delay,eax;

}while(n_delay<80);
精度更高(可以精确到1微秒以上)
3.另外,KeStallExecutionProcessor的延时效果不佳,用KeStallExecutionProcessor进行延时,指定延时50微秒,结果实际延时为200微秒,害得我查了好久才出正确结果。

[dazzy 编辑于 2001-07-28 08:10]
skysky
驱动小牛
驱动小牛
  • 注册日期2001-07-18
  • 最后登录2003-06-03
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2001-07-27 17:07
也可以试试
NTSTATUS
  KeDelayExecutionThread(
  IN KPROCESSOR_MODE  WaitMode,
  IN BOOLEAN  Alertable,
  IN PLARGE_INTEGER  Interval
  );
会将当前线程挂起interval长的时间。
其中Interval,即延时时间是以100ns为单位的。
具体使用看2000DDK文档。

以德服人,以德服人
dazzy
驱动中牛
驱动中牛
  • 注册日期2001-03-23
  • 最后登录2008-08-12
  • 粉丝1
  • 关注0
  • 积分0分
  • 威望10点
  • 贡献值1点
  • 好评度10点
  • 原创分0分
  • 专家分0分
地板#
发布于:2001-07-28 08:09
skysky兄台:
以前我也用过KeDelayExecutionThread,但是经过测试,
它的延时精度不但不准确,
而且每次延时的时间长短不一(也许是我用的有问题)。
以下是我的测试代码(在我的p3 800 机器上测试):
LARGE_INTEGER internal;
       internal.QuadPart =-100;//10微秒
#define RDTSC __asm _emit 0x0f __asm _emit 0x31
unsigned int tsc1,tsc2,tsc3,tsc4;
unsigned int delay;
asm RDTSC;
_asm mov tsc1,eax;
_asm mov tsc2,edx;

KeDelayExecutionThread(KernelMode,FALSE,&internal);//延时10微秒

_asm RDTSC;
  _asm mov tsc3,eax;
_asm mov tsc4,edx;

_asm mov eax,tsc3;
_asm sub eax,tsc1;
_asm mov tsc3,eax;

_asm mov eax,tsc4;
_asm sbb eax,tsc2;
_asm mov tsc4,eax;

_asm mov eax,tsc3;
_asm mov edx,tsc4;

_asm mov ecx,800;//800为计算机时钟(800M)
_asm div ecx;

_asm mov delay,eax;//eax里放的是微秒数

DbgPrint("The delay is %d \n",delay);
另外,我有一个问题想不明白:
ddk的内核定时器等有100ns要求的,它们的硬件基础是什么?
在实际应用中我觉得不太准确。
wzhdev
驱动牛犊
驱动牛犊
  • 注册日期2001-09-24
  • 最后登录
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2001-12-30 09:07
你应该采用采集板硬件定时,软件无法实现高精度定时
xeonjohn
驱动牛犊
驱动牛犊
  • 注册日期2001-07-25
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
5楼#
发布于:2001-12-30 13:19
wzxdev说的对,由于操作系统的关系,软件很难实现你的功能,建议你买一块计数板,或用机器8254。
我思故我在
游客

返回顶部