一:首先我用的是http://jingyan.baidu.com/article/09ea3ede3b2496c0afde3944.html百度经验里面给的VS2013,是有串口控件(Microsoft communication control)
二:参照这个百度经验http://jingyan.baidu.com/article/8ebacdf0c96b5549f65cd5fa.html新建一个MFC基于对话框的工程,取名为MFC_COMMN,然后主对话框右键,有个添加Active控件,
点中后往里面的列表找到Microsoft communication control这个控件,
添加到对话框中,控件的样子是一个电话,如果没有的话得去百度寻找答案了。。
三: http://wenku.baidu.com/link?url=7MyT1jpd6AUtAcQ6wPKZAlnDOyplxIv0lX2hGUOY_YZZWnzsCxY-e3RLeDo7EvsrHzpQTpiPfGrHrEm3NQrlDfsZ4lP7Gj8c52iqGku2qPe
我们用上面这篇文档来讲VC++6.0的代码移植到VS2013中,主要的改动为串口类的成员函数的名字与VC++6.0的有些不同,比如SetCommport变为了put_CommPort,之类的。。所以通过查看CMScomm1的类定义可以做相应的修改。。
四:切换工作窗口为解决方案资源管理器,打开MFC_COMMNDlg.h头文件
在CMFC_COMMNDlg类中添加代码:
<pre name="code" class="cpp">int gllen;//定义整型标量gllen,用于记录接收数据的个数 CString strRXDdata; //编辑框显示的文本,记录历次转换值
如图所示:
五:VC++6.0的代码到VS2013要解决编码问题,将独热码修改为多字节编码:菜单栏中的项目->MFC_COMMN属性->配置属性->常规->字符集->选择多字节字符集。
但是改完后编译会报错,因为我找了百度发现是因为:http://jingyan.baidu.com/article/6181c3e06ab30f152ff1534d.html
然后我们得去http://www.microsoft.com/zh-cn/download/details.aspx?id=40770下载这个插件安装,上面百度经验的解释为:最后啰嗦一句,出现这样的问题,微软的解释是:用于多字节字符编码 (MBCS) 的 MFC 库 (DLL) 不再包含于 Visual Studio 中,但是可用作插件,您可以在任何装有 Visual Studio Professional、Visual Studio Premium 或 Visual Studio Ultimate 的计算机上下载和安装。
六:切换到对话框,添加编辑框,ID为IDC_EDIT2 两个按钮,ID分别为IDOK和ID_serial_state_switch 然后往IDOK按钮的事件处理函数中添加代码
// TODO: 在此添加控件通知处理程序代码 CByteArray m_Array; //定义字节数组 m_Array.RemoveAll(); //字节数组清空 m_Array.SetSize(1); //设定维数为1 m_Array.SetAt(0,0x15); //给m_array[0]赋值发送的字节为0x15 m_comm1.put_Output(COleVariant(m_Array));//由于SetOutput函数的参数为VARIANT型,必须强制转换后才能发送如图所示
往另一个按钮中添加代码:
<pre name="code" class="cpp">void CMFC_COMMNDlg::OnBnClickedserialstateswitch() { // TODO: 在此添加控件通知处理程序代码 if (!m_comm1.get_PortOpen())//判断串口是否已经打开 { m_comm1.put_PortOpen(TRUE); //如果串口是关闭的,则打开串口 GetDlgItem(ID_serial_state_switch)->SetWindowText("关闭串口"); } else { m_comm1.put_PortOpen(FALSE); //如果已经打开串口,则关闭串口 GetDlgItem(ID_serial_state_switch)->SetWindowText("打开串口"); } }
下面是往OnInitDialog中添加代码。。。
//**************添加的串口代码 gllen = 0; //记录转换次数全局变量清零 if (!m_comm1.get_PortOpen())//判断串口是否已经打开 { m_comm1.put_CommPort(3); //选择串口号3 m_comm1.put_PortOpen(TRUE); //打开串口 m_comm1.put_RThreshold(2); //收到两个字节引发OnComm事件 m_comm1.put_InputMode(1);//输入模式选为二进制 m_comm1.put_Settings("9600,n,8,1"); //设置串口参数,波特率9600,无奇偶校验,1位停止位,8位数据位 MessageBox("串口初始化完毕", "提示"); //提示串口成功初始化 } else MessageBox("串口被占用", "提示"); //如果已经打开串口,消息框提醒 GetDlgItem(ID_serial_state_switch)->SetWindowText("关闭串口");//按钮显示状态改变 //*********************************添加的串口代码如图所示:
最后往串口响应函数OnCommMscomm1中添加代码
// TODO: 在此处添加消息处理程序代码 VARIANT variant1;//定义VARIANT型变量,用于存放接收到的数据 COleSafeArray safearray;//定义safearray型变量 long k;//定义长整型变量len,k long len; BYTE rxdata[2048];//定义BYTE型数组 CString stremp1, stremp2;//定义两个字符串 if (m_comm1.get_CommEvent() == 2) //判断引起OnComm时间的原因,接收事件 {//如果是接收到特定个字节数,则读取接收到的数据 variant1 = m_comm1.get_Input();//把接收到的数据存放到VARIANT型变量里 safearray = variant1;//VARIANT型变量转换为ColeSafeArray型变量 len = safearray.GetOneDimSize(); for (k = 0; k<len; k++) { safearray.GetElement(&k, rxdata + k); //得到接接收到的数据放到BYTE型数组rxdata里 } for (k = 0; k<len; k++) { BYTE bt = (*(unsigned char*)(rxdata + k)); //读取AD转换的高字节 if ((k % 2) == 0) if ((k + 1)<len) { gllen++;//全局的变量,对接收到的转换结果的个数进行计算 stremp2.Format("第%d次转换结果:", gllen);//显示第几次转换 int temp = bt * 16 + ((*(unsigned char *)(rxdata + k + 1)) ); //高低字节合并成实际的转换结果,注意转换结果是左对齐 //AllocConsole();//注意检查返回值 //_cprintf("rxdata0=%d\n rxdata1=%d\n temp=%d\n", rxdata[0], rxdata[1],temp); //_getch(); stremp1.Format("%2.2f", (2.56*temp / 1024));//计算成实际电压值 SetDlgItemText(IDC_STATIC, ("当前电压值为: " + stremp1 + " V")); //更新静态文本控件 strRXDdata += stremp2;//把新的数据放到全局的字符串里 strRXDdata += stremp1; strRXDdata += " V\r\n";//字符串加单位V后换行 } } } SetDlgItemText(IDC_EDIT2, strRXDdata);//更新文本控件的显示
七:单片机测试代码:
<pre name="code" class="cpp"><pre name="code" class="cpp">/********************************************************************************* * 【编写时间】: 2011.07.07 * 【作 者】: 雁翎电子 * 【版 本】: V1.0 * 【网 站】: http://ylelectronic.taobao.com/ * 【Q Q】: 348439350 * 【声 明】: 此程序仅用于学习与参考,引用请注明版权和作者信息! * 【函数功能】: 串口中断程序实验——通过单片机向电脑发送数据,同时电脑将收到的数据发出 **********************************************************************************/ /*预处理命令*/ #include <reg52.h> //包含单片机寄存器的头文件 #define uchar unsigned char #define uint unsigned int uchar num,a; /* ******************************************************************************** ** 函数名称 : main(void) ** 函数功能 : 主函数 ******************************************************************************** */ void main() { TMOD=0x20; //用定时器设置串口波特率 9600 TH1=0xfd; TL1=0xfd; TR1=1; REN=1; //串口初始化 SM0=0; SM1=1; EA=1; //开启总中断 ES=1; while(1) { if(num==1) //判断是否有串口数据的传送 { ES=0; num=0; SBUF=a; //发送数据a到SBUF,即将单片机的数据发送到计算机 while(!TI); TI=0; SBUF=0xff; //发送数据0xff到上位机 while(!TI); TI=0; ES=1; } } } void ser() interrupt 4 { RI=0; P2=SBUF; //接收数据SBUF,即将计算机的数据接收。 a=SBUF; num=1; }
八:安装好单片机的USB驱动,然后再设备管理器显示的是COM3,如果是其他的COM号码,那么你就修改
m_comm1.put_CommPort(3); //选择串口号3
里面的参数。
九:运行软件:
为什么是1.48呢,因为发送了0x15,然后 返回0x15和0xff 然后0x15=21 0xff=255 21乘以16加上255等于591,然后591*2.56/1024=1.4775
十:调试:声明#include <conio.h>
在定义temp的代码下面添加
AllocConsole();//注意检查返回值 _cprintf("rxdata0=%d\n rxdata1=%d\n temp=%d\n", rxdata[0], rxdata[1],temp); _getch();就可以输出接收到的数据和temp的值了
如图
运行程序,点击开始转换,就可以有: