crowfrog
驱动牛犊
驱动牛犊
  • 注册日期2002-04-30
  • 最后登录2002-05-21
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:2400回复:9

一个关于DOS下串口和中断的问题。SOS!

楼主#
更多 发布于:2002-04-30 11:58
在dos环境下,BorlandC++编译,程序驻留内存(keep函数)。
用一个omc3口的设备。当com3口使用IRQ3,IRQ4的中断时,
一切正常,此时我用的中断码为0xb,0xc,用函数setvect()后
, 我的中断处理函数会得到调用
  
但是换成IRQ8至IRQ15的中断就不行了,中断函数完全没有反应,
我用的中断码是0x70至0x77,
中断码错了吗?还是说0x70以上的中断码用函数servect不管用。

后来用hwinfo查看,说是IRQ10(比如在bios中规定com3口用的
是IRQ10)没有分配,seems to free。为什么?
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2002-04-30 14:45
if(yourIRQ >= 8) Vect = yourIRQ + 0x68;
else Vect = yourIRQ + 8;
oldVect = getvect(Vect);
setvect(yourISR, Vect);
btIRQ = yourIRQ >= 8 ? (yourIRQ - 8) : yourIRQ;
outp(0x21, inp(0x21) & 0xfb);     // enable 8259-1 IRQ2
outp(0xa1, inp(0xa1) & (~btIRQ)); // enable 8259-2 IRQ
bh_zhouqian
驱动牛犊
驱动牛犊
  • 注册日期2002-04-19
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望2点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-04-30 17:57
也谈“DOS下的中断”
楼上的那位老兄的话给我了很大的启示,估计我的并口中断也可以调通了!
顺便问个问题:TC里的函数enable();disable();
同上面说的outportb(0x21,inportb(0x21)&0xfb);
有什么区别?
crowfrog
驱动牛犊
驱动牛犊
  • 注册日期2002-04-30
  • 最后登录2002-05-21
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-04-30 22:44
我用的是中断11,中断向量0x73,enableports的源代码如下:

    unsigned char B;
    int_old = getvect( intvect );
    disable();

    B = inportb( port_adr+4 ) | 0x0f;
    outportb( port_adr+4, B );
    B = inportb( port_adr+1 ) | 0x01;
    outportb( port_adr+1, 0x01 );

    B = inportb(0x21) & 0xFB; //打开主片IRQ2
    outportb(0x21, B );
    B = inportb(0xA1) & 0xF7; //打开从片IRQ11
    outportb( 0xA1, B );

    setvect( intvect, int_com );  //int_com是中断处理函数
    enable();

但是仍然不能取得com3口设备的数据,是否我的程序有问题,还是11的中断没有分配给com3?如果是的话我怎么才能分配?
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
地下室#
发布于:2002-05-02 17:30
disable()是禁止所有的中断。
outportb(0x21,inportb(0x21)&0xfb); 是打开int2。
8259的控制寄存器地址是0x21,8259-2是挂在8259-1的int2上的,所以要打开>=8的中断,要先打开int2。
crowfrog老兄,~(11-8) == 0xf7????
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
5楼#
发布于:2002-05-02 17:33
补充一下:
btIRQ = 0x1 << (yourIRQ % 8);
outp(0x21, inp(0x21) & 0xfb);     // enable 8259-1 IRQ2
outp(0xa1, inp(0xa1) & (~btIRQ)); // enable 8259-2 IRQ
是我错了 :(
crowfrog
驱动牛犊
驱动牛犊
  • 注册日期2002-04-30
  • 最后登录2002-05-21
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2002-05-03 14:56
是啊,我现在是不知道为什么还是不能截取到com3口的11中断,
如果我给它分配的是4的中断,我的程序就一切正常了。
遗憾的是,在有些机器上bios给com3分配中断4根本就没有用,
至少我现在需要的那种机型没用,bios是phoenix的,Note bios 4.0
 :(
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
7楼#
发布于:2002-05-04 13:45
我想应该不是驱动的问题了吧。
mjm_d
驱动牛犊
驱动牛犊
  • 注册日期2004-05-21
  • 最后登录2004-11-11
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-07-05 13:32
disable() 好像 是cli的意思
enable()是sti
不知道对不对
zhenlongyang
驱动小牛
驱动小牛
  • 注册日期2004-10-28
  • 最后登录2010-07-26
  • 粉丝1
  • 关注0
  • 积分729分
  • 威望100点
  • 贡献值0点
  • 好评度66点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-10-31 01:19
告诉你一种方法,保准能解决问题:
1,首先要对8259可编程中断控制器进行正确的初始化,不能使用系统启动时默认的初始化方式(因为要使用第二片8259)。
2,开8259的中断允许,这和enable()无关,请仔细查阅8259手册。
3,enable(),这个函数的对应intel汇编指令为sti,意思是要CPU响应8259发来的硬件中断,同样,disable()即为cli,意思是要CPU不响应一切可屏蔽中断(它包括所有8259产生的中断信号)。这两个函数完全是针对CPU的,与8259毫无关系,更详细的说:如果对8259发命令字使其开中断,但是同时执行disable()指令,则8259能够产生中断请求信号但是CPU不会去响应它,当然也就不会转到中断服务程序中去;反过来,关闭8259的中断信号产生而同时执行enable()指令,则8259将不向CPU发送中断请求信号,这时尽管允许CPU响应中断请求,但是由于没有中断请求发来,那么自然也就不会去执行中断功能了。
游客

返回顶部