深入浅出VC++串口编程之基于控件Word格式.docx
- 文档编号:21523978
- 上传时间:2023-01-31
- 格式:DOCX
- 页数:12
- 大小:187.27KB
深入浅出VC++串口编程之基于控件Word格式.docx
《深入浅出VC++串口编程之基于控件Word格式.docx》由会员分享,可在线阅读,更多相关《深入浅出VC++串口编程之基于控件Word格式.docx(12页珍藏版)》请在冰豆网上搜索。
protected:
DECLARE_DYNCREATE(CMSComm)
public:
CLSIDconst&
GetClsid()
{
staticCLSIDconstclsid={0x648a5600,0x2c6e,0x101b,{0x82,0xb6,0x0,0x0,0x0,0x0,0x0,0x14}};
returnclsid;
}
virtualBOOLCreate(LPCTSTRlpszClassName,
LPCTSTRlpszWindowName,DWORDdwStyle,
constRECT&
rect,
CWnd*pParentWnd,UINTnID,
CCreateContext*pContext=NULL)
{returnCreateControl(GetClsid(),lpszWindowName,dwStyle,rect,pParentWnd,nID);
}
BOOLCreate(LPCTSTRlpszWindowName,DWORDdwStyle,
rect,CWnd*pParentWnd,UINTnID,
CFile*pPersist=NULL,BOOLbStorage=FALSE,
BSTRbstrLicKey=NULL)
{returnCreateControl(GetClsid(),lpszWindowName,dwStyle,rect,pParentWnd,nID,
pPersist,bStorage,bstrLicKey);
//Attributes
public:
//Operations
voidSetCDHolding(BOOLbNewValue);
BOOLGetCDHolding();
voidSetCommID(longnNewValue);
longGetCommID();
voidSetCommPort(shortnNewValue);
//设置端口号,如nNewValue=1表示COM1
shortGetCommPort();
voidSetCTSHolding(BOOLbNewValue);
BOOLGetCTSHolding();
voidSetDSRHolding(BOOLbNewValue);
BOOLGetDSRHolding();
voidSetDTREnable(BOOLbNewValue);
BOOLGetDTREnable();
voidSetHandshaking(longnNewValue);
longGetHandshaking();
voidSetInBufferSize(shortnNewValue);
shortGetInBufferSize();
voidSetInBufferCount(shortnNewValue);
shortGetInBufferCount();
voidSetBreak(BOOLbNewValue);
BOOLGetBreak();
voidSetInputLen(shortnNewValue);
shortGetInputLen();
voidSetNullDiscard(BOOLbNewValue);
BOOLGetNullDiscard();
voidSetOutBufferSize(shortnNewValue);
shortGetOutBufferSize();
voidSetOutBufferCount(shortnNewValue);
shortGetOutBufferCount();
voidSetParityReplace(LPCTSTRlpszNewValue);
CStringGetParityReplace();
voidSetPortOpen(BOOLbNewValue);
//打开或关闭串口,TRUE:
打开,FALSE:
关闭
BOOLGetPortOpen();
//串口是否已打开,TRUE:
voidSetRThreshold(shortnNewValue);
//如果设置为1,表示一接收到字符就发送2号事件
shortGetRThreshold();
voidSetRTSEnable(BOOLbNewValue);
//硬件握手使能?
BOOLGetRTSEnable();
voidSetSettings(LPCTSTRlpszNewValue);
//Settings由4部分组成,其格式为:
"
BBBB,P,D,S"
,即"
波特率,是否奇偶校验,数据位//个数,停止位"
,如设置为:
9600,n,8,1"
CStringGetSettings();
voidSetSThreshold(shortnNewValue);
//如果保持缺省值0不变,则表示发送数据的过程中串口上不发生事件
shortGetSThreshold();
voidSetOutput(constVARIANT&
newValue);
//一个非常重要的函数,用于写串口,注意其接收的输入参数为VARIANT类型对象,
//我们需要将字符串转化为VARIANT类型对象
VARIANTGetOutput();
voidSetInput(constVARIANT&
VARIANTGetInput();
//一个非常重要的函数,用于读串口,注意其返回的是VARIANT类型对象,我们需要
//将其转化为字符串
voidSetCommEvent(shortnNewValue);
shortGetCommEvent();
//一个非常重要的函数,获得串口上刚发生的事件("
事件"
可以理解为软件意义上的
//"
消息"
或硬件意义上的"
中断"
),事件的发送会导致OnComm消息的诞生!
voidSetEOFEnable(BOOLbNewValue);
BOOLGetEOFEnable();
voidSetInputMode(longnNewValue);
longGetInputMode();
};
//{{AFX_INSERT_LOCATION}}
//MicrosoftVisualC++willinsertadditionaldeclarationsimmediatelybeforethepreviousline.
#endif
分析上述源代码可知,基本上,MSComm的诸多接口可以分为如下几类:
(1)打开与设置串口接口函数;
(2)获得串口设置和串口状态接口函数;
(3)设置串口发送数据方式、缓冲区接口及发送数据接口函数;
(4)设置串口接收数据方式、缓冲区接口及接收数据接口函数;
(5)设置与获取串口上发生的事件接口函数。
2.例程
程序的功能和界面(如下图)都与本文连载三中《基于WIN32API的串口编程》相同,不同的只是连载三的串口通信以API实现,而本节的串口通信则以MSComm控件实现。
使用第1节的方法将控件添加入工程并添加mscomm.h和mscomm.cpp文件后,为了使用控件,我们将控件拖入对话框内任意一个位置(运行时"
电话"
图标会隐藏),其操作如下图:
有趣而极富人性化的是我们可以直接右键单击这个"
,来设置串口的属性,如下图:
接着,我们需要为控件添加一个对应的成员变量m_mscom,其对应的变量类型为CMSComm,如下图:
这样就建立了m_mscom和IDC_MSCOMM1控件的相互映射:
voidCSerialPortActivexDlg:
:
DoDataExchange(CDataExchange*pDX)
CDialog:
DoDataExchange(pDX);
//{{AFX_DATA_MAP(CSerialPortActivexDlg)
DDX_Text(pDX,IDC_RECV_EDIT,m_recv);
DDX_Text(pDX,IDC_SEND_EDIT,m_send);
DDX_Control(pDX,IDC_MSCOMM1,m_mscom);
//}}AFX_DATA_MAP
}
同时,在对话框的头文件也会由"
MFC类向导"
自动定义CSerialPortActivexDlg类的CMSComm型成员变量m_mscom:
CMSCommm_mscom;
在对话框初始化时(即在CSerialPortActivexDlg:
OnInitDialog函数中)打开串口1:
BOOLCSerialPortActivexDlg:
OnInitDialog()
OnInitDialog();
//Add"
About..."
menuitemtosystemmenu.
//IDM_ABOUTBOXmustbeinthesystemcommandrange.
ASSERT((IDM_ABOUTBOX&
0xFFF0)==IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX<
0xF000);
CMenu*pSysMenu=GetSystemMenu(FALSE);
if(pSysMenu!
=NULL)
CStringstrAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if(!
strAboutMenu.IsEmpty())
{
pSysMenu->
AppendMenu(MF_SEPARATOR);
AppendMenu(MF_STRING,IDM_ABOUTBOX,
strAboutMenu);
}
//Settheiconforthisdialog.Theframeworkdoesthisautomatically
//whentheapplication'
smainwindowisnotadialog
SetIcon(m_hIcon,TRUE);
//Setbigicon
SetIcon(m_hIcon,FALSE);
//Setsmallicon
//TODO:
Addextrainitializationhere
m_mscom.SetCommPort
(1);
//串口1
m_mscom.SetInBufferSize(1024);
//设置输入缓冲区的大小,Bytes
m_mscom.SetOutBufferSize(512);
if(!
m_mscom.GetPortOpen())//打开串口
m_mscom.SetPortOpen(true);
m_mscom.SetInputMode
(1);
//设置输入方式为二进制方式
m_mscom.SetSettings("
);
//设置波特率等参数
m_mscom.SetRThreshold
(1);
//为1表示有一个字符即引发事件
m_mscom.SetInputLen(0);
returnTRUE;
//returnTRUEunlessyousetthefocustoacontrol
最核心的发送串口数据函数("
发送"
按钮单击事件)如下:
OnSendButton()
Addyourcontrolnotificationhandlercodehere
UpdateData(true);
CByteArraysendArr;
WORDwLength;
wLength=m_send.GetLength();
sendArr.SetSize(wLength);
for(inti=0;
i<
wLength;
i++)
sendArr.SetAt(i,m_send.GetAt(i));
m_mscom.SetOutput(COleVariant(sendArr));
为了处理接收事件,我们需要为MScomm控件添加对应的消息处理函数。
如下图,我们通过"
添加了CSerialPortActivexDlg类的成员函数OnCommMscomm1():
这样,在对话框的头文件中就会自动增加下面两句:
afx_msgvoidOnCommMscomm1();
//函数声明
DECLARE_EVENTSINK_MAP()
来自AFX_MSG部分:
//Generatedmessagemapfunctions
//{{AFX_MSG(CSerialPortActivexDlg)
virtualBOOLOnInitDialog();
afx_msgvoidOnSysCommand(UINTnID,LPARAMlParam);
afx_msgvoidOnPaint();
afx_msgHCURSOROnQueryDragIcon();
afx_msgvoidOnClearButton();
afx_msgvoidOnSendButton();
afx_msgvoidOnCommMscomm1();
DECLARE_EVENTSINK_MAP()
//}}AFX_MSG
同时在对话框的.cpp文件中会增加下列代码实现串口消息映射:
BEGIN_EVENTSINK_MAP(CSerialPortActivexDlg,CDialog)
//{{AFX_EVENTSINK_MAP(CSerialPortActivexDlg)
ON_EVENT(CSerialPortActivexDlg,IDC_MSCOMM1,1/*OnComm*/,
OnCommMscomm1,VTS_NONE)
//}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()
我们定义CSerialPortActivexDlg:
OnCommMscomm1()函数主要处理数据的接收,其源代码为:
OnCommMscomm1()
VARIANTvariant_inp;
COleSafeArraysafearray_inp;
longi=0;
intlen;
charrxdata[1000];
CStringtmp;
switch(m_mscom.GetCommEvent())
case2:
//表示接收缓冲区内有字符
variant_inp=m_mscom.GetInput();
safearray_inp=variant_inp;
len=safearray_inp.GetOneDimSize();
for(i=0;
i<
len;
{
safearray_inp.GetElement(&
i,&
rxdata[i]);
}
rxdata[i]='
\0'
;
m_recv+=rxdata;
UpdateData(false);
break;
default:
break;
最后,与连载三类似,再次借助"
串口调试助手"
以实例验证了本程序的正确性,如下图:
最后,需要特别提示的是:
如果要在基于"
文档/视图"
的框架结构程序而非对话框程序中使用串口控件,我们不能轻松地使用"
,这时候必须手动地添加相关代码。
在MainFrm.h头文件中加入:
afx_msgvoidOnCommMscomm();
DECLARE_EVENTSINK_MAP()
并定义CMSComm成员变量:
CMSCommm_ComPort;
在MainFrm.cpp文件中添加
BEGIN_EVENTSINK_MAP(CMainFrame,CFrameWnd)
ON_EVENT(CMainFrame,ID_COMMCTRL,1,OnCommMscomm,VTS_NONE)
//映射ACTIVEX控件的事件
在MainFrm.cpp文件的OnCreate(LPCREATESTRUCTlpCreateStruct)函数中添加:
ComPort.Create(NULL,WS_VISIBLE|WS_CHILD,CRect(0,0,0,0),this,ID_COMMCTRL);
以创建CMSComm控件。
此后,我们就可以在CMainFrame类的函数中使用串口控件对应的ComPort控件成员变量
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 深入浅出 VC 串口 编程 基于 控件