strongsir
驱动牛犊
驱动牛犊
  • 注册日期2002-07-27
  • 最后登录2002-08-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2594回复:11

DOS下的定时中断程序如何开发?

楼主#
更多 发布于:2002-08-01 21:17
请教各位大虾,我要用C语言编写一个定时中断服务程序,但该如何编写定时中断程序(中断频率较高,比如4096HZ)?
magicx
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2014-08-18
  • 粉丝1
  • 关注0
  • 积分-14分
  • 威望13点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-08-01 21:22
请教各位大虾,我要用C语言编写一个定时中断服务程序,但该如何编写定时中断程序(中断频率较高,比如4096HZ)?


dos 下的这样高。。。。。。难。



[color=red]大头鬼! :P[/color]
jhp
jhp
驱动牛犊
驱动牛犊
  • 注册日期2001-10-05
  • 最后登录2009-09-26
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-08-01 22:09
要用C写中断程序最好用这个:
void    (_interrupt _far *oldTimer)(void);//老的int8
截取int8的中断向量
void installTimer()
{
oldTimer=_dos_getvect(0x8);
_disable();
_dos_setvect(0x8,newInt8);
_enable();
}

void restoreTimer()
{
_disable();
_dos_setvect(0x8,oldTimer);
_enable();
}

//新的中断程序
void _interrupt far newInt8()
{
....在这里面加你的代码,注意变量最好是用near 来声明,否则数据段会在外面

....
(*oldTimer)();
}
以上是用microsoft c 6.0
TC2.0和MSC6.0的函数不大一样,但都有对应的
magicx
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2014-08-18
  • 粉丝1
  • 关注0
  • 积分-14分
  • 威望13点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-08-01 23:33
要用C写中断程序最好用这个:
void    (_interrupt _far *oldTimer)(void);//老的int8
截取int8的中断向量
void installTimer()
{
oldTimer=_dos_getvect(0x8);
_disable();
_dos_setvect(0x8,newInt8);
_enable();
}

void restoreTimer()
{
_disable();
_dos_setvect(0x8,oldTimer);
_enable();
}

//新的中断程序
void _interrupt far newInt8()
{
....在这里面加你的代码,注意变量最好是用near 来声明,否则数据段会在外面

....
(*oldTimer)();
}
以上是用microsoft c 6.0
TC2.0和MSC6.0的函数不大一样,但都有对应的


在dos下的int 8h 有这样高的频率?

“中断频率较高,比如4096HZ”

 :(
[color=red]大头鬼! :P[/color]
lonkiss
驱动牛犊
驱动牛犊
  • 注册日期2002-01-15
  • 最后登录2004-07-28
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-08-02 12:05
INT8每秒钟可以产生18.2次
不可能达到你要求的4096Hz
要达到这么高的频率,可能需要自己做一个硬件,来产生这么高频率的中断,然后再用magicx说的那样接管那个中断。
我的真名就叫-龙旗
gung
驱动中牛
驱动中牛
  • 注册日期2001-06-10
  • 最后登录2008-04-21
  • 粉丝0
  • 关注0
  • 积分25分
  • 威望3点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-08-03 09:35
好像可以通过写主板上8253的寄存器(不记得地址了)来加快int8或int1c中断的发生频率,不过不知能不能这么高,以前的游戏工具如g3x就是这样来加快/减慢游戏速度的
zjg1603
驱动牛犊
驱动牛犊
  • 注册日期2002-06-27
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
6楼#
发布于:2002-08-03 10:19
完全可以实现。我以前曾编写过这样的采集程序,中断频率为8k。

int8 的时钟频率为1193180,系统作为时钟使用时,每秒产生18.2次中断。可以设置这个时钟的计数值来产生不同频率的中断。下面是我在BC++3.1中的部分代码。
float CTestBase::clockFrequency = 1193180.f;
void CTestBase::realtimerInit(unsigned int ccounter,void interrupt (far *realtimer_int_server)(__CPPARGS))
{
disable();                              /* 禁止中断响应 */
outportb(0x43,0x36);                    /* 重新设置计数器0 */
             /* 保护系统日历计数 */
pccad=(long *)MK_FP(0x0040,0x006c);
counterValue=*pccad;
outportb(0x40,lo(ccounter));            /* 设置实时计时单位 */
outportb(0x40,hi(ccounter));
tatick=(float)ccounter/1.193180f;
cticks=0;                               /* TICKS 计数器初始化 */
intVector=getvect(0x1c);              /* 保存并设置中断向量 */
setvect(0x1c,realtimer_int_server);
enable();                               /* 使能中断响应 */
}
上面程序为接管INT8的程序代码。ccounter为中断频率,realtimer_int_server为中断函数的指针,cticks为实际中断的次数,counterValue为当前系统时钟计数值。

void CTestBase::realtimerExit(void)
{
disable();                              /* 禁止中断响应 */
outportb(0x21,0);
/* 保护系统日历计数 */
counterValue+=(long)cticks*(long)tatick*18.2/1000000L;
*pccad=counterValue;
outportb(0x43,0x36);                    /* 恢复计数器0 */
outportb(0x40,0);                       /* 恢复系统计时单位 */
outportb(0x40,0);
setvect(0x1c,intVector);
enable();                               /* 使能中断响应 */
}

如果有问题可以给我联系。E-MAIL:zjg1603@sina.com
ldljlzw
驱动中牛
驱动中牛
  • 注册日期2002-03-16
  • 最后登录2014-01-02
  • 粉丝1
  • 关注0
  • 积分1021分
  • 威望372点
  • 贡献值0点
  • 好评度187点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2002-08-03 12:45
是的,可以设置内部计数器的值来改变INT8的中断频率,但一定要在你的新INT8中要很的处理原来INT8的中断例程,要不系统时钟就不对了!!!!!!!
strongsir
驱动牛犊
驱动牛犊
  • 注册日期2002-07-27
  • 最后登录2002-08-04
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2002-08-04 20:28
非常感谢zjg1603,通过你的帮助,我已可以实现中断频率很高的定时中断程序。

但是,还不清楚其中的一些具体的实现的道理。比如:realtimerInit()中的下列语句。

outportb(0x43,0x36); /* 重新设置计数器0 */
/* 保护系统日历计数 */
pccad=(long *)MK_FP(0x0040,0x006c);
counterValue=*pccad;
outportb(0x40,lo(ccounter)); /* 设置实时计时单位 */
outportb(0x40,hi(ccounter));
tatick=(float)ccounter/1.193180f;
cticks=0; /* TICKS 计数器初始化 */

请问从那些书籍上可以得到这方面的知识,请指教。
chnh
驱动小牛
驱动小牛
  • 注册日期2002-04-09
  • 最后登录2004-02-16
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2002-08-04 21:05
实时时钟就是主板上保存BIOS信息的CMOS芯片,在286上一块MC146818芯片,其地址口为70H,数据口为71H,升级后的主板应该与之兼容,修改实时钟只需对MC146818编程即可
chnh
驱动小牛
驱动小牛
  • 注册日期2002-04-09
  • 最后登录2004-02-16
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2002-08-04 21:56
对不起,你上面的程序是对8253编程的,40H是中断控制器的地址,
43H是8253的地址,不过,用实时钟也能实现你的要求,在286就能实现8K的速率,你找一本286的系统原理书上有详细描述
zjg1603
驱动牛犊
驱动牛犊
  • 注册日期2002-06-27
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
11楼#
发布于:2002-08-04 23:54
在很多DOS编程的书上都有,你可以查一下。
非常感谢zjg1603,通过你的帮助,我已可以实现中断频率很高的定时中断程序。

但是,还不清楚其中的一些具体的实现的道理。比如:realtimerInit()中的下列语句。

outportb(0x43,0x36); /* 重新设置计数器0 */
/* 保护系统日历计数 */
pccad=(long *)MK_FP(0x0040,0x006c);
counterValue=*pccad;
outportb(0x40,lo(ccounter)); /* 设置实时计时单位 */
outportb(0x40,hi(ccounter));
tatick=(float)ccounter/1.193180f;
cticks=0; /* TICKS 计数器初始化 */

请问从那些书籍上可以得到这方面的知识,请指教。
游客

返回顶部