通过串口取硬件数据,谁知道如何做(谈谈大致如何做)?
通过串口取硬件数据,谁知道如何做 问题点数:100、回复次数:9Top
1 楼hotxu(hotxu)回复于 2002-05-06 15:02:35 得分 10
这方面的内容太多了,你搜索一下以前的贴子;
一般情况有两种方式:
1.用控件
2.用APITop
2 楼jimsuker(Fish)回复于 2002-05-06 15:20:27 得分 0
大致讲讲就行,要不要写device driver?Top
3 楼songhtao(三十年孤独)回复于 2002-05-06 15:23:52 得分 10
用MSComm控件Top
4 楼shornmao(毛豆子[死猫])回复于 2002-05-06 16:47:39 得分 10
to jimsuker(Fish):
只要你不是在NT/2000下直接用in/out的汇编指令或等效的库直接访问串口,就不需要编写设备驱动程序。
Win32 Platform SDK提供了一套通信API,具体可以查MSDN\Platform SDK\Files and I/O\CommunicationsTop
5 楼child_bj(今天能看见山)回复于 2002-05-06 19:33:20 得分 10
取得硬件信息用API
传输用MSCOMMNTop
6 楼NowCan(城市浪人)回复于 2002-05-06 20:08:15 得分 10
串口硬件数据?是什么?Top
7 楼jerry921(jerry)回复于 2002-05-07 15:55:30 得分 20
把串口当文件打开,象文件一样来用,比如打开串口一如下。
hComm=CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
在线程中处理数据的接收,不怕麻烦看一下我写的VCL控件吧。
//---------------------------------------------------------------------------
#ifndef StCommH
#define StCommH
//---------------------------------------------------------------------------
#include <SysUtils.hpp>
#include <Controls.hpp>
#include <Classes.hpp>
#include <Forms.hpp>
#define STCOMM_NOT_OPEN -1
#define STCOMM_IO_ERROR -2
typedef void __fastcall (__closure *TSTCommNotifyEvent)(DWORD dwMask);
//---------------------------------------------------------------------------
//处理串口的收发数据的线程
class TSTCommThread : public TThread
{
private:
HANDLE hComm;
TSTCommNotifyEvent FNotify;
DWORD dwStoredFlags;
protected:
void __fastcall Execute();
public:
__fastcall TSTCommThread(bool CreateSuspended,HANDLE _hComm,
TSTCommNotifyEvent _FNotify,DWORD _dwStoredFlags);
};
//---------------------------------------------------------------------------
typedef enum {B1200,B1800,B2400,B4800,B7200,B9600,B14400,B19200,B38400}TBaudRateType;
typedef enum {COM1,COM2,COM3,COM4,COM5,COM6,COM7,COM8} TPortType;
typedef enum {None,Odd,Even,Mark,Space} TParityType;
typedef enum {S1,S15,S2} TStopBitsType;
typedef enum {D5,D6,D7,D8,D9,D16} TDataBitsType;
//---------------------------------------------------------------------------
class PACKAGE TStComm : public TComponent
{
private:
//property
bool FEnable_EVRX,FEnable_EVTX,FEnable_EVERR;
bool FEnable_ERFRAME,FEnable_ERPARITY;
bool FOverTimeFlag;
DWORD dwStoredFlags;
__property bool OverTimeFlag={ read=FOverTimeFlag,write=FOverTimeFlag};
TPortType FPortNumber;
//event
TNotifyEvent FOnIncomingData;
TNotifyEvent FOnLineStatusError;
TNotifyEvent FOnTransmitBufferEmpty;
//comm data
HANDLE hComm;
COMMTIMEOUTS timeout;
COMMPROP commprop;
DCB dcb;
DWORD dwEvent,dwError;
OVERLAPPED o;
COMSTAT comstat;
DWORD nByteRead,dwErrorMask,nToRead;
//the stcommthread
TSTCommNotifyEvent FNotify;
TSTCommThread *stcommThread;
protected:
TBaudRateType FBaudRate;
TParityType FParity;
TDataBitsType FDataBits;
TStopBitsType FStopBits;
protected:
virtual bool __fastcall GetActive();
virtual void __fastcall SetBaudRate(TBaudRateType BaudRate);
virtual void __fastcall SetParity(TParityType Parity);
virtual void __fastcall SetDataBits(TDataBitsType DataBits);
virtual void __fastcall SetStopBits(TStopBitsType StopBits);
virtual void __fastcall SetTimeOut();
virtual void __fastcall STCommNotify(DWORD dwMask);
public:
__fastcall TStComm(TComponent* Owner);
__fastcall ~TStComm();
//the stcom public metho
TTimer *sttimer;
virtual DWORD __fastcall WriteData(unsigned char *outbuf,DWORD outlen);
virtual DWORD __fastcall ReadData(unsigned char *inbuf,DWORD inlen);
virtual DWORD __fastcall ReadDataTime(unsigned char *inbuf,DWORD inlen,int milisecond);
virtual DWORD __fastcall WriteByte(unsigned char outchar);
virtual DWORD __fastcall ReadByte(unsigned char *inchar);
virtual DWORD __fastcall ReadByteTime(unsigned char *inchar,int milisecond);
virtual void __fastcall ClearRecvBuf();
virtual void __fastcall ClearSendBuf();
virtual int __fastcall OpenPort();
virtual void __fastcall ClosePort();
DYNAMIC void __fastcall TimeOut(System::TObject* Sender);
//property
__published:
__property bool Active={ read=GetActive};
__property bool Enable_EVRX={ read=FEnable_EVRX,write=FEnable_EVRX};
__property bool Enable_EVTX={ read=FEnable_EVTX,write=FEnable_EVTX};
__property bool Enable_EVERR={ read=FEnable_EVERR,write=FEnable_EVERR};
__property bool Enable_ERFRAME={ read=FEnable_ERFRAME,write=FEnable_ERFRAME};
__property bool Enable_ERPARITY={ read=FEnable_ERPARITY,write=FEnable_ERPARITY};
__property TBaudRateType BaudRate={ read=FBaudRate, write=SetBaudRate};
__property TPortType PortNumber={ read=FPortNumber, write=FPortNumber};
__property TParityType Parity={ read=FParity, write=SetParity};
__property TDataBitsType DataBits={ read=FDataBits, write=SetDataBits};
__property TStopBitsType StopBits={ read=FStopBits, write=SetStopBits};
//event
__property TNotifyEvent OnIncomingData={ read=FOnIncomingData, write=FOnIncomingData };
__property TNotifyEvent OnLineStatusError={ read=FOnLineStatusError, write=FOnLineStatusError };
__property TNotifyEvent OnTransmitBufferEmpty={ read=FOnTransmitBufferEmpty, write=FOnTransmitBufferEmpty };
};
//---------------------------------------------------------------------------
#endifTop
8 楼jerry921(jerry)回复于 2002-05-07 15:57:54 得分 30
CPP如下:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "StComm.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
__fastcall TSTCommThread::TSTCommThread(bool CreateSuspended,HANDLE _hComm,
TSTCommNotifyEvent _FNotify,DWORD _dwStoredFlags)
: TThread(CreateSuspended)
{
hComm=_hComm;
FNotify=_FNotify;
dwStoredFlags=_dwStoredFlags;
}
//---------------------------------------------------------------------------
void __fastcall TSTCommThread::Execute()
{
DWORD dwCommEvent;
OVERLAPPED osStatus = {0};
if (!SetCommMask(hComm, dwStoredFlags))
return;
osStatus.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (osStatus.hEvent == NULL) // error creating event; abort
return;
while(!Terminated) {
if (!WaitCommEvent(hComm, &dwCommEvent, &osStatus)){
if (GetLastError() == ERROR_IO_PENDING);
// fWaitingOnStat= TRUE;
else{ // error in WaitCommEvent; abort
ShowMessage("error in WaitCommEvent");
break;
}
}
else{ // Deal with status event as appropriate.
if((dwCommEvent&EV_RXCHAR)||(dwCommEvent&EV_TXEMPTY)||(dwCommEvent&EV_ERR))
if(FNotify)
FNotify(dwCommEvent);
}
}
CloseHandle(osStatus.hEvent);
}
//---------------------------------------------------------------------------
// ValidCtrChe ck is used to assure that the components created do not have
// any pure virtual functions.
//
static inline void ValidCtrCheck(TStComm *)
{
new TStComm(NULL);
}
//---------------------------------------------------------------------------
__fastcall TStComm::TStComm(TComponent* Owner)
: TComponent(Owner)
{
//the default property
FPortNumber=COM1;
FBaudRate=B9600;
FParity=None;
FDataBits=D8;
FStopBits=S1;
FEnable_EVRX=false;
FEnable_EVTX=false;
FEnable_EVERR=false;
FEnable_ERFRAME=false;
FEnable_ERPARITY=false;
hComm=INVALID_HANDLE_VALUE;
}
__fastcall TStComm::~TStComm()
{
//remember close the port before destroy
if(hComm!=INVALID_HANDLE_VALUE)
ClosePort();
}
void __fastcall TStComm::STCommNotify(DWORD dwMask)
{
if(dwMask&EV_RXCHAR){
if(FOnIncomingData)
FOnIncomingData(this);
}
if(dwMask&EV_TXEMPTY){
if(FOnTransmitBufferEmpty)
FOnTransmitBufferEmpty(this);
}
if(dwMask&EV_ERR){
if(FOnLineStatusError)
FOnLineStatusError(this);
}
}
bool __fastcall TStComm::GetActive()
{
if(hComm==INVALID_HANDLE_VALUE)
return false;
else
return true;
}
void __fastcall TStComm::SetBaudRate(TBaudRateType BaudRate)
{
FBaudRate=BaudRate;
//if the commport is opened,set the baudrate immediatly
if(hComm!=INVALID_HANDLE_VALUE){
GetCommState(hComm,&dcb);
switch(FBaudRate){
case B38400:
dcb.BaudRate=CBR_38400;
break;
case B19200:
dcb.BaudRate=CBR_19200;
break;
case B14400:
dcb.BaudRate=CBR_14400;
break;
case B9600:
dcb.BaudRate=CBR_9600;
break;
case B7200:
dcb.BaudRate=7200;
break;
case B4800:
dcb.BaudRate=CBR_4800;
break;
case B2400:
dcb.BaudRate=CBR_2400;
break;
case B1800:
dcb.BaudRate=1800;
break;
case B1200:
dcb.BaudRate=CBR_1200;
break;
}
}
SetCommState(hComm,&dcb);
}
void __fastcall TStComm::SetParity(TParityType Parity)
{
FParity=Parity;
if(hComm!=INVALID_HANDLE_VALUE){
GetCommState(hComm,&dcb);
switch(FParity){
case None:
dcb.Parity=NOPARITY;
break;
case Even:
dcb.Parity=EVENPARITY;
break;
case Odd:
dcb.Parity=ODDPARITY;
break;
case Mark:
dcb.Parity=MARKPARITY;
break;
case Space:
dcb.Parity=SPACEPARITY;
break;
}
SetCommState(hComm,&dcb);
}
}
void __fastcall TStComm::SetDataBits(TDataBitsType DataBits)
{
FDataBits=DataBits;
if(hComm!=INVALID_HANDLE_VALUE){
GetCommState(hComm,&dcb);
switch(FDataBits){
case D5:
dcb.ByteSize=5;
break;
case D6:
dcb.ByteSize=6;
break;
case D7:
dcb.ByteSize=7;
break;
case D8:
dcb.ByteSize=8;
break;
case D9:
dcb.ByteSize=9;
break;
case D16:
dcb.ByteSize=16;
break;
}
SetCommState(hComm,&dcb);
}
}
void __fastcall TStComm::SetStopBits(TStopBitsType StopBits)
{
FStopBits=StopBits;
if(hComm!=INVALID_HANDLE_VALUE){
GetCommState(hComm,&dcb);
switch(FStopBits){
case S1:
dcb.StopBits=ONESTOPBIT;
break;
case S15:
dcb.StopBits=ONE5STOPBITS;
break;
case S2:
dcb.StopBits=TWOSTOPBITS;
break;
}
SetCommState(hComm,&dcb);
}
}
//---------------------------------------------------------------------------
namespace Stcomm
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TStComm)};
RegisterComponents("Atc", classes, 0);
}
}
//---------------------------------------------------------------------------
void __fastcall TStComm::ClosePort()
{
//terminal the thread
sttimer->Enabled=false;
delete sttimer;
stcommThread->Terminate();
// delete stcommThread;
//close the handel
CloseHandle(hComm);
hComm=INVALID_HANDLE_VALUE;
}
Top
9 楼jerry921(jerry)回复于 2002-05-07 15:58:26 得分 0
int __fastcall TStComm::OpenPort()
{
//the FPortNumber must be set before openport
switch(FPortNumber){
case COM1:
hComm=CreateFile("COM1",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
break;
case COM2:
hComm=CreateFile("COM2",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
break;
case COM3:
hComm=CreateFile("COM3",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
break;
case COM4:
hComm=CreateFile("COM4",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
break;
case COM5:
hComm=CreateFile("COM5",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
break;
case COM6:
hComm=CreateFile("COM6",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
break;
case COM7:
hComm=CreateFile("COM7",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
break;
case COM8:
hComm=CreateFile("COM8",GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
break;
}
if(hComm==INVALID_HANDLE_VALUE)
{
GetLastError();
ShowMessage("不能打开指定串口");
return -1;
}
BuildCommDCB("9600,N,8,1",&dcb);
SetCommState(hComm,&dcb);
GetCommState(hComm,&dcb);
dcb.DCBlength = sizeof(dcb);
dcb.fParity=true;///
dcb.fBinary=true;///
dcb.fNull=false;
dcb.fOutxCtsFlow=false;
dcb.fOutxDsrFlow=false;
dcb.fDtrControl=DTR_CONTROL_ENABLE;
dcb.fRtsControl=RTS_CONTROL_ENABLE;
dcb.fOutX=false;
dcb.fInX=false;
dcb.fDsrSensitivity=false;
SetCommState(hComm,&dcb);
BaudRate=FBaudRate;
Parity=FParity;
DataBits=FDataBits;
StopBits=FStopBits;
SetTimeOut();
FNotify=STCommNotify;
dwStoredFlags=0;
if(FEnable_EVRX==true)
dwStoredFlags|=EV_RXCHAR;
if(FEnable_EVTX==true)
dwStoredFlags|=EV_TXEMPTY;
if(FEnable_EVERR==true)
dwStoredFlags|=EV_ERR;
if(dwStoredFlags!=0)
stcommThread=new TSTCommThread(false,hComm,FNotify,dwStoredFlags);
else
stcommThread=new TSTCommThread(true,hComm,FNotify,dwStoredFlags);
sttimer=new TTimer(this);
sttimer->Enabled=false;
sttimer->OnTimer=TimeOut;
return 0;
}
void __fastcall TStComm::SetTimeOut()
{
GetCommTimeouts(hComm,&timeout);
timeout.ReadTotalTimeoutMultiplier=15;
timeout.ReadTotalTimeoutConstant=15;
timeout.WriteTotalTimeoutMultiplier=15;
timeout.WriteTotalTimeoutConstant=15;
SetCommTimeouts(hComm,&timeout);
}
//---------------------------------------------------------------------------
DWORD __fastcall TStComm::WriteData(unsigned char *outbuf,DWORD outlen)
{
if(hComm==INVALID_HANDLE_VALUE)
return STCOMM_NOT_OPEN;
if(!WriteFile(hComm,outbuf,outlen,&nByteRead,NULL))
{
ClearCommError(hComm,&dwErrorMask,&comstat);
return STCOMM_IO_ERROR;
}
return nByteRead;
}
//---------------------------------------------------------------------------
DWORD __fastcall TStComm::ReadData(unsigned char *inbuf,DWORD inlen)
{
DWORD nToRead;
if(hComm==INVALID_HANDLE_VALUE)
return STCOMM_NOT_OPEN;
ClearCommError(hComm,&dwErrorMask,&comstat);
if(dwErrorMask)
{
if(dwErrorMask&CE_BREAK){
PurgeComm(hComm,PURGE_RXCLEAR);
return STCOMM_IO_ERROR;
}
if((dwErrorMask&CE_FRAME)&&(FEnable_ERFRAME==true)){
PurgeComm(hComm,PURGE_RXCLEAR);
return STCOMM_IO_ERROR;
}
if(dwErrorMask&CE_IOE){
PurgeComm(hComm,PURGE_RXCLEAR);
return STCOMM_IO_ERROR;
}
if(dwErrorMask&CE_MODE){
PurgeComm(hComm,PURGE_RXCLEAR);
return STCOMM_IO_ERROR;
}
if(dwErrorMask&CE_OVERRUN){
PurgeComm(hComm,PURGE_RXCLEAR);
return STCOMM_IO_ERROR;
}
if(dwErrorMask&CE_RXOVER){
PurgeComm(hComm,PURGE_RXCLEAR);
return STCOMM_IO_ERROR;
}
if((dwErrorMask&CE_RXPARITY)&&(FEnable_ERPARITY==true)){
PurgeComm(hComm,PURGE_RXCLEAR);
return STCOMM_IO_ERROR;
}
if(dwErrorMask&CE_TXFULL){
PurgeComm(hComm,PURGE_RXCLEAR);
return STCOMM_IO_ERROR;
}
if(dwErrorMask&CE_DNS){
PurgeComm(hComm,PURGE_RXCLEAR);
return STCOMM_IO_ERROR;
}
if(dwErrorMask&CE_PTO){
PurgeComm(hComm,PURGE_RXCLEAR);
return STCOMM_IO_ERROR;
}
if(dwErrorMask&CE_OOP){
PurgeComm(hComm,PURGE_RXCLEAR);
return STCOMM_IO_ERROR;
}
}
if(comstat.cbInQue<inlen)
nToRead=comstat.cbInQue;
else
nToRead=inlen;
if(inlen<=0)
return 0;
if(!ReadFile(hComm,inbuf,nToRead,&nByteRead,NULL))
{
ClearCommError(hComm,&dwErrorMask,&comstat);
return STCOMM_IO_ERROR;
}
inbuf[nByteRead]=0x00;
return nByteRead;
}
//---------------------------------------------------------------------------
void __fastcall TStComm::TimeOut(System::TObject* Sender)
{
sttimer->Enabled=false;
OverTimeFlag=true;
}
DWORD __fastcall TStComm::ReadDataTime(unsigned char *inbuf,DWORD inlen,int milisecond)
{
DWORD nToRead,DataPos=0;
if(hComm==INVALID_HANDLE_VALUE)
return STCOMM_NOT_OPEN;
sttimer->Interval=milisecond;
OverTimeFlag=false;
sttimer->Enabled=true;
while(!OverTimeFlag)
{
Application->ProcessMessages();
ClearCommError(hComm,&dwErrorMask,&comstat);
if(dwErrorMask){
sttimer->Enabled=false;
return STCOMM_IO_ERROR;
}
if(comstat.cbInQue==0)
continue;
if(comstat.cbInQue<inlen)
nToRead=comstat.cbInQue;
else
nToRead=inlen;
if(inlen<=0){
sttimer->Enabled=false;
return 0;
}
if(!ReadFile(hComm,inbuf+DataPos,nToRead,&nByteRead,NULL))
{
ClearCommError(hComm,&dwErrorMask,&comstat);
sttimer->Enabled=false;
return STCOMM_IO_ERROR;
}
DataPos+=nByteRead;
inbuf[DataPos]=0x00;
if(DataPos>=inlen)
break;
}
inbuf[DataPos]=0x00;
return DataPos;
}
//---------------------------------------------------------------------------
DWORD __fastcall TStComm::WriteByte(unsigned char outchar)
{
return(WriteData(&outchar,1));
}
//---------------------------------------------------------------------------
DWORD __fastcall TStComm::ReadByte(unsigned char *inchar)
{
DWORD ret;
unsigned char tempbuf[2];
ret=ReadData(tempbuf,1);
*inchar=tempbuf[0];
return ret;
}
//---------------------------------------------------------------------------
DWORD __fastcall TStComm::ReadByteTime(unsigned char *inchar,int milisecond)
{
DWORD ret;
unsigned char tempbuf[2];
ret=ReadDataTime(tempbuf,1,milisecond);
*inchar=tempbuf[0];
return ret;
}
//---------------------------------------------------------------------------
void __fastcall TStComm::ClearRecvBuf()
{
if(hComm!=INVALID_HANDLE_VALUE)
PurgeComm(hComm,PURGE_RXCLEAR);
}
//---------------------------------------------------------------------------
void __fastcall TStComm::ClearSendBuf()
{
if(hComm!=INVALID_HANDLE_VALUE)
PurgeComm(hComm,PURGE_TXCLEAR);
}Top




