一 MSComm
MSComm 控件通过串行端口传输和接收数据,为应用程序提供串行通讯功能。MSComm控件在串口编程时非常方便,程序员不必去花时间去了解较为复杂的API函数,而且在VC、VB、Delphi等语言中均可使用。 Microsoft Communications Control(以下简称MSComm)是Microsoft公司提供的简化Windows下串行通信编程的ActiveX控件,它为应用程序提供了通过串行接口收发数据的简便方法。MSComm的API介绍请参考
二 使用实例
1 新建一个基于对话框的MFC应用程序工程。
2 添加ActiveX控件。在对话框的空白处点击右键,在弹出的菜单中选择“Insert ActiveX Control”,这时弹出一个对话框,列出了本机已注册的所有控件,选择“Microsoft Communications Control, version 6.0”,点击“ok”。如果在插入控件的过程中出错,请参照http://www.cnblogs.com/edward259/archive/2009/08/21/1551463.html注册MSComm。
3 添加类和关联变量。右击对话框中新加的串口控件(电话图标),选择“Add-->Add Variable”,为该控件关系一个成员变量。
4 添加串口事件消息处理函数。右击对话框中的串口控件图标,在弹出的菜单中选择“Add Event Handler”,保持默认的函数处理程序名称,点击“Add and Edit”,即可完成串口事件消息处理函数的添加。这个函数是用来处理串口消息事件的,例如,每当串口接收到数据,就会产生一个串口接收数据缓冲中有字符的消息事件,这个函数就会执行。
5 初始化串口。假设串口控件的关联变量名为m_sComm,可通过以下代码进行初始化
BOOL CdipdetectionDlg::OnInitDialog() { CDialog::OnInitDialog(); // 将“关于...”菜单项添加到系统菜单中。 // IDM_ABOUTBOX 必须在系统命令范围内。 ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { BOOL bNameValid; CString strAboutMenu; bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX); ASSERT(bNameValid); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动 // 执行此操作 SetIcon(m_hIcon, TRUE); // 设置大图标 SetIcon(m_hIcon, FALSE); // 设置小图标 // TODO: 在此添加额外的初始化代码 if (m_MSComm.get_PortOpen()) { m_MSComm.put_PortOpen(FALSE); } m_MSComm.put_CommPort(6);//注意串口号设置为设备管理器中显示的串口号,不同的机器显示的串口号可能不同 m_MSComm.put_InBufferSize(1024); m_MSComm.put_OutBufferSize(1024); m_MSComm.put_InputMode(1);//二进制模式 m_MSComm.put_Settings(_T("9600, n, 8, 1")); m_MSComm.put_RThreshold(1);//这行code很关键,如果不设置,则在响应函数中接收不到数据(悲剧,当时没注意卡在这好久) m_MSComm.put_InputLen(0);//一次读取全部数据 if (!m_MSComm.get_PortOpen()) { m_MSComm.put_PortOpen(TRUE); } else { MessageBox(_T("Comm6 can not be opened!")); } return TRUE; // 除非将焦点设置到控件,否则返回 TRUE }
6 发送与接收数据
BEGIN_EVENTSINK_MAP(CdipdetectionDlg, CDialog) ON_EVENT(CdipdetectionDlg, IDC_MSCOMM, 1, CdipdetectionDlg::OnCommMscomm, VTS_NONE) END_EVENTSINK_MAP() void CdipdetectionDlg::OnCommMscomm() { // TODO: 在此处添加消息处理程序代码 VARIANT variant_inp; COleSafeArray safearray_inp; LONG len, k; char rxdata[15];//数据长度根据自己的实际要求设置 switch (m_MSComm.get_CommEvent()) { case 1: //发送数据 break; case 2: //接收数据 variant_inp = m_MSComm.get_Input(); //read data safearray_inp = variant_inp; len = safearray_inp.GetOneDimSize();//得到有效数据长度 for (k = 0; k < len; k++) { safearray_inp.GetElement(&k, rxdata+k); } //接收数据后,根据实际解析rxdata break; } }