这个问题把我搞昏了(200分)

  • 主题发起人 主题发起人 yyl
  • 开始时间 开始时间
Y

yyl

Unregistered / Unconfirmed
GUEST, unregistred user!
;
原来在DOS下做了一个数据采集程序,运行很正常。其中的
采集部分为附后程序中的Sjcj:后将程序做到Win98下,用的是
C++ Builder 3.0,因为没有现成的端口读写函数可用,便照
Delphi 4.0中文手册上写的两个汇编程序,写了
InPort(short PortNo)和
OutPort(short PortNo, unsigned char Data)代替inportb和
outportb.问题就出在Sjcj子程序中,出错处已标明。

//用TC2.0做,把inportb换成InPort,outportb换成OutPort
就是Win98下的程序
void Sjcj(void)
{
char i = 0,k = 0,m = 0;
for(i=0;i<=4;i++)
{
outportb(0x278,STARTH+i);
dela(20); //用于微量延时
outportb(0x278,STARTL+i);

//检测AD卡是否准备好,出问题处
//dos下不会死循环,而Win98下出现死循环
//用仪器检测发现采集的数据不稳定,即有随机现象
//请问有何法解
do{
k = inportb(0x279);
k = k&0x80;
}while(k ==0 );

dela(180);
k=inportb(0x27a);
wave1[DataLength-1] = k;
dela(10);
}
}
void dela(int Value)
{
int n = 0,ii = 0;
for(n = 0;n <= Value;n++)
{
ii = ii++;
ii = ii*10;
ii = ii/10;
}
}


void __fastcall TSjcjForm::PortOut(short PortNo,
unsigned char Data)
{
asm {
xor edx,edx
xor eax,eax
mov dx,PortNo
mov al,Data
out dx,al
}
}
//-----------------------------------------------------------
unsigned char __fastcall TSjcjForm::PortIn(short int PortNo)
{
unsigned char result;

asm {
xor edx,edx
xor eax,eax
mov dx,PortNo
in al,dx
mov result,al
}
return result;
}
 
; 可能你的循环计数器i用到寄存器在你的汇编中修改了值,所以你的程序就

出现你说的现象。你可以跟踪一下就知道了。

祝你好运!
 
将BX保存一下,再试一试!
 
写汇编时一般为安全起见, 要在开始时把用到的寄存器PUSH, 在结束时POP.
 
;
没想到这么快就得到了朋友们的回答,只是答案不是这样的。
用DELPHI 1.0编了一个同样功能的程序,发现那个地方还是死循环。
DELPHI 1.0中有端口函数Port,而且是16位的。所以不是因为计数
器的问题。问题出在从端口读进的值,在DOS下,Port[$279] = $80,
而在Win98下,Port[$279] = $7F,因为$7F and $80 == 0,正满足
死循环的要求。昨晚下载了那个的TDLPORTIO.ZIP,用它的DEMO Read
端口$279,发现也是$7F。这说明Win98和DOS下采集到的数据不一样。
哪位知道为什么?
 
你的程序很值得商榷:
1.__fastcall好象是用寄存器传参数的吧,这样的话你的参数在使用前
是否就被自己设置的值破坏了?
2.无论如何,我也不可能想到会把InPort和OutPort实现成类的函数!!!
还用__fastcall.用__fastcall的成员函数肯定是提供寄存器传递
this指针的,而且成员函数间的调用不保存和恢复this指针.你就不
怕this指针被破坏了吗????

你的程序能进入死循环就已经够幸运了,还谈甚麽正确性?

BTW:TDLPORTIO.ZIP是基于甚麽原理?如果不是基于32位驱动程序的原理,
可以完全不必考虑其可靠性,网上有很多可以用32位驱动程序的原理
实现IO的,很多都有源码,我就用过一个,没有问题的.
 
M$明文说明如下:

Microsoft Specific ®
The __fastcall calling convention specifies that arguments to functions are to be passed in registers, when possible.

我的观点和lhz一样:
1、读写端口的函数独立出去
2、没事不要乱用寄存器
3、你的读写端口的函数里面什么寄存器都没保存,
不是好习惯,确定没问题前还是小心点好,
要不然死都不知怎么死的 >:-<<
 
; 现用了DLPortIO.Zip提供的驱动程序和读取函数,经测试
读的数是对的。大伙的意见是对的。
 
多人接受答案了。
 

Similar threads

I
回复
0
查看
844
import
I
I
回复
0
查看
718
import
I
I
回复
0
查看
739
import
I
I
回复
0
查看
670
import
I
I
回复
0
查看
843
import
I
后退
顶部