DELPHI盒子
!实时搜索: 盒子论坛 | 注册用户 | 修改信息 | 退出
检举帖 | 全文检索 | 关闭广告 | 捐赠
技术论坛
 用户名
 密  码
自动登陆(30天有效)
忘了密码
≡技术区≡
DELPHI技术
lazarus/fpc/Free Pascal
移动应用开发
Web应用开发
数据库专区
报表专区
网络通讯
开源项目
论坛精华贴
≡发布区≡
发布代码
发布控件
文档资料
经典工具
≡事务区≡
网站意见
盒子之家
招聘应聘
信息交换
论坛信息
最新加入: lixuan123
今日帖子: 20
在线用户: 11
导航: 论坛 -> DELPHI技术 斑竹:liumazi,sephil  
作者:
男 wanglei916 (rock) ★☆☆☆☆ -
普通会员
2004/2/9 10:16:16
标题:
现在已经可以进行通信了,呵呵,高兴呀。只是还有一个问题没有解决,说给大家听听 浏览:1815
加入我的收藏
楼主: 现在已经可以进行通信了,呵呵,高兴呀。只是还有一个问题没有解决,说给大家听听。

可能是数据缓冲区的问题,我每次接收完一组数据,然后再重新发送的时候,第一次发送的总是最后接收到的数据,晕呀,是程序的问题,还是应该在接收完数据以后将缓冲区清0呢? 

----------------------------------------------
-
作者:
男 bios (阿贡) ★☆☆☆☆ -
盒子中级会员
2004/2/9 10:35:46
1楼: 学习!
----------------------------------------------
按此在新窗口浏览图片
按此在新窗口浏览图片
作者:
男 wanglei916 (rock) ★☆☆☆☆ -
普通会员
2004/2/9 11:50:47
2楼: 不好意思,没有把问题说明白,原先是这样的:
日前想用做DELPHI做一个跟数据采集卡(单片机)串口数据传输的程序,用SPCOMM控件通信,遇到了两个问题,还望大家赐教。
第一,传输数据的类型问题,我在程序中是直接发送的string类型的数据,但是数据采集卡接受到的是ascii码,或者是其他什么码,反正接收不到正常的数据。
第二,使用第三者开发的串口调试程序,通过16进制发送的时候,单片机可以正常接收数据,但是单片机发送的数据的时,串口调试程序如果设定为ASCII码时,无法接收数据,或者接收的数据无法显示。如果设为16进制接收的话,接收后显示的数据有误差。

目前上述两个问题已经解决按此在新窗口浏览图片 ,只剩下这个问题了:

每次接收完一组数据,然后再重新发送的时候,第一次发送的总是最后接收到的数据

接收代码如下
var
    p:pchar;
    //RevP : array [1..4096] of byte;
    i : integer;
    s : byte;
    CommRevStr : String;
begin
     p:=buffer;
     //Move(IArr(buffer)^,Revp,bufferLength);
    CommrevStr:=';
   For i:=1 to BufferLength do
    begin
     s:=ord(p^);
     CommrevStr:=CommrevStr+inttostr(s)+' ';
     inc(p);
    end;
  Memo2.Lines.Add(CommrevStr);
  StatusBar1.Panels[2].Text := '串口2正在接收数据'; 


还需要发送数据的代码吗?



----------------------------------------------
-
作者:
男 bios (阿贡) ★☆☆☆☆ -
盒子中级会员
2004/2/9 12:38:56
3楼: 偶始终不会这些,只能拼命向大哥你学习,无能为力
----------------------------------------------
按此在新窗口浏览图片
按此在新窗口浏览图片
作者:
男 whhuzq (whhuzq) ★☆☆☆☆ -
盒子活跃会员
2004/2/9 12:48:20
4楼: 有没有api实现串口通讯的demo?
----------------------------------------------
-
作者:
男 bjdribllec ( ) ★☆☆☆☆ -
盒子活跃会员
2004/2/9 13:05:06
5楼: 是的,烦您把发送代码放上来看看.
----------------------------------------------
-
作者:
男 wanglei916 (rock) ★☆☆☆☆ -
普通会员
2004/2/9 14:10:44
6楼: bjdribllec 大哥来了,见到你感觉真好,在这个程序上,你帮我的忙太多了,非常感谢你。呵

发送代码如下:

procedure TFormCommTest.StartSendActionExecute(Sender: TObject);
var  strSend: String;
   i : Integer;
begin
if r=0 then
  begin

try
Comm1.StopComm;
Comm1.StartComm;
except
  Messagedlg('无法打开COMM1!', mterror, [mbOK],0);
end;
Sleep(10);
StatusBar1.Panels[1].Text := '串口1已启动';
strsend:=';

    for i:= 0 to Memo1.Lines.Count -1 do
    begin

      strSend := (Memo1.Lines[i]);

      try
      StatusBar1.Panels[1].Text := '串口1正在发送数据';
      Comm1.WriteCommData(PChar(strSend) , Length(strSend));
      except
       Showmessage('发送错误');
      end;
    end;
  end;
if r=1 then
      begin
     try
Comm1.StopComm;
Comm1.StartComm;
except
  Messagedlg('无法打开COMM1!', mterror, [mbOK],0);
end;
      memo2.lines[2]:='999';
      strsend:= (Memo2.Lines[0]);
      Comm1.WriteCommData(PChar(strSend) , Length(strSend));
      r:=0;
      str1:=';
      str2:=';
      memo2.Lines.Clear;
      
      strSend:=';


      end;
    end;

----------------------------------------------
-
作者:
男 skertone (奇奇怪) ★☆☆☆☆ -
盒子活跃会员
2004/2/9 14:29:33
7楼: 用API直接操作串的 恰巧我的一个项目要用既然写好了就贴上来大家来完善一下

由于是用在Dlls中所以没有用String 我不敢用啊,怕其它开发工具调用起来会出什

么问题, 不知哪位有这样的经验 在 Dlls中用String处理 接口部分转化成 PChar 可行?

////////////////////////////////////////////////////////////////////////////////

  function OpenCommPort(CommPort: PChar): COMHWND;stdcall;
  function CloseCommPort(hCom: COMHWND): BOOL;stdcall;
  function ReadCommPort(hCom: COMHWND;var Buffer: array of Char;BufSize: Integer): Integer;stdcall;
  function WriteCommPort(hCom: COMHWND;Buffer: array of Char;WriteSize: Integer): Integer;stdcall;

  function GetCheckSum(DestStr: PChar;Count: Integer): Integer;stdcall;
  function GetCheckSumEx(DestStr: PChar;Start,Count: Integer): Integer;stdcall;

  function SendData(hCom: COMHWND;Buffer: array of Char;Size: Integer): Integer;stdcall;
var
  ErrorCode: Integer;
implementation
////////////////////////////////////////////////////////////////////////////////
//
//       以下部分函数实现串口操作
//
////////////////////////////////////////////////////////////////////////////////
  function OpenCommPort(CommPort: PChar): COMHWND;
  var
    ComStruct: TDCB;
    CommTimeOut : TCOMMTIMEOUTS;
  begin
    ErrorCode := 0;
    Result := CreateFile(CommPort,
                         GENERIC_READ OR GENERIC_WRITE,   //设置串口为可读写
                         0,
                         nil,
                         OPEN_EXISTING,
                         FILE_ATTRIBUTE_NORMAL,          // OR FILE_FLAG_OVERLAPPED,
                         0);
    if Result = INVALID_HANDLE_VALUE then
    begin
      ErrorCode := Result;
      Result := 0;
      Exit;
    end;

    CommTimeOut.ReadIntervalTimeout := MAXDWORD;
    CommTimeOut.ReadTotalTimeoutMultiplier := 0;
    CommTimeOut.ReadTotalTimeoutConstant := 0;

    SetCommTimeouts(Result,CommTimeOut);
    SetupComm(Result,_BufIn,_BufOut);
    GetCommState(Result,ComStruct);
    with ComStruct do
    begin
      BaudRate := _BaudRate;
      ByteSize := 8;
      StopBits := ONESTOPBIT;              //一个停止位 实际值为 0
      Parity := NOPARITY;
    end;
    SetCommState(Result,ComStruct);
    SetCommMask(Result,EV_RXCHAR);
  end;
{------------------------------------------------------------------------------}
  function CloseCommPort(hCom: COMHWND): BOOL;
  begin
    Result := CloseHandle(hCom);
  end;
{------------------------------------------------------------------------------}
  function ReadCommPort(hCom: COMHWND;var Buffer: array of Char;BufSize: Integer): Integer;
  var
    bClear: Boolean;
    dwInNumb,dwReadNumb,dwErr: DWORD;
    rState: TComStat;
    ii: Integer;
    ReadBuf: array[0.._MAXBUFFERSIZE] of Char;
  begin
    Result := 0;
    bClear := ClearCommError(hCom,dwErr,@rState);
    if bClear AND (rState.cbInQue > 0) then
    begin
      if BufSize > _MAXBUFFERSIZE then
      BufSize := _MAXBUFFERSIZE;
      repeat
        Sleep(50); //检测到有数据 等一会 再次收取
        dwInNumb := rState.cbInQue;
        ClearCommError(hCom,dwErr,@rState);
      until dwInNumb = rState.cbInQue;
      
      if rState.cbInQue > BufSize  then
      begin
        PurgeComm(hCom,PURGE_RXCLEAR); //清除COM 数据
        Result := -1;
        Exit;
      end;

      dwInNumb := rState.cbInQue;
      ReadFile(hCom,ReadBuf,dwInNumb,dwReadNumb,nil);
      StrMove(Buffer,ReadBuf,dwReadNumb);
      Result := dwReadNumb;
    end;
  end;
{------------------------------------------------------------------------------}
  function WriteCommPort(hCom: COMHWND;Buffer: array of Char;WriteSize: Integer): Integer;
  var
    dwWrite: DWORD;
  begin
    Result := 0;
    if WriteSize <= 0 then Exit;
    try
      WriteFile(hCom,Buffer,WriteSize,dwWrite,nil);
    except
      Result := -1;
    end;
  end;
{------------------------------------------------------------------------------}

----------------------------------------------
按此在新窗口浏览图片 按此在新窗口浏览图片 按此在新窗口浏览图片
作者:
男 bjdribllec ( ) ★☆☆☆☆ -
盒子活跃会员
2004/2/9 14:31:04
7楼: 别频繁的stop/start串口;实际上start成功后,就又能发又能收了.

还有, strsend:= (Memo2.Lines[0]);
      Comm1.WriteCommData(PChar(strSend) , Length(strSend));
这是把您收到的第一行发送出去了.

多问一句: r=0 / r=1 , r是什么时候变成1的?
----------------------------------------------
-
作者:
男 wanglei916 (rock) ★☆☆☆☆ -
普通会员
2004/2/9 15:15:43
8楼: 呵,谢谢大哥帮我找到了原因,我改过了。
这是修改后的接收代码,r我把它当标志位了。

procedure TFormCommTest.Comm2ReceiveData(Sender: TObject; Buffer: Pointer;
  BufferLength: Word);
type
    IArr = ^integer;
  var
    p:pchar;
    //RevP : array [1..4096] of byte;
    i : integer;
    s : byte;
    CommRevStr : String;

begin
     p:=buffer;
     CommrevStr:=';
   For i:=1 to BufferLength do
    begin
     s:=ord(p^)-128;
        CommrevStr:=CommrevStr+inttostr(s) ;
     inc(p);
    end;
  Memo2.Lines.Add(CommrevStr);


  if x1=0 then
  begin
  str1:=memo2.lines[x1];
  x1:=x1+1;
  BTNStartSend.click;
  end;
  if x1=1 then
      begin
     str2:=memo2.lines[x1];
      if str1=str2 then
        r:=1;
       x1:=0;
     BTNStartSend.click;
      end;


奇奇怪大哥好厉害,这么复杂呀,看了就晕。
----------------------------------------------
-
作者:
男 bjdribllec ( ) ★☆☆☆☆ -
盒子活跃会员
2004/2/9 15:25:37
9楼: 您再读一下您的流程图(如果有);现在看到的变量越来越多, 用途越来越不明,
如果可以发个包上来,或email.真的不太容易看出意图来. 呵呵
BTNStartSend.click; 是要调用发送?
r=1 : 如果接收到两行相同的数据 ?
只是觉得流程有些怪异!

----------------------------------------------
-
作者:
男 wanglei916 (rock) ★☆☆☆☆ -
普通会员
2004/2/9 16:27:01
10楼: 我把我的源程序打包放上去了。你看一下。
我是想实现,连续两次发送111或者222或者333,然后对方连续返回两次数据,如果数据一至,则放到程序中进行计算,计算这一块还没有做,现在只是做好了与串口的通信。

而且,嘿,本人初学程序,但受人之托,做此程序,虽然拿出来给大家看有些贻笑大方,但也是本人努力的结果,而且受到这么多大哥们的支持,小弟真的深受感动。
此帖子包含附件:wanglei916_20042916270.zip 大小:320.5K
----------------------------------------------
-
作者:
男 bjdribllec ( ) ★☆☆☆☆ -
盒子活跃会员
2004/2/9 16:52:27
11楼:   if BaudRate = 1200 then CmbBaudRate.ItemIndex :=0
  else if BaudRate = 2400 then CmbBaudRate.ItemIndex :=1
  else if BaudRate = 4800 then CmbBaudRate.ItemIndex :=2
  else if BaudRate = 9600 then CmbBaudRate.ItemIndex :=3
  else if BaudRate = 19200 then CmbBaudRate.ItemIndex :=4
  else if BaudRate = 38400 then CmbBaudRate.ItemIndex :=5
  else if BaudRate = 57600 then CmbBaudRate.ItemIndex :=6
  else CmbBaudRate.ItemIndex :=7;
==>
si:=CmbBaudRate.Items.IndexOf(IntToStr(BaudRate));
if si=-1 then si:=7;
CmbBaudRate.ItemIndex:=si;

连续发两次111,中间需要间隔吗?
如果不需要,strSend:='111'+'111';

接收到的数据成为一个串,这个串变量在发111111时清空,
延时后,将串一分为两,比较是否相同,应该不象现在这个程序这么复杂.



----------------------------------------------
-
作者:
男 wanglei916 (rock) ★☆☆☆☆ -
普通会员
2004/2/10 11:59:06
12楼: 因为要适应单片机的关系,单片机只能接受3个字节,所以我需要连续发两次111,而且需要间隔,验证的话,如果相同便发送999,不同再接着发送111。
呵呵,谢谢 bjdribllec大哥的操心了。可惜这里不像大富翁里可以送分,否则我一定全全送上。
----------------------------------------------
-
信息
登陆以后才能回复
Copyright © 2CCC.Com 盒子论坛 v3.0.1 版权所有 页面执行156.25毫秒 RSS