需要<br>1.了解传输方式,比如RS232,489等等<br>2.了解通讯协议,是二进制传送还是字符串方式传送<br>3.使用控件或者API<br><br>下面是我的一个单元的代码希望对你有帮助<br><br><br>{ 实验室设备软件 }<br>{ System Resource }<br>{ 串口定义单元 }<br><br>{ Copyright (c) 2005, CHR Corporation }<br>{ Date: 2005-10-01 }<br>{ Build: 2005-11-17 }<br>{ Author: muhx }<br><br>unit UntCommDefine;<br><br>interface<br><br>uses<br> Windows, Classes, SyncObjs, SysUtils, UntTypeDefine;<br><br>type<br> { 串口通讯类 }<br> TCom = class<br> private<br> FCriticalSection: TCriticalSection;<br> FHandle: THandle;<br><br> FComName: string;<br> FBaud: TBaudRate;<br> FParity: TParity;<br> FStopBit: TStopBit;<br> FDataBit: TDataBit;<br> FInQueue: Integer;<br> FOutQueue: Integer;<br> FReadTimeOut: Integer;<br> FWriteTimeOut: Integer;<br> FTimeOut: COMMTIMEOUTS;<br> FEventMask: Integer;<br> private<br> procedure Lock;<br> procedure Unlock;<br> function HandtoClip(AAddress: Byte): Boolean;<br> function ReceiveData(APReceive: PByte; AReceiveLen: Integer): Boolean;<br> function FiltrateUnableDate: Boolean;<br> public<br> constructor ComCreate(AComSet: TComSet);<br> destructor Destroy; override;<br> public<br> procedure ChangeComSet(const AComSet: TComSet);<br> procedure ChangeParity(AParity: TParity);<br> procedure CloseCom;<br> procedure OpenCom;<br> procedure PurgeCom;<br> function Enabled: Boolean;<br> function Read(var APData; ADataLen: Integer): Boolean;<br> function Write(var APData; ADataLen: Integer): Boolean;<br> public<br> function SendCommand(APCommand: PCmdParam): Boolean;<br> public<br> property gHandle: THandle read FHandle;<br> property gBaud: TBaudRate read FBaud default br57600;<br> property gDataBit: TDataBit read FDataBit default da8;<br> property gInQueue: Integer read FInQueue default 4096;<br> property gOutQueue: Integer read FOutQueue default 2048;<br> property gParity: TParity read FParity default paSpace;<br> property gStopBits: TStopBit read FStopBit default sb10;<br> property gReadTimeOut: Integer read FReadTimeOut default 2000;<br> property gComName: string read FComName;<br> property gWriteTimeOut: Integer read FWriteTimeout default 2000;<br> end;<br><br> TComArray = array[0..NUM_UNIT - 1] of TCom;<br><br>implementation<br><br>{ 创建串口类 }<br>constructor TCom.ComCreate(AComSet: TComSet);<br>begin<br> inherited Create;<br> { 临界区 }<br> FCriticalSection := TCriticalSection.Create;<br> { 串口控制句柄 }<br> FHandle := INVALID_HANDLE_VALUE;<br> { 串口参数 }<br> FComName := COMComID[AComSet.csComID];<br> FParity := AComSet.csParity;<br> FBaud := AComSet.csBaud;<br> FDataBit := AComSet.csDataBit;<br> FStopBit := AComSet.csStopBit;<br> FInQueue := AComSet.csInQueue;<br> FOutQueue := AComSet.csOutQueue;<br> FReadTimeOut := AComSet.csReadTimeOut;<br> FWriteTimeOut := AComSet.csWriteTimeOut;<br> FEventMask := EV_RXCHAR;<br> { 两个字节传输间隔 }<br> FTimeOut.ReadIntervalTimeout := 30;<br> { 每字节传输时间 }<br> FTimeOut.ReadTotalTimeoutMultiplier := 5;<br> { 没有字节时返回时间 }<br> FTimeOut.ReadTotalTimeoutConstant := 80;<br> { 每字节传输时间 }<br> FTimeOut.WriteTotalTimeoutMultiplier := 5;<br> { 传输时间常量 }<br> FTimeOut.WriteTotalTimeoutConstant := 50;<br> { 打开串口 }<br> OpenCom;<br>end;<br><br>{ 释放串口类 }<br>destructor TCom.Destroy;<br>begin<br> CloseCom;<br> if FCriticalSection <> nil then<br> begin<br> FCriticalSection.Free;<br> FCriticalSection := nil;<br> end;<br> inherited Destroy;<br>end;<br><br>{ 判断串口是否创建 }<br>function TCom.Enabled: Boolean;<br>begin<br> Result := FHandle <> INVALID_HANDLE_VALUE;<br>end;<br><br>{ 关闭串口 }<br>procedure TCom.CloseCom;<br>begin<br> if Enabled then<br> begin<br> Sleep(100);<br> CloseHandle(FHandle);<br> FHandle := INVALID_HANDLE_VALUE;<br> end;<br>end;<br><br>{ 更改串口参数 }<br>procedure TCom.ChangeComSet(const AComSet: TComSet);<br>var<br> tmpDCB: DCB;<br>begin<br> try<br> with AComSet do<br> begin<br> FParity := csParity;<br> FBaud := csBaud;<br> FDataBit := csDataBit;<br> FStopBit := csStopBit;<br> FInQueue := csInQueue;<br> FOutQueue := csOutQueue;<br> FReadTimeOut := csReadTimeOut;<br> FWriteTimeOut := csWriteTimeOut;<br> end;<br><br> if Enabled then<br> begin<br> tmpDCB.DCBlength := SizeOf(DCB);<br> GetCommState(FHandle, tmpDCB);<br> tmpDCB.BaudRate := COMBaudRate[FBaud];<br> tmpDCB.Parity := COMParity[FParity];<br> tmpDCB.ByteSize := COMDataBit[FDataBit];<br> tmpDCB.StopBits := COMStopBit[FStopBit];<br> <br> if not (SetupComm(FHandle, FInQueue, FOutQueue) and SetCommState(FHandle, tmpDCB))<br> then Abort;<br> PurgeCom;<br> end;<br> except<br> on E: Exception do<br> begin<br> CloseCom;<br> end;<br> end;<br>end;<br><br>{ 更改串口奇偶校验设置 }<br>procedure TCom.ChangeParity(AParity: TParity);<br>var<br> tmpDCB: DCB;<br>begin<br> try<br> FParity := AParity;<br> if Enabled then<br> begin<br> tmpDCB.DCBlength := SizeOf(DCB);<br> GetCommState(FHandle, tmpDCB);<br> tmpDCB.Parity := COMParity[FParity];<br><br> if not SetCommState(FHandle, tmpDCB) then<br> Abort;<br> PurgeCom;<br> end;<br> except<br> on E: Exception do<br> begin<br> CloseCom;<br> end;<br> end;<br>end;<br><br>{ 进入临界区 }<br>{ 在对串口进行操作的时候确保没有同时进行其他操作 }<br>procedure TCom.Lock;<br>begin<br> FCriticalSection.Enter;<br>end;<br><br>{ 退出缓冲区 }<br>procedure TCom.Unlock;<br>begin<br> FCriticalSection.Leave;<br>end;<br><br>{ 创建串口 }<br>procedure TCom.OpenCom;<br>var<br> tmpDCB: DCB;<br>begin<br> if Enabled then<br> Exit;<br> try<br> FHandle := CreateFile(PChar(FComName), GENERIC_READ or GENERIC_WRITE,<br> 0, nil,<br> OPEN_EXISTING,<br> FILE_FLAG_OVERLAPPED,<br> 0);<br><br> if not Enabled then<br> Abort<br> else begin<br> { 设置串口参数 }<br> tmpDCB.DCBlength := SizeOf(DCB);<br> GetCommState(FHandle, tmpDCB);<br> tmpDCB.BaudRate := COMBaudRate[FBaud];<br> tmpDCB.Parity := COMParity[FParity];<br> tmpDCB.ByteSize := COMDataBit[FDataBit];<br> tmpDCB.StopBits := COMStopBit[FStopBit];<br><br> if not (SetCommMask(FHandle, FEventMask) and<br> SetCommTimeouts(FHandle, FTimeOut) and<br> SetupComm(FHandle, FInQueue, FOutQueue) and<br> SetCommState(FHandle, tmpDCB) and<br> (FCriticalSection <> nil)) then<br> Abort;<br> end;<br> except<br> on E: Exception do<br> begin<br> CloseCom;<br> end;<br> end;<br>end;<br><br>{ 清空缓冲区 }<br>procedure TCom.PurgeCom;<br>begin<br> if Enabled then<br> begin<br> PurgeComm(FHandle, PURGE_RXCLEAR);<br> PurgeComm(FHandle, PURGE_TXCLEAR);<br> end;<br>end;<br><br>{ 从串口读取数据 }<br>function TCom.Read(var APData; ADataLen: Integer): Boolean;<br>var<br> tmpOverlapped: TOverlapped;<br> tmpEvent: TSimpleEvent;<br> tmpReceive: DWord;<br>begin<br> Result := True;<br> //Lock;<br> tmpEvent := TSimpleEvent.Create;<br> try<br> tmpReceive := 0;<br> FillChar(tmpOverlapped, SizeOf(tmpOverlapped), 0);<br> tmpOverlapped.hEvent := tmpEvent.Handle;<br><br> if not ReadFile(FHandle, APData, ADataLen, DWord(tmpReceive),<br> @tmpOverlapped) and (GetLastError <> ERROR_IO_PENDING) then<br> Result := False;<br><br> if tmpEvent.WaitFor(FReadTimeOut) <> wrSignaled then<br> Result := False<br> else begin<br> GetOverlappedResult(FHandle, tmpOverlapped, DWord(tmpReceive), False);<br> tmpEvent.ResetEvent;<br> end;<br> finally<br> //Unlock;<br> tmpEvent.Free;<br> if tmpReceive <> DWord(ADataLen) then<br> Result := False;<br> end;<br>end;<br><br>{ 向串口写入数据 }<br>function TCom.Write(var APData; ADataLen: Integer): Boolean;<br>var<br> tmpOverlapped: TOverlapped;<br> tmpEvent: TSimpleEvent;<br> tmpWrite: DWord;<br>begin<br> //Lock;<br> Result := True;<br> tmpEvent := TSimpleEvent.Create;<br> try<br> tmpWrite := 0;<br> FillChar(tmpOverlapped, SizeOf(tmpOverlapped), 0);<br> tmpOverlapped.hEvent := tmpEvent.Handle;<br> <br> if not WriteFile(FHandle, APData, ADataLen, DWord(tmpWrite),<br> @tmpOverlapped) and (GetLastError <> ERROR_IO_PENDING) then<br> Result := False;<br><br> if tmpEvent.WaitFor(FWriteTimeOut) <> wrSignaled then<br> Result := False<br> else begin<br> GetOverlappedResult(FHandle, tmpOverlapped, DWord(tmpWrite), False);<br> tmpEvent.ResetEvent;<br> end;<br> finally<br> //Unlock;<br> tmpEvent.Free;<br> if tmpWrite <> DWord(ADataLen) then<br> Result := False;<br> end;<br>end;<br><br>{ 发送命令 }<br>function TCom.SendCommand(APCommand: PCmdParam): Boolean;<br>var<br> i: Integer;<br>begin<br> Result := False;<br> Lock;<br> try<br> i := 0;<br> while (i < 5) do<br> begin<br> { 地址握手 }<br> ChangeParity(paMark);<br> if not HandtoClip(APCommand^.cmdAddress) then<br> begin<br> Inc(i);<br> Continue;<br> end;<br> { 发送命令 }<br> ChangeParity(paSpace);<br> if not Write(APCommand^.cmdCommand, SizeOf(APCommand^.cmdCommand)) then<br> begin<br> Inc(I);<br> Continue;<br> end;<br> { 发送数据 }<br> if APCommand^.cmdSendLen <> 0 then<br> begin<br> if not Write(APCommand^.cmdPSend^, APCommand^.cmdSendLen) then<br> begin<br> Inc(I);<br> Continue;<br> end;<br> end;<br> { 接收数据 }<br> if not ReceiveData(APCommand^.cmdPReceive, APCommand^.cmpReceiveLen) then<br> begin<br> Inc(I);<br> Continue;<br> end;<br> Result := True;<br> Break;<br> end;<br> finally<br> Sleep(100);<br> PurgeCom;<br> UnLock;<br> end;<br>end;<br><br>{ 与MCU地址握手 }<br>{ 2005-12-30 15:40 build by muhx }<br>function TCom.HandtoClip(AAddress: Byte): Boolean;<br>var<br> tmpByte: Byte;<br>begin<br> Result := False;<br> { 发送地址 }<br> if not Write(AAddress, SizeOf(AAddress)) then<br> Exit;<br> { 过滤无效数据 }<br> if not FiltrateUnableDate then<br> Exit;<br> { 读取数据 }<br> if not Read(tmpByte, SizeOf(tmpByte)) then<br> Exit;<br> { 比较数据 }<br> if (tmpByte <> AAddress) then<br> Exit;<br> { 若接收成功且数据正确返回True }<br> Result := True;<br>end;<br><br>{ 过滤无效数据 }<br>{ 2005-12-30 16:49 build by muhx }<br>function TCom.FiltrateUnableDate: Boolean;<br>var<br> tmpByte: Byte;<br> tmpIndex: Integer;<br>begin<br> Result := False;<br> { 过滤无效数据 }<br> tmpIndex := 0;<br> repeat<br> Inc(tmpIndex);<br> if tmpIndex > TIMES_FILTER_BYTE then<br> Exit;<br> if not Read(tmpByte, SizeOf(tmpByte)) then<br> Exit;<br> if tmpByte <> $AA then<br> Continue;<br> if not Read(tmpByte, SizeOf(tmpByte)) then<br> Exit;<br> if tmpByte <> $55 then<br> Continue;<br> Result := True;<br> until<br> Result = True;<br>end;<br><br>{ 接收数据,根据通讯协议,在接收数据前有AA55两字节校验码 }<br>{ 2005-12-30 17:25 build by muhx }<br>function TCom.ReceiveData(APReceive: PByte; AReceiveLen: Integer): Boolean;<br>var<br> tmpRead: array[0..1023] of Byte;<br> tmpPByte: PByte;<br> i: Integer;<br>begin<br> Result := False;<br> { 过滤无效数据 }<br> if not FiltrateUnableDate then<br> Exit;<br> if AReceiveLen <> 0 then<br> begin<br> if Read(tmpRead, AReceiveLen) then<br> begin<br> tmpPByte := APReceive;<br> for i := 0 to AReceiveLen - 1 do<br> begin<br> tmpPByte^ := tmpRead;<br> Inc(tmpPByte);<br> end;<br> end<br> else<br> Exit;<br> end<br> else<br> begin<br> if not Read(tmpRead, 1) then<br> Exit;<br> if tmpRead[0] = $88 then<br> Exit;<br> end;<br> Result := True;<br>end;<br><br>end.<br><br>部分定义如下<br>{ 串行通讯定义 }<br> { 串口号 }<br> TCOMID = (ciCOM1, ciCOM2, ciCOM3, ciCOM4, ciCOM5, ciCOM6, ciCOM7, ciCOM8, ciCOM9,<br> ciCOM10, ciCOM11, ciCOM12, ciCOM13, ciCOM14, ciCOM15, ciCOM16);<br> { 波特率 }<br> TBaudRate = (br110, br300, br600, br1200, br2400, br4800, br9600, br14400, br19200,<br> br38400, br56000, br57600, br115200, br128000, br256000);<br> { 奇偶校验 }<br> TParity = (paNone, paOdd, paEven, paMark, paSpace);<br> { 停止位 }<br> TStopBit = (sb10, sb15, sb20);<br> { 数据位 }<br> TDataBit = (da4, da5, da6, da7, da8);<br> { 串口设置属性 }<br> TComSet = record<br> csComID: TComID;<br> csBaud: TBaudRate;<br> csParity: TParity;<br> csDataBit: TDataBit;<br> csStopBit: TStopBit;<br> csOutQueue: Integer;<br> csInQueue: Integer;<br> csReadTimeOut: Integer;<br> csWriteTimeOut: Integer;<br> end;<br><br> { 命令结构定义 }<br> TCmdParam = record<br> cmdCommand: Byte; //命令字<br> cmdAddress: Byte; //设备地址<br> cmdSendLen: Integer; //发送数据长度<br> cmdPSend: PByte; //发送数据指针<br> cmpReceiveLen: Integer; //接收数据长度<br> cmdPReceive: PByte; //接收数据指针<br> end;<br> { 命令结构指针 }<br> PCmdParam = ^TCmdParam;<br><br>还有其他问题可以给我的邮箱发邮件<br>muhx1981@126.com