阅读:1505回复:12
频繁IRQ硬件中断对计算、显示产生影响的问题。
看来看去还是应该到这里来问:
硬件环境:386工控主板(44M),20KHZ方波信号源。 软件环境:DOS6.22,BC31。 问题描述: 写了一个程序,接收20K的IRQ硬件中断,在中断中进行一些比较、计数等操作。主程序将计数得到的数据进行再计算、比较然后显示出来。 现象:中断计数没问题,但是主程序中的计算和显示工作量比较大,造成应该显示“00.00”的时候会显示一些其它的数据如“1111.11”。 也就是说某一个全局变量data1在程序中通过公式FUNCTION1(data1)得到data2,然后再显示data2。 现在程序中data1的值没有发生变化,但是显示出来的data2却会变 不知道有没有讲清楚,大家有没有遇到过这种问题?搞了一天有没搞定,所以来请教大家。 |
|
|
沙发#
发布于:2002-11-28 20:30
兄弟,你设置断点试试!监视FUNCTION1(data1)中的data1。
|
|
板凳#
发布于:2002-11-29 09:02
兄弟,你设置断点试试!监视FUNCTION1(data1)中的data1。 软件是不停地刷新,几秒钟会有一次异常,怎么捕捉啊? |
|
|
地板#
发布于:2002-11-29 09:19
应该是软件的问题。
看看局部变量都给初值了吗? |
|
地下室#
发布于:2002-11-29 09:31
应该是软件的问题。 依老大的看法,还是算法有问题? 不是由于中断过于频繁导致计算或显示出错? 这么问吧,主频是44M的386主板内存4M硬盘8M,OS是DOS6.22(未完全安装,只是SYS了一下可以启动),在程序运行时有20KHZ的硬件中断不停地干扰其它的计算、显示,那么是否会发生显示出错? |
|
|
5楼#
发布于:2002-11-29 10:22
请问你是怎么来显示数据的呢?是用printf还是直接写显示内存0xb800呢?
你是在中断程序里显示数据还是在中断外的程序里显示数据呢? 在中断里做事情要格外小心不要重入DOS |
|
|
6楼#
发布于:2002-11-29 10:44
请问你是怎么来显示数据的呢?是用printf还是直接写显示内存0xb800呢? 数据的显示是通过调用一个自己写的函数(可以显示汉字),里面用到了一些内存操作 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的操作。 |
|
|
7楼#
发布于:2002-11-29 10:51
[quote]请问你是怎么来显示数据的呢?是用printf还是直接写显示内存0xb800呢? 数据的显示是通过调用一个自己写的函数(可以显示汉字),里面用到了一些内存操作 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] |
|
|
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 |
|
|
9楼#
发布于:2002-11-29 11:21
我没时间仔细的分析你的代码哪里可能会导致异常情况的发生。
你没法跟踪的话只能采取比较笨的办法确定哪里的代码有问题 比如你可以把running()函数最后的一句p_text(x1,y1+24*i,ch,WCOLOR,BCOLOR);改成显示一些固定数据的字符串来显示,由此可以判断出你的显示函数有没有问题。 另外你可以用别的方法来代替p_text()的的输出来测试,比如你可以在文本方式下直接写屏来显示数据。由此可以判断是不是running()函数中一堆sprintf里出了问题。 |
|
|
10楼#
发布于:2002-11-29 11:28
我没时间仔细的分析你的代码哪里可能会导致异常情况的发生。 哦,言之有理。 呵呵看来排查问题的办法还是很多的。等下来试。 :D |
|
|
11楼#
发布于:2002-11-29 18:03
NND
终于搞定了。 把中断里的 if(IntCounter%freq[0]==0){ } else if(IntCounter%freq1[0]==0) 两个除法用加法代替就行了。 5555555555555~~~~~~~~ 花了我两天的时间啊。 好惨又到周末了。 :mad: :mad: |
|
|
12楼#
发布于:2002-11-29 19:25
好,解决了就好!!
同喜! |
|