高分求解,有关使用spcomm进行串口通讯的基础知识问题。(300分)

  • 主题发起人 主题发起人 HanFeng
  • 开始时间 开始时间
H

HanFeng

Unregistered / Unconfirmed
GUEST, unregistred user!
1、 波特率谁说了算?假如我用pc机同外设通过串口通讯,我想设多少波特率就是
多少吗?如果设备说他支持最高19200,那么就意味着只要19200以下的波特率
都可以吗?我怎么知道外设用的多少波特率?是不是首次同外设握手的时候必
须使用一个固定的波特率?假如外设的串口设定为600,我把pc机设为1200,
我发送的字符个数是否外设只能接收一半?还是同校验位、数据长度等等有关?
2、 我用spcomm同外设通讯,握手总是不成功,原因是:我发送了握手命令:
D0 D1 D2,外设立即做了响应,可是我的spcomm过了好半天(超时)才收到返回信
息,感觉好像spcomm的eventMask不对,这是为何?
3、 我的外设主要是交互应答的方式,我给他发不同的请求命令,它给我返回不同的
结果,命令比较多,每种命令的翻回结果可能性也比较多,用spcomm的事件处理
总觉得很别扭,是不是直接用API更简单些?
4、 OverLapped的准确译法是什么?有何作用?
5、 还有其他问题,遇到了再问。
6、 欢迎关注我的另一个问题:http://www.delphibbs.com/delphibbs/dispq.asp?LID=1622544
 
波特率要保证数据传输正确,而且两边应一致,不能太高。
其他的看别的帖子
 
SPCOMM RS-232多线程控件例子:现时DELPHI上有很多串行口控件,SPCOMM控件有Data Bits、Parity、 Stop Bits 等配置,支持 Read/Write 时序控制 (Timing control)、 ReadIntervalTimeout、 WriteIntervalTimout 等 ,支持 DTR/DSR, RTS/CTS 硬件流程控置及 Xon/Xoff 软件流程控置,是目前比较完善的控件。 以下是一个用RS-232进行数据接收、显示的例子。必须将RS232的通信参数设置好才能正确接收数据。(Data Bits,Parity,Stop Bits,COM口参数)
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, SPComm;
type
TForm1 = class(TForm)
Comm1: TComm;
Memo1: TMemo;
procedure Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
var
s: string;
begin
SetLength(S, BufferLength); //接收RS232的数据并显示Memo1上。
Move(Buffer^, PChar(S)^, BufferLength);
Memo1.Lines.Add(S);
Memo1.Invalidate;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Comm1.startcomm;//创建窗体时,将comm1控件打开。
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
comm1.StopComm;//关闭窗体时,将comm1控件关闭。
end;
end.
 
同步方式:NonOverlapped,
异步方式:Overlapped
 
procedure Tform1.Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
begin
SetLength(s, BufferLength);
Move(Buffer^, pchar(s)^, BufferLength);
edit2.text:=s;
end;

procedure Tform1.BitBtn1Click(Sender: TObject);
begin
comm1.WriteCommData(pchar(edit1.text),length(edit1.text));
end;

procedure Tform1.BitBtn2Click(Sender: TObject);
begin
comm1.commname:=combobox1.Text;
comm1.StartComm;
comm1.BaudRate:=strtoint(combobaudrate.Text);
case combodatabits.ItemIndex of
0:comm1.ByteSize:=_5;
1:comm1.ByteSize:=_6;
2:comm1.ByteSize:=_7;
3:comm1.ByteSize:=_8;
end;
case combostopbits.ItemIndex of
0:comm1.stopbits:=_1;
1:comm1.stopbits:=_1_5;
2:comm1.stopbits:=_2;
end;
case comboparity.ItemIndex of
0:comm1.Parity:=None;
1:comm1.Parity:=Odd;
2:comm1.Parity:=Even;
3:comm1.Parity:=Mark;
4:comm1.Parity:=Space;
end;
if comboparity.ItemIndex=0 then comm1.ParityCheck:=false
else comm1.paritycheck:=true;
BitBtn2.Enabled:=false;
end;

procedure Tform1.BitBtn3Click(Sender: TObject);
begin
comm1.StopComm;
BitBtn2.Enabled:=true;
end;

procedure Tform1.Button1Click(Sender: TObject);
begin
edit1.Clear;
edit2.clear;
end;
 
journer,
为什么有的软件能够设置波特率呢?比如说modem,双方是如何协商的哪?
 
波特率要在两边都设置好,两边要一致才行。

外设的波特率你的知道,然后把pc机的设为和他一样。
 
都是由主机决定的,如你的PC程序
对方只是协调处理
 
journer,薄荷:
对方如何协调呢?比方说我这里设了波特率600,对方能够判断出来我设的是多少吗?
我要是设了1200,是不是对方也能判断出来呢?我实际再同外设打交道的时候,好像
握手信号必须是600。如果调成1200,就乱套了。
 
看看AT命令吧,你登陆后应该就不能改了
修改后(重新设置后)应再次登陆吧
 
我只是用modem做例子说明这个问题罢了,其实我的外设不是modem,我对at命令也不熟,
希望您能详细讲解,at命令有是如何实现对方波特率时别的。
 
1、对于使用串口和外设通讯,必须保证:spcomm中的速度、位数、停止位、检验位、检验方式和外设
一致,而且该是修改spcomm的参数以适应外设,否则无法正常通信。
2、通常外设的通信参数无法通过计算机进行修改,只有查找外设的手册中通信参数后修改
程序。
3、对于交互方式可以使用spcomm的事件处理,我一直这样处理,效果不错。
4、
 
丢了好多贴!哪里去了?
 
知道了!丢失了两天的数据。替barton和dangel补上,还有barton说的话我在语气上稍作修改,不是原版,
但保持原意。

barton 在 2003-2-28 16:43:47 提供了如下回答, 请您查阅和评估:
--------------------------------------------------------------------------
---
>>外设握手必须采用600,但数据传输可以设到19200
这话不对!两端连接好后怎么可以换波特率!spcomm设定好波特率后再不能变,否
则必须先断开,然后按新的波特率再连接。刚才这么多大虾说得已经很清楚了。外设的波特率应该由外设自己解决!
>>各项参数都已经设定正确,但是spcomm响应不及时,为何?
试试将缓冲改小一点或者一次多发一些数据看看。反正我用spcomm时没有遇到这样的情况。
>>或者这个初始值是由驱动程序写道注册表里的。
串口驱动程序是由系统安装的,系统怎么知道你用什么外设,什么波特率!

dangel 在 2003-2-28 16:57:47 提供了如下回答, 请您查阅和评估:
--------------------------------------------------------------------------
---
1。波特率必须两个外设是一致的。。如果你的通讯是PC机和单片机,这种速率必须
严格
一致,不然数据传输 会发生丢失,。如果你用的MODEM做外设,波特率也许要一致,
这个
速率你可以再控制面板你进行设置。传输速率不是说能有多高就有多高的,要考虑现
场的
环境,不如说干扰,。或者你是有线通讯还是无线通讯,这些赢都要考虑、同事其他
设置都
应该一直。
2。不能及时相应不知道你再程序中有没有设置自动应答。这不是数据缓冲区的问
题,
SPCOMM的缓冲区大约是2056字节。。我曾经用过最大的缓冲,都没有出现这种情况,
3。还有一种情况是用SPCOMM拨号时,如果是MODEM之间的话,它们再响应以后需要时
间来
进行监测和建立通讯的链路,时间大约是5秒到10秒,这个时间是正常的等待时间。
--------------------------------------------------------------------------

 
我的回答也补上:
自动应答如何设?
to barton:
换波特率是参考程序作的,与spcom无关。
驱动程序是指modem的。
barton后来又说:
barton 在 2003-2-28 23:03:14 提供了如下回答, 请您查阅和评估:
--------------------------------------------------------------------------
你看看spcomm的源码就明白我说的缓冲区问题了。用别的控件也许与缓冲区无关,但spcomm
会。我这是经验之谈。
--------------------------------------------------------------------------
请barton dangle继续讨论,否则将来无法给分你们
 
直接用api:
下面是我编写的打开端口的程序;
//以下是打开通信端口的程序
procedure TMenuForm.OpenComm;
var
cc:TCOMMCONFIG;
Temp:string;
begin
self.port:=myini.ReadString('端口设置','端口','COM1');
self.baudrate:=myini.ReadInteger('端口设置','波特率',9600); // 设置波特率为9600
self.data_bit:=myini.ReadInteger('端口设置','数据位',8); // 字节为 8 bit
self.efficacy_bit:=myini.ReadInteger('端口设置','效验位',0); // /NOPARITY; // Parity 为 None
self.stop_bit:=myini.ReadInteger('端口设置','停止位',0); //ONESTOPBIT; // 1 个Stop bit}
self.delay_time:=myini.ReadInteger('端口设置','延迟时间',500);
self.ftu_address:= myini.ReadInteger('FTU设置','FTU地址',0);//add
Temp:= port; // 选择所要打开的COM
hComm:=CreateFile(PChar(Temp),//文件名指针,如com1,com2
GENERIC_READ or GENERIC_WRITE, //存取属性

2, //共享模式 0-不共享, 1-共相书
nil, OPEN_EXISTING, 0, 0); // 打开COM
if (hComm = INVALID_HANDLE_VALUE) then begin // 如果COM 未打开
MessageBox (0, '打开通信端口错误!!','',MB_OK);
exit;
end;

GetCommState(hComm,cc.dcb); // 得知目前COM 的状态

cc.dcb.BaudRate:= baudrate;//CBR_9600; // 设置波特率为9600
cc.dcb.ByteSize:=data_bit; // 字节为 8 bit
cc.dcb.Parity:=efficacy_bit; //NOPARITY; // Parity 为 None
cc.dcb.StopBits:=stop_bit; //ONESTOPBIT; // 1 个Stop bit
{ port:string;
baudrate:integer;
efficacy_bit:integer;
data_bit:integer;
stop_bit:string;
str_com:string;}
if not SetCommState(hComm, cc.dcb) then begin// 设置COM 的状态
MessageBox (0, '通信端口设置错误!!!','',MB_OK);


CloseHandle(hComm);
exit;
end;
self.S1.Visible:=true;
self.StatusBar1.Panels[1].Text:='端口状态:打开';
self.Tbtn_open.Enabled:=false;
self.Tbtn_close.Enabled:=true;
//
self.O1.Enabled:=false;
self.N1.Enabled:=true;


end;
(我也有个问题,请各位大侠帮忙啊:)
------------------------------


那位大虾能帮帮忙,感激万分,下面是具体要求:

-------------------------------------

继承Delphi现有的 Grid (StringGrid Etc.) 作一个新的Grid
要求:
增加Columns Property
在Columns中设定每一列的
1) Alignment taLeftJustify taCenterJustify taRightJustify
2) Color
3) Font
4) ImeMode
5) ImeName
6) ReadOnly
7) Title
Alignment
Font
Caption

 
还没有结吗?
 
后退
顶部