Windows CE 串口通信编程

1、打开串口

HANDLE CreateFile(

  LPCTSTR lpFileName,

  DWORD dwDesiredAccess,

  DWORD dwShareMode,

  LPSECURITY_ATTRIBUTES lpSecurityAttributes,

  DWORD dwCreationDisposition,

  DWORD dwFlagsAndAttributes,

  HANDLE hTemplateFile

);

在Windows CE下,利用CreateFile函数打开一个COM口时,dwShareMode(共享模式)必须设置为0,表示独占方式;lpSecurityAttributes(安全参数)必须设置为NULLhTemplateFile(模板文件)必须设置为NULLdwCreationDisposition需要设置为OPEN_EXISTING。则上述函数简化为:

HANDLE CreateFile(

  LPCTSTR lpFileName,

  DWORD dwDesiredAccess,

  0,

  NULL,

  OPEN_EXISTING,  

  DWORD dwFlagsAndAttributes,

  NULL

);

其中dwDesiredAccess设置为GENERIC_READ表示可读,设置为GENERIC_WRITE表示可写。通常可通过如下示例打开一个串口。

CreateFile(

_T("COM1:"),

GENERIC_READ | GENERIC_WRITE,   //允许读和写

0,                          //独占方式(共享模式)

NULL,

OPEN_EXISTING,        //打开而不是创建(创建方式)

0,

NULL

);

打开串口成功,函数返回串口句柄;打开串口失败,函数返回INVALID_HANDLE_VALUE


2.关闭串口

BOOL CloseHandle(

  HANDLE hObject

);

如:CloseHandle(m_hComm); //m_hComm是CreateFile函数返回的串口句柄。

关闭串口成功,函数返回非零值;关闭串口失败,函数返回零。

DCB(设备控制块)

  DCB结构完全描述了串口的使用参数。

typedef struct _DC{

/*

 具体内容见:http://blog.chinaunix.net/uid-23260031-id-2466195.html

*/

}DCB,*LPDCB;

·配置串口

BOOL GetCommState(

  HANDLE hFile,

  LPDCB lpDCB

);

该函数用来获取已打开串口的参数信息,并将这些信息填充到lpDCB参数所指向的DCB(设备控制块)中。

返回值:成功返回非零值,失败返回零

BOOL SetCommState(

  HANDLE hFile,

  LPDCB lpDCB

);

返回值:成功返回非零值,失败返回零

  该函数用来设置已打开串口的参数信息。

  在设置串口参数时,一般先调用GetCommState函数获取串口参数信息到一个DCB(设备控制块)中,然后对感兴趣的参数进行修改,最后再调用SetCommState函数完成串口参数的配置。

例如可以通过如下代码配置串口参数:

——————————————————————————————————

//得到打开串口的当前属性参数,修改后再重新设置串口。

if (!GetCommState(m_hComm,&DCB_COM1))

{

    TRACE(_T("GetCommState error"));      

    return FALSE;

}

   

//设置串口参数

DCB_COM1.BaudRate = CBR_9600;   // 设置波特率9600

DCB_COM1.fBinary = TRUE; // 设置二进制模式,此处必须设置TRUE

DCB_COM1.fParity = TRUE; // 支持奇偶校验

DCB_COM1.fOutxCtsFlow = FALSE;  // No CTS output flow control

DCB_COM1.fOutxDsrFlow = FALSE;  // No DSR output flow control

DCB_COM1.fDtrControl = DTR_CONTROL_DISABLE; // No DTR flow control

DCB_COM1.fDsrSensitivity = FALSE; // DSR sensitivity

DCB_COM1.fTXContinueOnXoff = TRUE; // XOFF continues Tx

DCB_COM1.fOutX = FALSE;     // No XON/XOFF out flow control

DCB_COM1.fInX = FALSE;        // No XON/XOFF in flow control

DCB_COM1.fErrorChar = FALSE;    // Disable error replacement

DCB_COM1.fNull = FALSE;  // Disable null stripping

DCB_COM1.fRtsControl = RTS_CONTROL_DISABLE;   //No RTS flow control

DCB_COM1.fAbortOnError = FALSE;  // 当串口发生错误,并不终止串口读写

DCB_COM1.ByteSize = 8;   // 数据位,范围:4-8

DCB_COM1.Parity = NOPARITY; // 校验模式

DCB_COM1.StopBits = 0;   // 1位停止位

   

//设置串口参数

if (!SetCommState(m_hComm, &DCB_COM1))

{

    TRACE(_T("SetCommState error"));      

    return FALSE;

}

--------------------------------------------

·读写串口

BOOL ReadFile(

  HANDLE hFile,//CreateFile函数返回的串口句柄

  LPVOID lpBuffer,//指定接收数据的缓冲区

  DWORD nNumberOfBytesToRead,//想要读取的字节数

  LPDWORD lpNumberOfBytesRead,//实际读取的字节数

  LPOVERLAPPED lpOverlapped//Windows CE不支持,设置         

                           //为NULL

);

BOOL WriteFile(

  HANDLE hFile,//CreateFile函数返回的串口句柄

  LPCVOID lpBuffer,//指定存储发送数据的缓冲区

  DWORD nNumberOfBytesToWrite,//想要发送的字节数

  LPDWORD lpNumberOfBytesWritten,//实际发送的字节数

  LPOVERLAPPED lpOverlappedWindows CE不支持,设置         

                           //为NULL

);

读写函数的返回值都是成功时返回非零值,失败时返回零。

例:

DWORD dwLength;

char *recvBuf = new char[1024];

BOOL fReadState = ReadFile(m_hComm, recvBuf, 1024, &dwLength, NULL);

delete[] recvBuf;

 

DWORD dwactlen;

char *psendbuf = new char[32];

BOOL fWriteState = WriteFile(m_hComm, psendbuf, 32, &dwactlen, NULL);

delete[] psendbuf;

需要注意的是,由于从串口读写数据的速度比较慢,因此一般情况下,不会在主线程中读写大量的数据,而是创建单独的线程来读写数据,特别是读数据


==================================================

异步串口I/O

BOOL GetCommMask(

  HANDLE hFile,

  LPDWORD lpEvtMask

);

BOOL SetCommMask(

  HANDLE hFile,

  DWORD dwEvtMask

);

BOOL WaitCommEvent(

  HANDLE hFile,

  LPDWORD lpEvtMask,

  LPOVERLAPPED lpOverlapped

);

GetCommMask函数用于得到串口已经设置了的串口事件,参数hFile指定已打开的串口句柄,参数lpEvtMask用于存取得到的串口事件集。SetCommMask函数的功能与GetCommMask函数正好相反,用于设置串口事件集。WaitCommEvent函数用于等待预先设置的串口事件中的某一个事件发生,该函数将阻塞线程,直到预先设置的串口事件中的某一事件的发生。参数lpEvtMask用于存储已经发生的事件,参数lpOverlapped必须设置为NULL,因为在Windows CE中不支持重叠I/O操作。

-----------------------------------------------------

·设置端口读写超时:(不使用这个逾时功能,ReadFile直到所有字符接收完才会返回

BOOL GetCommTimeouts(

  HANDLE hFile,

  LPCOMMTIMEOUTS lpCommTimeouts

);

BOOL SetCommTimeouts(

  HANDLE hFile,

  LPCOMMTIMEOUTS lpCommTimeouts

);

  在用ReadFile和WriteFile读写串口时,需要考虑超时问题。如果在指定的时间内没有读出或者写入指定数量的字节数据,那么ReadFile函数或者WriteFile函数就会返回。GetCommTimeouts函数用来查询当前的超时时间设置,该函数会填充一个COMMTIMEOUTS结构。SetCommTimeouts函数用来通过一个COMMTIMEOUTS结构设置超时时间。两个函数的返回值都是成功时返回非零值,失败时返回零。


实例分析:

COMMTIMEOUTS CommTimeouts; 
    GetCommTimeouts (hCom, &CommTimeouts);
    //不使用这个逾时功能,ReadFile直到所有字符接收完才会返回
    CommTimeouts.ReadIntervalTimeout = 10;//如果此值为表示不使用功能,如果为,则表示在ms内没有接收到下一个字节,则认为超时,表示本次读串口操作结束
    CommTimeouts.ReadTotalTimeoutMultiplier = 0;
    CommTimeouts.ReadTotalTimeoutConstant = 0;
    CommTimeouts.WriteTotalTimeoutMultiplier =10;
    CommTimeouts.WriteTotalTimeoutConstant  =2000;  
  ReadIntervalTimeout :以毫秒为单位设置通信线路上的两个字符到达之间最大时间间隔。在ReadFile操作期间,从接收到第一个字符开始计时。如果任意两个字符到达之间的时间间隔超过这个最大值,则ReadFile操作完成,返回缓冲数据。如果该值设置为0,则不使用间隔超时。

ReadTotalTimeoutMultiplier:读时间系数。以毫秒为单位设置一个用来计算读操作总超时时间的时间系数。

ReadTotalTimeoutConstant:读时间常量。以毫秒为单位设置一个用来计算读操作总超时时间的时间常量。

读总超时时间 = 读时间系数*要读的字节数 + 读时间常量

WriteTotalTimeoutMultiplier:写时间系数。以毫秒为单位设置一个用来计算写操作总超时时间的时间系数。

WriteTotalTimeoutConstant:写时间常量。以毫秒为单位设置一个用来计算写操作总超时时间的时间常量。

写总超时时间 = 写时间系数*要写的字节数 + 写时间常量


 ---------------------------------------------------------------------------------------------

·设置接收/发送缓冲区大小

BOOL SetupComm(

  HANDLE hFile,

  DWORD dwInQueue,

  DWORD dwOutQueue

);

hFile指定已打开的串口句柄,dwInQueue指定接收缓冲区的大小,dwOutQueue指定发送缓冲区的大小。

返回值:成功时返回非零值,失败时返回零。

例:

SetupComm(m_hComm,512,512);

如果不使用该函数,系统会推荐一个适合的默认值。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值