串口上位机vc

合集下载

vc串口编程实例 -回复

vc串口编程实例 -回复

vc串口编程实例-回复VC串口编程实例,是指使用VC(Visual C++)进行串口编程的实例。

串口编程是指通过串口(在计算机中又称通信端口)与外部设备进行数据的收发和通信。

串口编程在很多应用中都非常常见,例如与嵌入式设备、传感器、单片机等进行通信。

本文将以串口编程为主题,详细介绍如何在VC中进行串口编程的步骤和相关实例。

第一步,准备工作。

在进行串口编程之前,需要准备好一些必要的工作和工具。

首先,我们需要一台计算机和一个可用的串口接口。

然后,我们需要安装一个适合的集成开发环境(IDE)。

在本例中,我们选择使用VC进行编程。

确保已经安装好VC及其相关的开发工具和库。

第二步,创建工程。

在VC中创建一个新的工程。

在创建工程的界面中,选择“Windows桌面应用程序”作为项目类型。

输入一个项目名称,选择工作空间的目录。

点击“确定”按钮创建工程。

第三步,设置串口参数。

在VC中进行串口编程,首先需要设置串口的参数,包括波特率、数据位、停止位和校验位等。

通过设置这些参数,我们可以控制串口的通信速度和数据的可靠性。

在VC的代码中使用DCB 结构体来设置这些参数。

下面是一个示例代码段:c++DCB dcbSerialParams = { 0 };dcbSerialParams.DCBlength = sizeof(dcbSerialParams); GetCommState(hSerial, &dcbSerialParams); 获取串口配置参数dcbSerialParams.BaudRate = 9600; 设置波特率dcbSerialParams.ByteSize = 8; 设置数据位dcbSerialParams.StopBits = ONESTOPBIT; 设置停止位dcbSerialParams.Parity = NOPARITY; 设置校验位SetCommState(hSerial, &dcbSerialParams); 设置串口配置参数在上述代码中,首先定义一个DCB结构体变量dcbSerialParams,用于保存串口参数。

基于C#的串口通信上位机和下位机源程序

基于C#的串口通信上位机和下位机源程序

基于C#的串口通信上位机和下位机源程序基于单片机串口通信的上位机和下位机实践串口是计算机上一种非常通用设备通信的协议(不要与通用串行总线Universal Serial Bus 或者USB混淆)。

大多数计算机包含两个基于RS232的串口。

串口同时也是仪器仪表设备通用的通信协议;很多GPIB兼容的设备也带有RS-232口。

同时,串口通信协议也可以用于获取远程采集设备的数据。

串口通信的概念非常简单,串口按位(bit)发送和接收字节。

尽管比按字节(byte)的并行通信慢,但是串口可以在使用一根线发送数据的同时用另一根线接收数据。

它很简单并且能够实现远距离通信。

比如IEEE488定义并行通行状态时,规定设备线总常不得超过20米,并且任意两个设备间的长度不得超过2米;而对于串口而言,长度可达1200米。

首先亮出C#的源程序吧。

主要界面:只是作为简单的运用,可以扩展的。

源代码:using System;using System.Collections.Generic;using System.ponentModel;using System.Data;using System.Drawing;using System.Text;using System.Windows.Forms;using System.IO.Ports;using System.Timers;namespace 单片机功能控制{public partial class Form1 : Form{public Form1(){Initializeponent();}SerialPort sp = new SerialPort();private void button1_Click(object sender, EventArgs e) {String str1 = boBox1.Text;//串口号String str2 = boBox2.Text;//波特率String str3 = boBox3.Text;//校验位String str4 = boBox5.Text;//停止位String str5 = boBox4.Text;//数据位Int32 int2 = Convert.ToInt32(str2);//将字符串转为整型Int32 int5 = Convert.ToInt32(str5);//将字符串转为整型groupBox3.Enabled = true;//LED控制界面变可选try{if (button1.Text == "打开串口"){if (str1 == null){MessageBox.Show("请先选择串口!", "Error"); return;}sp.Close();sp = new SerialPort();sp.PortName = boBox1.Text;//串口编号sp.BaudRate = int2;//波特率switch (str4)//停止位{case "1":sp.StopBits = StopBits.One;break;case "1.5":sp.StopBits = StopBits.OnePointFive;break;case "2":sp.StopBits = StopBits.Two;break;default:MessageBox.Show("Error:参数不正确", "Error"); break;}switch (str3){case "NONE":sp.Parity = Parity.None; break;case "ODD":sp.Parity = Parity.Odd; break;case "EVEN":sp.Parity = Parity.Even; break;default:MessageBox.Show("Error:参数不正确", "Error"); break;}sp.DataBits = int5;//数据位sp.Parity = Parity.Even;//设置串口属性sp.Open();//打开串口button1.Text = "关闭串口";textBox1.Text = Convert.T oString(sp.PortName) + "已开启!"; }else{sp.Close();button1.Text = "打开串口";groupBox3.Enabled = false;//LED控制界面变灰色textBox1.Text = Convert.T oString(sp.PortName) + "已关闭!"; }}catch (Exception er){MessageBox.Show("Error:" + er.Message, "Error"); return;}}private void Form1_Load(object sender, EventArgs e){//初始化textBox1.Text = "欢迎使用简易的串口助手!";groupBox3.Enabled = false;//LED控制界面变灰色groupBox6.Enabled = false;groupBox7.Enabled = false;groupBox8.Enabled = false;button3.Enabled = false;button6.Enabled = false;timer1.Start();try{foreach (string in System.IO.Ports.SerialPort.GetPortNames()) //自动获取串行口名称this.boBox1.Items.Add();//默认设置boBox1.SelectedIndex = 0;//选择第一个口boBox2.SelectedIndex = 4;//波特率4800boBox3.SelectedIndex = 0;//校验位NONEboBox4.SelectedIndex = 0;//停止位为1boBox5.SelectedIndex = 0;//数据位为8}catch{MessageBox.Show("找不到通讯端口!", "串口调试助手");}}private void timer1_Tick(object sender, EventArgs e){label6.Text = DateTime.Now.T oString();}private void button2_Click(object sender, EventArgs e){try {if (button2.Text == "开启"){groupBox6.Enabled = true;radioButton1.Checked = false;radioButton2.Checked = false;radioButton3.Checked = false;radioButton4.Checked = false;checkBox1.Checked = false;checkBox2.Checked = false;checkBox3.Checked = false;checkBox5.Checked = false;checkBox6.Checked = false;checkBox7.Checked = false;checkBox8.Checked = false;button3.Enabled = true;textBox2.Text = String.Empty;button2.Text = "关闭";}else{groupBox6.Enabled = false;button3.Enabled = false;button2.Text = "开启";textBox2.Text = String.Empty;}}catch (Exception er){MessageBox.Show("Error:" + er.Message, "Error"); return;}}private void button3_Click(object sender, EventArgs e) {groupBox6.Enabled = true;label7.Text = "已发送";if (textBox2.Text == "")MessageBox.Show("发送失败,请选择发送的数据!");elsesp.WriteLine(textBox2.Text);//往串口写数据}private void checkBox1_CheckedChanged(object sender, EventArgs e){try {if (checkBox1.Checked){checkBox1.Checked = true;checkBox2.Checked = false;checkBox3.Checked = false;checkBox5.Checked = false;checkBox6.Checked = false;checkBox7.Checked = false;checkBox8.Checked = false;label7.Text = "准备发送";textBox2.Text = "1";}}catch (Exception er){MessageBox.Show("Error:" + er.Message, "Error");return;}}private void checkBox2_CheckedChanged(object sender, EventArgs e) {try {if (checkBox2.Checked){checkBox1.Checked = false;checkBox2.Checked = true;checkBox3.Checked = false;checkBox4.Checked = false;checkBox5.Checked = false;checkBox6.Checked = false;checkBox7.Checked = false;checkBox8.Checked = false;label7.Text = "准备发送";textBox2.Text = "2";radioButton1.Checked = false;radioButton2.Checked = false;radioButton3.Checked = false;radioButton4.Checked = false;}}catch (Exception er){MessageBox.Show("Error:" + er.Message, "Error");return;}}private void checkBox3_CheckedChanged(object sender, EventArgs e) {try{if (checkBox3.Checked){checkBox1.Checked = false;checkBox3.Checked = true;checkBox4.Checked = false;checkBox5.Checked = false;checkBox6.Checked = false;checkBox7.Checked = false;checkBox8.Checked = false;radioButton1.Checked = false;radioButton2.Checked = false;radioButton3.Checked = false;radioButton4.Checked = false;label7.Text = "准备发送";textBox2.Text = "3";}}catch (Exception er){MessageBox.Show("Error:" + er.Message, "Error");return;}}private void checkBox4_CheckedChanged(object sender, EventArgs e) {try{if (checkBox4.Checked){checkBox1.Checked = false;checkBox2.Checked = false;checkBox3.Checked = false;checkBox5.Checked = false;checkBox6.Checked = false;checkBox7.Checked = false;checkBox8.Checked = false;radioButton1.Checked = false;radioButton2.Checked = false;radioButton3.Checked = false;radioButton4.Checked = false;label7.Text = "准备发送";textBox2.Text = "4";}}catch (Exception er){MessageBox.Show("Error:" + er.Message, "Error");return;}}private void checkBox5_CheckedChanged(object sender, EventArgs e) {try{if (checkBox5.Checked){checkBox1.Checked = false;checkBox2.Checked = false;checkBox3.Checked = false;checkBox4.Checked = false;checkBox5.Checked = true;checkBox7.Checked = false;checkBox8.Checked = false;radioButton1.Checked = false;radioButton2.Checked = false;radioButton3.Checked = false;radioButton4.Checked = false;label7.Text = "准备发送";textBox2.Text = "5";}}catch (Exception er){MessageBox.Show("Error:" + er.Message, "Error");return;}}private void checkBox6_CheckedChanged(object sender, EventArgs e){try{if (checkBox6.Checked){checkBox1.Checked = false;checkBox2.Checked = false;checkBox3.Checked = false;checkBox4.Checked = false;checkBox5.Checked = false;checkBox6.Checked = true;checkBox8.Checked = false;radioButton1.Checked = false;radioButton2.Checked = false;radioButton3.Checked = false;radioButton4.Checked = false;label7.Text = "准备发送";textBox2.Text = "6";}}catch (Exception er){MessageBox.Show("Error:" + er.Message, "Error");return;}}private void checkBox7_CheckedChanged(object sender, EventArgs e){try{if (checkBox7.Checked){checkBox1.Checked = false;checkBox2.Checked = false;checkBox3.Checked = false;checkBox4.Checked = false;checkBox5.Checked = false;checkBox6.Checked = false;checkBox7.Checked = true;radioButton1.Checked = false;radioButton2.Checked = false;radioButton3.Checked = false;radioButton4.Checked = false;label7.Text = "准备发送";textBox2.Text = "7";}}catch (Exception er){MessageBox.Show("Error:" + er.Message, "Error");return;}}private void checkBox8_CheckedChanged(object sender, EventArgs e) {try{if (checkBox8.Checked){checkBox1.Checked = false;checkBox2.Checked = false;checkBox3.Checked = false;checkBox4.Checked = false;checkBox5.Checked = false;checkBox6.Checked = false;checkBox7.Checked = false;checkBox8.Checked = true;radioButton1.Checked = false;radioButton2.Checked = false;radioButton3.Checked = false;radioButton4.Checked = false;label7.Text = "准备发送";textBox2.Text = "8";}}catch (Exception er){MessageBox.Show("Error:" + er.Message, "Error"); return;}}private void button5_Click(object sender, EventArgs e) { try{if (button5.Text == "开启"){radioButton1.Checked = false;radioButton2.Checked = false;radioButton3.Checked = false;radioButton4.Checked = false;checkBox1.Checked = false;checkBox2.Checked = false;checkBox3.Checked = false;checkBox4.Checked = false;checkBox5.Checked = false;checkBox6.Checked = false;checkBox7.Checked = false;checkBox8.Checked = false;groupBox7.Enabled = true;button6.Enabled = true;textBox2.Text = String.Empty;button5.Text = "关闭";}else{groupBox7.Enabled = false;button6.Enabled = false;button5.Text = "开启";textBox2.Text = String.Empty;}}catch (Exception er){MessageBox.Show("Error:" + er.Message, "Error");return;}}private void button6_Click(object sender, EventArgs e) {label7.Text = "已发送";if (textBox2.Text == "")MessageBox.Show("发送失败。

VC编程实现串口通信软件

VC编程实现串口通信软件

一、VC编程实现串口通信软件首先,我们来大概的回忆一下单片机的串口通信。

8051单片机的串行接口由数据缓冲寄存器SBUF、移位寄存器、串行控制寄存器SCON组成。

8051单片机的串行接口是一个可编程的全双工通信接口,通过软件编程可以作为通用异步接收和发送器使用,也可作为同步移位寄存器,还可实现多机通信。

其帖格式有8位、10位和11位,通过T1或T2设置各种波特率。

1.1 串行口工作原理在发送和接收数据前,先对串行口进行初始化设置,要明确串行口的工作方式、波特率等。

1.发送数据发送数据,由累加器A送入发送缓冲寄存器SBUF,在发送控制器控制下组成帧结构,并自动以串行方式从TXD输出,每发送完一帧TI置位,可以通过中断方式或查询方式来了解数据的发送情况。

值得注意的是TI只能用软件复位。

2.接收数据单片机每接收完一帧数据,RI置位,通过中断或查询方式来了解数据的接收情况,然后用MOV A,S BUF指令,将接收缓冲寄存器(SBUF)的值送累加器A。

RI与TI一样,也只能用软件复位。

1.2串行口工作方式8051单片机通过编程可选择4种串行通信工作方式。

1.方式0在方式0下,串行口用作同步移位寄存器,以8位数据为1帧,先发送或接收最低位,每个机器周期发送或接收1位,其波特率为fosc/12。

串行数据由RXD端输入或输出,同步移位脉冲由TXD端送出。

方式0数据发送与接收是无起始位和停止位,先发送或接收最低位,数据格式为:—D0 D1 D2 D3 D4 D5 D6 D72.方式1在方式1下,串行口为10位通用异步接口,数据格式为:——0 D0 D1 D2 D3 D4 D5 D6 D7 1 ——发送数据:当执行MOV SBUF,A指令,CPU将1字节的数据写入发送缓冲寄存器SBUF,数据从引脚TXD端输出,当发送完1帧数据后,TI标志置1,可用中断或查询方式来了解数据发送情况,TI只有通过软件复位。

接收数据:接收时,先使REN置1,使串行口处于允许接收状态,RI标志为0,串行口采样到RXD由1到0时,确认是起始位0,就开始接收1帧数据。

vc++上位机程序

vc++上位机程序

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 and Controls->双击Registered ActiveX Controls->选择Microsoft Communications Control, version 6.0->Insert,按默认值添加,你会发现多了个电话图标,这是增加后串口通信控件。

手把手教你VC上位机MFC利用串口控件发送接收数据

手把手教你VC上位机MFC利用串口控件发送接收数据

1.建立项目:打开VC++6.0,建立一个基于对话框的MFC应用程序SCommTest;2.在项目中插入MSComm控件选择Project菜单下Add To Project子菜单中的Components and Controls…选项,在弹出的对话框中双击Registered ActiveX Controls项(稍等一会,这个过程较慢),则所有注册过的ActiveX控件出现在列表框中。

选择Microsoft Communications Control, version 6.0,,单击Insert按钮将它插入到我们的Project中来,接受缺省的选项。

(如果你在控件列表中看不到Microsoft Communications Control, version 6.0,那可能是你在安装VC6时没有把ActiveX 一项选上,重新安装VC6,选上ActiveX就可以了),这时在ClassView视窗中就可以看到CMSComm类了,(注意:此类在ClassWizard中看不到,重构clw文件也一样),并且在控件工具栏Controls中出现了电话图标(如图1所示),现在要做的是用鼠标将此图标拖到对话框中,程序运行后,这个图标是看不到的。

3.利用ClassWizard定义CMSComm类控制对象打开ClassWizard->Member Viariables选项卡,选择CSCommTestDlg类,为IDC_MSCOMM1添加控制变量:m_ctrlComm,这时你可以看一看,在对话框头文件中自动加入了//{{AFX_INCLUDES() #i nclude "mscomm.h"//}}AFX_INCLUDES 。

4.在对话框中添加控件向主对话框中添加两个编辑框,一个用于接收显示数据ID为IDC_EDIT_RXDATA,另一个用于输入发送数据,ID为IDC_EDIT_TXDATA,再添加一个按钮,功能是按一次就把发送编辑框中的内容发送一次,将其ID设为IDC_BUTTON_MANUALSEND。

VC++创建上位机接收界面

VC++创建上位机接收界面

编程任务:编写一个基于对话框的应用程序,用MSComm控件控制串口,能在界面上接收从该串口发来的数据,并且能发送数据。

1.建立应用程序工程SCommTest打开VISUAL C++6.0,建立一个基于对话框的MFC应用程序:SCommTest。

然后在主对话框中添加控件,最后效果如图1.5.1所示。

其中的电话状图标是MSComm控件,参照第2步的方法将其添加到对话框中。

控件及其属性设置情况控件控件ID Caption 变量及变量类型静态文本IDC_STA TIC 接收电压显示静态文本IDC_STA TIC V编辑框IDC_EDIT_RXDA TA m_strEditRXData V alue CString MSComm控件IDC_MSCOMM1 m_ctrlComrn control2.在当前工程中添加MSComm控件单击菜单Add To Project-> Components and Controls…,就打开了如图1.5.2所示的添加组(控)件对话框。

再在其中双击“Reg istered ActiveX Controls"项(这时要稍等一会,这个过程较慢),就出现了如图1.5.3所示的控件选择(Component and Controls Gallery)对话框。

在该对话框中选择“Microsoft Communications Control,versio n 6.0”控件。

再单击“Insert”按钮,提示“Insert this component?”,确认后,可以看到加入CMSComm 类的确认(Confirm Class)对话框,提示加入到当前工程中的CMSComm类头文件为MSComm.h,实现文件为MSXommcpp。

点击"OK"按钮,(Confirm Class)对话框关闭。

再点击“Close”关闭(Component and Controls Gallery)对话框。

智能车调试--串口上位机程序的编制[转]

智能车调试--串口上位机程序的编制[转]

我们飞思卡尔智能车的比赛已经接近尾声了,23号就要去上海决赛了呵。

论文基本完成,Duuboo已经排版结束,排出来还真挺长的。

整个过程都挺累的,持续的时间还这么长,最累的恐怕只有惠哥了,这些比赛完再说吧。

这里介绍下在Donald写的一个串口调试程序,主要是方便我们查看运行起来的小车的内部参数。

程序的作用是接收来自Freescale MC9SDG128单片机发送来的数据,并显示出来。

分为两部分。

一部分是普通的数据,ASCII数据,另一部分是实时的图像,也是以ASCII方式传输。

程序可通过“模式”按钮设置工作在这两种模式。

当进入CCD模式时,通过“连接”按钮触发DG128单片机发送图像信息,这时“连接”按钮变为“断开”,可通过其触发DG128单片机停止发送,降低单片机内部资源消耗。

程序中串口部分的编程参考的是《Visual C++串口通信技术与工程实践》,李现勇编著。

书中对串口的编程讲得很不错,除了C的,还有VB的。

详细请参考该书。

这里介绍本程序的一部分程序代码。

一、添加串口控件本程序是在VC6下MFC实现,所以添加一个串口控件,方法是选择Project菜单下Add To Project子菜单中的 Components and Controls选项,在弹出的对话框中进入Registered ActiveX Controls目录,选择Microsoft Communication s Control, version 6.0,,Insert到Project中就行了。

然后可在窗体中添加串口控件,接着Ctrl+W到ClassWizard中为该控件添加一个对应的变量就行。

二、串口工作方式的改变串口的工作方式有很多种,比如串口的选择、波特率、校验位、数据位和停止位等。

这些的设置可以通过组合框实现,实现方法基本一样,Donald就以波特率说明下。

之前已经为波特率组合框对象IDC_COMBO_BAUD添加对应变量m_cboBaud。

VC环境下PLC与上位机的实时通信

VC环境下PLC与上位机的实时通信

VC环境下PLC与上位机的实时通信1 前言可编程控制器(plc)是集计算机技术、自动控制技术、通信技术为一体的新型自动控制装置。

由于体积小、可靠性高以及组态灵活等优点,plc在工业控制领域得到了广泛的应用。

在plc组成的自动测量和控制系统中,一般采用主从式控制结构,由plc向计算机发送数据,计算机处理数据后根据具体情况向plc发出相应的指令,控制plc的运行。

plc作为下位机,完成数据采集、状态判别、输出控制等任务,上位机(微型计算机、工业控制机)完成采集数据信息的存储、分析处理、状态显示以及打印输出等任务,以实现对系统的实时监控。

目前市场上常用的人机界面或监控组态软件价格昂贵且由国外公司垄断, 对于小型企业的单机系统来说,许多功能并不实用,同时组态软件的本身也还存在不足之处,不能满足一些特殊要求。

因此,目前仍然需要技术人员根据实际情况开发小型经济适用的软件。

笔者针对比较简单的控制系统,利用vc++6.0设计了一个通信程序,实现了windows环境下上位计算机对多台pl c的灵活监控。

2 通信类型日本三菱公司是国际著名的工厂自动化设备制造商,其工业可编程控制器在国内市场占有相当大的份额。

本项目选用三菱fx2n-48mr型plc,fx系列plc支持以下5种通信类型:(1) plc的n:n通信方式;(2) plc双机并联通信方式;(3) plc与计算机专有协议通信方式;(4) plc与计算机无协议通信方式(使用rs指令或fx2n-232if 特殊功能块);(5)自由端口设计方式(需要特殊通信模块,使用较少)。

各种通信类型的具体特性列于表1。

本系统采用专有协议通信方式,以pc机为主站,通过fx-485pc-if及fx2n-485bd与多台pl c从站连接(最多16台),每台plc被赋予唯一的站号用以标志身份,上位机通过rs-485通信总线对plc进行控制。

3 通信协议fx2n系列plc通信采用异步格式,较常用的数据帧由1位起始位、7位数据位、1位停止位及1位校验位组成,波特率为9600b ps。

上位机串口通信编程

上位机串口通信编程

上位机串⼝通信编程摘要本⽂主要描述了利⽤PC机与AT89C51单⽚机之间的通信程序设计实现温度显⽰。

并详述了在VC6.0环境下,上位机利⽤MSCOMM通信控件与单⽚机之间串⼝通信实现温度显⽰。

由单⽚机采集⼀个温度信号,将采集到的温度信号传送给PC机显⽰,PC机⽤VC6.0编写程序,单⽚机程序⽤C语⾔编写,最后⽤PROTUES软件进⾏仿真实现温度显⽰。

关键词:单⽚机MSCOMM控件VC6.0 AT89C51 温度显⽰⽬录摘要1 引⾔ (1)2 结构设计与⽅案选择 (2)2.1设计任务 (2)2.1.1单⽚机的选择 (2)2.1.2电平转换 (2)2.1.1单⽚机的选择 (2)2.1.3单⽚机与pc机通信原理 (2)2.2软件⽅案选择 (2)2.2.1 上位机编程⽅案选择 (3)2.2.2 单⽚机编程⽅案选择 (3)2.3 总体⽅案选择 (2)3 硬件设计 (8)3.1单⽚机主要特性 (5)3.2 MAX232电平芯⽚介绍10 (10)3.3 硬件电路设计图 (11)3.3.1 PC机与单⽚机通信接⼝电路设计框图 (11)3.3.2整体设计原理图 (11)4软件设计 (12)4.1上位机程序设计 (12)4.2下位机程序设计 (13)5 软硬件调试部分 (21)5.1 PROTEUS软件仿真 (21)5.1.1 Protues简介 (21)5.1.2 Protues仿真电路图 (22)5.2 VC软件仿真 (21)结束语 (27)致谢 (28)参考⽂献 (29)1引⾔随着⼈们⽣活⽔平的不断提⾼,单⽚机控制⽆疑是⼈们追求的⽬标之⼀,它所给⼈带来的⽅便也是不可否定的,要为现代⼈⼯作、科研、⽣活、提供更好的更⽅便的设施就需要从单⽚机技术⼊⼿,⼀切向着数字化控制,智能化控制⽅向发展。

现代化集中管理需要对现场数据进⾏统计、分析、制表、打印、绘图、报警等,同时,⼜要求对现场装置进⾏实时控制,完成各种规定操作,达到集中管理的⽬的。

VC编写串口调试助手含VC工程源文件

VC编写串口调试助手含VC工程源文件

纯业余者用V C(M F C)编写串口调试助手序毕业到现在,转眼就做射频开发10年了,一直从事直放站、干放等通信边缘行业,从低噪放、锁相源、选频、功放到整机,射频就那么点东西,而且越来越集成化,软件无线电是必然趋势。

做射频从业面会越来越窄,我知道所有人都会说,当你成为专家的时候,一切就都不是问题,可有几个真正的专家,再者说,射频需要经验的积累,只有实际项目做的越多越广,经验也就积累得越多,并不是一朝一夕能达到的。

前不久突然觉得,我的射频模块控制要是也是自己来编程控制多好啊!那就得学单片机编程,学习上位机编程了,可我都不会啊,要不就先来整整上位机,windows方面的。

大学唯一学的编程语言是C语言,可根本不能理解用C做什么,还都还给老师10多年了,这怎么办?从BASIC,C/C++,JAVA,PASCAL搜索了一圈,还是选C++吧,毕竟是C语言发展而来,用VC环境,身边有可以请教的人。

在网上转悠了很久,发现《windows程序设计》是必看,《MFCWindows程序设计》是学MFC最经典的书籍。

OMG,这些书啊,都是上千页的,白天都在上班,哪有时间看哦,只有先下载下来作为参考资料了。

扯远了啊。

这也不行那也不行,怎么办呢?干脆硬着头皮上吧,找几个实例照搬,再修修改改加深理解吧。

第一个目标,自己编写个串口调试助手,掌握串口通信编程,这样上位机的编写就有希望了。

好了,目标定下来了。

网上下载了个串口调试助手,确定基本功能:1.自动寻找串口,并自动添加到下拉框中共选择;2.有波特率、数据位、停止位、校验位的选择设置;3.串口打开控制按钮;4.发送、清除按钮;5.接收是自动实现的;6.有定时自动发送功能;7.有传送文件功能;8.有状态栏显示,指示串口状态,设置参数和发送接收显示。

下面就一步步实现,本人纯业余,只是记录下来这个学习过程,请勿拍砖。

?开发平台VisualC++6.0英文版,电脑是i7-2670Q四核8G内存1G独显的笔记本,装的win764位旗舰版,因此VC6兼容不是太好,有些小毛病,不过不影响编写。

VC控制串口

VC控制串口

打开VC++6.0,新建基于对话框的工程RS485Comm,在主对话框窗口IDD_RS485COMM_DIALOG 上添加两个按钮,ID分别为IDC_SEND和IDC_RECEIVE,标题分别为“发送”和“接收”;添加一个静态文本框IDC_DISP,用于显示串口接收到的内容。

在RS485CommDlg.cpp文件中添加全局变量: HANDLE hCom; //全局变量,串口句柄在RS485CommDlg.cpp文件中的OnInitDialog()函数添加如下代码:// TODO: Add extra initialization here hCom=CreateFile("COM1",//COM1口 GENERIC_READ|GENERIC_WRITE, //允许读和写 0, //独占方式NULL, OPEN_EXISTING, //打开而不是创建0, //同步方式NULL); if(hCom==(HANDLE)-1) { AfxMessageBox("打开COM失败!"); return FALSE; } SetupComm(hCom,100,100); //输入缓冲区和输出缓冲区的大小都是1024 COMMTIMEOUTS TimeOuts; //设定读超时TimeOuts.ReadIntervalTimeout=MAXDWORD; TimeOuts.ReadTotalTimeoutMultiplier=0; TimeOuts.ReadTotalTimeoutConstant=0; //在读一次输入缓冲区的内容后读操作就立即返回, //而不管是否读入了要求的字符。

//设定写超时TimeOuts.WriteTotalTimeoutMultiplier=100; TimeOuts.WriteTotalTimeoutConstant=500; SetCommTimeouts(hCom,&TimeOuts); //设置超时DCB dcb; GetCommState(hCom,&dcb); dcb.BaudRate=9600; //波特率为9600 dcb.ByteSize=8; //每个字节有8位dcb.Parity=NOPARITY; //无奇偶校验位dcb.StopBits=TWOSTOPBITS; //两个停止位SetCommState(hCom,&dcb); PurgeComm(hCom,PURGE_TXCLEAR|PURGE_RXCLEAR); 分别双击IDC_SEND按钮和IDC_RECEIVE 按钮,添加两个按钮的响应函数: void CRS485CommDlg::OnSend() { // TODO: Add your control notification handler code here // 在此需要简单介绍百特公司XMA5000的通讯协议: //该仪表RS485通讯采用主机广播方式通讯。

VC实现串口通信项目源码

VC实现串口通信项目源码

VC实现串口通信项目源码以下是一个简单的串口通信项目的VC实现源码,包括了串口初始化、发送数据、接收数据等基本功能。

```#include <Windows.h>#include <stdio.h>#define BUFFER_SIZE 1024HANDLE hSerial;//初始化串口参数BOOL InitSerialPort//打开串口hSerial = CreateFile("\\\\.\\COM1", GENERIC_READ ,GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);if (hSerial == INVALID_HANDLE_VALUE)printf("Failed to open serial port\n");return FALSE;}//配置串口参数DCB dcbSerialParams = { 0 };dcbSerialParams.DCBlength = sizeof(dcbSerialParams); printf("Failed to get serial port state\n"); CloseHandle(hSerial);return FALSE;}dcbSerialParams.BaudRate = CBR_9600; // 波特率为9600 dcbSerialParams.ByteSize = 8; // 8位数据位dcbSerialParams.Parity = NOPARITY; // 无奇偶校验dcbSerialParams.StopBits = ONESTOPBIT;// 1位停止位printf("Failed to set serial port state\n"); CloseHandle(hSerial);return FALSE;}//设置超时操作CloseHandle(hSerial);return FALSE;}return TRUE;//发送数据BOOL SendData(const char* data)DWORD bytesWritten;if (!WriteFile(hSerial, data, strlen(data), &bytesWritten, NULL))printf("Failed to send data\n");CloseHandle(hSerial);return FALSE;}return TRUE;//接收数据BOOL ReceiveData(char* buffer, DWORD size)DWORD bytesRead;if (!ReadFile(hSerial, buffer, size, &bytesRead, NULL))printf("Failed to receive data\n");CloseHandle(hSerial);return FALSE;}return TRUE;if (!InitSerialPort()return 1;}char sendBuffer[BUFFER_SIZE];char receiveBuffer[BUFFER_SIZE];//发送数据printf("Enter data to send: ");gets_s(sendBuffer, BUFFER_SIZE);if (!SendData(sendBuffer))return 1;}//接收数据printf("Receiving data...\n");if (!ReceiveData(receiveBuffer, BUFFER_SIZE)) return 1;}printf("Received data: %s\n", receiveBuffer); CloseHandle(hSerial);```这个项目使用了Windows的串口通信API函数来实现串口的初始化、发送数据和接收数据操作。

VC上位机For51

VC上位机For51

VC上位机For51济南职业学院电子工程系朱志强2010年8月17日概述:此文章作为学习上位机的复习资料和总结性资料。

是《VC++MSComm串口接收程序制做》的后继制作,在前文的基础上添加了部分新的功能,可以实现接收十六进制单个字符。

但是还是没有完成上位机对下位机的发送。

对于图片的应用和静态文本的更换,这此也没有解决。

第一步制作上位机程序,参考《VC++MSComm串口接收程序制做》。

步骤如下:新建一个基于对话框的程序,全部选择默认选项。

得到如下的对话框。

图1 新创建的对话框我们去掉上面的所有的控件,向工程中添加入MSCOMM控件,添加变量为m_ctrlComm。

再添加一个编辑框,作为接收框,使用类向导添加变量为m_strRXData。

同时,我们也给对话框添加上最小化按钮(方法:右键对话框,属性,样式里勾选上最小化按钮)。

双击MSCOMM控件,添加入如下的代码:void CFor51Dlg::OnOnCommMscomm1(){// TODO: Add your control notification handler code hereV ARIANT variant_inp;COleSafeArray safearray_inp;LONG len,k;BYTE rxdata[2048]; //设置BYTE数组An 8-bit integerthat is not signed.CString strtemp;if(m_ctrlComm.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符{////////以下你可以根据自己的通信协议加入处理代码variant_inp=m_ctrlComm.GetInput(); //读缓冲区safearray_inp=variant_inp; //V ARIANT型变量转换为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); //字符型strtemp.Format("%02X",bt); //将字符送入临时变量strtemp存放strtemp=" 按下的按钮编号是"+strtemp+"\r\n";m_strRXData+=strtemp; //加入接收编辑框对应字符串}}UpdateData(FALSE); //更新编辑框内容}编译可以通过。

c上位机串口通信助手源代码详解

c上位机串口通信助手源代码详解

c#上位机串口通信助手源代码实例详解一、功能1软件打开时,自动检测有效COM端口2 软件打开时,自动复原到上次关闭时的状态3 不必关闭串口,即可直接进行更改初始化设置内容(串口号、波特率、数据位、停止位、校验位),可按更改后的信息自动将串口重新打开4 可统计接收字节和发送字节的个数5 接收数据可按16进制数据和非16进制数据进行整体转换6 可将接收到数据进行保存7 可设置自动发送,发送时间可进行实时更改8可按字符串、16进制字节、文件方式进行发送,字符串和16进制字节可分别进行存储,内容互不干扰9 按16进制发送时,可自动校验格式,不会输错10 可清空发送或接收区域的数据二、使用工具Visual Studio2015三、程序详解1 界面创建图1用winform创建如图1所示界面,控件名字分别为:端口号:cbxCOMPort波特率:cbxBaudRate数据位:cbxDataBits停止位:cbxStopBits校验位:label5打开串口按钮:btnOpenCom发送(byte):tbSendCount接收(byte):tbReceivedCount清空计数按钮:btnClearCount按16进制显示:cb16Display接收区清空内容按钮:btnClearReceived保存数据按钮:btnSaveFile接收数据框:tbReceivedData发送数据框:tbSendData自动发送:cbAutomaticSend间隔时间:tbSpaceTime按16进制发送:cb16Send发送区清空内容按钮:btnClearSend读入文件按钮:btnReadFile发送按钮:btnSend2 创建一个方法类按Ctrl+shift+A快捷键创建一个类,名字叫Methods,代码为:using System;using System.Collections;using System.Collections.Generic;using System.IO.Ports;using System.Linq;using System.Text;using System.Threading.Tasks;namespace串口助手sdd{class Methods{//获取有效的COM口public static string[] ActivePorts(){ArrayList activePorts = new ArrayList();foreach (string pname in SerialPort.GetPortNames()){activePorts.Add(Convert.ToInt32(pname.Substring(3))); }activePorts.Sort();string[] mystr = new string[activePorts.Count];int i = 0;foreach (int num in activePorts){mystr[i++] = "COM" + num.ToString();}return mystr;}//16进制字符串转换为byte字符数组public static Byte[] _16strToHex(string strValues){string[] hexValuesSplit = strValues.Split(' ');Byte[] hexValues = new Byte[hexValuesSplit.Length];Console.WriteLine(hexValuesSplit.Length);for (int i = 0; i < hexValuesSplit.Length; i++){hexValues[i] = Convert.ToByte(hexValuesSplit[i], 16);}return hexValues;}//byte数组以16进制形式转字符串public static string ByteTo16Str(byte[] bytes){string recData = null;//创建接收数据的字符串foreach (byte outByte in bytes)//将字节数组以16进制形式遍历到一个字符串内 {recData += outByte.ToString("X2") + " ";}return recData;}//16进制字符串转换字符串public static string _16strToStr(string _16str){string outStr = null;byte[] streamByte = _16strToHex(_16str);outStr = Encoding.Default.GetString(streamByte);return outStr;}}}2 Form1.cs的代码为:using System;using System.Collections.Generic;using ponentModel;using System.Data;using System.Drawing;using System.IO.Ports;using System.Linq;using System.Text;using System.Text.RegularExpressions;using System.Threading.Tasks;using System.Windows.Forms;using System.IO;using System.Collections;namespace串口助手sdd{public partial class Form1 : Form{//声明变量SerialPort sp = new SerialPort();bool isSetProperty = false;//串口属性设置标志位private enum PortState//声明接口显示状态,枚举型打开,关闭}string path = AppDomain.CurrentDomain.BaseDirectory + "confing.ini";//声明配置文件路径string tbSendDataStr = "";//发送窗口字符串存储string tbSendData16 = "";//发送窗口16进制存储List<byte> receivedDatas = new List<byte>();//接收数据泛型数组//接收串口数据private void sp_DataReceived(object sender, SerialDataReceivedEventArgs e){byte[] ReceivedData = new byte[sp.BytesToRead];//创建接收字节数组sp.Read(ReceivedData, 0, ReceivedData.Length);//读取所接收到的数据receivedDatas.AddRange(ReceivedData);tbReceivedCount.Text = (Convert.ToInt32(tbReceivedCount.Text) + ReceivedData.Length).ToString();if (cb16Display.Checked)tbReceivedData.Text = Methods.ByteTo16Str(receivedDatas.ToArray());elsetbReceivedData.Text =Encoding.Default.GetString(receivedDatas.ToArray());sp.DiscardInBuffer();//丢弃接收缓冲区数据}//发送串口数据private void DataSend(){try{if (cb16Send.Checked){byte[] hexBytes = Methods._16strToHex(tbSendData16);sp.Write(hexBytes, 0, hexBytes.Length);tbSendCount.Text = (Convert.ToInt32(tbSendCount.Text) + hexBytes.Length).ToString();}else{sp.WriteLine(tbSendDataStr);tbSendCount.Text = (Convert.ToInt32(tbSendCount.Text) + tbSendDataStr.Length).ToString();}}catch (Exception ex){MessageBox.Show(ex.Message.ToString());return;}//设置串口属性private void SetPortProperty(){sp.PortName = cbxCOMPort.Text.Trim();//设置串口名sp.BaudRate = Convert.ToInt32(cbxBaudRate.Text.Trim());//设置波特率switch (cbxStopBits.Text.Trim())//设置停止位{case"1": sp.StopBits = StopBits.One; break;case"1.5": sp.StopBits = StopBits.OnePointFive; break;case"2": sp.StopBits = StopBits.Two; break;default: sp.StopBits = StopBits.None; break;}sp.DataBits = Convert.ToInt32(cbxDataBits.Text.Trim());//设置数据位switch (cbxParity.Text.Trim())//设置奇偶校验位{case"无": sp.Parity = Parity.None; break;case"奇校验": sp.Parity = Parity.Odd; break;case"偶校验": sp.Parity = Parity.Even; break;default: sp.Parity = Parity.None; break;}sp.ReadTimeout = 5000;//设置超时时间为5sControl.CheckForIllegalCrossThreadCalls = false;//这个类中我们不检查跨线程的调用是否合法(因为.net 2.0以后加强了安全机制,,不允许在winform中直接跨线程访问控件的属性)//定义DataReceived事件的委托,当串口收到数据后出发事件sp.DataReceived += new SerialDataReceivedEventHandler(sp_DataReceived);}//设置端口显示状态private void DisplayPortState(PortState portState){toolStripStatusLabel1.Text = cbxCOMPort.Text + "端口处于" + portState + "状态 " + cbxBaudRate.Text + " " + cbxDataBits.Text + " " + cbxStopBits.Text + " " + cbxParity.Text;}//重新打开串口private void AgainOpenPort(){if (sp.IsOpen){try{sp.Close();SetPortProperty();isSetProperty = true;sp.Open();}catch (Exception){isSetProperty = false;btnOpenCom.Text = "打开串口";DisplayPortState(PortState.关闭);MessageBox.Show("串口无效或已被占用!", "错误提示");return;}DisplayPortState(PortState.打开);}else{DisplayPortState(PortState.关闭);}}public Form1(){InitializeComponent();}//软件启动时加载事件private void Form1_Load(object sender, EventArgs e){#region加载配置文件Hashtable ht = new Hashtable();if ((path)){try{string myline = "";string[] str = new string[2];using (StreamReader sr = new StreamReader(path)){myline = sr.ReadLine();while (myline != null){str = myline.Split('=');ht.Add(str[0], str[1]);myline = sr.ReadLine();}}}catch(Exception ex){MessageBox.Show(ex.Message.ToString());}}#endregion#region设置窗口为固定大小且不可最大化this.MaximumSize = this.Size;this.MinimumSize = this.Size;this.MaximizeBox = false;#endregion#region列出常用的波特率cbxBaudRate.Items.Add("1200");cbxBaudRate.Items.Add("2400");cbxBaudRate.Items.Add("4800");cbxBaudRate.Items.Add("9600");cbxBaudRate.Items.Add("19200");cbxBaudRate.Items.Add("38400");cbxBaudRate.Items.Add("43000");cbxBaudRate.Items.Add("56000");cbxBaudRate.Items.Add("57600");cbxBaudRate.Items.Add("115200");if (ht.ContainsKey("cbxBaudRate"))cbxBaudRate.SelectedIndex =cbxBaudRate.Items.IndexOf(ht["cbxBaudRate"].ToString());elsecbxBaudRate.SelectedIndex = 3;cbxBaudRate.DropDownStyle = ComboBoxStyle.DropDownList; #endregion#region列出停止位cbxStopBits.Items.Add("1");cbxStopBits.Items.Add("1.5");cbxStopBits.Items.Add("2");if (ht.ContainsKey("cbxStopBits"))cbxStopBits.SelectedIndex =cbxStopBits.Items.IndexOf(ht["cbxStopBits"].ToString());elsecbxStopBits.SelectedIndex = 0;cbxStopBits.DropDownStyle = ComboBoxStyle.DropDownList; #endregion#region列出数据位cbxDataBits.Items.Add("8");cbxDataBits.Items.Add("7");cbxDataBits.Items.Add("6");cbxDataBits.Items.Add("5");if (ht.ContainsKey("cbxDataBits"))cbxDataBits.SelectedIndex =cbxDataBits.Items.IndexOf(ht["cbxDataBits"].ToString());elsecbxDataBits.SelectedIndex = 0;cbxDataBits.DropDownStyle = ComboBoxStyle.DropDownList; #endregion#region列出奇偶校验位cbxParity.Items.Add("无");cbxParity.Items.Add("奇校验");cbxParity.Items.Add("偶校验");if (ht.ContainsKey("cbxParity"))cbxParity.SelectedIndex =cbxParity.Items.IndexOf(ht["cbxParity"].ToString());elsecbxParity.SelectedIndex = 0;cbxParity.DropDownStyle = ComboBoxStyle.DropDownList;#endregion#region COM口重新加载cbxCOMPort.Items.Clear();//清除当前串口号中的所有串口名称 cbxCOMPort.Items.AddRange(Methods.ActivePorts());if (ht.ContainsKey("cbxCOMPort") &&cbxCOMPort.Items.Contains(ht["cbxCOMPort"].ToString()))cbxCOMPort.SelectedIndex =cbxCOMPort.Items.IndexOf(ht["cbxCOMPort"].ToString());elsecbxCOMPort.SelectedIndex = 0;cbxCOMPort.DropDownStyle = ComboBoxStyle.DropDownList; #endregion#region初始化计数器tbSendCount.Text = "0";tbSendCount.ReadOnly = true;tbReceivedCount.Text = "0";tbReceivedCount.ReadOnly = true;#endregion#region初始化当前时间toolStripStatusLabel3.Text = DateTime.Now.ToString();#endregion#region初始化串口状态toolStripStatusLabel1.ForeColor = Color.Blue;if (!isSetProperty)//串口未设置则设置串口属性{SetPortProperty();isSetProperty = true;}try{sp.Open();btnOpenCom.Text = "关闭串口";DisplayPortState(PortState.打开);}catch (Exception){//串口打开失败后,串口属性设置标志位设为falseisSetProperty = false;MessageBox.Show("串口无效或已被占用!", "错误提示"); }#endregion#region初始化间隔时间if (ht.ContainsKey("tbSpaceTime"))tbSpaceTime.Text = ht["tbSpaceTime"].ToString();elsetbSpaceTime.Text = "1000";#endregion#region初始化按16进制显示状态if (ht.ContainsKey("cb16Display") && ht["cb16Display"].ToString() == "True") cb16Display.Checked = true;elsecb16Display.Checked = false;#endregion#region初始化按16进制发送状态if (ht.ContainsKey("cb16Send") && ht["cb16Send"].ToString() == "True")cb16Send.Checked = true;elsecb16Send.Checked = false;#endregion#region初始化发送区文本if(ht.ContainsKey("tbSendData16") && ht.ContainsKey("tbSendDataStr")){tbSendData16 = ht["tbSendData16"].ToString();tbSendDataStr = ht["tbSendDataStr"].ToString();if (cb16Send.Checked)tbSendData.Text = ht["tbSendData16"].ToString();elsetbSendData.Text = ht["tbSendDataStr"].ToString();}#endregiontbSendData.Focus();}//显示当前时间private void timer1_Tick(object sender, EventArgs e){toolStripStatusLabel3.Text = DateTime.Now.ToString();}//点击打开串口按钮private void btnOpenCom_Click(object sender, EventArgs e){if (!sp.IsOpen)//串口没有打开时{if (!isSetProperty)//串口未设置则设置串口属性{SetPortProperty();isSetProperty = true;}try{sp.Open();btnOpenCom.Text = "关闭串口";DisplayPortState(PortState.打开);}catch (Exception){//串口打开失败后,串口属性设置标志位设为falseisSetProperty = false;MessageBox.Show("串口无效或已被占用!", "错误提示");}}else//串口已经打开{try{sp.Close();isSetProperty = false;btnOpenCom.Text = "打开串口";DisplayPortState(PortState.关闭);}catch (Exception){MessageBox.Show("关闭串口时发生错误", "错误提示");}}}//发送串口数据private void btnSend_Click(object sender, EventArgs e){if (tbSendData.Text.Trim() == "")//检测发送数据是否为空{MessageBox.Show("请输入要发送的数据!", "错误提示");return;}if (sp.IsOpen){DataSend();}else{MessageBox.Show("串口未打开!", "错误提示");}}//点击端口号选择下拉框按钮private void cbxCOMPort_SelectedIndexChanged(object sender, EventArgs e) {AgainOpenPort();}//点击波特率选择下拉框按钮private void cbxBaudRate_SelectedIndexChanged(object sender, EventArgs e) {AgainOpenPort();}//点击数据位选择下拉框按钮private void cbxDataBits_SelectedIndexChanged(object sender, EventArgs e) {AgainOpenPort();}//点击停止位选择下拉框按钮private void cbxStopBits_SelectedIndexChanged(object sender, EventArgs e) {AgainOpenPort();}//点击校验位选择下拉框按钮private void cbxParity_SelectedIndexChanged(object sender, EventArgs e){AgainOpenPort();}//点击数据接收区清空按钮private void btnClearReceived_Click(object sender, EventArgs e){receivedDatas.Clear();tbReceivedData.Text = "";}//点击是否按16进制显示接收数据private void cb16Display_CheckedChanged(object sender, EventArgs e){if (cb16Display.Checked)tbReceivedData.Text = Methods.ByteTo16Str(receivedDatas.ToArray());elsetbReceivedData.Text =Encoding.Default.GetString(receivedDatas.ToArray());}//点击是否按16进制发送数据private void cb16Send_CheckedChanged(object sender, EventArgs e){if (cb16Send.Checked){tbSendData.Text = tbSendData16;}else{tbSendData.Text = tbSendDataStr;}}//发送文本框键盘按键检测private void tbSendData_KeyPress(object sender, KeyPressEventArgs e){if (cb16Send.Checked){//正则匹配string pattern = "[0-9a-fA-F]|\b";//\b:退格键Match m = Regex.Match(e.KeyChar.ToString(), pattern);if (m.Success){if(e.KeyChar != '\b'){if (tbSendData.Text.Length % 3 == 2){tbSendData.Text += " ";tbSendData.SelectionStart = tbSendData.Text.Length;}e.KeyChar = Convert.ToChar(e.KeyChar.ToString().ToUpper()); }e.Handled = false;}else{e.Handled = true;}}else{e.Handled = false;}}//点击清空发送内容private void btnClearSend_Click(object sender, EventArgs e){tbSendData.Text = "";if (cb16Send.Checked)tbSendData16 = "";elsetbSendDataStr = "";}//点击清空计数器数据private void btnClearCount_Click(object sender, EventArgs e){tbReceivedCount.Text = "0";tbSendCount.Text = "0";}//点击是否设置自动发送private void cbAutomaticSend_CheckedChanged(object sender, EventArgs e){if (cbAutomaticSend.Checked){timer2.Enabled = true;timer2.Interval = Convert.ToInt32(tbSpaceTime.Text);}else{timer2.Enabled = false;}}//自动发送时间文本框键盘按键检测private void tbSpaceTime_KeyPress(object sender, KeyPressEventArgs e) {//正则匹配string pattern = "[0-9]|\b";Match m = Regex.Match(e.KeyChar.ToString(),pattern);if (m.Success){timer2.Interval = Convert.ToInt32(tbSpaceTime.Text);e.Handled = false;}else{e.Handled = true;}}//串口显示状态private void timer2_Tick(object sender, EventArgs e){if (sp.IsOpen){DataSend();}else{timer2.Enabled = false;cbAutomaticSend.Checked = false;MessageBox.Show("串口未打开!", "错误提示");return;}if (tbSendData.Text.Trim() == "")//检测发送数据是否为空{timer2.Enabled = false;cbAutomaticSend.Checked = false;MessageBox.Show("请输入要发送的数据!", "错误提示");return;}}//关闭窗口时出发的事件private void Form1_FormClosed(object sender, FormClosedEventArgs e) {try{using (StreamWriter sw = new StreamWriter(path, false)){sw.WriteLine("cbxCOMPort=" + cbxCOMPort.Text);sw.WriteLine("cbxBaudRate=" + cbxBaudRate.Text);sw.WriteLine("cbxDataBits=" + cbxDataBits.Text);sw.WriteLine("cbxStopBits=" + cbxStopBits.Text);sw.WriteLine("cbxParity=" + cbxParity.Text);sw.WriteLine("cb16Display="+ cb16Display.Checked.ToString()); sw.WriteLine("tbSpaceTime=" + tbSpaceTime.Text);sw.WriteLine("cb16Send=" + cb16Send.Checked.ToString());sw.WriteLine("tbSendDataStr=" + tbSendDataStr);sw.WriteLine("tbSendData16=" + tbSendData16);sp.Close();}}catch(Exception ex){MessageBox.Show(ex.Message.ToString());}}//发送文本框按键抬起时出发的事件private void tbSendData_KeyUp(object sender, KeyEventArgs e){if (cb16Send.Checked){tbSendData16 = tbSendData.Text.Trim();}else{tbSendDataStr = tbSendData.Text;}}//点击读入文件按钮private void btnRead(object sender, EventArgs e){open = "所有文件(*.*)|*.*";//文件筛选器的设定open = 1;open = "选择文件";open = "";open = true;if(open() == DialogResult.OK){using ( fs = new (open,.Open)){byte[] bufferByte = new byte[fs.Length];fs.Read(bufferByte, 0, Convert.ToInt32(fs.Length));sp.Write(bufferByte, 0, bufferByte.Length);tbSendCount.Text = (Convert.ToInt32(tbSendCount.Text) + bufferByte.Length).ToString();}}}//点击保存数据按钮private void btnSave(object sender, EventArgs e){save = "所有文件(*.*)|*.*";if(save() == DialogResult.OK){string fName = save;using( fs = (fName, .Append)){fs.Write(receivedDatas.ToArray(), 0, receivedDatas.Count);}}}}}需要源代码或有疑问的c#爱好者们,欢迎加入c#技术交流群(),附加信息为”我以下载此文档”,进群后找群主索要源代码或进行技术交流。

基于VC_串口通信的设计与实现

基于VC_串口通信的设计与实现

图 3 串口进行一些参数配置代码
图 4 数据发送代码
图 5 测试结果显示
5


+ +
VC 是一个非常优秀的用户开发平台 , 提供了多 种方法对串口进行通信控制 , 使用户不必了解, 使程序透明化, 并且适应性好 , 可 移植性高。采用 Win 32 AP I 串口通信编程是最灵活、 最常用并且功能强大的方法 , 适用于同各种不同的外设 进行串行通信 , 但需要程序员对硬件工作原理有较深的 了解 , 本程序设计的串口通信软件基本实现了数据交换 的功能, 还有数据的保存于设置参数的等功能, 能够满 足一般的通信测试需要。
[ 1] 龚建伟 , 熊 光 明 . V isual C+ + / T urbo C 串 口 通信 编 程实 践 [ M ] . 北京 : 电子工业出版社 , 2008. ( 下转第 24 页 )
24
现代电子技术 在 执法考核 信息系统中应用 WebL og ic 中间件
2011 年第 34 卷
通过 W ebL ogic 我们可以解决各系统的操作系统 异构和数据库异构。 4 结 语
Design and Implementation of Serial Communication Program Based on VC+ + Software
W A NG Y ing , SU N H ua - jun
( C ollege of Inform ation E ng ineering , Sheny ang U niv ersity o f C hem ica l T echnolo gy, Sheny ang 110142, C hina)
+

基于VisualC++与串口的智能车上位机调试系统

基于VisualC++与串口的智能车上位机调试系统

S r lot a nt r、 P 与 网络 技 术 的结 合 , 得原 有 串 口设 备 能够低 成 本 、 使 高兼 C ei P r 类 常 用到 的函 数 有 串 口初 始 化 函数 Ii ot 启动 串 口通 信监 测线程 函 Sat ntr g 、 tr Mo i i ()暂停 或停 止 on 容性 扩 展 , 不需 要对 现 有 串 口进 行 大 规模 改 造 , 口通 信 串 监 测线 程 函数 S o Mo i r g 、 闭 串 口 , 放 串 口资 t p n o i ()关 t n 释 在 未来 长 时期 内不会 消亡。 源 函数 Co e ot 、 口发送 字 符 / 串 口函数 W re ls P r () 串 写 i— t 1单 片机 串 口介 绍
基 于 Vs a C + 串 口的智能车上位机调试 系统 i l +与 u
胡惟文 曹斌 芳 彭元 杰 ( 南 理 院 理与 子 学 院 湖 文 学 物 电 科 学 )
摘 要 : 对智 能 小 车 测试 与 控 制 要 求 设计 了上 位 机 控 制平 台。 针 系 和 一位 停止位 ( o X 1 T D为发 送数据 , X R D为接 收数据 。 波 统 通 过 P 机 的 串 口将 指令 发 送 给 主 控 模 块 ,主 控 模 块 通 过 无 线 收 特 率 可变 , 由定 时器 / 数器 T C 计 1的溢 出率和 电源控 制 寄 发模 块 遥 控 小 车。 采 用 Vs a C +编 写 了可 视化 P i l + u C机 控 制 界 面 ,
实现 了 P C机 与 单 片 机 的 双 向通 信 , 设计 了相 应 的 通信 协 议 , 现 单 实 片 机 和 上 位 机 间 的 双 向 通 信 。 数 据 通 信 采 用 Vs a C + 中 的 i l + u C eilot 来 实 现 。 经 实 验 证 明 , 试 平 台性 能稳 定 能够 较 好 的 S r P r类 a 调

vc++_串口上位机编程实例 附vc串口通信(接收)

vc++_串口上位机编程实例  附vc串口通信(接收)

VC++串口上位机简单例程(源码及详细步骤)VC++编写简单串口上位机程序串口通信,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 and Controls->双击Registered ActiveX Controls->选择Microsoft Communications Control, version 6.0->Insert,按默认值添加,你会发现多了个电话图标,这是增加后串口通信控件。

基于VisualC_与串口的智能车上位机调试系统

基于VisualC_与串口的智能车上位机调试系统

到数据处理标志位“0”时,将存储在字符串数组中的数据 收到的数据进行处理,并发送另一组数据给 PC 机,PC
根据通信协议对数据进行处理,并将数据显示在界面的编 机对接收的数据进行处理的过程。m ain()函数的标志位
辑框中。
处理如表 3 所示。
2.4 PC 机界面的介绍
与单片机 P0 口相连的是 8 个 LED,可参考图 1,这样
了 PC 机控制单片机的功能,通过显示单片机传送过来的
表 3 main()函数中标志位的操作
数据,可以了解到单片机的运行情况。
标志位 qidong_flag=1 flag=1 flag=2 flag=3 flag=4 flag=5 qidong_flag=0
参考文献:
操作 向 PC 发送温度 P0=0x02 P0=0x03 P0=0x04 P0=0x05 蜂鸣器 停止向 PC 机
CSerialPort 类来实现。经实验证明,调试平台性能稳定能够较好的 出率)/32;而 T1 的溢出率 =f(osc)/(12*(256- 初值))。
完成各种测试工作。
2 单片机与 PC 机通信源自关键词:上位机 单片机 串口通信 可视化界面
2.1 单片机硬件电路
0 引言
单片机与 PC 机之间的电平不一致,必须对单片机输
[1]谢维成,杨家国.单片机原理与应用及
和检测次数的数据
发声 数据的发送 C51 程序设计 [M]. 北京: 清华大学出版社,
在单片机 m ain () 函数中首先是进行了温度传感器 2006.
18B20 初始化函数 Init_DS18B20 ();和串口初始化函数
[2]史兵,周重益.基于控件的 DCS 系统内部多机通信[J ].低压电
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

串口上位机vcVC++编写简单串口上位机程序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 CommunicationsControl, version 6.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' : undeclared identifierZ:\vc++串口上位机\test\testDlg.cpp(139) : error C2065: 'IDC_EDIT1' : undeclared identifier解决方法是,在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~1023 pbar ->SetPos(0);//当前位置为0m_serial.SetWindowText("关闭串口");//按钮显示状态改变可以看到,串口的参数等等都在在这里初始化的,可以根据自己的需要修改的,具体可以查看VC++里的详细介绍,看看有哪些参数可以给我们修改来用。

添加后再编译一下,运行后可以看到多了一个串口初始化的提示信息窗口。

至此,我们已经完成了主要的串口操作及界面,剩下的就是两个按钮的操作了。

9、回到资源视图的IDD_TEST_DIALOG窗口,双击开始转换按钮,给它添加事件,点击后PC通过串口发送0xaa出来,给单片机接收。

添加如下代码:CByteArray m_Array; //定义字节数组m_Array.RemoveAll(); //字节数组清空m_Array.SetSize(1); //设定维数为1m_Array.SetAt(0,0xaa); //给m_array[0]赋值0m_comm1.SetOutput(COleVariant(m_Array));//由于SetOutput凼数的参数为VARIANT型,必须强制转换后才能发送同样地,双击另外一个按钮,给串口操作按钮添加代码,用于关闭戒者打开串口。

相关文档
最新文档