串口通信基础知识及VC++实现

最后更新于:2022-04-01 20:35:03

串口是计算机上一种非常通用设备通信的协议。大多数计算机包含两个基于RS232的串口。串口通信的概念非常简单,串口按位(bit)发送和接收字节。尽管比按字节(byte)的并行通信慢,但是由于串口通信是异步的,串口可以在使用一根线发送数据的同时用另一根线接收数据。它很简单并且能够实现远距离通信。串口通信最重要的参数是[波特](http://baike.baidu.com/view/543280.htm)率、数据位、停止位和奇偶校验。 而在VC++中实现串口通信也是一名VC程序员必须要掌握的技能。下面结合实例详细介绍在VC++中实现串口通信的过程(完整的实例可在我的CSDN资源中下载:[http://download.csdn.net/detail/margin1988/6408513](http://download.csdn.net/detail/margin1988/6408513))。 在这个实例中,实现了系统中可用串口的自动检测(通过注册表信息)、打开、发送、接收、关闭等基本的操作,若将串口线的TX(发送)和RX(接收)引脚连起来,便采用了“一根线发送数据的同时用另一根线接收数据”的方式测试了发送和接收功能的可用性和正确性。该实例对于初学者学习和掌握基于VC的串口通信将会有非常大的帮助。 (1)实例中所要用的主要控件及其属性、事件设置情况:

控件

ID

caption

绑定变量

绑定事件

组合框

IDC_COMBO1

CComboBox m_com;

按钮

IDC_BUTTON1

打开

CButton m_open;

OnBnClickedButton1()

按钮

IDC_BUTTON2

发送

CButton m_send;

OnBnClickedButton2()

按钮

IDC_BUTTON3

关闭

CButton m_close;

OnBnClickedButton3()

编辑框

IDC_EDIT1

发送输入

CString m_sendstr;

编辑框

IDC_EDIT2

接收显示

CString m_receivestr;

MSComm

IDC_MSCOMM1

CMSComm m_ctrlComm;

OnComm()

(2)需要的硬件条件及情况说明: 需要一根串口线,一端接在PC的某个串口上,另一端的TX引脚和RX引脚用铜线连接起来,这样便形成了一个回路,数据发送通过TX引脚出去后,又从RX引脚进来,程序中便可以得到接收到的数据了,接收到的数据应该和发送的数据一致,说明串口的发送、接收操作成功了。 (3)COM组件(MSComm控件)消息响应宏定义的**重要注意点**: ~~~ BEGIN_EVENTSINK_MAP (CPoint20Dlg, CDialog) ON_EVENT (CPoint20Dlg, IDC_MSCOMM1, 1, OnComm, VTS_NONE) END_EVENTSINK_MAP () ~~~ (4)从注册表中检测系统中可用串口并添加到界面组合框中: ~~~ HKEY hKey; int rtn; rtn = RegOpenKeyEx( HKEY_LOCAL_MACHINE, "Hardware\\DeviceMap\\SerialComm", NULL, KEY_READ, &hKey); if( rtn == ERROR_SUCCESS) // 打开串口注册表 { int i=0; char portName[256], commName[256]; DWORD dwLong,dwSize; while (1) { dwSize = sizeof(portName); dwLong = dwSize; rtn = RegEnumValue ( hKey, i, portName, &dwLong, NULL, NULL, (PUCHAR)commName, &dwSize ); // 枚举串口 if( rtn == ERROR_NO_MORE_ITEMS ) break; // commName就是串口名字 m_com.AddString(commName);// 将可用串口添加到界面组合框 i++; } RegCloseKey(hKey); } m_com.SetCurSel(0); ~~~ (5)打开并设置串口参数: ~~~ if (!m_ctrlComm.GetPortOpen()) { char commName[256];//串口名 m_com.GetWindowText (commName, 256); m_ctrlComm.SetCommPort(_ttoi(&commName[3]));//从串口名中得到串口号 m_ctrlComm.SetInputMode (1); m_ctrlComm.SetSettings ("9600, n, 8, 1"); m_ctrlComm.SetPortOpen (TRUE); m_ctrlComm.SetRThreshold (1); m_ctrlComm.SetInputLen (0); m_ctrlComm.GetInput (); MessageBox(" 串口已打开 "); } else MessageBox("没有发现此串口或被占用"); ~~~ (6)发送数据: ~~~ if (m_ctrlComm.GetPortOpen()) { UpdateData(); CByteArray sendArr;//欲发送的数据,需从CString转化为CByteArray型 WORD wLen; wLen=m_sendstr.GetLength(); sendArr.SetSize(wLen); for (int i=0;i ';