基于ARM9嵌入式微处理器的远程仓库管理系统- 张晓东 - 图文(8)

2019-03-22 23:46

进行操作实现对串口硬件的操作。由于串口驱动程序为流设备驱动,于是它将由设备管理器进行加载。

在Windows CE中,可以通过CreateFile函数打开串口,如果串口打开成功的话,将会返回打开串口的句柄,否则将返回INVALID_HANDLE_VALUE。在实际使用串口时,还必须设置好串口的波特率,奇偶校验和数据位等参数。Windows CE中提供了GetCommState和SetCommState函数,分别获取串口当前的参数和设置串口的参数。打开串口的代码如程序清单 5.1所示,epcSerialOpen方法根据指定的参数打开串口,并创建此串口的读线程和写线程,以实现串口的异步读写。在使用系统的串口API函数时,还要使用到一个名为DCB的结构体,在GetCommState函数中,它属于输出参数,在SetCommState函数中,它属于输入参数。

程序清单 5.1 串口控制类中的打开串口方法

int CCeSerial::epcSerialOpen (EPort Port, EBaudrate BaudRate, {

int iErr;

if (hCOM != INVALID_HANDLE_VALUE) { /* 判断串口是否已打开,打开则返回 */ return (COM_ERR_USING); } */ */

if (hCOM == INVALID_HANDLE_VALUE) { }

31

__messageDispDebug(_T(\无法打开端口或端口已打开!请检查是否已被占用.\return (COM_ERR_OPEN); }

if( (BaudRate > EBaud115200) || (BaudRate < EBaud110) ) { }

hCOM = CreateFile(GstrPortTbl[Port-1], GENERIC_READ | GENERIC_WRITE, 0, 0,

__messageDispDebug(_T(\波特率参数错误.\return (COM_ERR_PARA);

__messageDispDebug(_T(\打开串口号参数错误.\return (COM_ERR_PARA);

if ( (Port > ECOM9) || (Port < ECOM1) ) {

/* 参数判断

EDataBits DataBits, EStopBits StopBits, EParity Parity, BOOL bDTRShake, BOOL bRTSShake)

OPEN_EXISTING, 0, 0); /* 打开串口

*/

if (iErr != COM_OK) { return (iErr); } */ }

return (COM_OK);

PurgeComm(hCOM, PURGE_TXCLEAR | PURGE_RXCLEAR);

/* 清除收/发缓冲区 iErr = epcSerialSetCom(BaudRate, DataBits, StopBits, Parity, bDTRShake, bRTSShake);

/* 设置串口 (禁止硬件流控制)

使用完串口后,应该管关闭串口,程序清单 5.2 的epcSerialClose方法将实现串口读写线程并关闭串口,其首先调用SetEvent函数向串口线程发出一个通知,等待线程自动推出后再关闭接受线程句柄,最后关闭串口句柄。

程序清单 5.2 串口控制类的的关闭串口方法

BOOL CCeSerial::epcSerialClose (void) { */ */

CloseHandle(hRcvThread); */ */ */

}

return (FALSE);

32

hCOM = INVALID_HANDLE_VALUE; return (TRUE); }

if (hCOM != INVALID_HANDLE_VALUE) {

SetCommMask(hCOM, 0);

PurgeComm(hCOM, PURGE_TXCLEAR | PURGE_RXCLEAR); CloseHandle(hCOM);

/* 关闭串口操作句柄

hRcvThread = NULL;

CloseHandle(hExitThreadEvent);

/* 关闭线程退出事件句柄

/* 关闭接收线程句柄

WaitForSingleObject(hRcvThread, 500);

/* 等待线程退出

if (hRcvThread != NULL) {

SetEvent(hExitThreadEvent);

/* 通知串口接收线程退出

/* 清除收/发缓冲 */

}

epcSerialSendData方法使共外部使用的用来向串口发送数据,epcSerialSendData方法首先会把要发送的数据传递给写程序的消息队列,然后有写线程将数据发送出去,从而避免阻塞主线程,epcSerialSendData方法的详细代码如程序清单 5.3所示。

程序清单 5.3 串口控制类的的发送数据方法

BOOL CCeSerial::epcSerialSendData (BYTE *pucSendBuf, DWORD dwLength) {

if ( (pucSendBuf == NULL) || (dwLength < 1) ) { /* 参数判断 */ return (FALSE); } }

if (hCOM == INVALID_HANDLE_VALUE) { /* 判断串口是否已经打开 */ }

ClearCommError(hCOM, &dwErrorFlags, &comstatTest); /* 清除串口错误 */ WriteFile(hCOM, pucSendBuf, dwLength, &dwActLen, NULL); /* 发送数据 */ return (TRUE);

__messageDispDebug(_T(\串口未打开!\return (FALSE); DWORD dwActLen; COMSTAT comstatTest; DWORD dwErrorFlags;

接收串口数据使用epcSerialRcvDataTread函数,其采用的是线程方式,在建立数据库接收线程之前应该先确认当前串口串口没有被占用,然后再设置接收参数,如接收数据个数,读数据总超时常量,其详细代码如程序清单 5.4所示。

程序清单 5.4 串口控制类的的接收数据方法

BOOL CCeSerial::epcSerialRcvDataTread (DWORD dwLength, DWORD dwOutTime, {

DWORD dwThreadID; COMMTIMEOUTS ctoTimeOut;

PFUN_COMRCV pfunOnComRcv, LPVOID pvUserParam)

if ( (dwLength < 1) || (pfunOnComRcv == NULL) ) { return (FALSE); }

if (dwLength > (1024*8)) {

33

dwLength = 1024*8; }

if (dwOutTime < 10) { dwOutTime = 10; } */ */ }

}

__messageDispDebug(_T(\创建接收线程失败!\return (FALSE);

if (hRcvThread == NULL) {

CloseHandle(hExitThreadEvent);

/* 关闭线程退出事件句柄

hRcvThread = CreateThread(0, 0, epcSerialComRcvTread, this, 0, &dwThreadID);

hExitThreadEvent = CreateEvent(NULL, TRUE, FALSE, NULL); /* 创建串口接收线程退出事件 dwRcvLength = dwLength; pfunRcvOnComRcv = pfunOnComRcv; pvRcvUserParam = pvUserParam;

GetCommTimeouts(hCOM, &ctoTimeOut); ctoTimeOut.ReadTotalTimeoutMultiplier = 1; SetCommTimeouts(hCOM, &ctoTimeOut);

* 接收字符间最大时间间隔 */ * 读数据总超时常量 */

ctoTimeOut.ReadIntervalTimeout = dwOutTime; ctoTimeOut.ReadTotalTimeoutConstant = dwOutTime; if (hCOM == INVALID_HANDLE_VALUE) { }

if (hRcvThread != NULL) { }

return (FALSE);

__messageDispDebug(_T(\串口未打开!\return (FALSE);

__messageDispDebug(_T(\串口接收线程已建立过!\

return (TRUE);

5.3.3 VB.net调用DLL文件

虽然VB.net是个简单易用的开发环境,但是自身功能有限,限制了VB.net在某些方面的应用。微软提供了两种方式来增强VB的功能,一种是调用COM

34

组件,另一种就是调用Dll函数,本设计中就是通过在VB.net中动态调用DLL达到调用串口动态链接库中的函数的母的。

在VB.net中调用动态链接库的函数很简单,首先在类中使用Declare函数声明要调用的动态链接库和函数名,本设计中主要调用了打开串口关闭串口发送数据和接受数据四个函数其详细的代码清单如程序清单 5.5所示。

程序清单 5.5 声明调用动态链接库

?声明调用打开串口函数

Public Declare Function epcSerialOpen1 Lib %ucBaudRate As Byte, ByVal ucDataBit As Byte, ByVal ucStopBit As Byte, ByVal ucParity As Byte) As Integer ?声明调用关闭串口函数

Public Declare Function epcSerialClose Lib \Boolean

?声明调用发送数据函数

Public Declare Function epcSerialSendData Lib \ByVal pucSendBuf As Byte(), ByVal dwLength As UInteger) As Boolean ?声明调用接收数据函数

Public Declare Function epcSerialClose Lib \ByVal pucRcvBuf As Byte(), ByVal dwLength As Integer, ByVal dwOutTime As Integer, ByVal bClrComBuf As Boolean) As Integer

5.3.4 打印机驱动模块

本设计中使用的打印机属于微型的串口打印机,这种打印机的优点是不需要编写特定的驱动程序,打印机内部自带了控制器,用户只需要通过目标系统的标准RS232接口与打印机连接。然后按照厂家提供的打印指令表,即可控制打印机打印各种文字或图形。

由上一节可知道,系统的串口API已经被封装成一个串口类,并且打包成以标准C语言为导出函数的动态链接库,控制打印机的操作只需要调用串口类然后发送相应的指令和编辑好的数据,其策划年供需流程图如图 5.6所示。

35


基于ARM9嵌入式微处理器的远程仓库管理系统- 张晓东 - 图文(8).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:结构施工统一做法

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: