注册MSComm32.ocx控件
首先在我使用的是VS2010旗舰版,里面默认是没有该控件的,因此首先要进行注册。
在网上下载了一个MSComm32.ocx控件,放在C:\Windows\SysWOW64目录下(因为我的是64位的,如果是32位的话就放在C:\Windows\System32下面),然后用管理员身份打开控制台程序cmd.exe(一定要是管理员身份,为此我折腾了好久),然后输入:regsvr32 C:\Windows\SysWOW64\mscomm32.ocx就完成了注册;
添加mscomm类并使能MSComm32.ocx控件
右击项目名称:添加->类,选择ActiveX控件中的MFC类;
在可用控件中选择MSComm32.ocx控件,下方生成类。如下图所示:

此时想添加该控件还是不行,因为工具箱里面找不到,所以点击:工具->选择工具箱,将COM组件勾上就可以了如下图所示:

之后工具箱中便出现了该控件,是一个电话的形状。当然,我后来发现,直接在窗体上右击添加ActiveX控件就可以了。。。这个也是小弯路吧。。。。
设计程序窗体
框体的设计这一点应该是比较简单的,如下图所示,在这里我也只是用了一些简单的控件:

定义每一个控件的ID、属性等等:

这里面我只用了发送和退出两个按钮。
定义各个成员变量,但是串口的变量不能再类向导中直接添加,因为你会发现在成员变量的ID号中根本找不到串口,所以我就是通过右击这个串口控件,选择添加变量来实现的,当然这两种效果是一个样子的~

接下来就是为各个控件添加响应了,一般的控件比如按钮,直接双击就可以了,但是这里的串口又特殊了,双击没有用,必须的还是右击选择添加响应。
就这样整个框体就设计好了~~~
编辑程序代码
代码比较简单,这里直接贴出来就行啦,
void CSerialDlg::OnCommMscomm()
{
// TODO: 在此处添加消息处理程序代码
VARIANT variant_inp;
COleSafeArray safearray_inp;
LONG len,k;
BYTE rxdata[2048];//设置byte数组
CString strtemp;
if(m_ctrlComm.get_CommEvent()==2)//事件2表示接受缓冲区有字符
{
variant_inp=m_ctrlComm.get_Input();//读缓冲区
safearray_inp=variant_inp;//variant数据转换成colesafearray型变量
len=safearray_inp.GetOneDimSize();//得到有效数据长度
for(k=0;k<len;k++)
safearray_inp.GetElement(&k,rxdata+k);//转换为byte型数组
for(k=0;k<len;k++)//将数组转换成CString型变量
{
BYTE bt=*(char *)(rxdata+k);//字符型
m_strReceive+=(char) bt;//加入接收编辑框相应字符串
}
}
UpdateData(0);//更新编辑框内容
}
void CSerialDlg::OnBnClickedCancel()
{
// TODO: 在此添加控件通知处理程序代码
m_ctrlComm.put_PortOpen(0);//关闭串口
CDialogEx::OnCancel();
}
void CSerialDlg::OnBnClickedOk()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(1);//读取编辑框内容
m_ctrlComm.put_Output(COleVariant(m_strSend));//发送数据
}
BOOL CSerialDlg::OnInitDialog()
{
CDialogEx::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: 在此添加额外的初始化代码
m_ctrlComm.put_CommPort(2);//选择com2口
m_ctrlComm.put_InputMode(1);//输入方式为二进制方式
m_ctrlComm.put_InBufferSize(1024);//输入缓冲区大小为1024byte
m_ctrlComm.put_OutBufferSize(512);//输出缓冲区大小为512byte
m_ctrlComm.put_Settings(_T("9600,n,8,1"));//设置串口参数:9600波特率,无奇偶校验,8个数据位,1个停止位
if(!m_ctrlComm.get_PortOpen())
m_ctrlComm.put_PortOpen(1);//打开串口
m_ctrlComm.put_RThreshold(1);//每当串口接收缓冲区有多余或等于1个字符时将引发一个接收数据的oncomm事件
m_ctrlComm.put_InputLen(0);//设置当前接收区数据长度为0
m_ctrlComm.get_Input();//预读缓冲区以清空残留数据
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
就这样整个程序就实现了基本的串口通信的功能了~~~
总结:其实写的东西比较少,但是实际过程中遇到的问题十分的多:
第一个就是找不到串口的控件,上了网才知道需要单独的添加(上面提到的);
第二个是第一遍无法执行的问题,我也没有找到问题的解决办法,但是当我把整个项目都删掉重来的时候,发现刚才的问题已经没有了,这个我也不知道怎么办了。。。。。。
第三个是字符串合并的问题,将接收到的ASCII字符转换成CString并拼接起来,我采用的是这样的办法:
for(k=0;k<len;k++)//将数组转换成CString型变量
{
BYTE bt=*(char *)(rxdata+k);//字符型
m_strReceive+=(char) bt;//加入接收编辑框相应字符串
}
但是我在网上找到的一份是这样的:
for(k=0;k<len;k++)
{
BYTE bt=*(char *)(rxdata+k);//字符型
strtemp.Format((char) bt);//将字符送入临时变量strtemp存放
m_strreceive+=strtemp;//加入接收编辑框相应字符串
}
本来我是找不出什么区别的,但是一运行就出现了问题,我单步调试就是发生在字符格式化的时候,这一点我又搞不懂了,只能暂时放在这里了,希望哪位看到能给我一个解释,我自己也会再找找原因的。
这篇博客介绍了在VS2010中如何使用MSComm32.ocx控件进行串口通信。首先,需要在C:\Windows\SysWOW64目录下注册控件,然后在项目中添加MFC类,选择MSComm32.ocx。接着,通过工具箱设置控件,并为按钮和串口添加响应。在设计中遇到了找不到控件、无法执行和字符串转换的问题,但最终实现了基本的串口通信功能。
1118

被折叠的 条评论
为什么被折叠?



