串口通信常用API总结

 
  

串口通信

1、定义

串口(COM接口):串行接口(Serial Interface) 是指数据一位一位地顺序传送,其特点是通信线路简单,只要一对传输线就可以实现双向通信。

串口通信常用API总结_第1张图片

2、结构

串口通信常用API总结_第2张图片

串口通信常用API总结_第3张图片

 

 

 

3、连接方式

串口通信常用API总结_第4张图片

 

计算机(上面的串口) <-> (开发板或其他设备上面的)串口

分别对应着的概念是:

DCE数据发送方串口A<-> DTE数据接收方串口B。A打算发送数据到B中

A设置RTS(Request To Send),表示:请求发送(数据到对方)

正常情况下,数据接收方,B不忙的时候,即不是busy的状态,则:B去设置对应的CTS(Clear To Send):表示OK,对方可以发送数据了

发送者A,可以直接发送数据给B,B也可以去接受数据,处理收到的数据;偶尔特殊的时候,B处于忙的状态,即busy,比如忙着处理上次发送的数据,所以没空理会你这次还要发的数据:那么此时B不去设置对应的CTS,表示自己忙,来不及处理你将要发送的数据,数据发送者A,就继续检测CTS,直到(数据接受者B,忙清了自己手上的活,有空接受数据了,然后)CTS被接受者B去设置对应的CTS,表示可以接受数据了,然后A才去发送数据给B。

DTR/DSR主要是用来做:建立链接,在数据发送和接受之前,先要建立A和B的连接。这时候,才用到DTR/DSR。

4通信的步骤

在串口通讯的协议层中,规定了数据包的内容,它由启始位、主体数据、校验位以及停止位组成,通讯双方的数据包格式要约定一致才能正常收发数据

串口通信的四个步骤:

(1) 打开串口

CreateFile打开串口,无论是文件、通信设备、命名管道、邮件槽、磁盘、还是控制台,都是用API函数CreateFile来打开或创建的。

HANDLECreateFileA(

 LPCSTR                lpFileName,         // 文件名

DWORD                 dwDesiredAccess,    // 对文件或设备的请求访问

 DWORD                 dwShareMode,       //共享模式

 LPSECURITY_ATTRIBUTES lpSecurityAttributes,  //安全属性,

 DWORD                dwCreationDisposition, //创作倾向

 DWORD                 dwFlagsAndAttributes,//标志和属性

 HANDLE                hTemplateFile        //模板文件

);

(2) 配置串口

GetCommState函数来获取串口的初始配置。需要通过一个DCB结构来进行。DCB结构包含了诸如波特率、数据位数、奇偶校验和停止位数等信息。在查询或配置串口的属性时,都要用DCB结构来作为缓冲区。要修改串口的配置,应该先修改DCB结构。

BOOL GetCommState(

HANDLE hFile,  //标识通讯端口的句柄

LPDCB lpDCB    //指向一个设备控制块(DCB结构)的指针

 );

程序片段如下:

由SetCommState函数设置COM口的设备控制块:

BOOL SetCommState( HANDLE hFile, LPDCB lpDCB );

 

调用SetupComm函数可以设置串行口的输入和输出缓冲区的大小。如果通信的速率较高,则应该设置较大的缓冲区

(3) 读写串口

使用ReadFile和WriteFile读写串口。

 

BOOLReadFile(
HANDLEhFile,                        // handle to file
LPVOIDlpBuffer,                     // data buffer
DWORD nNumberOfBytesToRead, // number of bytesto read
LPDWORD lpNumberOfBytesRead, // number of bytesread
LPOVERLAPPED lpOverlapped     // overlapped buffer
);

BOOLWriteFile(

     HANDLE hFile,                  //句柄

     LPVOID lpBuffer,                //数据缓冲区指针

     DWORD nNumberOfBytesToRead,   //写入的字节数

     LPDWORD lpNumberOfBytesRead,  //用于保存实际写入的字节数的存储区域     LPOVERLAPPED lpOverlapped     //OVERAPPED结构体指针,一般取NULL

);

(4) 关闭串口

调用CloseHandle,使用CreateFile函数返回的句柄作为参数。

CloseHandle(m_hCom);

5、检测串口状态

   可以用 GetCommMask() 和 SetCommMask() 来获取或设定目前设定的通讯事件。 WaitCommEvent发出一个状态检查。

 

(1)    BOOL GetCommMask(

     HANDLE hFile,        //标识通信端口的句柄

     LPDWORDlpEvtMask  //获取通信事件的指针

);

GetCommMask(m_hCom, &dwMask);

(2)    BOOL SetCommMask(

  HANDLE hFile,         //标识通信端口的句柄

  DWORD dwEvtMask     //能够使能的通信事件

);


(3)   BOOL WINAPI WaitCommEvent(  

HANDLE  hFile,               //标识通信端口的句柄

LPDWORD  lpEvtMask,         //获取通信事件的指针

LPOVERLAPPED  lpOverlapped  //异步结构,用来保存异步操作结果。

);

WaitCommEvent(m_hCom,&dwMask, &os)

串口上可能发生的事件:

EV_BREAK

收到BREAK信号

EV_CTS

CTS(clear to send)线路发生变化

EV_DSR

DST(Data Set Ready)线路发生变化

EV_ERR

线路状态错误,包括了CE_FRAME / CE_OVERRUN / CE_RXPARITY 3种错误

EV_RING

检测到振铃信号

EV_RLSD

CD(Carrier Detect)线路信号发生变化

EV_RXCHAR

输入缓冲区中已收到数据,即接收到一个字节并放入输入缓冲区

EV_RXFLAG

使用SetCommState()函数设置的DCB结构中的等待字符已被传入输入缓冲区中

EV_TXEMPTY

输出缓冲区中的数据已被完全送出

 

举例来说,可以用 SetCommMask() 设定事件为EV_RXCHAR, 那么在呼叫 WaitCommEvent() 时, 它会等到有字符可供读取时才会返回, 那么在它返回之后, 可以检查一下 lpEvtMask 中是否 set 了 EV_RXCHAR, 如果是的话就可以用 ReadFile() 去读取. 这样的话, 可以避免掉某些情形之下, 需要做polling 所引起效率不彰的问题.

6、硬件信号控制

Win32 中提供了EscapeCommFunction() 发送扩展COMM函数允许对几个硬件讯号做控制。参数如下表:

CLRDTR

让 DTR OFF

CLRRTS

让 RTS OFF

SETDTR

让 DTR ON

SETRTS

让 RTS ON

SETXOFF

"仿真" 接收到 XOFF 字符

SETXON

"仿真" 接收到 XON 字符

SETBREAK

和 SetCommBreak() 的意思相同

CLRBREAK

和 ClearCommBreak() 的意思相同

BOOLEscapeCommFunction(

HANDLE hFile,     //标识通信端口的句柄

  DWORD dwFunc   //要执行的扩展函数

);

EscapeCommFunction(m_hCom, CLRDTR);

7、其他函数

(1)错误处理

ClearCommError函数也提供通信状态用来表明为什么传输被停止。

BOOLClearCommError(

HANDLE   hFile,      //标识通信端口的句柄

LPDWORD  lpErrors,   //接收错误类型的指针

LPCOMSTAT  lpStat     //返回状态信息的指针

);

ClearCommError(hComm,&dwErrors, &comStat);

(2)通信超时

SetCommTimeouts函数用于为端口指定通信超时。调用GetCommTimeouts函数可以得到端口目前的超时。

BOOLSetCommTimeouts(

HANDLE           hFile,      //标识通信端口的句柄

LPCOMMTIMEOUTS lpCommTimeouts //指向超时值的指针

);

BOOLGetCommTimeouts(

HANDLE        hFile,         //标识通信端口的句柄

LPCOMMTIMEOUTS lpCommTimeouts    //指向超时值的指针

);

GetCommTimeouts(m_hCom,&TimeOut);

 

 

你可能感兴趣的:(串口通信常用API总结)