C语言中如何对串口进行操作

  1 串口是一种时常用来与外界通信的一种设备,虽然现在网络已经很普及,但由于PC机时常需要通过MODEM与远距离主机或是与单片机设备进行通信所以串口的用途还是很广泛。
  2 串口在Win32的开发中可以以文件的形式来进行打开和关闭,并且串口的读写也可以利用ReadFile和WriteFile来进行操作。以前在Windows 3.X下的OpenComm等部分串口操作函数已经被废弃。
  3 串口的开打可以使用下面的方法:
  4 HANDLE hDev = CreateFile( "COM1",              指明串口名称,COM1代表第一个串口,COM2代表第二个串口
  5               GENERIC_READ | GENERIC_WRITE,     用于读和写
  6               0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 指明为异步操作方式
  7
  8               NULL );
  9 串口被打开后,马上要进行的操作就是设置串口的状态和属性,通过指定一个DCB的结构来对串口进行设置,所使用的函数有下面这些
 10 BOOL SetCommState(
 11         HANDLE hFile,  handle to communications device
 12         LPDCB lpDCB  device-control block
 13         );
 14
 15 其中DCB结构为
 16 typedef struct _DCB {
 17     DWORD DCBlength;  sizeof(DCB) 结构长度
 18         DWORD BaudRate;  current baud rate 波特率 可取下面的值,表示每秒的速率(bit per second)
 19         /*
 20            CBR_110  CBR_19200  CBR_300  CBR_38400  CBR_600  CBR_56000  CBR_1200  CBR_57600
 21            CBR_2400  CBR_115200  CBR_4800  CBR_128000  CBR_9600  CBR_256000  CBR_14400 */
 22         DWORD fBinary: 1;  binary mode, no EOF check 二进制方式
 23         DWORD fParity: 1;  enable parity checking 允许奇偶校验
 24         DWORD fOutxCtsFlow:1;  CTS output flow control CTS(clear-to-send)流控
 25         DWORD fOutxDsrFlow:1;  DSR output flow control DSR(data-set-ready)流控
 26         DWORD fDtrControl:2;  DTR flow control type DTR(data-terminal-ready)流制
 27         DWORD fDsrSensitivity:1;  DSR sensitivity 是否检测握手信号
 28         DWORD fTXContinueOnXoff:1;  XOFF continues Tx
 29         DWORD fOutX: 1;  XON/XOFF out flow control
 30         DWORD fInX: 1;  XON/XOFF in flow control
 31         DWORD fErrorChar: 1;  enable error replacement
 32         DWORD fNull: 1;  enable null stripping
 33         DWORD fRtsControl:2;  RTS flow control
 34         DWORD fAbortOnError:1;  abort on error
 35         DWORD fDummy2:17;  reserved
 36         WORD wReserved;  not currently used
 37         WORD XonLim;  transmit XON threshold
 38         WORD XoffLim;  transmit XOFF threshold
 39         BYTE ByteSize;  number of bits/byte, 4-8 数据位
 40         BYTE Parity;  0-4=no,odd,even,mark,space 校验方式
 41         BYTE StopBits;  0,1,2 = 1, 1.5, 2 停止位
 42         char XonChar;  Tx and Rx XON character
 43         char XoffChar;  Tx and Rx XOFF character
 44         char ErrorChar;  error replacement character
 45         char EofChar;  end of input character
 46         char EvtChar;  received event character
 47         WORD wReserved1;  reserved; do not use
 48 } DCB;
 49 通过一个字符串来建立DCB结构
 50 例如字符串:baud=1200 parity=N data=8 stop=1 表明使用1200BPS速率,偶校验,8位数据位,1位停止位
 51 BOOL BuildCommDCB(
 52         LPCTSTR lpDef,  device-control string
 53         LPDCB lpDCB  device-control block
 54         );
 55 设置端口的缓冲区大小
 56 BOOL SetupComm(
 57         HANDLE hFile,  handle to communications device
 58         DWORD dwInQueue,  size of input buffer 输入缓冲区大小
 59         DWORD dwOutQueue  size of output buffer 输出缓冲区大小
 60         );
 61
 62 串口的读写依然可以利用ReadFile和WriteFile函数,这里介绍另一个函数来查询端口状态,
 63 BOOL ClearCommError(
 64         HANDLE hFile,  handle to communications device
 65         LPDWORD lpErrors,  error codes
 66         LPCOMSTAT lpStat  communications status
 67         );
 68
 69 COMSTAT结构如下
 70 typedef struct _COMSTAT {
 71     DWORD fCtsHold : 1;
 72     DWORD fDsrHold : 1;
 73     DWORD fRlsdHold : 1;
 74     DWORD fXoffHold : 1;
 75     DWORD fXoffSent : 1;
 76     DWORD fEof : 1;  
 77     DWORD fTxim : 1;
 78     DWORD fReserved : 25;
 79     DWORD cbInQue;          //接收队列内数据量
 80     DWORD cbOutQue;     发送队列内数据量
 81 } COMSTAT, *LPCOMSTAT;
 82 //从串口内读取数据
 83 {   
 84     BOOL bReadStatus;       
 85     DWORD dwBytesRead, dwErrorFlags;
 86     COMSTAT ComStat;
 87     ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );
 88     if( !ComStat.cbInQue ) return( 0 );                                 //检查当前是否有数据在接收队列内
 89         dwBytesRead = (DWORD) ComStat.cbInQue;
 90     if( limit < (int) dwBytesRead ) dwBytesRead = (DWORD) limit;        //确定当前可能读入的最大数量
 91         bReadStatus = ReadFile( m_hIDComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead );
 92     if( !bReadStatus )
 93     {
 94         if( GetLastError() == ERROR_IO_PENDING )
 95         {
 96             WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );       //等待读操作完成
 97                 return( (int) dwBytesRead );
 98         }
 99         return( 0 );
100     }   
101 }           
102                 
103 //在本节提供一个经过封装的类CSerial来完成串口的操作,这份代码来自于网上,我写了一个简单的DEMO用于向MODEM发送AT命令并读回数据。相关代码如下:
104 //CSerial ser;假设COM1端口上是一个MODEM,通过发送AT命令来和MODEM进行通信
105 //关于AT命令请查询其他资料
106 if(ser.Open(1,9600))
107 {   
108     char szCmd[100],szRet[100];
109     strcpy(szCmd,"ATI0\r\n");返回调制解调器默认的速率
110         int iSend = ser.SendData(szCmd,strlen(szCmd));
111     while(ser.ReadDataWaiting() == 0)
112     {//等待数据
113         Sleep(100);
114     }
115     int iRead =ser.ReadData(szRet,99);
116     if(iRead != 0)
117     {
118           szRet[iRead]='\0';
119           printf("send %s read %s\n",szCmd,szRet);
120     }
121 }       
122 else    
123 {   
124     printf("error open COM port\n");
125 }

picked from:http://yadang418.blog.163.com/blog/static/2684365620096103126456/

原文地址:https://www.cnblogs.com/johnchain/p/2760029.html