Windows 平台下 API调用与单片机进行串口通信
本博客并非完全原创,其中大部分内容由作者在网上教程结合自己的理解写成,如有侵权,请指出并联系我删除。作者现为嵌入式系统初学者,如有错误还请见谅
-
API串口通信
-
使用Win32的API
API串口通信
串行端口是系统资源的一部分,其本质是作为CPU和串行设备间的编码转换器。当数据从 CPU经过串行端口发送出去时,字节数据转换为串行的位(Bit); 接收数据时,串行的位被转换为字节数据。应用程序要使用串口进行通信,必须在使用之前向操作系统提出资源申请要求(即打开串口),通信完成后再释放资源(即关闭串口)。
串行通信一般可以分为同步和异步两种操作方式。所谓同步方式是指在串口的接收缓冲区中读取规定数目的数据,直到规定数目的数据全部被读出或设定的超时时间已到才返回。如果规定的待读取数据量大且设定的超时时间也较长,而接收缓冲区较小,则可能引起线程阻塞。而异步方式是利用Windows的多线程结构,让串口的读写操作在后台进行,而应用程序的其他部分在前台执行。 如果按驱动方式分,串口通信也可分为查询和事件驱动两种操作类型。
通过Visual C++的标准通信函数_inp和_outp可直接通过串口输入和输出数据。一般来说,在Visual C++中开发串口通信程序主要有调用API函数和使用ActiveX控件技术两种方式。基本步骤为:打开串口设备,设置串口通信属性,进行串口读写操作,关闭串口。下面将较为详细地讨论在VC中实现串口通信的上述两种方法。
———
使用Win32的API
API是附带在Windows内部的一个极其重要的组成部分。Windows的32位API主要是一系列复杂的函数和消息集合,可以看做是Windows系统为其下运行的各种开发系统提供的开放式通用功能增强接口。Windows环境下对串行端口进行操作,是把它作为文件来处理的,其中涉及到大量API函数,操作起来比较复杂,可以概括为以下的几个操作步骤:
1. 打开串行通信设备。在VC中使用CreateFile函数打开串口,CreateFile将返回串口的句柄。该句柄将被用于后续的通信操作,并贯穿整个通信过程。当采用异步方式时,CreateFile函数的参数fdwAttrsAndFlags必须设为FILE_FLAG_ OVERLAPPED,如:
m_hComFile =CreateFile(“COM1”,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL );
2.指定并初始化读写缓冲区。程序通过调用SetupComm函数来指定读写缓冲区的大小,并执行重新分配内部输入和输出缓冲的任务,用PurgeComm函数对输入和输出缓冲进行初始化,如:
SetCommMask(m_hComFile, EV_RXCHAR | EV_TXEMPTY );
SetupComm(m_hComFile, 1024,1024) ;
PurgeComm(m_hComFile,
PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR );
3.设置串口属性,配置DCB结构。当用CreateFile函数完成串口打开操作时,默认继承设备控制块(DCB结构)设置。通过调用GetCommState函数读取当前串口设备控制块DCB设置,修改后通过SetCommState函数将其写入。也可以使用GetCommProperties获取COMMPROP结构,其中记载了系统支持的各项设置,包括当前所使用的串行设备、数据传输波特率、输入输出缓冲区大小等。例如:
DCB dcb
//定义设备控制块结构
GetCommState(m_hComFile, &dcb )
//读取串口原来的参数设置
dcb.BaudRate =9600
dcb.ByteSize =8
dcb.Parity = NOPARITY
dcb.StopBits = ONESTOPBIT
dcb.fBinary = TRUE
dcb.fParity = FALSE
SetCommState(m_hComFile, &dcb )
//串口参数配置
4.设置超时值。串口打开后,I/O操作的超时值采用默认值。超时值的设置与结构COMMTIMEOUTS及函数GetCommTimeouts和SetCommTimeouts有关。用GetCommTimeouts函数可以获得当前I/O操作的超时值配置,而调用SetCommTimeouts函数可以修改此配置,如:
COMMTIMEOUTS timeouts
//定义超时结构,并填写该结构
timeouts.ReadIntervalTimeout = 500
timeouts.ReadTotalTimeoutMultiplier = 1
timeouts.ReadTotalTimeoutConstant = 1000
timeouts.WriteTotalTimeoutMultiplier = 1
timeouts.WriteTotalTimeoutConstant = 1000
SetCommTimeouts(m_hComFile,&timeouts )
//设置读写操作所允许的超时
5.进行串行数据通信。调用函数ReadFile和WriteFile读写串口。若采用异步通信方式,两函数中最后一个参数为指向OVERLAPPED结构的非空指针,在读写函数返回值为FALSE的情况下,调用GetLastError函数,返回值为ERROR_IO_PENDING,表明I/O操作悬挂,即操作转入后台继续执行。此时,可以用WaitForSingleObject函数来等待结束信号并设置最长等待时间。下面的例子中,在主线程中发送命令,用一个辅助线程来监视串口,有数据到达时依靠事件驱动读入数据并向主线程报告。
6.关闭串行端口。调用函数CloseHandle即可。
总体说来,调用API 函数实现串行通信,程序更为复杂,但应用更加灵活。在API串口通信中可以将串口的属性设置和操作封装成一个专用的串口类,同时结合Windows非阻塞通信、多线程、动态链接库等手段,编写出高质量的通信程序,特别是在CPU处理任务比较繁重、与外围设备中有大量的通信数据时,更具实际意义。
此处应有引用,但是已经找不到文章出处( o=^•ェ•)o ┏━┓