rudolf
驱动小牛
驱动小牛
  • 注册日期2002-10-09
  • 最后登录2006-04-25
  • 粉丝0
  • 关注0
  • 积分81分
  • 威望9点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
阅读:1505回复:12

频繁IRQ硬件中断对计算、显示产生影响的问题。

楼主#
更多 发布于:2002-11-28 17:14
看来看去还是应该到这里来问:

硬件环境:386工控主板(44M),20KHZ方波信号源。
软件环境:DOS6.22,BC31。
问题描述:
写了一个程序,接收20K的IRQ硬件中断,在中断中进行一些比较、计数等操作。主程序将计数得到的数据进行再计算、比较然后显示出来。
现象:中断计数没问题,但是主程序中的计算和显示工作量比较大,造成应该显示“00.00”的时候会显示一些其它的数据如“1111.11”。
也就是说某一个全局变量data1在程序中通过公式FUNCTION1(data1)得到data2,然后再显示data2。
现在程序中data1的值没有发生变化,但是显示出来的data2却会变


不知道有没有讲清楚,大家有没有遇到过这种问题?搞了一天有没搞定,所以来请教大家。
靠天靠地靠父母,不如靠自己。
Gong_XG
驱动太牛
驱动太牛
  • 注册日期2002-10-01
  • 最后登录2010-11-25
  • 粉丝0
  • 关注0
  • 积分313分
  • 威望46点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-11-28 20:30
兄弟,你设置断点试试!监视FUNCTION1(data1)中的data1。
rudolf
驱动小牛
驱动小牛
  • 注册日期2002-10-09
  • 最后登录2006-04-25
  • 粉丝0
  • 关注0
  • 积分81分
  • 威望9点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-11-29 09:02
兄弟,你设置断点试试!监视FUNCTION1(data1)中的data1。


软件是不停地刷新,几秒钟会有一次异常,怎么捕捉啊?
靠天靠地靠父母,不如靠自己。
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
地板#
发布于:2002-11-29 09:19
应该是软件的问题。
看看局部变量都给初值了吗?
rudolf
驱动小牛
驱动小牛
  • 注册日期2002-10-09
  • 最后登录2006-04-25
  • 粉丝0
  • 关注0
  • 积分81分
  • 威望9点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-11-29 09:31
应该是软件的问题。
看看局部变量都给初值了吗?


依老大的看法,还是算法有问题?

不是由于中断过于频繁导致计算或显示出错?

这么问吧,主频是44M的386主板内存4M硬盘8M,OS是DOS6.22(未完全安装,只是SYS了一下可以启动),在程序运行时有20KHZ的硬件中断不停地干扰其它的计算、显示,那么是否会发生显示出错?
靠天靠地靠父母,不如靠自己。
lonkiss
驱动牛犊
驱动牛犊
  • 注册日期2002-01-15
  • 最后登录2004-07-28
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-11-29 10:22
请问你是怎么来显示数据的呢?是用printf还是直接写显示内存0xb800呢?
你是在中断程序里显示数据还是在中断外的程序里显示数据呢?
在中断里做事情要格外小心不要重入DOS
我的真名就叫-龙旗
rudolf
驱动小牛
驱动小牛
  • 注册日期2002-10-09
  • 最后登录2006-04-25
  • 粉丝0
  • 关注0
  • 积分81分
  • 威望9点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2002-11-29 10:44
请问你是怎么来显示数据的呢?是用printf还是直接写显示内存0xb800呢?
你是在中断程序里显示数据还是在中断外的程序里显示数据呢?
在中断里做事情要格外小心不要重入DOS
 


数据的显示是通过调用一个自己写的函数(可以显示汉字),里面用到了一些内存操作
  memset(img,0xff,1280);
还有:
    rp.r_ax=0x1130;
    rp.r_bx=0x0600;
    rp.r_cx=16;
    rp.r_dx=25;
    intr(0x10,&rp);
    eseg=rp.r_es;
    eoff=rp.r_bp;
    movedata(eseg,eoff+i*16,FP_SEG(by),FP_OFF(by),16);

最后     putimage(x, y, img, COPY_PUT);

在中断里只有加减和比较等运算,没有显示等重入DOS的操作。

靠天靠地靠父母,不如靠自己。
lonkiss
驱动牛犊
驱动牛犊
  • 注册日期2002-01-15
  • 最后登录2004-07-28
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2002-11-29 10:51
[quote]请问你是怎么来显示数据的呢?是用printf还是直接写显示内存0xb800呢?
你是在中断程序里显示数据还是在中断外的程序里显示数据呢?
在中断里做事情要格外小心不要重入DOS
 


数据的显示是通过调用一个自己写的函数(可以显示汉字),里面用到了一些内存操作
  memset(img,0xff,1280);
还有:
    rp.r_ax=0x1130;
    rp.r_bx=0x0600;
    rp.r_cx=16;
    rp.r_dx=25;
    intr(0x10,&rp);
    eseg=rp.r_es;
    eoff=rp.r_bp;
    movedata(eseg,eoff+i*16,FP_SEG(by),FP_OFF(by),16);

最后     putimage(x, y, img, COPY_PUT);

在中断里只有加减和比较等运算,没有显示等重入DOS的操作。

 [/quote]
我的真名就叫-龙旗
rudolf
驱动小牛
驱动小牛
  • 注册日期2002-10-09
  • 最后登录2006-04-25
  • 粉丝0
  • 关注0
  • 积分81分
  • 威望9点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2002-11-29 11:06
啊,是不是我没说清楚?
这样好了,我把代码贴出来:

在图形方式下可以在指定位置显示有背景和前景颜色的汉字(有特别生成的字库)和字符。
int p_text(int x,int y,char *p,unsigned clr,unsigned bk_clr){
 int j,n,flag=0;
 unsigned int index;
 unsigned long n1,n2,nn;
 unsigned char *tempby;
   unsigned eseg,eoff;
   unsigned int i,c1,c2,f=0;
   unsigned int ii,i1;
   struct REGPACK rp;
   int a=0,m;
   char by[32];
   int color[4];
   char zm[16][80];

   index=clib.n;
   memset(img,0xff,1280);
    m=strlen(p);
    if(m>64)m=64;
   if(x==8&&y==(Y3+5)){
//     delt_ABC(p,2);
     m=strlen(p);
    }

   if(m>32){
     img[0]=8*(m%32)-1;
     img[1]=8*m/256;
     }
     else {
       img[0]=8*m-1;
       img[1]=0x00;
     }
   img[2]=0x0f;
   img[3]=0x00;
   color[3]=(clr & 0x01) + ((bk_clr&0x01)<<1);
   color[2]=(bk_clr&0x02)+((clr&0x02)>>1);
   color[1]=((bk_clr&0x04)>>1)+((clr&0x04)>>2);
   color[0]=((bk_clr&0x08)>>2)+((clr&0x08)>>3);

   while((i=*p++)!=0) {
     if(i<0xa1){
       if(i==\'\\x1a\') break;
else if(i==\'\\x09\'){
  x=((int)(x+8)/8)*8;
  }
  else {
    rp.r_ax=0x1130;
    rp.r_bx=0x0600;
    rp.r_cx=16;
    rp.r_dx=25;
    intr(0x10,&rp);
    eseg=rp.r_es;
    eoff=rp.r_bp;
    movedata(eseg,eoff+i*16,FP_SEG(by),FP_OFF(by),16);
    ii=0;
    for(i1=0;i1<16;i1++){
      for(ii=0;ii<4;ii++){
switch(color[ii]){
  case 0:
    img[4+a+4*i1*m+ii*m]=0x00;
    break;
  case 1:
    img[4+a+4*i1*m+ii*m]=by[i1];
    break;
  case 2:
    img[4+a+4*i1*m+ii*m]=(~by[i1]);
    break;
  case 3:
    img[4+a+4*i1*m+ii*m]=0xff;
    break;
  }
}
      }
    a++;
    }
  f=0;
  }
  else if(f==0){
    c1=(i-0xa1)&0x07f;
    f=1;
    n1=i-0xff00;
    }
    else {
      c2=(i-0xa1)&0x07f;
      f=0;
      nn=(i-0xff00)*0xff+n1;
      if(flag==1){
 printf(\"nn:%06d \",nn);
 }
      ii=0;
      for(i1=0;i1<16;i1++){
for(ii=0;ii<4;ii++){
  switch(color[ii]){
    case 0:
      img[4+a+4*i1*m+ii*m]=0x00;
      img[4+a+1+4*i1*m+ii*m]=0x00;
      break;
    case 1:
      img[4+a+4*i1*m+ii*m]=by[i1*2];
      img[4+a+1+4*i1*m+ii*m]=by[i1*2+1];
      break;
    case 2:
      img[4+a+4*i1*m+ii*m]=(~by[i1*2]);
      img[4+a+1+4*i1*m+ii*m]=(~by[i1*2+1]);
      break;
    case 3:
      img[4+a+4*i1*m+ii*m]=0xff;
      img[4+a+1+4*i1*m+ii*m]=0xff;
      break;
    }
  }
}
      a+=2;
      }
    }
     putimage(x, y, img, COPY_PUT);
     return(x);
    }

中断里的代码:
void interrupt NewIRQi(__CPPARGS)
{  int sum=0;

    disable();                           //关中断
    if(EnIntFlag){
      IntCounter++;                        //计数器加一

      if(MoveRev1[0]>0){
sum=1;
if(IntCounter%freq[0]==0){
   MoveRev1[0]--;
   dout &=~(0x0001<<5); }
 else if(IntCounter%freq1[0]==0)
   dout |= (0x0001<<5);
}
      if(MoveRev1[1]>0){
sum=1;
if(IntCounter%freq[1]==0){
   MoveRev1[1]--;
   dout &=~(0x0001<<6); }
 else if(IntCounter%freq1[1]==0)
   dout |= (0x0001<<6);
}
      if(MoveRev1[2]>0){
sum=1;
if(IntCounter%freq[2]==0){
   MoveRev1[2]--;
   dout &=~(0x0001<<7); }
 else if(IntCounter%freq1[2]==0)
   dout |= (0x0001<<7);
}
      if(MoveRev1[3]>0){
sum=1;
if(IntCounter%freq[3]==0){
   MoveRev1[3]--;
   dout &=~(0x0001<<13); }
 else if(IntCounter%freq1[3]==0)
   dout |= (0x0001<<13);
}
      if(MoveRev1[4]>0){
sum=1;
if(IntCounter%freq[4]==0){
   MoveRev1[4]--;
   dout &=~(0x0001<<14); }
 else if(IntCounter%freq1[4]==0)
   dout |= (0x0001<<14);
}

      if(sum==0){
EnIntFlag=0;
outportb(BASE_ADD+24,0);
MoveFlag=2;
}
      else{
MoveFlag=1;
outport(BASE_ADD+0x10,dout);
}
    }
    outportb(0xA0,0x20);                 //硬件中断结束
    outportb(0x20,0x20);                 //硬件中断结束
    enable();                            //开中断

}

显示刷新部分:
void running()
{
   int i,j,x1,y1;
   long ShowPos;
   char ch[16],ch1[16];


     for(j=0;j<2;j++){
       for(i=0;i<5;i++){
ch[0]=\'\\0\';ch1[0]=\'\\0\';
if(j==0){
  if(i==0||i==3){        
    ShowPos=StartRev/Step1;
    sprintf(ch1,\"%05.02f \",abs(ShowPos-1000)/100.0);
    if(StartRev>=5e4) sprintf(ch,\"+ %s\",ch1);
      else               sprintf(ch,\"- %s\",ch1);}
  else if(i==1||i==4){  
    ShowPos=StartRev*3/10;
    sprintf(ch1,\"%06.02f \",abs(ShowPos-18000)/100.0);
    if(StartRev>=6e4) sprintf(ch,\"+%s\",ch1);
      else               sprintf(ch,\"-%s\",ch1); }
  else if(i==2){        
    ShowPos=StartRev/Step1;
    sprintf(ch1,\"%05.02f \",abs(ShowPos-4000)/100.0);
    if(StartRev>=5e4) sprintf(ch,\"+ %s\",ch1);
      else               sprintf(ch,\"- %s\",ch1);}
   x1=30;y1=Y2;
}
else if(j==1){
  if(i==0||i==3){        
    ShowPos=CurrentRev/Step1;
    sprintf(ch1,\"%05.02f \",abs(ShowPos-1000)/100.0);
    if(CurrentRev>=5e4) sprintf(ch,\"+ %s\",ch1);
      else                 sprintf(ch,\"- %s\",ch1);}
  else if(i==1||i==4){  
    ShowPos=(CurrentRev*3+5)/10;
    sprintf(ch1,\"%06.02f \",abs(ShowPos-18000)/100.0);
    if(CurrentRev>=6e4) sprintf(ch,\"+%s\",ch1);
      else           sprintf(ch,\"-%s\",ch1);   }
  else if(i==2){        
    ShowPos=CurrentRev/Step1;
    sprintf(ch1,\"%05.02f \",abs(ShowPos-4000)/100.0);
    if(CurrentRev>=5e4) sprintf(ch,\"+ %s\",ch1);
      else                 sprintf(ch,\"- %s\",ch1);}
  x1=98;y1=Y2;
}

p_text(x1,y1+24*i,ch,WCOLOR,BCOLOR);
       }
     }
}



霍霍,贴了这么多代码,别K我哦。

 :D
靠天靠地靠父母,不如靠自己。
lonkiss
驱动牛犊
驱动牛犊
  • 注册日期2002-01-15
  • 最后登录2004-07-28
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2002-11-29 11:21
我没时间仔细的分析你的代码哪里可能会导致异常情况的发生。
你没法跟踪的话只能采取比较笨的办法确定哪里的代码有问题
比如你可以把running()函数最后的一句p_text(x1,y1+24*i,ch,WCOLOR,BCOLOR);改成显示一些固定数据的字符串来显示,由此可以判断出你的显示函数有没有问题。

另外你可以用别的方法来代替p_text()的的输出来测试,比如你可以在文本方式下直接写屏来显示数据。由此可以判断是不是running()函数中一堆sprintf里出了问题。

我的真名就叫-龙旗
rudolf
驱动小牛
驱动小牛
  • 注册日期2002-10-09
  • 最后登录2006-04-25
  • 粉丝0
  • 关注0
  • 积分81分
  • 威望9点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2002-11-29 11:28
我没时间仔细的分析你的代码哪里可能会导致异常情况的发生。
你没法跟踪的话只能采取比较笨的办法确定哪里的代码有问题
比如你可以把running()函数最后的一句p_text(x1,y1+24*i,ch,WCOLOR,BCOLOR);改成显示一些固定数据的字符串来显示,由此可以判断出你的显示函数有没有问题。

另外你可以用别的方法来代替p_text()的的输出来测试,比如你可以在文本方式下直接写屏来显示数据。由此可以判断是不是running()函数中一堆sprintf里出了问题。

 


哦,言之有理。

呵呵看来排查问题的办法还是很多的。等下来试。 :D
靠天靠地靠父母,不如靠自己。
rudolf
驱动小牛
驱动小牛
  • 注册日期2002-10-09
  • 最后登录2006-04-25
  • 粉丝0
  • 关注0
  • 积分81分
  • 威望9点
  • 贡献值0点
  • 好评度8点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2002-11-29 18:03
NND
终于搞定了。

把中断里的
if(IntCounter%freq[0]==0){
}
else if(IntCounter%freq1[0]==0)
两个除法用加法代替就行了。

5555555555555~~~~~~~~
花了我两天的时间啊。
好惨又到周末了。
 :mad: :mad:
靠天靠地靠父母,不如靠自己。
Gong_XG
驱动太牛
驱动太牛
  • 注册日期2002-10-01
  • 最后登录2010-11-25
  • 粉丝0
  • 关注0
  • 积分313分
  • 威望46点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2002-11-29 19:25
好,解决了就好!!
同喜!
游客

返回顶部