使用VS2013
需要注册MSCOMM插件
1、添加串口变量
对话框上右键 插入Active X控件,选择 Micsrosft Commuunication Control,version 6.0 ,之后界面上有一个类似于电话的控件图标,把ID号改为 IDC_MSCOMM,右键这个控件 添加变量,命名为m_mscomm,(此时会新建mscomm的头文件和源文件),把DoDataExchange中的DDX_Control(pDX, IDC_MSCOMM, m_mscomm)这行删除掉。
2、初始化串口
//创建模块串口
if (!m_mscomm.Create(nullptr, WS_VISIBLE | WS_CHILD, CRect(0, 0, 0, 0), this, IDC_MSCOMM))
{
MessageBox(_T("创建mscomm串口失败"));
}
3、打开串口
if (m_mscomm.get_PortOpen())//如果是打开的,则关闭
{
m_mscomm.put_PortOpen(FALSE);
GetDlgItem(IDC_Btn_OpenComm)->SetWindowText(g_CommState[g_eCSI::CSOFF]);
return;
}
m_mscomm.put__CommPort(m_ci.comm);//选择串口
m_mscomm.put_InBufferSize(1024);//接收缓冲区
m_mscomm.put_OutBufferSize(1024);//发送缓冲区
m_mscomm.put_InputLen(0);//设置当前接受去数据长度为0,表示全部读取
m_mscomm.put_InputMode(1);//以二进制方式读写数据
m_mscomm.put_RThreshold(1);//接收缓冲区有1个及以上字符时,将响应接收数据事件
CString setting;
setting.Format(_T("%s,%c,%s,%s"),
m_ci.baudrate, m_ci.parity[0], m_ci.data, m_ci.stop);
m_mscomm.put_Settings(setting);//波特率、校验位、数据位、停止位
try
{
m_mscomm.put_PortOpen(TRUE);
GetDlgItem(IDC_Btn_OpenComm)->SetWindowText(g_CommState[g_eCSI::CSON]);
}
catch (CException*)
{
m_mscomm.put_OutBufferCount(0);
CString errmsg;
errmsg.Format(_T("打开串口失败[串口信息:串口号%d,波特率%s,校验位%s,数据位%s,停止位%s]"),
m_ci.comm, m_ci.baudrate, m_ci.parity, m_ci.data, m_ci.stop);
//AddShowInfo(errmsg);
}
4、发送数据
//CByteArray m_senddata;//发送的数据
//发送数据
m_mscomm.put_Output(COleVariant(m_senddata));
5、接收数据
头文件:
DECLARE_EVENTSINK_MAP()
void OnCommMscomm();//串口接收处理
源文件消息映射
BEGIN_EVENTSINK_MAP(CKELONCommDlg, CDialogEx)
ON_EVENT(CKELONCommDlg, IDC_MSCOMM, 1, CKELONCommDlg::OnCommMscomm, VTS_NONE)
END_EVENTSINK_MAP()
OnCommMscomm里面的处理
if (m_mscomm.get_CommEvent() != 2)
{
return;
}
//读缓冲区信息
unsigned char rcvdata[1024] = { 0 };//接收的数据
COleSafeArray safearray_inp = m_mscomm.get_Input();//读缓冲区消息
DWORD len = safearray_inp.GetOneDimSize();//获取有效数据长度
for (long j = 0; j < len; j++)//转化为unsigned char数组
{
safearray_inp.GetElement(&j, rcvdata + j);
}
6、完整程序
(不含组帧和解析帧)
头文件:
#ifndef KELONCommDlg_h__
#define KELONCommDlg_h__
// KELONCommDlg.h : 头文件
//
#include "mscomm.h"
#include "DLGCommConfig.h"
#include "FrameHandle.h"
#include "GridCtrl\GridCtrl.h"
// CKELONCommDlg 对话框
class CKELONCommDlg : public CDialogEx
{
// 构造
public:
CKELONCommDlg(CWnd* pParent = NULL); // 标准构造函数
~CKELONCommDlg();
// 对话框数据
enum { IDD = IDD_KELONCOMM_DIALOG };
using comminfo = CDLGCommConfig::comminfo;
struct ShowInfo//显示信息的格式
{
const CString &info;//显示的信息
CString state;//显示状态,三种状态:发送、接收、无,有显示状态时一定会显示时间,一定要换行
bool breturnline;//是否换行
ShowInfo(const CString &info)
:info(info)
{
breturnline = false;
}
};
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
HICON m_hIcon;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
private:
CMscomm m_mscomm;//串口控件
comminfo m_ci;//串口信息
FrameHandle m_rcvdata;//接收的数据
CByteArray m_senddata;//发送的数据
int m_sendtimes;//发送次数
UINT m_timesE, m_timesRetE;//多次发送事件句柄
CGridCtrl m_datagrid;//显示接收数据的表格
public:
DECLARE_EVENTSINK_MAP()
void OnCommMscomm();//串口接收处理
afx_msg void OnTimer(UINT_PTR nIDEvent);
void SendData();//发送数据
afx_msg void OnBnClickedBtnOpencomm();
void GetConfigInfo(const CString &ifile);//读配置信息
void SetConfigInfo(const CString &ifile);//写配置信息
afx_msg void OnBnClickedBtnSenddata();
afx_msg void OnBnClickedBtnSetcomm();
void OnInitUI();//初始化界面
UIDataInfo GetUIDataInfo();//获取界面信息
//检测消息,消息合法返回真,并组织成unsigned char数组,消息不合法,存储错误消息
bool JudgeMsg(CString imsg,std::vector &omsg,CString &errmsg);
afx_msg void OnBnClickedOk();
void AddShowInfo(const ShowInfo &si);//添加显示信息
afx_msg void OnBnClickedBtnClearshowinfo();
afx_msg void OnBnClickedBtnAbout();
void AddGridData(const std::vector &uidi);//添加接收数据到表格上
CString parseMsg(const UIDataInfo & uidi);//解析消息内容
unsigned long BCDToDec(const unsigned char *bcd, int length);//BCD码
void copy_V2A(std::vector::const_iterator begin, unsigned char *arr, int length);//拷贝:vector -> 数组
afx_msg void OnBnClickedBtnCleargrid();
};
#endif // KELONCommDlg_h__
源文件:
// KELONCommDlg.cpp : 实现文件
//
#include "stdafx.h"
#include "KELONComm.h"
#include "KELONCommDlg.h"
#include "afxdialogex.h"
#include
配置文件:
//串口配置信息
//串口comm
//波特率baudrate
//校验位parity
//数据位data
//停止位stop
[comminfo]
comm=4
baudrate=9600
parity=even
data=8
stop=1
//时间信息
//timespan ms 重发数据
// 重复发送sendtimes次
[timeinfo]
timespan=500
sendtimes=1
//消息头配置
//每一个消息头有:命令类型、命令子类型、操作结果、描述信息
[msghead]
msgcount=18
[msg0]
cmdtype=7
cmdsubtype=1
result=0
description=查询设备版本号
//。。。。。。
[msg17]
cmdtype=103
cmdsubtype=1
result=0
description=读电量模块型号和厂家信息