⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 teach_sp_55.htm

📁 VC专题教程 -- 第一章 Internet相关开发 打包下载 --- 1.1 如何编写CGI程序 ------ 1.2 一种更亲切的CGI开发系统WinCGI ------ 1.3 利用ISAPI开
💻 HTM
字号:

<!-- LANGUAGE='JavaScript'>write_body();<-->
<!-- LANGUAGE='JavaScript'>write_bar();<-->



<table width=98% cellspacing="0" cellpadding="0" align=center><!--整体框架-->
<tr><td>

<table border=0 width="100%" cellspacing="0" cellpadding="2"><!--标记放置区域-->
<tr>
	<td width="30%" align="center" bgcolor="#8E8E8E" valign=middle><img src=../../img/brand_200_60.gif width=200 height=60 alt="LOGO1"></td>
	<td width="70%" align="center" bgcolor="#8E8E8E" valign=middle><!-- LANGUAGE='JavaScript'>write_ban();<--></td>
</tr>
<tr>
	<td colspan="2" bgcolor="#939393" align=center><font color=white>您当前位置</font> <a href=../../index.htm><font color=white>首页</font></a> <a href=../index.htm><font color=white>开发教程</font></a> <a href=index.htm><font color=white><font class=engul>Visual C++/MFC</font>专题讲座</font></a> <font color=white>5.5 串口的操作</font> <font color=white><!-- LANGUAGE='JavaScript'>write_command();<--></font></td>
</tr>
</table><!--标记放置区域 END-->

<table border=0 width=100% cellspacing="0" cellpadding="0">
<tr bgcolor="#F4F4F4">
<td><!-- article title begin here-->
<br>
<p align=center><big>5.5 串口的操作</big>
<p>串口是一种时常用来与外界通信的一种设备,虽然现在网络已经很普及,但由于PC机时常需要通过MODEM与远距离主机或是与单片机设备进行通信所以串口的用途还是很广泛。
<p>串口在Win32的开发中可以以文件的形式来进行打开和关闭,并且串口的读写也可以利用ReadFile和WriteFile来进行操作。以前在Windows 3.X下的OpenComm等部分串口操作函数已经被废弃。
<p>串口的开打可以使用下面的方法:
<pre>
HANDLE hDev = CreateFile( "COM1", //指明串口名称,COM1代表第一个串口,COM2代表第二个串口
			GENERIC_READ | GENERIC_WRITE, //用于读和写
			0, 
			NULL, 
			OPEN_EXISTING, 
			FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, //指明为异步操作方式
			NULL );
</pre>
串口被打开后,马上要进行的操作就是设置串口的状态和属性,通过指定一个DCB的结构来对串口进行设置,所使用的函数有下面这些
<pre>
BOOL SetCommState(
  HANDLE hFile,  // handle to communications device
  LPDCB lpDCB    // device-control block
);
其中DCB结构为
typedef struct _DCB { 
  DWORD DCBlength;           // sizeof(DCB) 结构长度
  DWORD BaudRate;            // current baud rate 波特率 可取下面的值,表示每秒的速率(bit per second)
  /*
	CBR_110 
	CBR_19200
	CBR_300 
	CBR_38400
	CBR_600 
	CBR_56000
	CBR_1200
	CBR_57600
	CBR_2400
	CBR_115200
	CBR_4800
	CBR_128000
	CBR_9600
	CBR_256000
	CBR_14400 
  */
  DWORD fBinary: 1;          // binary mode, no EOF check 二进制方式
  DWORD fParity: 1;          // enable parity checking 允许奇偶校验
  DWORD fOutxCtsFlow:1;      // CTS output flow control CTS(clear-to-send)流控
  DWORD fOutxDsrFlow:1;      // DSR output flow control DSR(data-set-ready)流控
  DWORD fDtrControl:2;       // DTR flow control type DTR(data-terminal-ready)流制
  DWORD fDsrSensitivity:1;   // DSR sensitivity 是否检测握手信号
  DWORD fTXContinueOnXoff:1; // XOFF continues Tx 
  DWORD fOutX: 1;          // XON/XOFF out flow control 
  DWORD fInX: 1;           // XON/XOFF in flow control 
  DWORD fErrorChar: 1;     // enable error replacement 
  DWORD fNull: 1;          // enable null stripping 
  DWORD fRtsControl:2;     // RTS flow control 
  DWORD fAbortOnError:1;   // abort on error 
  DWORD fDummy2:17;        // reserved 
  WORD wReserved;          // not currently used 
  WORD XonLim;             // transmit XON threshold 
  WORD XoffLim;            // transmit XOFF threshold 
  BYTE ByteSize;           // number of bits/byte, 4-8 数据位
  BYTE Parity;             // 0-4=no,odd,even,mark,space 校验方式
  BYTE StopBits;           // 0,1,2 = 1, 1.5, 2 停止位
  char XonChar;            // Tx and Rx XON character 
  char XoffChar;           // Tx and Rx XOFF character 
  char ErrorChar;          // error replacement character 
  char EofChar;            // end of input character 
  char EvtChar;            // received event character 
  WORD wReserved1;         // reserved; do not use 
} DCB; 

//通过一个字符串来建立DCB结构
//例如字符串:baud=1200 parity=N data=8 stop=1 表明使用1200BPS速率,偶校验,8位数据位,1位停止位
BOOL BuildCommDCB(
  LPCTSTR lpDef,  // device-control string
  LPDCB lpDCB     // device-control block
);

//设置端口的缓冲区大小
BOOL SetupComm(
  HANDLE hFile,     // handle to communications device
  DWORD dwInQueue,  // size of input buffer 输入缓冲区大小
  DWORD dwOutQueue  // size of output buffer 输出缓冲区大小
);
</pre>
<p>串口的读写依然可以利用ReadFile和WriteFile函数,这里介绍另一个函数来查询端口状态,
<pre>
BOOL ClearCommError(
  HANDLE hFile,     // handle to communications device
  LPDWORD lpErrors, // error codes
  LPCOMSTAT lpStat  // communications status
);
//COMSTAT结构如下
typedef struct _COMSTAT { 
  DWORD fCtsHold : 1; 
  DWORD fDsrHold : 1; 
  DWORD fRlsdHold : 1; 
  DWORD fXoffHold : 1; 
  DWORD fXoffSent : 1; 
  DWORD fEof : 1; 
  DWORD fTxim : 1; 
  DWORD fReserved : 25; 
  DWORD cbInQue; // 接收队列内数据量
  DWORD cbOutQue; // 发送队列内数据量
} COMSTAT, *LPCOMSTAT; 

//从串口内读取数据
{
	BOOL bReadStatus;
	DWORD dwBytesRead, dwErrorFlags;
	COMSTAT ComStat;

	ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );
	if( !ComStat.cbInQue ) return( 0 );//检查当前是否有数据在接收队列内

	dwBytesRead = (DWORD) ComStat.cbInQue;
	if( limit < (int) dwBytesRead ) dwBytesRead = (DWORD) limit; //确定当前可能读入的最大数量

	bReadStatus = ReadFile( m_hIDComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead );
	if( !bReadStatus )
	{
		if( GetLastError() == ERROR_IO_PENDING )
		{
			WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );//等待读操作完成
			return( (int) dwBytesRead );
		}
		return( 0 );
	}
}
</pre>
<p>在本节提供一个经过封装的类CSerial来完成串口的操作,这份代码来自于网上,我写了一个简单的DEMO用于向MODEM发送AT命令并读回数据。相关代码如下:
<pre>
	CSerial ser;//假设COM1端口上是一个MODEM,通过发送AT命令来和MODEM进行通信
	//关于AT命令请查询其他资料
	if(ser.Open(1,9600))
	{

		char szCmd[100],szRet[100];
		
		strcpy(szCmd,"ATI0\r\n");//返回调制解调器默认的速率
		int iSend = ser.SendData(szCmd,strlen(szCmd));
		while(ser.ReadDataWaiting() == 0)
		{//等待数据
			Sleep(100);
		}
		int iRead =ser.ReadData(szRet,99);
		if(iRead != 0)
		{
			szRet[iRead]='\0';
			printf("send %s read %s\n",szCmd,szRet);
		}
	}
	else
	{
		printf("error open COM port\n");
	}
</pre>
<p><a href=sam_sp_55.zip>下载本节示范代码</a>

                  <p align=center><a href=index.htm#charpter5>返回</a></p>
<p align=center><small>版权所有 闻怡洋 <a href=http://www.vchelp.net/><font class=engul>http://www.vchelp.net/<font></font></font></a></small></p>
</small>
	</td></tr><!-- article content end-->
	</table>
</td>
</tr><!-- article title end-->
</table>

</td></tr></table><!--整体框架 END-->



<!-- LANGUAGE='JavaScript'>write_tail();<-->


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -