敬业的IT人 >> 考试认证 >> 微软认证 >> 深入浅出VC++串口编程之第三方类

深入浅出VC++串口编程之第三方类

敬业的IT人 互联网 佚名 2008-1-8 17:46:24

串口类

  从本系列文章连载三、四可以看出,与通过WIN32 API进行串口访问相比,通过MScomm这个Activex控件进行串口访问要来的方便许多,它基本上可以向用户屏蔽多线程的细节,以事件(发出OnComm消息)方式实现串口的异步访问。

  尽管如此,MScomm控件的使用仍有诸多不便,譬如其发送和接收数据都要进行VARIANT类型对象与字符串的转化等。因此,国内外许多优秀的程序员自己编写了一些串口类,使用这些类,我们将可以更方便的操作串口。在笔者的《深入浅出Win32多线程程序设计之综合实例》(网址:http://dev.yesky.com)一文中,曾向读者展示了由Remon Spekreijse编写的CSerialPort串口类,而本文将向您展示由程序员llbird编写的cnComm(中国串口?)串口类。

  llbird是一位优秀的程序员,他的代码风格简洁而紧凑,类的声明和实现都被定义在一个头文件中,使用这个类的朋友只需要在工程中包含这一头文件即可:

/*
Comm Base Library(WIN98/NT/2000) ver 1.1
Compile by: BC++ 5; C++ BUILDER 4, 5, 6, X; VC++ 5, 6; VC.NET; GCC;
copyright(c) 2004.5 - 2005.8 llbird wushaojian@21cn.com
*/
#ifndef _CN_COMM_H_
#define _CN_COMM_H_

#pragma warning(disable: 4530)
#pragma warning(disable: 4786)
#pragma warning(disable: 4800)

#include <assert.h>
#include <stdio.h>
#include <windows.h>

//送到窗口的消息 WPARAM 端口号
#define target=_blank>基于WIN32 API的串口编程》和《基于控件的串口编程》相同,不同的只是本节的串口通信要以llbird定义的cnComm类来实现。


  我们需要为串口的接收事件定义一个用户消息ON_COM_RECEIVE,因此对话框的消息映射为:

BEGIN_MESSAGE_MAP(CSerialPortClassDlg, CDialog)
//{{AFX_MSG_MAP(CSerialPortClassDlg)
 ON_WM_SYSCOMMAND()
 ON_WM_PAINT()
 ON_WM_QUERYDRAGICON()
 ON_BN_CLICKED(IDC_CLEAR_BUTTON, OnClearButton)
 ON_BN_CLICKED(IDC_SEND_BUTTON, OnSendButton)
 ON_MESSAGE(ON_COM_RECEIVE,OnCommRecv)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
  同时,我们需要在对话框类的头文件中定义cnComm类的成员变量com和接收数据消息处理函数OnCommRecv:

cnComm com;
afx_msg void OnCommRecv(WPARAM wParam, LPARAM lParam);
  在对话框初始化时调用打开串口:

BOOL CSerialPortClassDlg::OnInitDialog()
{
 CDialog::OnInitDialog();

 // Add "About..." menu item to system menu.

 // IDM_ABOUTBOX must be in the system command range.
 ASSERT((IDM_ABOUTBOX &0xFFF0) == IDM_ABOUTBOX);
 ASSERT(IDM_ABOUTBOX < 0xF000);

 CMenu *pSysMenu = GetSystemMenu(FALSE);
 if (pSysMenu != NULL)
 {
  CString strAboutMenu;
  strAboutMenu.LoadString(IDS_ABOUTBOX);
  if (!strAboutMenu.IsEmpty())
  {
   pSysMenu->AppendMenu(MF_SEPARATOR);
   pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  }
 }

 // Set the icon for this dialog. The framework does this automatically
 // when the application's main window is not a dialog
 SetIcon(m_hIcon, TRUE); // Set big icon
 SetIcon(m_hIcon, FALSE); // Set small icon

 // TODO: Add extra initialization here

 com.Open(1); //打开串口1并使用默认设置
 com.SetWnd(AfxGetMainWnd()->m_hWnd); //设置消息处理窗口

 return TRUE; // return TRUE unless you set the focus to a control
}
  发送字符串的过程很简单,只需要调用cnComm类的Write函数:

//"发送"按钮函数(完成数据的发送功能)
void CSerialPortClassDlg::OnSendButton()
{
 // TODO: Add your control notification handler code here
 UpdateData(true);

 com.Write(m_send); //发送字符串
}
  接收字符串的过程也很简单,只需要调用cnComm类的ReadString函数:

void CSerialPortClassDlg::OnCommRecv(WPARAM wParam, LPARAM lParam)
{
 UpdateData(true);

 //读取串口上的字符
 char str[100];
 com.ReadString(str, 100);
 m_recv += str;

 UpdateData(false);
}
  读者朋友们这时一定会发出感慨:使用cnComm类后,进行串口数据收发的程序是多么简单啊!的确,串口的初始化、读写几乎都是用1~2条语句搞定的!

  这就是我们要特别用一次连载来讲述使用第三方类来进行串口通信的原因。实际上,笔者在进行网络通信程序编程时,也不认为MS提供的CSocket类是最方便的选择,照样习惯使用第三方的网络通信类。它们的确有非常简洁明快的接口,这一点也是值得MS哥哥们学习的。

粤ICP备06119539号
Copyright CiscoSky.Org,Some Rights Reserved.
Email:me1228#tom.com