admin 管理员组

文章数量: 887021


2024年2月24日发(作者:ascii与unicode互转软件)

1 引言

在很多情况下,远程监控和工业自动化领域系统经常采用串并口通信编程,其中串行接口被广泛地应用于工程实践的长距离通信中。运用Windows通信API可以在Windows环境下进行串口编程,不用对硬件直接进行操作,并通过VC、VB和Delphi等语言进行调用,大大方便了对数据的处理。本文对和串口通信相关的32位Windows API函数进行了介绍,并给出了相应的程序实例。

2 Windows API简介

Win32 API作为 Microsoft 32位平台(包括:Windows 9x,Windows NT3.1/4.0/5.0,WindowsCE)的应用程序编程接口,它是构筑所有32位Windows平台的基石,所有在Windows平台上运行的应用程序都可以调用这些函数。API是windows的核心,从事Windows应用程序开发,离不开对Win32 API函数的调用。只有充分理解和利用API函数,才能深入到Windows的内部,充分挖掘系统提供的强大功能和灵活性。

3 Windows API相关串口通信函数介绍

在32位的Windows系统中,串口通信是作为文件处理的,串口操作一般为的打开、关闭、读取、写入等操作,相应的Windows API 函数如下:

3.1 打开和关闭串口

1 打开串口

在Windows系统中串口通信会话以调用CreateFile ( )函数开始。CreateFile ( )函数可以读写访问串口,并返回一个句柄,并在以后的端口操作中使用。

1. CreateFile ( )函数声明如下:

2. HANDLE CreateFile(

3. LPCTSTR lpszNAME, // 指定要打开的串口逻辑名

4. DWORD fdwAccess, // 指定串口访问的类型

5. DWORD fdwShareMode, // 指定端口的共享属性

6. LPSECURITY_ATTRIBUTES lpsa, // 引用安全属性结构SECURITY_ATTRIBUTES

7. DWORD fdwCreate, // 指定CreateFile( )正在被已有的文件调用时应采取的措施

8. DWORD fdwAttrsAndFlags, // 描述端口的各种属性

9. HANDLE hTemolateFile // 指向模板文件的句柄

10. )

11. 其中安全属性结构SECURITY_ATTRIBUTES结构声明如下:

12. typedef struct_SECURITY_ATTRIBUTES{

13. DWORD nLength; // 指明该结构的长度

14. LPVOID lpSecurityDescriptor; // 指向一个安全描述字符

15. BOOL bInheritHandle; // 表明句柄是否能被继承

16. }SECURITY_ATTRIBUTES;

17. 调用CreateFile ( )函数打开COM1串口操作如下所示:

18. HANDLE hCOM;

19. DWORD DWeRROR;

20. hCom=Creatfile (“COM1”, // 对串口1进行操作

21. GENERIC_READ | GENERIC_WRITE, //允许读和写

22. 0, //独占方式

23. NULL,

24. OPEN_EXISTING,

25. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, //重叠方式

26. NULL

27. );

28. if(hCOM==INVALID_HANDLE_VALUE)

29. {

30. dwError=GetLastError( ); //处理错误

31. }

一旦串口处于打开状态,就可以分配一个发送缓冲区和接收缓冲区,并且通过调用SetupComm( )函数实现其他初始化工作。

1. SetupComm( )函数声明如下:

2. BOOL SetupComm(

3. HANDLE Hfile, // 由CreatFile ( )返回的指向已打开端口的句柄句柄

4. DWORD dwInQueue, // 输入缓冲区大小

5. DWORD dwOutQueue // 输出缓冲区大小

6. );

2 关闭串口

关闭串口通过调用CloseHandle ( )函数关闭由CreatHandle ( )函数返回的句柄来完成。

1. CloseHandle ( )函数声明如下:

2. BOOL CloseHandle(

3. HANDLE hObject // 需关闭的设备句柄

4. );

3.2 串口配置和串口属性

在用CreatFile ( )函数打开串口后,系统将根据上次打开串口时设置的值来初始化串口,可以集成上次打开操作后的数值,包括设备控制块(DCB)和超时控制结构(COMMTIMEOUTS)。如果是首次打开串口,Windows会使用缺省配置。

1 串口配置

Windows 2000 中使用GetCommState( )函数获取串口的当前配置,使用SetCommState ( )函数重新分配串口资源的各个参数。

1. GetCommState ( )函数声明如下:

2. BOOL GetCommState(

3. HANDLE hFile, // 由CreatFile ( )函数返回的指向已打开的串口的句柄

4. LPDCB lpDCB // 指向device-control block structure 的指针

5. );

6. 其中DCB的结构声明如下:

7. typedef struct_DCB{

8. DWORD DCBlength; // DCB块大小

9. DWORD BaudRate; // 数据传输率

10. DWORD fBinary:1; // 二进制模式,不检验EOF

11. DWORD fParity:1; // 允许奇偶校验

12. DWORD fOutCtsFlow:1; // CTS输出流控制

13. DWORD fOutDsrFlow:1; // DSR输出流控制

14. DWORD fDtrContorl:2; // DTR流控制类型

15. DWORD fDsrSensitivity:1; // 对DTR信号线是否敏感

16. DWORD fTXContinueOnOxff:1; // XOFF continue Tx

17. DWORD fOutX:1; // XON/XOFF输出流控制

18. DWORD fInX:1; // XON/XOFF输入流控制

19. DWORD fErrorChar:1; // 错误替换

20. DWORD fNull:1; // 是否丢弃接收到的NULL字符

21. DWORD fRtsControl:2; // RTS流控制

22. DWORD fAbortOnError:1; // 发送错误,指定是否终止读、写操作

23. DWORD fDummy2:17; // 保留

24. WORD wReserved; // 现在不用

25. WORD XonLim; // XOFF字符发送之前接收到缓冲区中可允许的最小字节数

26. WORD XoffLim; // XOFF字符发送之前缓冲区中可允许的最小可用字节数

27. BYTE ByteSize; // 端口当前使用的数据位数

28. BYTE Parity; // 当前使用的奇偶校验法

29. BYTE StopBits; // 当前使用的停止位数

30. char XonChar; // 发送和接收的XON字符值

31. char XoffChar; //发送和接收的XOFF字符值

32. char ErrorChar; // 用来替代接收到的奇偶校验发生错误的字符

33. char EofChar; // 表示数据的结束

34. char EvtChar; // 事件字符

35. WORD wReserved1; // 保留的位

36. }DCB;

如果GetCommState ( )函数调用成功,则返回值不为零。若函数调用失败,则返回值为零,可以调用GetLastError ( )函数来获取进一步的错误信息。

GetLastError ( )也是Windows API函数,函数声明如下:

DWORD GetLastError(VOID);

如果应用程序需要修改配置,可以通过调用GetCommState ( )函数获得当前的DCB结构,然后更改DCB结构中的参数,调用SetCommState ( )函数配置修改过的DCB来配置端口。

1. SetCommState ( )函数声明如下:

2. BOOL SetCommState (

3. HANDLE hFile, // 由CreatFile ( )函数返回的已打开的串口的句柄

4. LPDCB lpDCB // 指向DCB结构的指针

5. );

2 串口属性

串口的属性通过GetCommProperties ( )函数获得,GetCommProperties ( )函数声明如下:

1. BOOL GetCommProperties(

2. HANDLE hFile, //返回句柄

3. LPCOMMPROP lpCommProp //指向COMMPROP的结构

4. );

其中lpCommProp指向一个COMMPROP的结构,串口的性能从COMMPROP中返回。

3 通信设备配置

Windows API提供了CommConfigDialog ( )函数对通信设备进行配置,从中改变数据传输速率、数据位、奇偶校验方法、停止位和流控制方法。

1. CommConfigDialog ( )函数的声明如下:

2. BOOL CommConfigDialog(

3. LPTSTR lpszName, // 要配置的端口名

4. HWND hWnd, // 拥有对话框的窗口句柄

5. LPCOMMCONFIG lpCC // 指向一个COMMCONFIG结构

6. );

当CommConfigDialog ( )函数返回时,选定的设置在COMMFIG的DCB参数中返回,对已打开的串口,对端口设置进行更改通过SetCommState ( )函数来改变。

3.3 读写串口

1 读串口操作

一般在程序中使用Win32 API ReadFile ( )函数从串口中读取数据。

ReadFile ( )函数声明如下:

1. BOOL ReadFile(

2. HANDLE hFILE, // 指向由CreatFile ( )函数产生的句柄

3. LPVOID lpbuffer, // 指向一个缓冲区

4. DWORD nNumberOfBytesToRead, // 读取的字节数

5. LPDWORD lpNumberOfBytesToRead, // 指向调用该函数读出的字节数

6. LPOVERLAPPED lpOverlapped // 一个OVERLAPPED结构

7. );

2 写串口操作

一般在程序中使用Win32 API WriteFile ( )函数向串口中写数据。

WriteFile ( )函数声明如下:

1. BOOL WriteFile(

2. HANDLE hFILE, // 指向由CreatFile( )函数产生的句柄

3. LPVOID lpbuffer, // 指向一个缓冲区

4. DWORD nNumberOfBytesToWrite, // 向串口设备写入的字节数

5. LPDWORD lpNumberOfBytesToWritten, // 指向调用该函数已写入的字节数

6. LPOVERLAPPED lpOverlapped // 一个OVERLAPPED结构

7. );

3 异步I/O操作

读、写串口操作中的OVERLAPPED结构用于在Windows中进行异步I/O操作,使应用程序可以在前台、后台同时执行不同的任务,并由GetOverLappedResult ( )函数获取结果。

OVERLAPPED结构类型声明如下:

1. Typedef struct_OVERLAPPED{

2. DWORD Internal; // 指出一个和系统相关的状态

3. DWORD InternalHigh; // 指出发送或接收的数据长度

4. DWORD Offset;

5. DWORD OffsetHigh; // Offset和OffsetHigh指明文件传送的开始位置和字节偏移量

6. HANDLE hEvent; // 指定一个I/O操作完成后出发的事件

7. }OVERLAPPED;

8. 异步I/O操作可以由GetOverLappedResult ( )函数来获取结果。

9. GetOverLappedResult ( )函数声明如下:

10. BOOL GetOverLappedResult(

11. HANDLE hFILE, // 标识通信句柄,开始调用重叠结构ReadFile、WriteFile

12. LPOVERLAPPED lpOverlapped, // 启动异步操作时指定的OVERLAPPED结构

13. LPDWORD lpNumberOfBytesTransferred, // 接收读、写操作实际传递的字节数

14. BOOL bWait // 指定函数是否等待挂起的异步操作完成。

15. );

4 超时设置

Windows 2000中读写串口引入了超时结构。超时结构直接影响读和写的操作行为,当事先设定的超时间隔消逝时,ReadFile ( )、WriteFile ( )操作将被无条件结束。

超时结构定义如下

1. typedef struct_COMMTIMEOUTS{

2. DWORD ReadIntervalTimeout;

3. DWORD ReadTotalTimoutMultiplier;

4. DWORD ReadTotalTimouConstant;

5. DWORD WriteTotalTimoutMultiplier;

6. DWORD WriteTotalTimoutConstant;

7. } COMMTIMEOUTS,*LPCOMMTIMEOUTS;

其中:ReadIntervalTimeout以ms为单位指定通信线路上两个字符到达之间的最大时间间隔;ReadTotalTimoutMultiplier以ms为单位指定一个系数,该系数用来计算读操作的总超时时间;ReadTotalTimouConstant以ms为单位指定一个常数,该常数用来计算读操作的总超时时间;WriteTotalTimoutMultiplier以ms为单位指定一个系数,该系数用来计算写操作的总超时时间;WriteTotalTimoutConstant以ms为单位指定一个常数,该常数用来计算读写作的总超时时间。

1. Windows API GetCommTimeOuts ( )函数来获得当前超时参数。

2. GetCommTimeOuts ( )函数声明如下:

3. BOOL GetCommTimeOuts (

4. HANDLE hFILE, // 标识通信设备,CreatFile ( )函数返回该句柄

5. LPCOMMTIMEOUTS lpCommTimeouts // 指向一个COMMTIMEOUTS结构,返回超

6. // 时信息

7. );

如果想获得进一步的错误信息,可以调用GetLastError ( )函数来获取。

5 通信状态和通信错误

如果在串口通信中发生错误,如发生终端、奇偶错误等,I/O操作将会终止。如果程序要进一步执行I/O操作,必须调用ClearCommError ( )函数。ClearCommError ( )函数有两个作用,一是清除错误条件,一是确定串口通信状态。

1. ClearCommError ( )函数声明如下:

2. BOOL ClearCommError(

3. HANDLE hFILE, // 由CreatFile ( )函数返回的句柄

4. LPDWORD lpErrors, // 指向一个指明错误类型的掩码填充的32位变量

5. LPCOMSTAT lpStat // 指向一个COMSTAT结构接收设备的状态

6. );

3.4 程序实例

下面的程序为打开并初始化端口:

1. HANDLE hCom;

2. DWORD dwError;

3. DCB dcb;

4. COMMTIMEOUTS TimeOuts;

5. hCom=CreateFile(“COM1”, //对串口1进行操作

6. GENERIC_READ | GENERIC_WRITE, //允许读和写

7. 0, //独占方式

8. NULL,

9. OPEN_EXISTING,

10. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, //重叠方式

11. NULL

12. );

13. if(hCom==INVALID_HANDLE_VALUE)

14. { dwError=GetLastRrror( );

15. …//错误处理

16. }

17. SetupComm(hCom,1024,1024) //缓冲区的大小为1024

18. tervalTimeout=1000;

19. talTimoutMultiplier=500;

20. talTimouConstant=5000;

21. otalTimoutMultiplier=500;

22. otalTimoutConstant=5000;

23. SetCommTimeouts(hCom,&TimeOuts); // 设置超时

24. GetCommState(hCom,&dcb);

25. te=2400; // 数据传输速率为2400

26. ze=8; // 每个字符为8位

27. =NOPARITY; // 无校验

28. ts=ONESTOPBIT; // 一个停止位

29. SetCommState(hCom,&dcb);

4 结束语

Win32 API作为 Windows平台的应用程序编程接口,是windows的核心。通过充分理解和利用API函数,可以使我们深入到Windows的内部,充分挖掘系统提供的强大功能和灵活性,为我们在工程实践中进行串口通信编程提供方便。


本文标签: 串口 函数 操作 结构 打开