MFC上位机软件设计
周立功USBCAN-II上位机开发(MFC)

周⽴功USBCAN-II上位机开发(MFC)使⽤的USB转CAN的设备是周⽴功的USBCAN-II,在购买的时候,会有上位机⼆次开发的库⽂件、例程和API⽂档等材料,可以参考。
1、库函数的调⽤⾸先,把库函数⽂件都放在⼯作⽬录下。
库函数⽂件总共有三个⽂件:ControlCAN.h、ControlCAN.lib、ControlCAN.dll和⼀个⽂件夹kerneldlls。
VC调⽤动态库的⽅法(1) 在扩展名为.CPP的⽂件中包含ControlCAN.h头⽂件。
如:#include “ControlCAN.h”(2) 在⼯程的连接器设置中连接到ControlCAN.lib⽂件。
如:在VC7环境下,在项⽬属性页⾥的配置属性→连接器→输⼊→附加依赖项中添加ControlCAN.lib中间换了⼀台电脑,出现电脑丢失ControlCAN.dll的问题,将ControlCAN.dll拷到了可执⾏⽂件的⽂件夹中即可2、基本操作2.1 连接设备我这⾥每次连接都会重新开启接收数据的线程,创建⼀次接收数据的txt⽂档void CTest_OilDlg::OnBnClickedButtonConnect(){//⾸先判断CAN是否打开,,如果已经打开,则先复位及重启CAN--1.8//关闭程序前必须点击断开连接按钮,否则报错if(m_connect == 1){m_connect = 0;//isShow = 0;Sleep(500);GetDlgItem(IDC_BUTTON_CONNECT)->SetWindowTextW(_T("连接"));VCI_CloseDevice(m_deviceType,m_deviceIndex);showListInfo(_T("断开设备成功"));//结束⾃发⾃收测试的定时器KillTimer(0);//结束当前线程if(m_pThread != NULL){//::WaitForSingleObject(m_pThread->m_hThread,INFINITE);//该函数会造成死锁//https:///silvervi/article/details/5874212 将上⾯函数修改成如下,以避免上⾯函数阻塞对话框主线程的消息队列DWORD dwRet = 0;MSG msg;while(true){//等待处理数据线程结束,和等待消息队列中的任何消息dwRet = MsgWaitForMultipleObjects(1,&m_pThread->m_hThread,false,INFINITE,QS_ALLINPUT);//dwRet = WaitForSingleObject(m_pThread->m_hThread,50);switch (dwRet){case WAIT_OBJECT_0:break;case WAIT_OBJECT_0 + 1://get the message from Queue and dispatch it to specific windowPeekMessage(&msg,NULL,0,0,PM_REMOVE);DispatchMessage(&msg);continue;default:break;}break;}//CloseHandle(m_pThread->m_hThread);delete m_pThread;m_pThread = NULL;//不太懂}//关闭存储数据的⽂件for(int i = 0;i < 4;i++){//判断⽂件是否打开,若打开了关闭if(m_waveDataFile[i].m_hFile != CFile::hFileNull){m_waveDataFile[i].Close();}}GetDlgItem(IDC_BUTTON_START)->SetWindowTextW(_T("开始⼯作"));return;}//------------打开设置---------------------////设备类型m_deviceType = VCI_USBCAN2;//设备索引号,只有⼀个设备,索引号为0m_deviceIndex = 0;//第0路CAN--只有⼀路,⽤户选择CString canNum;m_selectCANNum.GetWindowTextW(canNum);m_canNumA = _ttoi(canNum);if(VCI_OpenDevice(m_deviceType,m_deviceIndex,0) != STATUS_OK)//m_deviceType:设备类型号;m_deviceIndex:设备索引号;最后⼀个是保留参数,⼀般为0 {MessageBox(_T("打开设备失败!",_T("警告"),MB_OK|MB_ICONQUESTION));showListInfo(_T("打开设备失败"));SetHScroll();return ;}else{showListInfo(_T("打开设备成功"));SetHScroll();}///-------------对CAN进⾏初始化------------------////对CAN进⾏初始化VCI_INIT_CONFIG init_config;init_config.AccCode = 0x00000000;init_config.AccMask = 0xffffffff;//表⽰全部接收,(全部接收,AccMask:0xffffffff;AccCode:0x00000000---这块可以通过测试软件中的滤波设置功能中计算)init_config.Mode = 0;//正常模式;1:表⽰只听模式(只接收,不影响总线)init_config.Timing0 = 0x00;init_config.Timing1 = 0x14;//相当于波特率1000kbpsif(VCI_InitCAN(m_deviceType,m_deviceIndex,m_canNumA,&init_config) != STATUS_OK){MessageBox(_T("初始化CAN失败!"),_T("警告"),MB_OK|MB_ICONQUESTION);VCI_CloseDevice(m_deviceType,m_deviceIndex);showListInfo(_T("初始化CAN失败"));SetHScroll();return ;}else{showListInfo(_T("初始化CAN成功"));SetHScroll();}m_connect = 1;GetDlgItem(IDC_BUTTON_CONNECT)->SetWindowTextW(_T("断开"));//创建存储数据的⽂件CTime time0 = CTime::GetCurrentTime();CString fileName = _T("WaveData");if(!PathIsDirectory(fileName)){::CreateDirectory(fileName,NULL);}fileName.Format(_T("WaveData/%d-%d %dh%dm%ds"),time0.GetMonth(),time0.GetDay(),time0.GetHour(),time0.GetMinute(),time0.GetSecond());if(!PathIsDirectory(fileName)){::CreateDirectory(fileName,NULL);}CString fileName0 = fileName;for(int i = 0;i < 4;i++){CString i0;i0.Format(_T("/%dth"),i+1);fileName = fileName0 + i0;fileName += _T(".txt");m_waveDataFile[i].Open(fileName,CFile::modeWrite|CFile::modeCreate|CFile::modeNoTruncate);//若⽂件存在,则清空}//开启接收数据的线程m_pThread = AfxBeginThread(ReceiveThread,this,0,CREATE_SUSPENDED,NULL);m_pThread->m_bAutoDelete = false;}2.2 接收数据UINT CTest_OilDlg::ReceiveThread(void *param){CTest_OilDlg *dlg = (CTest_OilDlg*)param;VCI_CAN_OBJ frameInfo[5000];//⼀次性从缓冲区获取50个帧VCI_ERR_INFO errInfo;int len = 1;//获取到的CAN帧的个数int i = 0;CString str,tmpstr;while(1){Sleep(1);if(dlg->m_connect == 0){break;}//获取缓冲区的长度int lenBuf = VCI_GetReceiveNum(dlg->m_deviceType,dlg->m_deviceIndex,dlg->m_canNumA);//获取到的数据的个数,如果缓冲区⼤于5000,则取出5000,否则将缓冲区全部取出len = VCI_Receive(dlg->m_deviceType,dlg->m_deviceIndex,dlg->m_canNumA,frameInfo,5000,400);//每次从缓冲区获取50帧,等待200ms⽆响应后结束if(len <= 0){//注意:如果没有读到数据则必须调⽤此函数来读取出当前的错误码//千万不能省略这⼀步(即使你可能不想知道错误码是什么)DWORD error = VCI_ReadErrInfo(dlg->m_deviceType,dlg->m_deviceIndex,dlg->m_canNumA,&errInfo);//返回值为1 表⽰操作成功if((errInfo.ErrCode & 0x0000) == 0x0000){//表⽰错误码是0x0000}}else{for(i = 0;i < len;i++){str = _T("数据:\n");if(frameInfo[i].DataLen > 8)frameInfo[i].DataLen = 8;//原始数据----但是这⾥没有保存for(int j = 0; j < frameInfo[i].DataLen;j++){tmpstr.Format(_T("%04x \n"),frameInfo[i].Data[j]);str += tmpstr;}::SendMessage(dlg->GetSafeHwnd(),WM_WAVEFORM,WPARAM(&frameInfo[i]),NULL);//TRACE(_T("receive\n"));}}}return0;}这⾥的数据处理是通过发送⾃定义消息的⽅法实现的,因为这些数据同时也要画成曲线显⽰在界⾯上,需要对界⾯进⾏更新操作,这时候需要给界⾯的主线程发消息去实现界⾯更新2.3 发送数据void CTest_OilDlg::OnBnClickedButtonSend(){//-----------------发送井下仪器⼯作模式命令-------------------//if(m_connect == 0)return ;VCI_CAN_OBJ frameInfo;//设置发送重发超时时间,建议不⼩于1500ms,默认4000msVCI_SetReference(m_deviceType,m_deviceIndex,m_canNumA,4,&m_sendTimeout);frameInfo.ID = 0x84444444;//需要再确定frameInfo.SendType = 0;//正常发送frameInfo.RemoteFlag = 0;//数据帧frameInfo.ExternFlag = 1;//扩展帧frameInfo.DataLen = 3;//⼀个字节frameInfo.Data[0] = 0x04;frameInfo.Data[1] = 0xff;//01仪器待机;02:仪器⾃检;03:仪器定时开关机;04:仪器测试;05:仪器连续⼯作frameInfo.Data[2] = m_selectMode.GetCurSel() + 1;int ret = VCI_Transmit(m_deviceType,m_deviceIndex,m_canNumA,&frameInfo,1);if(ret == 1){showListInfo(_T("命令发送成功"));SetHScroll();}else{showListInfo(_T("命令发送失败"));SetHScroll();}}View Code3、问题做到现在,程序⾃发⾃收可以,接收下位机数据能接受5个左右的循环就接不到了,后来把数据的操作都屏蔽掉,只接收,发现也接不到,缓冲区内的数据个数为0.这个问题还没解决。
VC上位机MFC利用串口控件发送接收数据程序代码

VC上位机MFC利用串口控件发送接收数据程序代码打开vc++6.0,建立一个基于对话框的mfc应用程序。
添加控件后会弹出一个确认框
点击“确定”
单击\,控件将被成功添加
然后在控件的属性里进行一些必要的配置:
Inputmode设置为1-binary,这意味着以二进制模式检查数据
其它的用默认值。
您还可以使用oninitdialog()函数中的代码进行设置,如下所示:
设置好以后,要在程序的开始打开串口,不然是没发使用的。
在oninitdialog中加入以下代码:
睡眠(100);方差数据;intdata_len;charcdata[1024];
cdata[data_len]=0;
//CDATA是指向所接收字符串的指针
m_list.addstring(cdata);//在listbox控件中显示接收到的数据}。
MFC程序设计范文

MFC程序设计范文MFC(Microsoft Foundation Class)是微软公司开发的一套用于Windows系统的应用程序框架,它提供了一系列的C++类,用于简化Windows程序的开发过程。
MFC基于面向对象的编程思想,提供了许多封装好的类和函数,使得开发者可以更加方便地进行界面设计、事件处理、数据管理等操作。
1. 创建MFC应用程序项目:在Visual Studio中选择新建项目,选择MFC应用程序向导,按照向导的指引完成项目的创建。
2.设计界面:MFC提供了可视化界面设计工具,开发者可以通过拖拽控件、设置属性等方式设计应用程序的界面布局。
控件包括按钮、文本框、列表框、菜单等等。
3.处理事件:事件是用户操作界面时发生的动作,如按钮被按下、列表框的选项被选中等。
在MFC中,可以通过重载响应函数的方式来处理事件。
每个控件都有一系列的事件处理函数,开发者可以根据需要选择合适的函数进行重载,然后在函数中编写事件处理的代码。
4.数据管理:MFC提供了一些数据管理的类,用于处理数据的读取、存储、处理等操作。
开发者可以使用这些类来操作数据库、读取文件、保存设置等。
除了上述基本流程,MFC还提供了一些其他的功能,如线程管理、消息处理、打印输出等。
开发者可以根据实际需求选择适合的功能进行使用。
然而,MFC程序设计也存在一些缺点。
首先,MFC只能在Windows系统上运行,不具备跨平台的能力。
其次,由于MFC是一套较为庞大的类库,如果没有掌握好MFC的使用方法,可能会导致开发效率低下,代码冗长。
另外,MFC的界面设计工具相对较为简陋,对于一些复杂的界面效果可能无法满足需求。
总体来说,MFC是一套适用于Windows系统的程序框架,可以帮助开发者快速搭建Windows程序的框架。
它提供了丰富的类库和工具,使得开发者能够更加轻松地进行界面设计、事件处理、数据管理等操作。
然而,MFC也有一些缺点,如只能在Windows系统上运行、界面设计工具相对简陋等。
MFC上位机软件设计

MFC上位机软件设计MFC(Microsoft Foundation Class)是微软公司开发的一套用于Windows操作系统的应用程序框架。
它提供了一系列用于快速开发Windows应用程序的类和函数库。
在开发MFC上位机软件时,需要考虑软件的设计,以确保软件的可靠性和易用性。
首先,需要进行软件需求分析。
这是软件开发过程中的首要步骤,可以通过与客户、用户的沟通和交流来收集和明确软件的需求。
需求分析包括对软件功能、性能、界面、用户角色等方面的明确。
其次,在设计阶段,需要确定软件的架构和模块划分。
MFC提供了一套基于窗口的界面设计,开发者可以根据软件的需求来设计主窗口和各个子窗口。
在设计上位机软件时,通常会包含与下位机通信的功能,如串口通信、网络通信等。
这就需要设计相应的通信模块。
在MFC上位机软件设计中,还需要考虑软件的界面设计。
界面设计应该具有良好的用户体验,界面布局合理,操作简单直观,符合用户的操作习惯。
可以通过使用MFC提供的控件和对话框进行界面设计,包括按钮、文本框、列表框、滚动条等。
另外,需要考虑软件的数据管理和数据处理。
上位机软件通常需要对从下位机接收到的数据进行处理和分析,可以使用MFC提供的数据库操作和数据结构来管理和处理数据。
同时,也需要设计相应的业务逻辑和算法来满足软件的功能需求。
在软件设计中,还需要进行系统测试和调试。
测试是确保软件质量的重要环节,可以通过单元测试、集成测试、系统测试等多种方式来进行测试。
调试是解决软件问题和bug的过程,可以利用MFC提供的调试工具和技术来进行调试。
此外,需要注意软件的安全性和稳定性。
对于上位机软件来说,安全性是重要的考虑因素之一、可以通过加密通信、用户权限管理等手段来增加软件的安全性。
稳定性是软件的基础要求,需要在设计和开发过程中尽量避免内存泄漏、空指针引用等问题,以确保软件的稳定性。
最后,在MFC上位机软件设计中,需要考虑软件的扩展性和可维护性。
基于MFC的单片机上下位机通信控制系统设计

Visual C++是一种由微软公司开发的包含协助开发环境的事件驱动编程语言,VC 拥有图形用户界面 (GUI)和快速应用程序开发(RAD)系统,程序员可以轻松的使用 VC 提供的组件快速建立一个应用程
________________________________ 作者简介:江维(1983-),男,讲师,博士,研究方向:智能控制与嵌入式系统. 基金项目:2018 年武汉纺织大学教学研究项目(2018JY019).
第 32 卷 第 2 期 2019 年 04 月
武汉纺织大学学报
JOURNAL OF WUHAN TEXTILE UNIVERSITY
Vol.32 No.2 Apr. 2019
江 维,吴雨川,李红军
TP273
MFC程序设计范文

MFC程序设计范文MFC(Microsoft Foundation Classes)是一种用于Windows操作系统的C++类库,它是Microsoft Visual C++应用程序开发的重要组成部分。
MFC提供了一种基于对象的编程模型,可以大大简化Windows GUI(图形用户界面)应用程序的开发过程。
通过MFC库,开发人员可以利用现有的类和功能来创建强大、可靠且可扩展的Windows应用程序。
在MFC程序设计中,通常需要遵循以下步骤:1. 创建一个MFC应用程序项目:首先,在Visual Studio中创建一个新的MFC应用程序项目。
在项目配置向导中,选择应用程序类型(对话框型、SDI型或MDI型)、支持的功能(ActiveX控制和OLE支持)、使用的界面风格等。
2. 编写应用程序代码:在MFC应用程序项目中,主要的代码文件是CWinApp类的派生类和CWnd类的派生类。
- CWinApp类的派生类通常包含应用程序的初始化和结束代码,包括应用程序的全局设置、消息处理程序的注册和初始化等。
- CWnd类的派生类通常用于创建主窗口或对话框,处理消息、事件和用户交互。
3. 设计用户界面:通过Visual Studio的可视化设计器,可以方便地设计应用程序的用户界面。
可以通过拖放控件、调整属性和布局来创建界面元素,如按钮、文本框、列表框等。
4.实现功能代码:在MFC应用程序中,可以使用MFC库提供的丰富功能和类来实现各种功能,如文件操作、数据库访问、多线程处理等。
5. 编译和调试程序:完成代码编写后,可以通过Visual Studio的编译器和调试器来编译和调试应用程序。
可以通过断点、单步执行等功能来查看程序的执行过程和变量的值。
6.发布应用程序:完成调试后,可以将应用程序打包成可执行文件,然后发布给用户使用。
可以将可执行文件、相关的库文件和资源文件打包成安装程序,通过安装程序来安装和部署应用程序。
MFC上位机软件设计

MFC上位机软件设计VC++串口上位机简单例程(源码及详细步骤)VC++串口上位机简单例程(源码及详细步骤) VC++串口上位机简单例程.rar (4.33 MB)VC++编写简单串口上位机程序2010年4月13日10:23:40串口通信,MCU跟PC通信经常用到的一种通信方式,做界面、写上位机程序的编程语言、编译环境等不少,VB、C#、LABVIEW等等,我会的语言很少,C语言用得比较多,但是还没有找到如何用C语言来写串口通信上位机程序的资料,在图书管理找到了用VC++编写串口上位机的资料,参考书籍,用自己相当蹩脚的C++写出了一个简单的串口上位机程序,分享一下,体验一下单片机和PC通信的乐趣。
编译环境:VC++6.0操作系统:VMWare虚拟出来的Windows XP程序实现功能:1、 PC初始化COM1口,使用n81方式,波特率57600与单片机通信。
PC的COM口编号可以通过如下方式修改:当然也可以通过上位机软件编写,通过按钮来选择COM端口号,但是此次仅仅是简单的例程,就没有弄那么复杂了。
COM1口可用的话,会提示串口初始化完毕。
否则会提示串口已经打开Port already open,表示串口已经打开,被占用了。
(a) to further cultivate and practice the socialist core value concept. Human civilization is the core and soul of the city. Created in deepening the urban civilization, to seize cultivation and practice the socialist core value concept of the fundamental task, to everyone talk about civilization, everywhere to see the civilization "as the goal, to promote the creation tasks implemented. First, we must deepen the Delhi City, good deeds sunshine" is the theme of moral practice, to build the brand of "Da Yi Ju, Houde good deeds" moral. Carefully create activity carrier, highlighting to create a theme, to carry out a wide range of "good side" recommended review activities, carry out moral modelitinerant preachers and most beautiful people, the series of model characters selection Activities, aggressively push the tree to a groupof people around to learn and amiable, respectable moral typical. To focus on the real refinement "good deeds for the four virtues list built, tubes, each link work; let the moral has become an important force for regulating the behavior of the citizens. A hand grasping the education, focusing on governance, the violation of public order, destruction of public facilities and other acts resolutely exposure. Second, we must deepen the activities to create a civilized. Actively carry outcivilized units, township of civilization, civilized window created, andfurther optimize the environment for government service. With the deep development of civilized community and family civilization, civilized community infrastructure to create activities, guide2、点击开始转换,串口会向单片机发送0xaa,单片机串口中断接收到0xaa后启动ADC转换一次,并把转换结果ADCL、ADCH共两个字节的结果发送至PC,PC 进行数值转换后在窗口里显示。
上位机软件开发工程师职位描述与岗位职责

上位机软件开发工程师职位描述与岗位职责上位机软件开发工程师是一种高级计算机软件工程师,主要负责设计和开发电脑应用程序,使其能够向下层设备(例如传感器或执行器)发送数据或命令,从而控制与监视系统的运行。
他们需要深入理解计算机系统的底层架构,熟练掌握不同的开发工具,并具备高度的创意和创新意识,以便开发出可靠高效的软件解决方案,以满足客户的需求。
下面是上位机软件开发工程师的职位描述与岗位职责:职位描述:1. 设计、开发和测试上位机应用程序,以实现系统的实时数据监视、远程控制和自动化计算;2. 使用C/C++、JAVA、Python等编程语言编写代码,应用MFC、QT、.NET等框架和库进行开发,保证软件的高可靠性和高稳定性;3. 与硬件工程师密切合作,协助其设计和开发传感器和控制器固件的通信协议,以保证上下层设备间的数据传输的正确性和及时性;4. 对上位机软件进行持续性改进,以增加其性能和功能,降低其系统错误率,并提高其易维护性;5. 支持产品的现场测试、部署和维护工作,并注重用户反馈,及时解决技术问题,为客户提供有效的技术支持和指导;岗位职责:1. 设计上位机软件的系统架构和数据流程,生成详细的项目计划和开发日程表;2. 与客户或其他工程师进行沟通和协调,共同解决技术问题和设计需求,确保软件方案的成功实施和客户满意度;3. 协助团队成员获得必要的技术培训和支持,提高他们的技术水平和应对复杂客户需求的能力;4. 执行代码版本控制和集成测试,协助团队确保软件产品的质量和适应性,研究新技术和新方案,为团队提供技术创新思路;5. 主动参与项目管理,并且不断改进工作流程和开发方法,为客户提供更快、更好和更经济的软件解决方案。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
MFC上位机软件设计VC++串口上位机简单例程(源码及详细步骤)VC++串口上位机简单例程(源码及详细步骤) VC++串口上位机简单例程.rar (4.33 MB)VC++编写简单串口上位机程序2010年4月13日10:23:40串口通信,MCU跟PC通信经常用到的一种通信方式,做界面、写上位机程序的编程语言、编译环境等不少,VB、C#、LABVIEW等等,我会的语言很少,C语言用得比较多,但是还没有找到如何用C语言来写串口通信上位机程序的资料,在图书管理找到了用VC++编写串口上位机的资料,参考书籍,用自己相当蹩脚的C++写出了一个简单的串口上位机程序,分享一下,体验一下单片机和PC通信的乐趣。
编译环境:VC++6.0操作系统:VMWare虚拟出来的Windows XP程序实现功能:1、 PC初始化COM1口,使用n81方式,波特率57600与单片机通信。
PC的COM口编号可以通过如下方式修改:当然也可以通过上位机软件编写,通过按钮来选择COM端口号,但是此次仅仅是简单的例程,就没有弄那么复杂了。
COM1口可用的话,会提示串口初始化完毕。
否则会提示串口已经打开Port already open,表示串口已经打开,被占用了。
2、点击开始转换,串口会向单片机发送0xaa,单片机串口中断接收到0xaa 后启动ADC转换一次,并把转换结果ADCL、ADCH共两个字节的结果发送至PC,PC 进行数值转换后在窗口里显示。
(见文章末尾图)3、为防止串口被一只占用,点击关闭串口可以关闭COM1,供其它程序使用,点击后按钮变为打开串口,点击可重新打开COM1。
程序的编写:1、打开VC++6.0建立基于对话框的MFC应用程序Test,2、在项目中插入MSComm控件:工程->增加到工程->Components andControls->双击Registered ActiveX Controls->选择Microsoft Communications Control, version6.0->Insert,按默认值添加,你会发现多了个电话图标,这是增加后串口通信控件。
3、删除确认、取消和提示框,添加“电话”、进程、静态文本、按钮、编辑框,拖动添加的控件,根据喜好布局。
4、右击编辑框Edit选择属性,在样式里设置,勾选多行、垂直滚动,其它可按默认值。
右击静态文本Text选择属性,在常规设置里,修改标题。
右击按钮PushButton选择属性,在在常规设置里,修改标题。
修改后界面如下,程序写出来运行时“电话”标志会自动消失。
5、查看->建立类向导MFC ClassWizard->Member Viariable,选择ClassName为CTestDlg的类,Control ID为MSCOMM1,双击它,为它添加控制变量m_comm1。
类似的,选择IDC_BUTTON2添加控制变量m_serial。
(建立类向导也可以右击然后在弹出的快捷菜单里选择建立类向导)至此,基本框架已经出来了,编译后运行可以看到如下所示的界面。
(组建->全部组件,然后组建->执行)6、点击左侧的视图窗口,可以在三种模式下切换,第三个是打开我们的源代码窗口,第一个是类,第二个是窗体的资源视图。
选择File View,展开test files->Header Files,打开testDlg.h,在全局变量下添加如下代码,然后保存:int gllen;//定义整型标量gllen,用于记录接收数据的个数CProgressCtrl * pbar; //指向进度条的指针,用于操作进度条CString strRXDdata; //编辑框显示的文本,记录历次转换值7、点击Recourse View,展开test recourses->Dialog,双击IDD_TEST_DIALOG,编辑我们的主界面对话框。
双击击“电话”,弹出如下对话框,按确认键:VC会进入源码编辑窗口,这个函数是用来处理串口事件的,当PC串口接收到数据时,会产生一个数据缓冲区有数据的消息事件,然后调用执行这个函数。
添加如下代码,进行数据处理,窗口更新等操作:VARIANT variant1;//定义VARIANT型变量,用于存放接收到的数据COleSafeArray safearray;//定义safearray型变量LONG len,k;//定义长整型变量len,kBYTE rxdata[2048];//定义BYTE型数组CString stremp1,stremp2;//定义两个字符串if(m_comm1.GetCommEvent()==2) //判断引起OnComm时间的原因{//如果是接收到特定个字节数,则读取接收到的数据variant1 = m_comm1.GetInput();//把接收到的数据存放到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*4+((*(unsigned char *)(rxdata+k+1))>>6); //高低字节合并成实际的转换结果,注意转换结果是左对齐stremp1.Format("%2.2f",(2.56*temp/1024));//计算成实际电压值SetDlgItemText(IDC_STATIC,("当前电压值为: "+stremp1+" V")); //更新静态文本控件 pbar -> SetPos(temp);//更新进度条的当前位置strRXDdata += stremp2;//把新的数据放到全局的字符串里strRXDdata += stremp1;strRXDdata += " V\r\n";//字符串加单位V后换行}}}SetDlgItemText(IDC_EDIT1,strRXDdata);//更新文本控件的显示这时重新编译一下,看会不会有什么错误,出现下面提示,可以选择全部组建来清除。
LINK : LNK4073: cannot create map for .ILK file; linking nonincrementally出现下面错误,请关闭运行的test.exe后重试。
LINK : fatal error LNK1104: cannot open file "Debug/test.exe"出现下面错误两种错误,是由于空间编号问题引起的,当我们添加了编辑框或者“电话”后再添加,其编号自动加一,就会出现控件没定义。
Z:\vc++串口上位机\test\testDlg.cpp(32) : error C2065: 'IDC_MSCOMM1' : undeclaredidentifierZ:\vc++串口上位机\test\testDlg.cpp(139) : error C2065: 'IDC_EDIT1' : undeclaredidentifier解决方法是,在RecourseView里,打开窗体IDD_TEST_DIALOG,右击“电话”或者编辑框等其它出错的控件,右击选择属性,在常规里修改ID,这里的程序,除BUTTON有1、2两个之外,其它都是1全部组建编译一下,看看有没有错误,没有错误就可以运行一下,可以看到界面更原来是一样的。
有错误就修改一下,省得弄多了,错在哪里都不知道,查起来麻烦。
8、在源码编辑里,打开testDlg.cpp文件,进行窗口初始化函数的编写。
找到BOOL CTestDlg::OnInitDialog()函数,在SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here 后面添加如下初始化代码:gllen = 0; //记录转换次数全局变量清零if(! m_comm1.GetPortOpen())//判断串口是否已经打开{m_comm1.SetCommPort(1); //选择串口号1m_comm1.SetPortOpen(TRUE); //打开串口m_comm1.SetRThreshold(2); //收到两个字节引发OnComm事件m_comm1.SetInputMode(1);//输入模式选为二进制m_comm1.SetSettings("57600,n,8,1"); //设置串口参数,波特率57600,无奇偶校验,1位停止位,8位数据位MessageBox("串口初始化完毕","提示"); //提示串口成功初始化}else MessageBox("串口被占用","提示"); //如果已经打开串口,消息框提醒pbar = (CProgressCtrl*)GetDlgItem(IDC_PROGRESS1);//获得指向IDC_PROGRESS1的指针pbar -> SetRange(0,1023);//设置进度条的范围0~1023pbar -> SetPos(0);//当前位置为0m_serial.SetWindowText("关闭串口");//按钮显示状态改变可以看到,串口的参数等等都在在这里初始化的,可以根据自己的需要修改的,具体可以查看VC++里的详细介绍,看看有哪些参数可以给我们修改来用。
添加后再编译一下,运行后可以看到多了一个串口初始化的提示信息窗口。
至此,我们已经完成了主要的串口操作及界面,剩下的就是两个按钮的操作了。
9、回到资源视图的IDD_TEST_DIALOG窗口,双击开始转换按钮,给它添加事件,点击后PC通过串口发送0xaa出来,给单片机接收。