继续提问有关时钟中断的问题
#include <stdio.h>
#include <dos.h>
#include <conio.h>
#define VK_ESC 0x11b /* Escape key */
#define TIMER 0x1c /* 时钟中断的中断号 */
int TimerCounter=0; /* 计时变量,每秒钟增加18。 */
/* 指向原来时钟中断处理过程入口的中
断处理函数指针(句柄) */
void interrupt ( *oldhandler)();
/* 新的时钟中断处理函数 */
void interrupt newhandler( )
{
/* increase the global counter */
TimerCounter++;
/* call the old routine */
oldhandler();
}
/* 设置新的时钟中断处理过程 */
void SetTimer(void interrupt (*IntProc)())
{
oldhandler=getvect(TIMER);
disable(); /* 设置新的时钟中断处理过程时,禁止
所有中断 */
setvect(TIMER,IntProc);
enable(); /* 开启中断 */
}
/* 恢复原有的时钟中断处理过程 */
void KillTimer()
{
disable();
setvect(TIMER,oldhandler);
enable();
}
void main(void)
{
int key,time=0;
SetTimer(newhandler); /* 修改时钟中断 */
for (;;)
{
if (bioskey(1))
{
key=bioskey(0);
if (key==VK_ESC) /* 按escape键提前退出程序 */
{
printf("User cancel!\n");
break;
}
}
if (TimerCounter>18) /* 1秒钟处理一次 */
{
/* 恢复计时变量 */
TimerCounter=0;
time++;
printf("%d\n",time);
if (time==10) /* 10秒钟后结束程序 */
{
printf("Program terminated normally!\n");
break;
}
}
}
KillTimer(); /* 恢复时钟中断 */
}
我的理解,原来的中断处理0x1c是空的,不做任何处理。修改后的newhandler,是每次处理都
TimeCounter自加。我理解的程序流程是这样的:
1,首先修改中断服务程序,原来是每秒18.2次中断,每次什么都不做。用setvect函数修改中断服务程序
为newhandler,即每次中断时TimeCounter++,这样TimerCounter会随着时间每秒增加18左右。
2,for语句判断:(1),是否按下ESC键,按下便退出;(2),检查TimeCounter是否增至18,真便输出字
符。
3,恢复0x1c;
不知道我的理解是否正确,请大虾们指正。还有不明白的地方:
1。newhandler()里面为什么TimeCounter++后要执行?oldhandler?为什么要返回老的中断呢?新的中断
不也是每秒18次么?
2。killtime不执行结果会是怎样呢?
3。for多少时间执行一次呢?
问题点数:30、回复次数:2Top
1 楼s38335320(恶魔踏着键盘来)回复于 2005-01-30 01:51:09 得分 0
沉了,顶下Top
2 楼zxdniu(先知)回复于 2005-01-30 02:01:22 得分 30
这3个问题都是基于中断得,所以先得明白什么是中断:
中断的原理
当从外部的硬件或者处理器向CPU发出异常信号的时候,中断就会发生了。CPU通过传递执行流来响应中断服务程序,其中CPU响应的过程是这样的:首先对事件进行处理,处理之后再返回中断代码。
ISR本质上是一个不设任何参数和不返回任何值得函数。但是,和一般的规则函数不一样,你几乎可以在任何情况下调用ISR函数,因此在调用的时候要特别小心,特别是登陆和退出ISR函数时,要严格按照特定的执行规则和执行顺序来执行。
登陆
保存登陆和其它一些中断处理过程中可能会改变的执行代码。
执行中断处理主体之前,要设置好CPU的系统环境。
退出
恢复登陆和其它一些保存的相关信息。
执行一个专门的“从中断返回”的指令来返回到中断的代码中去。
规则的函数没有这些专门的登陆和退出代码序列,因此你不能称之为ISRs。
Top




