求助,串口通讯,

tetsuya 2003-10-16 08:21:48
那位兄弟,可以帮我做个通讯接口的动态连接库,,我这个方面不熟,,考勤软件又要明天交货。急死我了!!
协议如下:
设日期时间:
1、随机发送20个’0’-‘9’之间的数
2、发机器号('A'-'J')。
3、发’?’ 。
4、 12位的日期时间数据(ASC码,加延时),如:'0','0','1','2','3','0','0',8'','3','0','1','2'。表示2000年12月30日8点30分12秒
5、2位的星期,如星期1用’0’,’1’来表示
6、接收到应答信号'Y' 。则表示时间已设好。
7、退出。
接收数据:
1、随机发送25个’0’-‘9’之间的数
2、发机器号('A'-'J')。
3、发'>' 。
4、发6位的年月数据(ASC码,加延时),如: '1','9','9','8','1','2'。表示1998年12月
5、接收连机应答'Y' 。若不是则退出。
6、接收数据应答'Y' 。若不是则退出(为'N'则表示没有当有)。
7、接收小于或等于260字节的数据块。
格式为0xBB + 数据 + 0xBB(或0xCC) + 检验和(2字节)
其中 :整个块为二进制数据
:0xBB为数据块起始和结束标志
:0xCC为数据传输结束标志
:检验和为数据(不加标志位)的二进制和对256的余数
8、如果数据正确接收则发块应答Y ,保存数据,继续过程6,直到结束(收到0xCC或在5秒之内只收到
1个0xBB)。否则发非应答'N' ,错误计数器加1(如超过5次,则整个过程无效,退出),继续过程5。
数据格式
(例子): 3A3A393831323031 30303031 30383330 30303032 30383330
3A3A393831323032 30303031 31343030 30303032 31343030
注: 1、空隔只是为了查看方便,实际上没有
2、上述情况为1号和2号卡在98年月12月1号-2号的考勤数据,列表则为:
卡号/日期 1998/12/01 1998/12/02
0001 08:30 12:00
0002 08:30 12:00
Evan_G@163.com
...全文
88 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
shiufurong007 2003-11-13
  • 打赏
  • 举报
回复
up
jpyc 2003-10-23
  • 打赏
  • 举报
回复
http://218.56.11.178:8020/web/technology.aspx

->串口通讯应用程序的解决方案


http://218.56.11.178:8020/web/technology.aspx

-> 下载基地->例程-硬件控制->串口通讯控制器/spcom事例程序

->控件-硬件控制->TurboPower Async Professional/spcom
lxhong1980 2003-10-23
  • 打赏
  • 举报
回复

发送D1 应答为 CC 握手成功 再发送其他
unit TiQianL_Set_Frm;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls, Buttons,IniFiles, SPComm;

type
TForm_Set_TiQianLiang = class(TForm)
Panel1: TPanel;
GroupBox1: TGroupBox;
Bbtn_Exit: TBitBtn;
Bbtn_Sure: TBitBtn;
GroupBox2: TGroupBox;
Edt_Right: TEdit;
EdT_Left: TEdit;
Pnl_Left: TPanel;
Pnl_Right: TPanel;
Comm1: TComm;
procedure Bbtn_ExitClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure Bbtn_SureClick(Sender: TObject);
procedure EdT_LeftKeyPress(Sender: TObject; var Key: Char);
procedure Comm1ReceiveData(Sender: TObject; Buffer: Pointer;
BufferLength: Word);
procedure FormShow(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form_Set_TiQianLiang: TForm_Set_TiQianLiang;
sRece1:string; //接收到的字符串
rbuf:array[1..20] of byte;//把接收到的二进制转化为整数,存储在数组里
pDataToWrite:array[1..20] of char; // 要发送的,转化为字符
LDate:Integer;//发送字符长度
implementation

uses Globe_Frm;

{$R *.dfm}

procedure TForm_Set_TiQianLiang.Bbtn_ExitClick(Sender: TObject);
begin
pDataToWrite[1]:=chr(byte($F3));
LDate:=1;
Comm1.Inx_XonXoffFlow:=false;
Comm1.Outx_XonXoffFlow:=false;
Comm1.WriteCommData(@(pDataToWrite),LDate);
Close;
end;

procedure TForm_Set_TiQianLiang.FormCreate(Sender: TObject);
var
IniF:TIniFile;
begin
IniF:=TIniFile.Create('.\HJKZ.ini');
EdT_Left.Text:=IniF.ReadString('TiQianLSet','Left','10');
EdT_Right.Text:=IniF.ReadString('TiQianLSet','Right','20');
IniF.Free;
end;

procedure TForm_Set_TiQianLiang.Bbtn_SureClick(Sender: TObject);
var
IniF:TIniFile;
dtTmp:TDateTime;
begin
IniF:=TIniFile.Create('.\HJKZ.ini');
IniF.WriteString('TiQianLSet','Left',EdT_Left.Text);
IniF.WriteString('TiQianLSet','Right',EdT_Right.Text);
IniF.Free;

pDataToWrite[1]:=chr(byte($D1));
LDate:=1;
Comm1.Inx_XonXoffFlow:=false;
Comm1.Outx_XonXoffFlow:=false;
Comm1.WriteCommData(@(pDataToWrite),LDate);

dtTmp:=Now;
while ((not (sRece1='CC'))do
begin
Application.ProcessMessages;
end;

if sRece1<>'CC' then
begin
Application.MessageBox('握手失败!','提示',MB_OK+MB_ICONINFORMATION);
Exit;
end;

pDataToWrite[1]:=chr(byte($A8));
pDataToWrite[2]:=chr(byte($02));
pDataToWrite[3]:=chr(byte (StrToInt('$'+ Edt_Left.Text )));
pDataToWrite[4]:=chr(byte (StrToInt('$'+ Edt_Right.Text)));
LDate:=4;
Comm1.Inx_XonXoffFlow:=false;
Comm1.Outx_XonXoffFlow:=false;
Comm1.WriteCommData(@(pDataToWrite),LDate);
end;

procedure TForm_Set_TiQianLiang.EdT_LeftKeyPress(Sender: TObject;
var Key: Char);
begin
if((key<#48 ) or(key>#57)) and (key<>#8) then
begin
key:=#0;
end;
end;

procedure TForm_Set_TiQianLiang.Comm1ReceiveData(Sender: TObject;
Buffer: Pointer; BufferLength: Word);
var
i:integer;
begin
sRece1:='';
move(buffer^,pchar((@rbuf)^),bufferlength);
for i:=1 to bufferlength do
begin
sRece1:=sRece1+ inttohex(rbuf[i],2);
end;
end;

procedure TForm_Set_TiQianLiang.FormShow(Sender: TObject);
begin
Comm1.CommName:=Glb_Com;
Comm1.StartComm;
end;

procedure TForm_Set_TiQianLiang.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
Comm1.StopComm;
end;

end.
OrientOh 2003-10-16
  • 打赏
  • 举报
回复
可以找我,我有一个已封装好的动态库,当然不免费哪!
yaven365 2003-10-16
  • 打赏
  • 举报
回复

procedure TComm.FreeComm;
begin
if hCommFile=0 then exit;

//Now close the comm port handle.
PurgeComm(hCommFile, PURGE_RXABORT + PURGE_RXCLEAR
+ PURGE_TXABORT + PURGE_TXCLEAR);
CloseHandle(hCommFile);
hCommFile := 0;
bOpened := False;
end;

function TComm.WriteData(pDataToWrite: PChar; dwSizeofDataToWrite: DWORD): Boolean;
var
nSent: DWORD;
begin
Result := WriteFile(hCommFile, pDataToWrite^, dwSizeofDataToWrite,
nSent, Nil);
end;

procedure TComm.SendStr(str: String);
begin
str := str+ Chr(13) + Chr(10);
WriteData(PChar(str), Length(str));
end;

function TComm.ReadData(pBuffer: PChar; BufferSize: DWORD): boolean;
var
nRead: DWORD;
begin
Result := ReadFile(hCommFile, pBuffer^, BufferSize, nRead, Nil);
end;

//
// FUNCTION: GetModemState
// PURPOSE: Read the state of modem input pin right now
// RETURN VALUE:
// A DWORD variable containing one or more of following codes:
//
// Value Meaning
// ---------- -----------------------------------------------------------
// MS_CTS_ON The CTS (clear-to-send) signal is on.
// MS_DSR_ON The DSR (data-set-ready) signal is on.
// MS_RING_ON The ring indicator signal is on.
// MS_RLSD_ON The RLSD (receive-line-signal-detect) signal is on.
//
// If this comm have bad handle or not yet opened, the return value is 0
//
function TComm.GetModemState : DWORD;
var
dwModemState : DWORD;
begin
if not GetCommModemStatus(hCommFile, dwModemState) then
Result := 0
else
Result := dwModemState
end;

function TComm.BytesInInQue: DWORD;
var
stat: TCOMSTAT;
errs: DWORD;
begin
ClearCommError(hCommFile, errs, @stat);
Result := stat.cbInQue;
end;

function TComm.BytesInOutQue: DWORD;
var
stat: TCOMSTAT;
errs: DWORD;
begin
ClearCommError(hCommFile, errs, @stat);
Result := stat.cbOutQue;
end;

function TComm.WaitForBytes(Bytes: DWORD; TimeLen: DWORD): boolean;
var
time1, time2: DWORD;
begin
time1 := getTickCount;
time2 := time1;
while (BytesInInQue<Bytes) and (hCommFile<>0) and ((time2-time1)<TimeLen)
do begin
Application.ProcessMessages;
time2 := GetTickCount;
end;
if BytesInInQue>=Bytes then Result := True
else Result := False;
end;

procedure TComm.ClearComm;
begin
PurgeComm(hCommFile, PURGE_TXABORT or PURGE_RXABORT or
PURGE_TXCLEAR or PURGE_RXCLEAR);
end;

function TComm.WaitOK(TimeLen: DWORD): boolean;
var
time1, time2: DWORD;
flag: integer;
TempByte: Byte;
begin
flag := 0;
time1 := GetTickCount();
time2 := time1;
Result := False;
while (flag<>2) and ((time2-time1)<TimeLen) do
begin
if not WaitForBytes(1, 1000) then exit;
ReadData(@TempByte, 1);
if flag=0 then
begin
if TempByte=Ord('O') then flag := 1
end else begin
if TempByte=Ord('K') then
begin
flag := 2;
Result := True;
end else flag := 0; //clear flag
end;
time2 := GetTickCount();
end;
end;

end.
yaven365 2003-10-16
  • 打赏
  • 举报
回复

implementation

constructor TComm.Create(AOwner: TComponent);
begin
inherited Create( AOwner );

hCommFile := 0;
bOpened := False;

// Default size of the Input Buffer used by this code.
INQUESIZE := 40960;
OUTQUESIZE := 8192;
end;

destructor TComm.Destroy;
begin
FreeComm;
inherited Destroy;
end;

function TComm.InitComm(ThisCommName: string; BaudRate,DataByte,StopByte,ParityByte: integer): Boolean;
var
dcb: Tdcb;
begin
//Are we already doing comm?
if hCommFile<>0 then
begin
InitComm := False;
exit;
end;

hCommFile := CreateFile( PChar(ThisCommName),
GENERIC_READ or GENERIC_WRITE,
0, {not shared}
nil, {no security ??}
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0);

if hCommFile=INVALID_HANDLE_VALUE then
begin
hCommFile := 0;
InitComm := False;
exit;
end;

//Is this a valid comm handle?
if GetFileType(hCommFile)<>FILE_TYPE_CHAR then
begin
CloseHandle(hCommFile);
hCommFile := 0;
InitComm := False;
exit;
end;

//Querying then setting the comm port configurations.
GetCommState(hCommFile, dcb);

dcb.BaudRate := BaudRate;
dcb.ByteSize := DataByte; //number of bits/byte, 4-8
dcb.Parity := ParityByte; //0-4=no,odd,even,mark,space
dcb.StopBits := StopByte; //0,1,2 = 1,1.5,2

{ dcb.Flags := 1; // Enable fBinary

if FParityCheck then
dcb.Flags := dcb.Flags or 2; // Enable parity check

if FOutx_CtsFlow then
dcb.Flags := dcb.Flags or 4;

if FOutx_DsrFlow then
dcb.Flags := dcb.Flags or 8;

if FDtrControl = DtrEnable then
dcb.Flags := dcb.Flags or $10;
else if FDtrControl = DtrHandshake then
dcb.Flags := dcb.Flags or $20;

if FDsrSensitivity then
dcb.Flags := dcb.Flags or $40;

if FTxContinueOnXoff then
dcb.Flags := dcb.Flags or $80;

if FOutx_XonXoffFlow then
dcb.Flags := dcb.Flags or $100;

if FInx_XonXoffFlow then
dcb.Flags := dcb.Flags or $200;

if FReplaceWhenParityError then
dcb.Flags := dcb.Flags or $400;

if FIgnoreNullChar then
dcb.Flags := dcb.Flags or $800;

if FRtsControl = RtsEnable then
dcb.Flags := dcb.Flags or $1000;
else if FRtsControl = RtsHandshake then
dcb.Flags := dcb.Flags or $2000
else if FRtsControl = RtsTransmissionAvailable then
dcb.Flags := dcb.Flags or $3000;
}
if not SetCommState(hCommFile, dcb) then
begin
CloseHandle(hCommFile);
hCommFile := 0;
InitComm := False;
exit;
end;

if not SetupComm(hCommFile, INQUESIZE, OUTQUESIZE) then
begin
CloseHandle(hCommFile);
hCommFile := 0;
InitComm := False;
exit;
end;

//purge any information in the buffer
PurgeComm(hCommFile, PURGE_TXABORT or PURGE_RXABORT or
PURGE_TXCLEAR or PURGE_RXCLEAR);

InitComm := True;
bOpened := True;
CommName := ThisCommName;
end;
yaven365 2003-10-16
  • 打赏
  • 举报
回复
最近太忙了,不然就帮你写一些,这些api的代码

给你,自己看看改改!

unit MyComm;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

const
//
// Modem Event Constant
//
ME_CTS = 1;
ME_DSR = 2;
ME_RING = 4;
ME_RLSD = 8;

type
TComm = class( TComponent )
private
hCommFile: THandle;
public
bOpened: boolean;
CommName: string;
INQUESIZE, OUTQUESIZE: integer;

constructor Create(AOwner: TComponent); override;
destructor Destroy; override;

function InitComm(ThisCommName: string; BaudRate,DataByte,StopByte,ParityByte: integer): Boolean;
procedure FreeComm;

function WriteData(pDataToWrite: PChar; dwSizeofDataToWrite: DWORD): Boolean;
function ReadData(pBuffer: PChar; BufferSize: DWORD): boolean;
function BytesInInQue: DWORD;
function BytesInOutQue: DWORD;
function WaitForBytes(Bytes: DWORD; TimeLen: DWORD): boolean;
procedure ClearComm;
function GetModemState: DWORD;

procedure SendStr(str: String);

function WaitOK(TimeLen: DWORD): boolean; //wait for OK till timeLen(in seconds)
end;

const
// This is the message posted to the WriteThread
// When we have something to write.
PWM_COMMWRITE = WM_USER+1;

implementation
tetsuya 2003-10-16
  • 打赏
  • 举报
回复
:(
yaven365 2003-10-16
  • 打赏
  • 举报
回复
你直接调用api函数吧,应该不是很难,难的只是调试
tetsuya 2003-10-16
  • 打赏
  • 举报
回复
写了,后我自己来,我及时在线
yaven365 2003-10-16
  • 打赏
  • 举报
回复
老大,这个东西没有硬件,没有调试环境,没谁能做出来

除非特别熟悉,否则怎么也得2个礼拜左右!
tetsuya 2003-10-16
  • 打赏
  • 举报
回复
ding
saien 2003-10-16
  • 打赏
  • 举报
回复
不是很难,将业务封装一个类,然后利用spComm控件即可。
tetsuya 2003-10-16
  • 打赏
  • 举报
回复
谁能帮我解释一下,传过来传过去的东西因该是这么样的萨,
iSee视频监控 v5.2 视频监控软件使用说明书 版权所有 翻录必究 2009年10月1日 Ver:01.01.05 注意事项 首先,感谢您选用我公司最新产品。 在使用本监控卡之前,请详细阅读本说明书所涉及的相关事项,熟悉 硬件、软件各部分的功能后,方能使用,以确保该系统为您发挥最佳功能。 否则一切后果自负。 本说明书将向您详细阐述全实时“视频监控系统”的安装、操作、设 置和网络使用方法。 本系统工作主机供电电压为220V_10%,如果在电压不稳或者干扰大 的场合,请您选用优质稳压电源(即UPS),保证系统正常良好的工作状态。 本系统在安装、拆卸视频采集卡时,必须将主机处于完全断电状态, 否则主板上残留的电压将损坏采集卡。 本系统可切换D1与CIF分辨率,切换分辨率设置后,在主界面必须关 闭通道视频,重新打开通道视频,设置才能生效。 本系统主机工作于常温(-10_3℃~55_2℃)、清洁的环境,并且保持 良好的通风状态。 本系统软件属于我公司专有产品,未经同意,请勿复制,否则影响机 器稳定概不负责,并将通过有关法律渠道追究盗版责任。 功能特点(H.264压缩) 压缩方式:H.264/MPEG 4; 显示分辨率:1024_768、1280_1024、16:9宽屏、16:10宽屏; 预览分辨率 (可调) :704_576(PAL制),740_480(NTSC制); 352_288(PAL制),370_240(NTSC制); 录像分辨率(所见即所得):704_576(PAL制), 740_480(NTSC制); 352_288(PAL制),370_240(NTSC制); 单机容量支持12路D1、48路CIF; 支持单画面、4画面、9画面、16画面、20画面、25画面显示,可全屏显示,支持自动 翻页; 多画面实时显示/录像/回放功能,支持多协议云镜控制,支持多种报警盒实现联动报警; 手动录像、连续录像、定时录像、动态录像、事件录像、联动报警录像等多种录像方式; 可以设置每个通道的显示名称; NTSC/PAL两种视频显示制式可选, 25帧/秒实时预览、录像、回放; 视频图像属性调节功能,使图像更清晰。 视频录像图像质量有多种等级可调,以改变存储文件大小,方便不同场合应用。 视频移动报警录像功能,报警录像灵敏度、预录像时间、延迟录像时间可调,支持声音 报警输出。 智能检索,可按摄像镜头年/月/日/时间段或长时间连续检索回放,自动检索报警录像, 能区分录像事件。 具有局部放大功能,可逐帧回放,快速播放,慢速播放,常规播放。 回放时可进行图片抓拍功能,回放时文件备份功能、文件剪辑功能。 可进行远程监控,远程控制云镜、色彩、手动录像、布撤防、重启计算机等控制工作。 支持现今最大容量的硬盘,并支持安装多个大容量的硬盘。 硬盘管理可以通过对最大使用硬盘和硬盘最小预留空间的设置使硬盘能够得到充分合理 的使用。 自动创建日志文件(用户操作日志、系统日志、远程控制日志),便于查询操作记录。 系统可任意设置定时关机,定时重启功能,保证系统运行的高稳定性。 可设定开机自动运行监控软件,断电自动关闭程序,来电自动重启,自动恢复录像。 硬件、软件经过严格的拷机试验,稳定可靠。 系统硬件配置要求低,48路同时录像显示时,CPU的占用率低于75%。 系统能有效防止用户多次重复运行监控系统导致系统崩溃的情况。 目录 第一部分 软件安装与卸载..............................................................................................................6 1.1 系统要求 ..................................................................................................................................................6 1.1.1 硬件要求(推荐) ................................................................................

5,386

社区成员

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

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