CserialPort类
qserialport readready信号 -回复

qserialport readready信号-回复QSerialPort是Qt提供的一个串口通信类,它允许应用程序与外部设备进行数据交换。
在QSerialPort类中,有一个非常重要的信号——readReady。
本文将详细解析这个信号以及其相关内容。
一、QSerialPort简介Qt是一套跨平台的C++应用程序开发框架,它提供了丰富的库和工具,用于开发图形用户界面(GUI)和非GUI应用程序。
QSerialPort是Qt中与串口通信相关的类,可以方便地与外部设备进行数据交互,如串口打印机、传感器、硬件接口等。
二、readReady信号的作用和功能readReady是QSerialPort类中一个非常重要的信号,它表示串口接收缓冲区中有数据可用于读取。
当外部设备向电脑(应用程序)发送数据时,QSerialPort会自动检测到数据的到达,并发出readReady信号,用于通知应用程序可以读取数据。
三、使用readReady信号的步骤1. 创建QSerialPort对象使用QSerialPort类之前,需要创建一个对象,即实例化一个QSerialPort 类。
可以通过构造函数或工厂函数创建对象,并指定串口名称、波特率、数据位、校验位等参数。
2. 打开串口在使用QSerialPort之前,需要先打开串口。
可以通过调用QSerialPort 类的open函数来打开串口。
在打开串口之前,需要确保串口未被其他程序占用。
3. 连接readReady信号在QSerialPort对象创建并打开串口后,可以连接其readReady信号。
通过调用QObject类的connect函数,将readReady信号与自定义的槽函数建立连接。
4. 实现槽函数在连接readReady信号之后,需要实现一个槽函数。
槽函数将在接收到readReady信号时被自动调用,并负责处理接收到的数据。
5. 启动事件循环在连接readReady信号并实现槽函数后,需要启动Qt的事件循环,以便能够接收和处理来自串口的数据。
基于VC的无人机飞控地面站软件的开发

VC++[43提供了丰富的数据库访问技术,例如ADO、ODEC 等,其中ADo是最新的数据库访问技术,它使用简单,速度快, 内存支出少,磁盘遗迹少,本软件就采用ADO访问技术。
在软件中使用AD()实现数据库操作,关键步骤如下: D用Connection对象莲接数据库 一ConneetionPtr m—pConneetl,//定义智能指针 //在try…catch异常处理中打开本地Access数据库
图1地面站系统结构
收蔫日期:2008—07—22;修回日期:2008—08—30。 作者简介:宁金星(1983一),男,山西人,顽士研究生.主要从事导 航、制导与控制方向的研究。 卢京潮(1956一),男。山西人.硕士生导师,主要从事数据处理、智能’ 控制,飞行控制雄仿真等方向的研究。
VC++是一种可视化的编程语言.通过嵌入NI控件, AetiveX控件或者调用DLL动态链接库,程序员就可以编写出 界面友好、功能强大的包括通讯、数据库应用等各种应用程序 的软件,尤其是VC++的基于事件触发的程序运行机制特别 适合应用于测控软件的设计[1]。在开发飞控地面站软件的过程 中,作者应用VC++设计了完备的显示和操作界面,并给出 了相应的应用程序关键代码。
万方数据
中华测控网
chinamca.corn
·598·
计算机洲譬与控制
第17卷
在资源视豳中添加以wav为后缀的报管声音文件,然后定义 一个声音函数,其中关键代码如下:
HINSTANCE h2AfxGetlnstanceHandle()I HRSRC hr。FindResouree(h,MAKEINTRF_.SOURCE
2基于串口通信的模块实现
2.1串口通信模块 串口通信模块主要利用串口RS232实时接收遥测指令,
基于数据库和串口技术的数据监控系统

基于数据库和串口技术的数据监控系统摘要:ADO和串口通信技术常用于数据采集监控等场合。
通过ADO 对象可以建立与数据库的连接,并读写数据库中的数据;利用串口通信程序可在上位机和下位机间进行数据传输。
介绍了ADO对象及其导入编程环境的方法,根据具体事例详细描述了利用ADO对象操作数据库,介绍了串口通信程序。
结果证明ADO和串口通信技术相结合可以更方便快捷地访问数据库。
关键词:VC++;ADO;数据库;串口;监控系统0 引言数据采集作为远程监控的重要组成部分,通常是创建一个普通数据文件如文本文件保存数据。
但当数据量很大时,频繁地读写将会消耗很多的系统资源,造成上位机负担加重,实时性恶化,利用数据库管理系统则能较好地解决这一问题。
串行通信因其简单方便、成本低廉、适合大规模长距离传输等优点,广泛地应用于远程监控系统中。
本文介绍了一种利用ADO技术访问数据库,实现串口数据采集存取的方法。
1 ADO数据库接口技术1.1 ADO技术简介ADO(ActiveX Data Object)是微软提出的一种应用程序接口,和DAO、RDO一样,均可以访问数据库中的数据。
它是一种功能强大的面向对象的数据访问编程模式,是对当前微软所支持的数据库进行操作的最有效和最简单直接的方法。
由于微软开发的Visual C++语言支持COM库,所以可在VC编译环境下利用ADO对象访问数据库。
1.2 ADO数据库初始化使用ADO访问数据库之前有两个准备步骤:①导入ADO类型库;②初始化COM库。
一般在stdafx.h头文件中,使用#import指令导入ADO类型库,程序语句如下:#import“C:Program FilesCommon FilesSystemadomsado15.dll”no_namespacerename(“EOF”,“adoEOF”)rename(“BOF ”,“adoBOF”)在调用ADO对象之前,必须先初始化库环境,调用结束后再释放资源。
电子大赛——跑步机论文

跑步机虚拟健身系统摘要:健康是生命的春天。
当今社会工作压力大是一种普遍的现象,健康问题就显得的尤为重要。
通过对上班族的调查及其身体状况分析,很多人没有足够时间到户外进行锻炼并且急需加强锻炼。
室内锻炼最普遍的就是跑步机,而传统跑步机就是在单一的跑步,让人感觉乏味,容易疲劳。
针对这种情况,设计了一套辅助系统,对传统跑步机进行改进。
使用户在跑步的同时,看到不同的场景,如四维电影一样置身其中。
让人们在室内进行锻炼的同时能体会回归大自然的感觉,锻炼的同时也愉悦了身心。
缓解锻炼中产生的疲劳,起到真正的锻炼目的,也满足了没有时间到室外锻炼的需求。
在原来普通的跑步机上增加了新的科技含量较高的技术,采用单片机传感技术测量跑步机速度,方向等参数值;运用串口通信技术,将参数传递给计算机;最后运用OPENGL三维动画技术绘制实时的虚拟室外场景,最终实现跑步机虚拟健身系统。
关键字:虚拟现实、单片机,串口通信,OPENGL三维图形,健身系统引言:随着社会的发展,生活节奏的加快,健康问题成了全社会普遍关注的焦点。
无论我们走在生命的哪段旅程中,我们扮演着什么样的角色,有一点是不容置疑的——只有拥有健康,我们才有足够的能力去面对生活中的风雨兼程。
据有关调查,对于都市上班族来说,在办公室内工作的人发病甚至死亡的比率正逐年上升。
所以健康已经成为重如泰山的问题。
据此我们设计了一种全新的跑步机,让人们喜欢上锻炼身体,而非强迫性不情愿的进行锻炼。
传统的跑步机强调的是单一的锻炼,没有考虑的人的视觉感受。
容易让人厌倦。
他们改进的仅仅是对一些技术指标,如可以显示时间、速度、心率等功能,更“先进”一点的就是采用一些LCD显示等。
这些传统的跑步机实质来说还是单一的跑步。
而我们的设计从人的精神感觉上出发,让你在锻炼的同时也能进行思考(如向哪一个方向走,路边风景好看与否等)。
加入这一创新,打破了传统跑步机的劣势。
让锻炼的人达到锻炼的同时也能够活跃思维,产生沉浸于自然环境的真实感觉,同时,该设计的娱乐性也比较强。
qserialport方法

QSerialPort方法介绍QSerialPort是Qt框架中用于串口通信的类,它提供了一种简单、易用的方式来实现串口通信。
串口通信在很多领域都有广泛的应用,例如嵌入式系统、物联网设备、机器人控制等。
QSerialPort类封装了底层的串口通信接口,使得开发者可以方便地进行串口通信的操作。
本文将详细介绍QSerialPort类的各种方法,包括打开串口、设置串口参数、读写数据等。
我们将从基本用法开始,逐步深入讲解其高级功能和应用场景。
基本用法首先,我们需要在Qt项目中引入QSerialPort类。
可以通过在.pro文件中添加以下语句来实现:QT += serialport接下来,在需要使用串口通信的类中包含头文件:#include <QSerialPort>打开和关闭串口使用QSerialPort类的第一步是打开串口。
可以通过以下方式进行打开:QSerialPort serialPort;serialPort.setPortName("COM1"); // 设置串口名称,根据实际情况修改serialPort.setBaudRate(QSerialPort::Baud115200); // 设置波特率serialPort.setDataBits(QSerialPort::Data8); // 设置数据位serialPort.setParity(QSerialPort::NoParity); // 设置校验位serialPort.setStopBits(QSerialPort::OneStop); // 设置停止位serialPort.setFlowControl(QSerialPort::NoFlowControl); // 设置流控制if (serialPort.open(QIODevice::ReadWrite)) {// 串口打开成功} else {// 串口打开失败}以上代码中,我们首先创建了一个QSerialPort对象,然后设置了串口的各种参数,包括串口名称、波特率、数据位、校验位、停止位和流控制。
qserialport用法

qserialport用法1. 什么是qserialportqserialport是Qt框架中的一个模块,用于在Windows、Linux和macOS等操作系统上进行串口通信。
它提供了一种简单而强大的方式来读取和写入串口数据,并支持多种常见的串口通信协议。
2. 安装qserialport在使用qserialport之前,需要先安装Qt开发环境。
Qt是一个跨平台的应用程序开发框架,可以在官方网站上下载并安装。
安装完Qt后,在项目文件中添加QT += serialport这一行来启用qserialport模块。
3. qserialport基本概念3.1 串口串口是一种常见的计算机外部设备连接接口,用于将计算机与其他设备(如传感器、打印机等)进行数据交换。
每个串口都有一个唯一的标识符,称为端口号。
3.2 波特率波特率是指每秒钟传输的比特数(即数据位)的数量。
它表示了信息传输速度的快慢,单位为bps(bits per second)。
3.3 数据位、停止位和校验位数据位表示每个字节中使用的比特数。
常见的取值为5、6、7和8位。
停止位用于表示一个字节的结束。
常见的取值为1位和2位。
校验位用于检测数据传输中的错误。
常见的取值为无校验、奇校验和偶校验。
3.4 流控制流控制用于控制数据在串口之间的传输速率,以防止数据丢失或溢出。
常见的流控制方式有硬件流控制和软件流控制。
4. qserialport类及其方法4.1 QSerialPort类QSerialPort类是qserialport模块中最重要的类,它提供了与串口进行交互的方法和信号。
4.2 打开和关闭串口使用QSerialPort类打开串口时,需要指定串口名称、波特率、数据位、停止位和校验位等参数。
可以通过调用open()方法来打开串口,并使用close()方法关闭串口。
QSerialPort serial;serial.setPortName("COM1");serial.setBaudRate(QSerialPort::Baud115200);serial.setDataBits(QSerialPort::Data8);serial.setStopBits(QSerialPort::OneStop);serial.setParity(QSerialPort::NoParity);if (serial.open(QIODevice::ReadWrite)) {// 串口打开成功} else {// 串口打开失败}4.3 读取和写入数据使用QSerialPort类可以方便地读取和写入串口数据。
串口写入和读取数据
串⼝写⼊和读取数据SerialPort类WriteComm 写串⼝函数DWORD CSerialPort::WriteComm(char *buf, DWORD dwLength){if(!IsOpen()){return0;}assert(buf != NULL);COMSTAT comStat;DWORD dwErrorFlags;if (!ClearCommError(m_hCom, &dwErrorFlags, &comStat) && dwErrorFlags > 0){PurgeComm(m_hCom, PURGE_TXABORT | PURGE_TXCLEAR);}OVERLAPPED osWrite;memset(&osWrite, 0, sizeof(OVERLAPPED));osWrite.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);BOOL bWriteStat = WriteFile(m_hCom, buf, dwLength, &dwLength, &osWrite);if(!bWriteStat){if(GetLastError() == ERROR_IO_PENDING){WaitForSingleObject(osWrite.hEvent, 2000);}else{dwLength = 0;}}return dwLength;}调⽤char buf[10]; //字符数组将字符串通过 strcpy 放⼊字符数组再向串⼝写⼊strcpy(buf,"1234");m_SerialPort.WriteComm(buf,4);MessageBox(_T("1234"));buf[0]=0x61; //将要发送的字符串或⼗六进制数据储存在char型字符数组中,利⽤WriteComm发送到串⼝m_SerialPort.WriteComm(buf,1);ReadCommDWORD CSerialPort::ReadComm(char *buf, DWORD dwLength){if(!IsOpen()){return0;}buf[0] = '\0';COMSTAT comStat;DWORD dwErrorFlags;if (!ClearCommError(m_hCom, &dwErrorFlags, &comStat) && dwErrorFlags > 0){PurgeComm(m_hCom, PURGE_RXABORT | PURGE_RXCLEAR);return0;}if(comStat.cbInQue == 0){return0;}DWORD dwBytesRead=0;BOOL bReadStat;dwBytesRead = min(dwLength - 1, (DWORD)comStat.cbInQue);OVERLAPPED osRead;memset(&osRead,0,sizeof(OVERLAPPED));osRead.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);DWORD dwByteOfRead = 0;bReadStat = ReadFile(m_hCom, buf, dwBytesRead, &dwByteOfRead, &osRead);if(!bReadStat){if(GetLastError() == ERROR_IO_PENDING){WaitForSingleObject(osRead.hEvent, 2000);// GetOverlappedResult(m_hCom, &osRead, &dwByteOfRead, FALSE) ;}}// PurgeComm(m_hCom, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR); ////清空串⼝的接收缓冲区,必要性不⼤,但有保证作⽤?清空的话如果⼤数据会丢失buf[dwByteOfRead] = '\0';return dwByteOfRead;}调⽤char *pBuf=new char[10]; //定义⼀个char型字符数组,动态分配内存 memset(pBuf,0,10);m_SerialPort.ReadComm(pBuf,10);。
C#串口通信
C#串⼝通信在C#中使⽤串⼝通信⽐较⽅便,.Net 提供了现成的类,类。
本⽂不对原理啥的进⾏介绍,只介绍SerialPort类的使⽤。
SerialProt类内部是调⽤了CreateFile,WriteFile等WinAPI函数来实现串⼝通信。
在后期的中,我会详细介绍Windows的IO打开串⼝1 SerialPort sp = new SerialPort();23public bool OpenSerialPort(string portName, string strBaudRate, string strDataBit, int stopBitIndex, int parityIndex) 4 {56if (sp.IsOpen)7 sp.Close();89 sp.PortName = portName; //串⼝号10 sp.BaudRate = Convert.ToInt32(strBaudRate); //波特率11 sp.DataBits = Convert.ToInt32(strDataBit); //数据位12 sp.StopBits = (StopBits)stopBitIndex; //停⽌位13 sp.Parity = (Parity)parityIndex; //奇偶校验位14 sp.RtsEnable = true; //启⽤请求发送 (RTS) 信号15 sp.ReadTimeout = 500; //超时时间1617 sp.Open(); //打开串⼝1819 }关闭串⼝1public bool CloseSerialPort()2 {3try4 {5if (sp.IsOpen == true)6 {7 sp.Close(); //关闭串⼝8return true;9 }10catch11 {12return false;13 }14 }发送普通字符数据1public bool SendNormalString(string data)2 {3try4 {5 sp.Encoding = Encoding.ASCII;6 sp.Write(data);7return true;8 }9catch10 {11return false;12 }13 }发送⼗六进制数据1///<summary>2///转换成ASCII字符3///</summary>4///<param name="str"></param>5///<param name="format"></param>6///<returns></returns>7private string GetASCIIString(string str, string format = "X2")8 {9var asciiStr = "";1011for (int i = 0; i < str.Length; i++)12 {13var asciiCode = (int)str[i];14 asciiStr += asciiCode.ToString(format);15 }1617return asciiStr;18 }1///<summary>2/// ASCII字符转换成⼗六进制字节数组3///</summary>4///<param name="str"></param>5///<returns></returns>6private byte[] ASCIIStringToHexByteArray(string str)7 {8try9 {10 str = str.Replace("", "");1112byte[] buffer = new byte[str.Length / 2];1314for (int i = 0; i < str.Length; i += 2)15 {16 buffer[i / 2] = Convert.ToByte(str.Substring(i, 2), 16);17 }1819return buffer;20 }21catch22 {23return new byte[] { };24 }25 }发送1 sp.Write(buffer, 0, buffer.Length);接收串⼝数据接收串⼝数据需要响应SerialProt类的DataReceived事件,指⽰已通过由 SerialPort 对象表⽰的端⼝接收了数据。
serialport 使用方法
serialport 使用方法(原创版3篇)目录(篇1)1.引言2.serialport 的定义和作用3.serialport 的使用方法4.serialport 的常见问题及解决方法5.结论正文(篇1)一、引言在电子设备和计算机之间的通信中,串行通信是一种常见的通信方式。
而在 Python 中,我们可以使用 pyserial 库中的 serialport 模块来实现串行通信。
本文将为大家介绍 serialport 的使用方法。
二、serialport 的定义和作用serialport,即串行端口,是计算机上的一个硬件设备,负责实现串行通信。
在 Python 中,我们可以通过 pyserial 库来操作 serialport,从而实现与外部设备的通信。
三、serialport 的使用方法1.导入库首先,我们需要导入 pyserial 库。
在命令行中输入以下命令:```pip install pyserial```然后在 Python 代码中加入以下导入语句:```pythonimport serial```2.创建串行对象使用`serial.Serial()`方法创建一个串行对象,其中参数`port`表示串行端口号,`baudrate`表示波特率,`parity`表示校验方式,`stopbits`表示停止位,`bytesize`表示数据位。
```pythonser = serial.Serial(port="COM3", baudrate=9600,parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_ONE, bytesize=serial.EIGHTBITS)```3.打开串行端口使用`ser.open()`方法打开串行端口。
如果端口打开成功,`ser.isOpen()`方法将返回 True。
```pythonif ser.isOpen():print("串行端口已打开")else:ser.open()```4.读写数据使用`ser.read()`方法从串行端口读取数据,使用`ser.write()`方法向串行端口发送数据。
SerialPort 类 (System.IO.Ports)
Write(String)
将指定的字符串写入串行端口。
Write数据将指定数量的字节写 入串行端口。
Write(Char(), Int32, Int32) 使用缓冲区的数据将指定数量的字符写 入串行端口。
WriteLine
页首
事件
将指定的字符串和 NewLine 值写入输 出缓冲区。
SerialPort 类 (System.IO.Ports)
页首
属性
StopBits)
SerialPort 类的新实例。
名称 BaseStream BaudRate BreakState BytesToRead BytesToWrite CanRaiseEvents
CDHolding Container
/...ameworkMoniker-%FRAMEWORK%2cVERSION%3dV4.0%22);k(DevLang-CSHARP)&rd=true[2011-10-9 11:19:21]
SerialPort 类 (System.IO.Ports)
SerialPort 类 (System.IO.Ports)
主页 技术资源库 学习 下载 支持 社区
登录 | 中国(简体中文) |
使用 Bing 搜索 MSDN
此主题由人工翻译。 将光标移到文章的句子上,以 查看原文。
译文 原文
MSDN Library .NET 开发 .NET Framework 4 .NET Framework 类库 System.IO 命名空间 System.IO.Ports
名称 InfiniteTimeout
说明 指示不应该发生超时。
此类用于控制串行端口文件资源。 此类提供同步 I/O 和事件驱动的 I/O、对管脚 和中断状态的访问以及对串行驱动程序属性的访问。 另外,此类的功能可以包装 在内部 Stream 对象中,可通过 BaseStream 属性访问,并且可以传递给包装 或使用流的类。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
简单而强大的多线程串口编程工具CserialPort类(附VC基于MFC单文档协议通讯源程序及详细编程步骤)作者:龚建伟2001.11.09(任意转载,请注明来自啸峰工作室及网址)老有人觉得MSComm通讯控件很土,更有人大声疾呼:忘了它吧。
确实当我们对串口编程有了一定的了解后,应该用API函数写一个属于自己的串口程序,由于编程者对程序了解,对程序修改自如。
但我一直没有停止过用MSComm通讯控件,那么简单的东西,对付简单的任务完全可以,但当我们需要在程序中用多个串口,而且还要做很多复杂的处理,那么最好不用MSComm通讯控件,如果这时你还不愿意自己编写底层,就用这个类:CserialPort类。
这是Remon Spekreijse写的一个串口类,地址在:/network/serialport.shtml类作者Remon Spekreijse已作了一个基于对话框的同时检测4个串口示例的程序,在上面的网址和我主页的串口源码下载页也可以找到。
我在这儿主要介绍如何将这个类应用到VC中基于文档的程序中。
为了加深对串口数据处理的了解,我们利用这个类解决如下问题:问题:串口2(COM2)每隔1秒向串口1(COM1)发送的NEMA格式的报文:串头为$,串尾为*,中间为一个xxxx 的整数(比如2345,不足4位则前面以0代替代),最后是hh校验,规定hh为xxxx四个数的半BYTE 校验和,最后加上回车<CR>与换行<LF>。
整个数据包为$xxxx*hh<CR><LF>。
串口1收到上述报文后,校验正确后,将发来的数据显示在视窗中,并记下发来的正确帧数和错误帧数,若正确,还向串口2发送Y,串口2收到Y后将收到的Y的计数显示在视窗中。
测试方法:将三线制串口线联接上同一台计算机的两个串口,编好程序后就可测试。
如果没有两个串口的微机,自己改改程序。
好了,你可以先下载源程序: scporttest.zip(大小:49KB,VC6,WIN9X/2000,SerialPort.h SerialPort.cpp是两个类文件)编程步骤:◆1. 建立程序:建立一个基于单文档的MFC应用程序SCPortTest,所有步骤保持缺省状态。
◆2. 添加类文件:将SerialPort.h SerialPort.cpp两个类文件复制到工程文件夹中,用Project-Add to Project-Files 命令将上述两个文件加入工程。
并在SCPortTestView.h中将头文件SerialPort.h说明:#include "SerialPort.h"。
◆3. 人工增加串口消息响应函数:OnCommunication(WPARAM ch, LPARAM port)首先在SCPortTestView.h中添加串口字符接收消息WM_COMM_RXCHAR(串口接收缓冲区内有一个字符)的响应函数声明://{{AFX_MSG(CSCPortTestView)afx_msg LONG OnCommunication(WPARAM ch, LPARAM port);//}}AFX_MSG然后在SCPortTestView.cpp文件中进行WM_COMM_RXCHAR消息映射:BEGIN_MESSAGE_MAP(CSCPortTestView, CView)//{{AFX_MSG_MAP(CSCPortTestView)ON_MESSAGE(WM_COMM_RXCHAR, OnCommunication)//}}AFX_MSG_MAPEND_MESSAGE_MAP()接着在SCPortTestView.cpp中加入函数的实现:LONG CSCPortTestView::OnCommunication(WPARAM ch, LPARAM port){ ….. }注意:由于这个串口类加入工程后,没有自动的消息映射机制,因此上述步骤均需要手工添加。
◆4 初始化串口在视创建时初始化串口,首先利用ClassWizardr按下图生成OnInitialUpdate()函数。
接着在SerialPort.h文件中说明我们在程序中要用到的全局变量:保存两个串口接收数据:char m_chChecksum; //用于COM1的校验和计算CString m_strRXhhCOM1; //用于存放COM1接收的半BYTE校验字节hhCString m_strRXDataCOM1; //COM1接收数据CString m_strRXDataCOM2; //COM2接收数据UINT m_nRXErrorCOM1; //COM1接收数据错误帧数UINT m_nRXErrorCOM2; //COM2接收数据错误帧数UINT m_nRXCounterCOM1; //COM1接收数据错误帧数UINT m_nRXCounterCOM2; //COM2接收数据错误帧数CString再在SerialPort.h文件中说明串口类对象:CSerailPort m_ComPort[2]; (public)。
因为要初始化2个串口,所以这里用了数组。
下面是初始化串口1和串口2:void CSCPortTestView::OnInitialUpdate(){CView::OnInitialUpdate();// TODO: Add your specialized code here and/or call the base classm_chChecksum=0; //校验和置0m_nRXErrorCOM1=0; //COM1接收数据错误帧数置0m_nRXErrorCOM2=0; //COM2接收数据错误帧数置0m_nRXCounterCOM1=0; //COM1接收数据错误帧数置0m_nRXCounterCOM2=0; //COM2接收数据错误帧数置0m_strRXhhCOM1.Empty(); //清空半BYTE校验hh存储变量for(int i=0;i<2;i++){if (m_ComPort[i].InitPort(this,i+1,9600,'N',8,1,EV_RXFLAG | EV_RXCHAR,512)) //portnr=1(2),baud=960,parity='N',databits=8,stopsbits=1,//dwCommEvents=EV_RXCHAR|EV_RXFLAG,nBufferSize=512{m_ComPort[i].StartMonitoring(); //启动串口监视线程if(i==1) SetTimer(1,1000,NULL); //设置定时器,1秒后发送数据}else{CString str;str.Format("COM%d 没有发现,或被其它设备占用",i+1);AfxMessageBox(str);}}}◆5 利用ClassWizard按下图生成CSCPortTestView 的时间消息WM_TIMER响应函数:void CSCPortTestView::OnTimer(UINT nIDEvent){// TODO: Add your message handler code here and/or call defaultint randdata=rand()%9000; //产生9000以内的随机数CString strSendData;strSendData.Format("%04d",randdata);SendString(strSendData, 2); //串口2发送数据;CView::OnTimer(nIDEvent);}上面用到的SendString()需按如下方式生成:在ClassView中单击鼠标右键,在环境菜单中选择AddS Member Function:void CSCPortTestView::SendString(CString &str, int Port){char checksum=0,cr=CR,lf=LF;char c1,c2;for(int i=0;i<str.GetLength();i++)checksum = checksum^str[i];c2=checksum & 0x0f; c1=((checksum >> 4) & 0x0f);if (c1 < 10) c1+= '0'; else c1 += 'A' - 10;if (c2 < 10) c2+= '0'; else c2 += 'A' - 10;CString str1;str1='$'+str+"*"+c1+c2+cr+lf;m_ComPort[Port-1].WriteToPort((LPCTSTR)str1);}请注意上面函数中是如何生成校验码的,要切记的是发送的校验码生成方式和对方接收的校验检测方式要一致。
◆6 在OnCommunication(WPARAM ch, LPARAM port)函数中进行数据处理说明:WPARAM、 LPARAM 类型是多态数据类型(polymorphic data type),在WIN32中为32位,支持多种数据类型,根据需要自动适应,这样程序有很强的适应性。
在此我们可以分别理解为char和 integer 类型数据。
每当串口接收缓冲区内有一个字符时,就会产生一个WM_COMM_RXCHAR消息,触发OnCommunication函数,这时我们就可以在函数中进行数据处理,所以这个消息就是整个程序的"发动机"。
下面是根据本文最初提出的问题写出的处理函数:LONG CSCPortTestView::OnCommunication(WPARAM ch, LPARAM port) {static int count1=0,count2=0,count3=0;static char c1,c2;static int flag;CString strCheck="";if(port==2) //COM2接收到数据{CString strtemp=(char)ch;if(strtemp=="Y"){m_nRXCounterCOM2++;CString strtemp;strtemp.Format("COM2: NO.%06d", m_nRXCounterCOM2);CDC* pDC=GetDC(); //准备数据显示pDC->TextOut(10,50,strtemp);//显示接收到的数据ReleaseDC(pDC);}}if(port==1) //COM1接收到数据{m_strRXDataCOM1 += (char)ch;switch(ch){case '$':m_chChecksum=0; //开始计算CheckSumflag=0;break;case '*':flag=2;c2=m_chChecksum & 0x0f; c1=((m_chChecksum >> 4) & 0x0f);if (c1 < 10) c1+= '0'; else c1 += 'A' - 10;if (c2 < 10) c2+= '0'; else c2 += 'A' - 10;break;case CR:break;case LF:m_strRXDataCOM1.Empty();break;default:if(flag>0){m_strRXhhCOM1 += ch; //得到收到的校验值hhif(flag==1){strCheck = strCheck+c1+c2; //计算得到的校验值hhif(strCheck!=m_strRXhhCOM1) //如果校验有错{m_strRXDataCOM1.Empty();m_nRXErrorCOM1++; //串口1错误帧数加1}else{m_nRXCounterCOM1++;if(m_strRXDataCOM1.Left(1)=="$") //接收数据的第一个字符是$吗?{char tbuf[6];char *temp=(char*)((LPCTSTR)m_strRXDataCOM1);tbuf[0]=temp[1]; tbuf[1]=temp[2];tbuf[2]=temp[3]; tbuf[3]=temp[4];tbuf[4]=0; //0表示字符串的结束,必要int data=atoi(tbuf);CString strDisplay1,strDisplay2;strDisplay1.Format("NO. %06d: The reseived data is %04d",m_nRXCounterCOM1,data); strDisplay2.Format("Error Counter=%04d.",m_nRXErrorCOM1);CDC* pDC=GetDC(); //准备数据显示//int nColor=pDC->SetTextColor(RGB(255,255,0));pDC->TextOut(10,10,strDisplay1);//显示接收到的数据pDC->TextOut(30,30,strDisplay2);//显示错误帧数//pDC->SetTextColor(nColor);ReleaseDC(pDC);}CString str1="Y";m_ComPort[0].WriteToPort((LPCTSTR)str1);//发送应答信号Y}m_strRXhhCOM1.Empty();}flag--;}elsem_chChecksum ^= ch;break;}}return 0; }。