资讯

精准传达 • 有效沟通

从品牌网站建设到网络营销策划,从策略到执行的一站式服务

c语言驱动com口函数,c++ com接口

C语言如何调用 驱动函数

驱动函数不是直接调用的,而是通过通讯完成调用的。可以参考:

创新互联建站专注于企业成都全网营销、网站重做改版、和县网站定制设计、自适应品牌网站建设、成都h5网站建设商城网站定制开发、集团公司官网建设、外贸网站制作、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为和县等各大城市提供网站开发制作服务。

BOOL WINAPI DeviceIoControl(

_In_         HANDLE hDevice,

_In_         DWORD dwIoControlCode,

_In_opt_     LPVOID lpInBuffer,

_In_         DWORD nInBufferSize,

_Out_opt_    LPVOID lpOutBuffer,

_In_         DWORD nOutBufferSize,

_Out_opt_    LPDWORD lpBytesReturned,

_Inout_opt_  LPOVERLAPPED lpOverlapped

);

如何用c语言编写向串口发送指令的程序 如0x01

#includewindows.h

#includestdio.h

int main()

{

HANDLE hComm;

hComm = CreateFile(“COM1”,          // for COM1—COM9 only

GENERIC_READ | GENERIC_WRITE, //Read/Write

0,               // No Sharing

NULL,            // No Security

OPEN_EXISTING,   // Open existing port only

0,               // Non Overlapped I/O

NULL);

if (hComm == INVALID_HANDLE_VALUE)

printf(“Error in opening serial port”);

else

printf(“opening serial port successful”);

char lpBuffer[] = 0x01;

DWORD dNoOFBytestoWrite;         // No of bytes to write into the port

DWORD dNoOfBytesWritten = 0;     // No of bytes written to the port

dNoOFBytestoWrite = sizeof(lpBuffer);

Status = WriteFile(hComm,        // Handle to the Serial port

lpBuffer,     // Data to be written to the port

dNoOFBytestoWrite,  //No of bytes to write

dNoOfBytesWritten, //Bytes written

NULL);

CloseHandle(hComm);//Closing the Serial Port

return 0;

}

用C语言实现,通过com端口的名字,获得com端口序号,(如com1,com2……)

在linux后者在unix下,可以用C,但在windows下,就要用C++,调用windows的串口驱动。

如何实现pc机上的com口通信

狂晕中....给你linux代码,你就问windows,给你windows串口控制方式,你就问linux,I 服了 You。

区别很大,两个不同的操作系统,在应用串口上就有所不同,但大体上,还是有共同点,1、设置串口,2、打开串口,3、读写数据,4、异常处理,5、关闭串口

这一系列的控制逻辑都大体相同,只是在代码实现上有所不一样,毕竟两种操作系统内核结构就不一样,linux的串口设置属性是通过头文件#include termios.h的struct termios结构实现,而windows的串口属性是commprop结构设定,其他的读写串口,都有相应的读写文件函数,两种系统都是把串口当作一个设备文件来读写,所以这里就不难理解,为什么使用文件函数来处理串口。linux下可以使用标准C库函数来控制读写串口,windows下可以使用WINDOWS API函数来做串口读写,具体请参看《windows API 大全》以及下文给出的参考地址,也是有详细的说明

在PC机上实现COM口通信并不困难,可你得说清楚是什么操作系统,不同的操作系统,控制串口的区别是很大。

在Windows系统上操作串口可以使用三种方式:MSCOMM控件,WINDOWS API,第三方控件

WINDOWS API使用起来相对麻烦些,主要是在设置串口属性、查询读取方面及异常处理方面。这里简要说下控制串口步骤:

1.打开串口:

使用createfile()打开串口,createfile()将返回串口的句柄。

handle createfile(

lpctstr lpfilename, // pointer to name of the file

dword dwdesiredaccess, // access (read-write) mode

dword dwsharemode, // share mode

lpsecurity_attributes lpsecurityattributes, // pointer to security attributes

dword dwcreationdistribution, // how to create

dword dwflagsandattributes, // file attributes

handle htemplatefile // handle to file with attributes to copy

);

lpfilename: 指明串口制备,例:com1,com2

dwdesiredaccess: 指明串口存取方式,例:generic_read|generic_write

dwsharemode: 指明串口共享方式

lpsecurityattributes: 指明串口的安全属性结构,null为缺省安全属性

dwcreateiondistribution: 必须为open_existin

dwflagandattributes: 对串口唯一有意义的是file_flag_overlapped

htemplatefile: 必须为null

2.关闭串口:

closehandle(hcommdev);

3.设置缓冲区长度:

bool setupcomm(

handle hfile, // handle of communications device

dword dwinqueue, // size of input buffer

dword dwoutqueue // size of output buffer

);

4.commprop结构:

可使用getcommproperties()取得commprop结构,commprop结构中记载了系统支持的各项设置。

typedef struct _commprop { // cmmp

word wpacketlength; // packet size, in bytes

word wpacketversion; // packet version

dword dwservicemask; // services implemented

dword dwreserved1; // reserved

dword dwmaxtxqueue; // max tx bufsize, in bytes

dword dwmaxrxqueue; // max rx bufsize, in bytes

dword dwmaxbaud; // max baud rate, in bps

dword dwprovsubtype; // specific provider type

dword dwprovcapabilities; // capabilities supported

dword dwsettableparams; // changeable parameters

dword dwsettablebaud; // allowable baud rates

word wsettabledata; // allowable byte sizes

word wsettablestopparity; // stop bits/parity allowed

dword dwcurrenttxqueue; // tx buffer size, in bytes

dword dwcurrentrxqueue; // rx buffer size, in bytes

dword dwprovspec1; // provider-specific data

dword dwprovspec2; // provider-specific data

wchar wcprovchar[1]; // provider-specific data

} commprop;

dwmaxbaud:

baud_075 75 bps

baud_110 110 bps

baud_134_5 134.5 bps

baud_150 150 bps

baud_300 300 bps

baud_600 600 bps

baud_1200 1200 bps

baud_1800 1800 bps

baud_2400 2400 bps

baud_4800 4800 bps

baud_7200 7200 bps

baud_9600 9600 bps

baud_14400 14400 bps

baud_19200 19200 bps

baud_38400 38400 bps

baud_56k 56k bps

baud_57600 57600 bps

baud_115200 115200 bps

baud_128k 128k bps

baud_user programmable baud rates available

dwprovsubtype:

pst_fax 传真设备

pst_lat lat协议

pst_modem 调制解调器设备

pst_network_bridge 未指定的网桥

pst_parallelport 并口

pst_rs232 rs-232口

pst_rs422 rs-422口

pst_rs423 rs-432口

pst_rs449 rs-449口

pst_scanner 扫描仪设备

pst_tcpip_telnet tcp/ip telnet协议

pst_unspecified 未指定

pst_x25 x.25标准

dwprovcapabilities

pcf_16bitmode 支持特殊的16位模式

pcf_dtrdsr 支持dtr(数据终端就绪)/dsr(数据设备就绪)

pcf_inttimeouts 支持区间超时

pcf_parity_check 支持奇偶校验

pcf_rlsd 支持rlsd(接收线信号检测)

pcf_rtscts 支持rts(请求发送)/cts(清除发送)

pcf_setxchar 支持可设置的xon/xoff

pcf_specialchars 支持特殊字符

pcf_totaltimeouts 支持总(占用时间)超时

pcf_xonxoff 支持xon/xoff流控制

标准rs-232和window支持除pcf_16bitmode和pcf_specialchar外的所有功能

dwsettableparams

sp_baud 可配置波特率

sp_databits 可配置数据位个数

sp_handshaking 可配置握手(流控制)

sp_parity 可配置奇偶校验模式

sp_parity_check 可配置奇偶校验允许/禁止

sp_rlsd 可配置rlsd(接收信号检测)

sp_stopbits 可配置停止位个数

标准rs-232和window支持以上所有功能

wsettabledata

databits_5 5个数据位

databits_6 6个数据位

databits_7 7个数据位

databits_8 8个数据位

databits_16 16个数据位

databits_16x 通过串行硬件线路的特殊宽度路径

windows 95支持16的所有设置

5.dcb结构:

typedef struct _dcb {// dcb

dword dcblength; // sizeof(dcb)

dword baudrate; // current baud rate

指定当前的波特率

dword fbinary: 1; // binary mode, no eof check

指定是否允许二进制模式,

windows 95中必须为true

dword fparity: 1; // enable parity checking

指定奇偶校验是否允许

dword foutxctsflow:1; // cts output flow control

指定cts是否用于检测发送控制。

当为true是cts为off,发送将被挂起。

dword foutxdsrflow:1; // dsr output flow control

指定cts是否用于检测发送控制。

当为true是cts为off,发送将被挂起。

dword fdtrcontrol:2; // dtr flow control type

dtr_control_disable值将dtr置为off, dtr_control_enable值将dtr置为on, dtr_control_handshake允许dtr"握手",dword fdsrsensitivity:1; // dsr sensitivity 当该值为true时dsr为off时接收的字节被忽略

dword ftxcontinueonxoff:1; // xoff continues tx

指定当接收缓冲区已满,并且驱动程序已经发

送出xoffchar字符时发送是否停止。

true时,在接收缓冲区接收到缓冲区已满的字节xofflim且驱动程序已经发送出xoffchar字符中止接收字节之后,发送继续进行。

false时,在接收缓冲区接收到代表缓冲区已空的字节xonchar且驱动程序已经发送出恢复发送的xonchar之后,发送继续进行。

dword foutx: 1; // xon/xoff out flow control

true时,接收到xoffchar之后便停止发送

接收到xonchar之后将重新开始

dword finx: 1; // xon/xoff in flow control

true时,接收缓冲区接收到代表缓冲区满的xofflim之后,xoffchar发送出去

接收缓冲区接收到代表缓冲区空的xonlim之后,xonchar发送出去

dword ferrorchar: 1; // enable error replacement

该值为true且fparity为true时,用errorchar 成员指定的字符代替奇偶校验错误的接收字符

dword fnull: 1; // enable null stripping

true时,接收时去掉空(0值)字节

dword frtscontrol:2; // rts flow control

rts_control_disable时,rts置为off

rts_control_enable时, rts置为on

rts_control_handshake时,

当接收缓冲区小于半满时rts为on

当接收缓冲区超过四分之三满时rts为off

rts_control_toggle时,

当接收缓冲区仍有剩余字节时rts为on ,否则缺省为off

dword fabortonerror:1; // abort reads/writes on error

true时,有错误发生时中止读和写操作

dword fdummy2:17; // reserved

未使用

word wreserved; // not currently used

未使用,必须为0

word xonlim; // transmit xon threshold

指定在xon字符发送这前接收缓冲区中可允许的最小字节数

word xofflim; // transmit xoff threshold

指定在xoff字符发送这前接收缓冲区中可允许的最小字节数

byte bytesize; // number of bits/byte, 4-8

指定端口当前使用的数据位

byte parity; // 0-4=no,odd,even,mark,space

指定端口当前使用的奇偶校验方法,可能为:

evenparity,markparity,noparity,oddparity

byte stopbits; // 0,1,2 = 1, 1.5, 2

指定端口当前使用的停止位数,可能为:

onestopbit,one5stopbits,twostopbits

char xonchar; // tx and rx xon character

指定用于发送和接收字符xon的值

char xoffchar; // tx and rx xoff character

指定用于发送和接收字符xoff值

char errorchar; // error replacement character

本字符用来代替接收到的奇偶校验发生错误时的值

char eofchar; // end of input character

当没有使用二进制模式时,本字符可用来指示数据的结束

char evtchar; // received event character

当接收到此字符时,会产生一个事件

word wreserved1; // reserved; do not use 未使用

} dcb;

6.改变端口设置

使用如下的两个方法

bool getcommstate(hcomm,dcb);

bool setcommstate(hcomm,dcb);

7.改变普通设置

buildcommdcb(szsettings,dcb);

szsettings的格式:baud parity data stop

例: "baud=96 parity=n data=8 stop=1"

简写:"96;,n,8,1"

szsettings 的有效值

baud:

11 or 110 = 110 bps

15 or 150 = 150 bps

30 or 300 = 300 bps

60 or 600 = 600 bps

12 or 1200 = 1200 bps

24 or 2400 = 2400 bps

48 or 4800 = 4800 bps

96 or 9600 = 9600 bps

19 or 19200= 19200bps

parity:

n=none

e=even

o=odd

m=mark

s=space

data:

5,6,7,8

stopbit

1,1.5,2

8.commconfig结构:

typedef struct _comm_config {

dword dwsize;

word wversion;

word wreserved;

dcb dcb;

dword dwprovidersubtype;

dword dwprovideroffset;

dword dwprovidersize;

wchar wcproviderdata[1];

} commconfig, *lpcommconfig;

可方便的使用bool commconfigdialog(

lptstr lpszname,

hwnd hwnd,

lpcommconfig lpcc);

来设置串行口。

9.超时设置:

可通过commtimeouts结构设置超时,

typedef struct _commtimeouts {

dword readintervaltimeout;

原文参考《VC实现串口通信例程》 作者:阮帮秋

下次记得把问题一次提出来。即便是帮你找资料,也方便一些。

如何用C语言控制计算机串口

基本方法是使用CreateFile来建立一个串口文件,然后用overlap的方式进行读写

#define SERAIL_PORT_BUF_MAX (1024*8)

typedef HRESULT (*PFN_CMD_PARSE_DATA)(HANDLE hParseApp, LPCSTR szRspCmd, int nCmdLen);

class CUsbSrvApp// : public CWinApp

{

public:

CUsbSrvApp();

~CUsbSrvApp();

BOOL OnSendData(const char *szBuf, int nLen);// 发送数据

int ComConnect(CString strPort); // 连接COM口

HANDLE OpenComPort(CString strPort, int nBaudRate, int nDataBits, int nStopBits, int nParity, int nFlowCtrlType); // 打开串口

void Close(); // 关闭串口

HANDLE m_hCom;

BOOL m_bConnected;

OVERLAPPED m_OverlappedRead;

OVERLAPPED m_OverlappedWrite;

CWinThread *m_pThread;

PFN_CMD_PARSE_DATA m_pRspCmdFunc; // 用来处理接受数据的CALLBACK

HANDLE m_hParseApp;

};

CUsbSrvApp::CUsbSrvApp()

{

// TODO: add construction code here,

// Place all significant initialization in InitInstance

m_bConnected = false;

m_hCom = NULL;

m_pRspCmdFunc = NULL;

}

CUsbSrvApp::~CUsbSrvApp()

{

}

//打开串口通信,并返回串口句柄

HANDLE CUsbSrvApp::OpenComPort(CString strPortName,

int nBaudRate,

int nDataBits,

int nStopBits,

int nParity,

int nFlowCtrlType)

{

DCB dcb;

COMMTIMEOUTS CommTimeOuts ;

COMMCONFIG ComConfig;

HANDLE hComPort;

CString strPort;

strPort.Format("\\\\.\\%s",strPortName); // COM口的文件名应该是 \\.\COMXX

//打开窗口其实就是创建一个文件

hComPort = CreateFile(strPort,

GENERIC_READ | GENERIC_WRITE,

FILE_SHARE_READ | FILE_SHARE_WRITE,

NULL,

OPEN_EXISTING,

FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,

NULL);

if (INVALID_HANDLE_VALUE == hComPort)

return INVALID_HANDLE_VALUE;

// 设置一些COM口通讯参数和OVERLAP

CommTimeOuts.ReadIntervalTimeout = -1;

CommTimeOuts.ReadTotalTimeoutConstant = 0;

CommTimeOuts.ReadTotalTimeoutMultiplier = 0;

CommTimeOuts.WriteTotalTimeoutConstant = 0;

CommTimeOuts.WriteTotalTimeoutMultiplier = 0x1388;

SetCommTimeouts( m_hCom, CommTimeOuts ) ;

SetDefaultCommConfig(strPortName, ComConfig, sizeof(COMMCONFIG));

GetCommState(m_hCom, dcb ) ;

dcb.BaudRate = nBaudRate;

dcb.ByteSize = nDataBits;

dcb.StopBits = nStopBits;

dcb.fParity = (NOPARITY != nParity);

dcb.Parity = nParity;

//set the receive char

dcb.EvtChar = 0x0D;

switch(nFlowCtrlType)

{

case 0: //no flow control

break;

case 1://HARD_FLOW_CTRL:

dcb.fOutxCtsFlow = TRUE;

dcb.fOutxDsrFlow = TRUE;

dcb.fDtrControl = DTR_CONTROL_DISABLE;

dcb.fDsrSensitivity = TRUE;

dcb.fRtsControl = RTS_CONTROL_TOGGLE;

break;

case 2://SOFT_FLOW_CTRL:

dcb.fOutX = TRUE;

dcb.fInX = TRUE;

break;

}

BuildCommDCB(_T("baud=115200 parity=N data=8 stop=1"),dcb);

SetCommState(hComPort, dcb ) ;

SetCommMask(hComPort, 0);

SetCommMask(hComPort, EV_RXCHAR|EV_CTS|EV_DSR|EV_RLSD|EV_RING);

SetupComm( hComPort, SERAIL_PORT_BUF_MAX,SERAIL_PORT_BUF_MAX) ;

//clear read and write buffer

PurgeComm( hComPort, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR );

return hComPort;

}

void CUsbSrvApp::Close()

{

if(m_bConnected)

{

m_bConnected = false;

CloseHandle(m_hCom);

m_hCom = NULL;

}

}

// 这个线程是监视串口数据,一旦有数据则读取并调用CALLBACK通知客户端

UINT ReceiveComData(LPVOID pParam)

{

CUsbSrvApp *pUsbSrv = (CUsbSrvApp *)pParam;

HANDLE hComPort = pUsbSrv-m_hCom;

DWORD dwEvtMask=0;

DWORD dwErrorFlags;

SetCommMask( hComPort, EV_RXCHAR);

OVERLAPPED osRead;

osRead.hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);

DWORD dwTransfer = 0;

while(pUsbSrv-m_bConnected)

{

if( !WaitCommEvent( hComPort, dwEvtMask,osRead))

{

if( GetLastError()== ERROR_IO_PENDING)

{

WaitForSingleObject(osRead.hEvent, INFINITE);

if(dwEvtMaskEV_RXCHAR==EV_RXCHAR)

{

COMSTAT ComStat={0} ;

DWORD dwReadLen = 0;

DWORD dwBytesRead = 0;

DWORD dwTotalLen = 0;

ClearCommError(hComPort, dwErrorFlags, ComStat );

dwTotalLen = ComStat.cbInQue;

dwReadLen = (SERAIL_PORT_BUF_MAX dwTotalLen)?dwTotalLen:SERAIL_PORT_BUF_MAX;

BYTE *pBuf = new BYTE[dwTotalLen+1];

memset(pBuf, 0 , dwTotalLen+1);

DWORD nReadBufLen=0;

while(dwTotalLen0)

{

if(FALSE == ReadFile( hComPort, pBuf+nReadBufLen,dwReadLen, dwBytesRead,pUsbSrv-m_OverlappedRead))

{

if(GetLastError() == ERROR_IO_PENDING)

{

GetOverlappedResult(hComPort,osRead, dwTransfer, TRUE );

}

break;

}

nReadBufLen +=dwBytesRead;

dwTotalLen -=dwBytesRead;

dwReadLen -= dwBytesRead;

dwReadLen = (SERAIL_PORT_BUF_MAXdwReadLen)?dwReadLen:SERAIL_PORT_BUF_MAX;

}

if(pUsbSrv-m_pRspCmdFunc!=NULLnReadBufLen!=0)

{

pUsbSrv-m_pRspCmdFunc(pUsbSrv-m_hParseApp, (char*)pBuf,nReadBufLen);

}

delete pBuf;

ClearCommError(hComPort, dwErrorFlags, ComStat );

int len =0;//= m_retList.GetSize();

}//endif if(dwEvtMaskEV_RXCHAR==EV_RXCHAR)

}//endif if( GetLastError()== ERROR_IO_PENDING)

}//endif if( !WaitCommEvent( hComPort, dwEvtMask,o))

else

{

if(GetLastError() == ERROR_IO_PENDING) {

GetOverlappedResult(hComPort, osRead, dwTransfer, TRUE ); // sleep thread

}

}

Sleep(1);

} //endwhile while(m_bConnected)

return 0;

}

int CUsbSrvApp::ComConnect(CString strPort)

{

int nBaudRate = 115200;

int nDataBits = 8;

int nStopBits = 1;

int nParity = 0;

int nFlowCtrl = 1;

if (NULL != m_hCom || m_bConnected)

{

return 0;

}

m_hCom = OpenComPort(strPort,nBaudRate,nDataBits,nStopBits,nParity,nFlowCtrl);

if( INVALID_HANDLE_VALUE == m_hCom)

{

m_hCom = NULL;

return 0;

}

memset( m_OverlappedRead, 0, sizeof( OVERLAPPED ) );

memset( m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );

m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );

m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );

m_pThread = AfxBeginThread( ReceiveComData,(void*)this,THREAD_PRIORITY_NORMAL,0,CREATE_SUSPENDED ,NULL );

if( NULL == m_pThread )

{

CloseHandle( m_hCom );

m_hCom = NULL;

return FALSE;

}

else

{

m_bConnected = TRUE;

m_pThread-ResumeThread( );

}

return TRUE;

}

int CUsbSrvApp::OnSendData(const char *szBuf, int nLen)

{

BOOL bWriteStat;

BOOL bWrite = TRUE;

DWORD dwBytesWrite = 0;

DWORD dwBytesWritten = 0;

int dwByteswrittenTotal = 0;

if (NULL == m_hCom)

return 0;

int nSentTimes=0;

while(dwByteswrittenTotalnLennSentTimes10)

{

nSentTimes++;

dwBytesWrite = nLen-dwByteswrittenTotal;

bWriteStat = WriteFile( m_hCom, szBuf+dwByteswrittenTotal, dwBytesWrite, dwBytesWritten, m_OverlappedWrite );

if( !bWriteStat)

{

if ( GetLastError() == ERROR_IO_PENDING )

{

dwBytesWritten = 0;

bWrite = FALSE;

}

}

if (!bWrite)

{

bWrite = TRUE;

bWriteStat = GetOverlappedResult(m_hCom, // Handle to COMM port

m_OverlappedWrite, // Overlapped structure

dwBytesWritten, // Stores number of bytes sent

TRUE); // Wait flag

//deal with the error code

}

dwByteswrittenTotal += dwBytesWritten;

}

if(dwByteswrittenTotalnLen)

return 0;

else

return 1;

}


名称栏目:c语言驱动com口函数,c++ com接口
转载来源:http://cdkjz.cn/article/phisid.html
多年建站经验

多一份参考,总有益处

联系快上网,免费获得专属《策划方案》及报价

咨询相关问题或预约面谈,可以通过以下方式与我们联系

大客户专线   成都:13518219792   座机:028-86922220