使用D4编的程序能否影响用嵌入式汇编读取IO口的值(200分)

  • 主题发起人 主题发起人 zzll
  • 开始时间 开始时间
Z

zzll

Unregistered / Unconfirmed
GUEST, unregistred user!
<pre><font size=3>
我使用D4&amp;amp;Update3(Win98)编了一个程序,用与读写一块ISA
卡的数据,我已知ISA卡的端口地址,读取其端口的值,由于需要延
时,我使用FOR..DO语句,而读取的值有误,而单步调试或不加任
何语句直接读取时值正确,为什么呢?
我怀疑使用某些语句会改写寄存器值,影响读取数据值,请问
有这种可能吗?如果有,如何避免呢?我这方面不懂,多谢您,不管
熟不熟请讨论讨论,我很着急用。不够可以再加分
</font></pre>
 
详细点. 如果不长, 请把代码贴上来
 
使用汇编出现的这个问题,就对了。
就如同TC一样,在高级语言里使用的AX、BX、...这些都是高级语言为调用汇编而
定义的内部变量,而非真正的AX,BX,CX...。你在延迟过程中,有些语句就有可能
影响到这些值,因而建议你在延迟前,将这些寄存器变量保存起来(保存的方法很
多),延迟过后再恢复并调用即可!
 
胡说八道
 
用Win32 API Sleep(n) 试试!
n为延迟时间、整数,单位是毫秒。
它也许不改变寄存器值,同时也释放CPU。
 
你是先读到然后再延时再处理?
读到了干吗不保存到变量里再进行下面步骤?
 
对呀!
为什么不保存到变量里呢?
 
to zzll:
我又想了一下,觉得可能不一定是For...do的原因。我以前在NT下对一块ISA
卡读写遇到过类似的情况,当时我用的是repeat...until循环。最后原因是对ISA
卡数据准备好标志(和设备准备好标志)判断有误,所以读写数据出错。建议你再
检查一下程序,尤其对你的ISA卡的操作说明再好好研究一下。
 
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;
charset=gb2312">
<title>New Page 1</title>
<meta name="GENERATOR" content="Microsoft FrontPage 3.0">
<meta name="Microsoft Theme" content="global 101, default">
<meta name="Microsoft Border" content="tl, default">
</head>
<body>
<p><small><font face="宋体">这里的人这么热情,真的感谢大家的帮忙!!!!<br>
TO Another_eYes:<br>
<br>
&amp;gt;详细点. 如果不长, 请把代码贴上来<br>
以下贴出核心部分<br>
<br>
说了不怕大家见笑,本人对汇编一窍不通,在某处抄不一段程序如下:<br>
procedure WritePort(PortAdress:word;Value:byte);
pascal;<br>
begin
<br>
asm<br>
mov al,Value<br>
mov dx,PortAdress<br>
out dx,al<br>
end;
<br>
end;
<br>
<br>
function ReadPort(PortAdress:word) : byte;
pascal;<br>
begin
<br>
asm<br>
mov dx,PortAdress<br>
in al,dx<br>
mov @result,al<br>
end;
<br>
end;
<br>
<br>
我的程序如下:<br>
<br>
...<br>
向端口写数据<br>
读端口数据Value1<br>
for i:=1 to ...do
begin
------------+<br>
&amp;nbsp;&amp;nbsp;
读数据,并和Value1比较
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
|<br>
&amp;nbsp;&amp;nbsp;
if 再读数据&amp;lt;&amp;gt;Value1 then
exit;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
|<br>
&amp;nbsp;&amp;nbsp;
For j:=1 to ...do
begin

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
+--用于消除读信号的抖动<br>
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
延时
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
|
<br>
&amp;nbsp;&amp;nbsp;
end;

&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
|<br>
end;
--------------------------------+<br>
...<br>
<br>
<br>
在第一次读的数据和以后的数据总是变动,有时相同,但多数都为高电平,</font></small></p>
<p><small><font face="宋体">即为255,但在单步时或不加循环时,读取数据正常<br>
<br>
To Jams:<br>
&amp;gt;因而建议你在延迟前,将这些寄存器变量保存起来(保存的方法很多),延</font></small></p>
<p><small><font face="宋体">迟过后再恢复并调用即可!<br>
多谢大侠指点,但本人实在根底浅薄,希望您能写一种取实用,简单的方法,最好写一下<br>
<br>
To kokusan:<br>
&amp;gt;用Win32 API Sleep(n) 试试!<br>
<br>
您的方法我用过,效果是不错,但程序中一用SLEEP(n)后,系统响应消息,例如拖动窗</font></small></p>
<p><small><font face="宋体">口,将变的非常迟钝,而且我需要大量读取数据,用SLEEP会很不好控制。<br>
<br>
TO Another_eYes,nuke:<br>
&amp;gt;你是先读到然后再延时再处理?<br>
&amp;gt;为什么不保存到变量里呢?<br>
<br>
我需要读多次后进行比较,来消除抖动,必须值稳定时才能保存<br>
<br>
To kokusan:<br>
&amp;gt;卡数据准备好标志(和设备准备好标志)判断有误,所以读写数据出错。<br>
<br>
什么是&amp;quot;数据准备好标志(和设备准备好标志)&amp;quot;,我的ISA卡是自己开发的,向某一地址</font></small></p>
<p><small><font face="宋体">写信号后,该卡由于连接了物理设备,再读取其相应端口数据值,没有&amp;quot;准备好标志&amp;quot;<br>
<br>
多谢大家的热情回答,请勿必继续讨论,明天上午的会继续回答,我很着急,谢谢谢谢谢谢谢谢!!!!!!!!!!</font></small>
</body>
</html>
 
<pre><font size=3>
这里的人这么热情,真的感谢大家的帮忙!!!!
TO Another_eYes:
&amp;gt;详细点. 如果不长, 请把代码贴上来
以下贴出核心部分
说了不怕大家见笑,本人对汇编一窍不通,在某处抄不一段程序如下:
procedure WritePort(PortAdress:word;Value:byte);
pascal;
begin
asm
mov al,Value
mov dx,PortAdress
out dx,al
end;
end;

function ReadPort(PortAdress:word) : byte;
pascal;
begin
asm
mov dx,PortAdress
in al,dx
mov @result,al
end;
end;

我的程序如下:
...
向端口写数据
读端口数据Value1
for i:=1 to ...do
begin
------------+
读数据,并和Value1比较 |
if 再读数据&amp;lt;&amp;gt;Value1 then
exit; |
For j:=1 to ...do
begin
+--用于消除读信号的抖动
延时 |
end;
|
end;
--------------------------------+
...

在第一次读的数据和以后的数据总是变动,有时相同,但多数都为高电平,即为255,但在单步时或不加循环
时,读取数据正常
To Jams:
&amp;gt;因而建议你在延迟前,将这些寄存器变量保存起来(保存的方法很多),延迟过后再恢复并调用即可!
多谢大侠指点,但本人实在根底浅薄,希望您能写一种取实用,简单的方法,最好写一下
To kokusan:
&amp;gt;用Win32 API Sleep(n) 试试!
您的方法我用过,效果是不错,但程序中一用SLEEP(n)后,系统响应消息,例如拖动窗口,将变的非常迟
钝,而且我需要大量读取数据,用SLEEP会很不好控制。
TO Another_eYes,nuke:
&amp;gt;你是先读到然后再延时再处理?
&amp;gt;为什么不保存到变量里呢?
我需要读多次后进行比较,来消除抖动,必须值稳定时才能保存
To kokusan:
&amp;gt;卡数据准备好标志(和设备准备好标志)判断有误,所以读写数据出错。
什么是&amp;quot;数据准备好标志(和设备准备好标志)&amp;quot;,我的ISA卡是自己开发的,向某一地址写信号后,该卡由于
连接了物理设备,再读取其相应端口数据值,没有&amp;quot;准备好标志&amp;quot;
多谢大家的热情回答,请勿必继续讨论,明天上午的会继续回答,我很着急,谢谢谢谢谢谢谢谢!!!!!!!!!!
</font></pre>
 
向端口写数据
读端口数据Value1
var
x, y: byte;
x := readport(...);
for i := 1 to ...do
begin
y := readport(...);
if x <> y then
exit;
延时
end;
这样做不会有错.
如果有问题改动一下readport:
function ReadPort(PortAdress:word) : byte;
pascal;
begin
asm
push edx // 保存寄存器
push eax
mov dx,PortAdress
in al,dx
mov @result,al
pop eax
pop edx // 恢复寄存器
end;
end;
 
<pre><pre class="text">
由于设备在客户那里,所以不能调试程序,您的方法我想是不是也能保存可能已经
错误的数据
</font></pre>
 
To zzll:
能否介绍一下你的ISA卡的端口设置、上面是否有处理器,当它与主机传递大量
数据时,怎样确保同步即: 数据一个一个被取出(写入),而不会重复读(写)同一个
数或出现漏掉一个数的措施。
按照我对您贴出来的程序的理解,似乎是由主机编程来消除抖动保证数据的可
靠,那么如何确定延迟多少时间合适呢?如果用了eYes的方法还不行的话,我觉得
就不是寄存器被改动的原因,而是for..do延迟时间很难调整造成的。想一想换一
台主频的机子怎么办。所以我认为ISA卡与主机传递大量数据时的同步很重要,要么
在硬件上同步时钟,要么另设置一个端口,在软件上读该端口的值实现同步,或者
高级一点的DMA(那我也不会),很想知道您是如何做的。
 
我的ISA卡并非象您所说的那样不须同步处理,只须定时读取其信号即可,
延时要求不是十分高,只要保持信号相对稳定即可
 
多人接受答案了。
 
请通知我
wzbhu@yeah.net
 
后退
顶部