这段代码怎样用DELPHI写出来?难啊!

liuyecai 2001-02-26 11:24:00
急死人啊!
注:这是C++ for win3.1 program.
限用MSCOMM组件,(因为在WIN2k下不能用别的东东!)
long MainWindow::H_position()
{
long position;
int j,
i,
delay,
length,
keycode,
H_exit = 0,
InPut,
slength;

char s[100],
sr[100],
s1[10],
c;
strcpy(sr, "%1PR%");
strcpy(s, "");
do{
InPut=inportb(0x2fd);

}while((InPut & 0x0E)||(!(InPut & 0x20))); //wait data

slength = strlen(sr);

for(i=0;i<slength;i++){
if(sr[i] != '%'){
outportb(0x2f8,(int)sr[i]);
H_delay();
}
else{
outportb(0x2f8,0x0d);
H_delay();
outportb(0x2f8,0x0A);
H_delay();
}
}

while(H_exit == 0)
{

while(inportb(0x2fd)&0x01)
{
c = inportb(0x2f8);

switch(c)
{
case 0x0D: break;
case 0x0A: if( strlen(s) <= 6)
{
strcpy(s," ");
break;
}
else
{
H_exit = 1;
break;
}
case '\0': break;
default :
{
sprintf(s1, "%c", c);
strcat(s, s1);
break;
}
}
}
}
if((keycode=strlen(s)) >= 8) //只取后8位
{
delay = strlen(s) - 8;
for(j=0; j < 8; j++)
{
s[j] = s[j+delay];
}
for(j=8; j<keycode; j++)
{
s[j] = '\0';
}
}
position=atol(s);
return(position);

}
...全文
716 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
strongzp 2001-03-02
  • 打赏
  • 举报
回复
我用的是D5,WIN2K。
你注意一下,rec定义的长度和inputLen是不是一样的。
看你报错的情形,应该是将rec定义为array of byte了,但接收时一次从缓冲区中读入的字节数大于rec数组的长度,注意使用它之前先setlength,长度和inputLen是一样的。
要不我将我写的那个类发给你,你稍稍修改一下即可。
liuyecai 2001-03-01
  • 打赏
  • 举报
回复
真是多谢strongzp 兄!
可能是你误会了我的意思,DS是根据读取的数据来确定的!
等我调试好了再来给分!
liuyecai 2001-03-01
  • 打赏
  • 举报
回复
strongzp: your self code can run?!
But still have an error on follow as :

rec := mscomm1.input;

总是报错: Variant array index out of bounds ( array of byte)
Invalid variant type conversion ( byte)

is the problem the mscomm's matter?
under DELPHI5 for win2k.
thanks!
strongzp 2001-02-28
  • 打赏
  • 举报
回复
最后的if rec=DS是多余的,请不必管它。
strongzp 2001-02-28
  • 打赏
  • 举报
回复
如果按你的意思,我想可以这样试一试,

function Tfrmproduce.H_position: longint;
var
str: string;
data: array[0..100] of byte; //假定接收的数据不超过100个字节
rec: byte;
timeout,count, DataLen: integer;
exitFlag: boolean;
begin
setportbyte; //用你自己的过程;
str := '1PR'+#13+#10;
SendAllData(pChar(str),5); // 用我后来给你的方法
count := 0;
DataLen := 0;
exitFlag := false;
repeat
rec := 0;
timeout := 0;
repeat
inc(timeout); // 超时计数
until (MSComm.InBufferCount>0) or (timeout>{这里加入标准超时的值});
rec := MSComm.Input; // 接收一个字节。
if rec<>0 then
begin
data[DataLen] := rec;
//加入分析数据的代码,如果接收到DS,则exitFlag := tru;
inc(DataLen);
count := 0;
end
else inc(count); // 需要测试的次数,假定为3
until (exitFlag) or (count>3);
if rec=DS then
begin
//加入分析Data数组的代码。

end;
end;

关于C中的'\0',实际上就是0,在Pascal中你可写为#0;
你的程序代码中出现的问题,有可能是你的InputByte未SetLength的缘故。

另外,我提供一个测试程序的方法,你先将串口的2,3针短接,先测试接收的数据,是不是你发送的数据,这样就表示你的发送是对的,那么你的程序已经成功了60%了。
liuyecai 2001-02-28
  • 打赏
  • 举报
回复
用API函数怎么写?各位帮帮忙啊!
急死人了!
liuyecai 2001-02-28
  • 打赏
  • 举报
回复
rec声明成什么类型呢?
liuyecai 2001-02-28
  • 打赏
  • 举报
回复
真是多谢 strongzp 兄! 我把C的代码和我改的代码发给你了! very thanks!

我是把 inputmode设成了二进制模式接收,可运行到这就报错!
inputbyte := mscomm1.input; //inputbyte: byte; or inputbyte: array of byte
总是报错: Variant array index out of bounds ( array of byte)
Invalid variant type conversion ( byte)
strongzp 2001-02-28
  • 打赏
  • 举报
回复
你上面的代码有点问题,我的函数sendcommand必须加以修改,因为命令协议是我
自己定的,用用SendAllData看看。

如果按照‘发送1PR,再接收’的话,可以这么做。

首先:
初始化端口,以COM1为例;
mscomm1.CommPort :=1;
mscomm1.Settings :='9600,N,8,1';
mscomm1.InputMode :=1;
mscomm1.InputLen := 1; // 指定每接收一次所取数据的个数

先发送控制符:
str := '1PR'+#13+#10;
SendAllData(pChar(str),5);

再等待接收;
while() do
begin
rec := $ff;
repeat
rec = Mscomm1.Input;
// 注意在此加入将每个接收的数据保存至缓冲区的代码。
case rec of
$0D:;//回车的处理代码;
$0A:;//换行的处理代码
$00:;//文件终止的处理代码
end;
until ; // 超时或跳出判断
end;

以下是SendAllData的程序代码。

function TStrongLock.SendAllData(Data: pChar; Len: byte): integer;
var
temp: variant;
i: integer;
begin
if MSComm.PortOpen then
begin
temp := varArrayCreate([0,Len-1],varbyte);
for i:=0 to Len-1 do
temp[i] := Ord(Data[i]);
MSComm.Output := temp;
result := SEND_OK;
end
else result := CONNECT_ERROR;
end;


你再测试一下,应该很好解决的。我的程序通讯部分已经调完,一切OK。
strongzp 2001-02-28
  • 打赏
  • 举报
回复
注意MSCOMM中有个属性为INPUTMODE,将其改为二进制模式接收。
或者,你把具体要求和C的代码,EMAIL给我,我帮你看看。
EMAIL:strongzp@sina.com
strongzp 2001-02-27
  • 打赏
  • 举报
回复
我已经写得很清楚了,reccommdata 为接收任意长度的字节,sendAdata 为发送一个字节,
sendcommand 是我的程序中必须用到通讯中数据的第9位。
liuyecai 2001-02-27
  • 打赏
  • 举报
回复
strongzp兄:
你救救我啊?
liuyecai 2001-02-27
  • 打赏
  • 举报
回复
strongzp兄:
恕我愚昧,你能否将那C++代码给我改过来!
在DELPHI中怎么处理 '\0' 呢?
帮帮忙吧!
我是这样改的,可是不行!


function Tfrmproduce.H_position: longint;
var
position: longint;
j, i, delay, length, keycode: integer;
H_exit, InPut, slengh: integer;
s, sr, s1, s2: string;
c: integer;
// InPutbyte: array of Byte;
begin
H_exit :=0;
sr :='1PR' + #13#10;
s :='';
s2:='';
sendcommand(sr);
//setportbyte();
// if mscomm1.PortOpen then mscomm1.PortOpen := false;
// mscomm1.CommPort :=1;
// mscomm1.Settings :='9600,N,8,1';
// mscomm1.Handshaking :=1;
// mscomm1.InputMode :=1;
// mscomm1.InputLen := 1;
// mscomm1.PortOpen :=true;

while ( H_exit = 0 ) do
begin
if not(mscomm1.PortOpen) then mscomm1.PortOpen :=true;
// repeat
// until mscomm1.InBufferCount >= 1;
// InPutByte :=mscomm1.input;

c :=mscomm1.input;

case c of
$D: break;
$A: if (strlen(pchar(s)) <= 6) then
begin
strcopy(pchar(s),pchar(''));
break;
end
else
begin
H_exit :=1;
break;
end;
// '\0': break;
else
begin
s1 :=inttostr(c);
strcat(pchar(s),pchar(s1));
break;
end;
end;
end;

keycode :=strlen(pchar(s));
if (keycode >= 8) then
begin
delay :=keycode - 8;
for j:=0 to 8 do s2[j] :=s[j+delay];

// for j:=8 to keycode do s[j]:='\0';
end;

position :=strtoint(s2);
result:=position;
end;
Kingron 2001-02-26
  • 打赏
  • 举报
回复
在9x里面好写,在2K&NT里面不好写!
wingerK 2001-02-26
  • 打赏
  • 举报
回复
先把你要实现的功能说一说
可能很多DELPHI程序员不懂WIN31的东东
2F8是什么地址了?打印?串口?
其实你把要实现的功能详细描述出来反而更好一些

哦,看到了,是串口
简单啊
呵呵,我暂时也不知道具体怎么写,等一会看看再说,不说就是不知道了
liuyecai 2001-02-26
  • 打赏
  • 举报
回复
没人愿意帮助我吗?
加分!加分!
liuyecai 2001-02-26
  • 打赏
  • 举报
回复
上面的程序是这样的功能:
向端口发送 1PR 命令, 端口响应并返回数据,
对数据进行分析,只取最后8位.
inportb, ourportb--------win3.1 function read,write a port!

欢迎大家踊跃回家后面加分加分啊!
急急!
strongzp 2001-02-26
  • 打赏
  • 举报
回复
自己看看下面的发送接收代码,应该能给你帮助,这是我自己的一个工控类中的代码,
在2K下编译的:
注意你的MSCOMM须在类的初始化中先建立好,MSCOMM := TMSCOMM.CREATE(SELF);

function TStrongLock.SendAData(Data, ParityMode: byte; SetFlag: boolean): integer;
var
temp: variant;
begin
if MSComm.PortOpen then
begin
temp := varArrayCreate([0,0],varbyte);
temp[0] := Data;
if SetFlag then
begin
if ParityMode=1 then MSComm.Settings := intTostr(FPortBPS)+',M,8,1'
else MSComm.Settings := intTostr(FPortBPS)+',S,8,1';
end;
MSComm.Output := temp;
result := 0;
end
else result := -1;
end;

function TStrongLock.SendCommand(Command: pChar; recACK: boolean): integer;
var
i: integer;
Rec: byte;
begin
result := -1;
if MSComm.PortOpen then
begin
sleep(150);
MSComm.InBufferCount := 0;
SendAData(CUSTOM_COMM_SYNCH,1, true);
SendAData(Ord(Command[0]),1,false);
sleep(1);
SendAData(Ord(Command[1]),0,true);
for i:=2 to 7 do
begin
result := SendAData(Ord(Command[i]),0,false);
if result<>0 then break;
end;
if recACK then
begin
repeat
until MSComm.OutBufferCount=0;
result := RecCommData(@Rec,1);
if (result = 2) and (Rec=Ord(Command[7])) then result := 0
else
if result=2 then result := 1;
end;
end;
end;

function TStrongLock.RecCommData(Data: pChar; Len: integer): integer;
var
tStart, tEnd, i: integer;
temp: array of byte;
begin
result := -1;
try
if MSComm.PortOpen then
begin
tStart := GetTickCount;
repeat
tEnd := GetTickCount;
until (MSComm.InBufferCount>=Len)or((tEnd-tStart)>=FRecTimeOut);//received or Time out then out.
if (tEnd-tStart)<FRecTimeOut then
begin
SetLength(temp,Len);
MSComm.InputLen := Len;
temp := MSComm.Input;
for i:=0 to Len-1 do Data[i] := Chr(temp[i]);
result := 2;
end
else result := 3;
end;
except on e: exception do
end;
end;
wingerK 2001-02-26
  • 打赏
  • 举报
回复
先在IMPORT ACTIVEX里导入MS COMM控件
然后再研究一下怎么用,可以查MSDN

5,388

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧