c#串口通讯软件设计

发布者:cw57324588最新更新时间:2015-05-27 来源: 51hei关键字:串口通讯  软件设计 手机看文章 扫描二维码
随时随地手机看文章
最近工作用到modbus,同时也用到了上位机软件,看到主管用vb写的软件可以通过串口与我的下位机通讯,显示数据,觉得很好玩。所以回家一时冲动,就下了个vs2005,准备也搞一搞,但用个啥语言呢?思考了一下,vb--太老,c++,太复杂,java,貌似得加软件,没敢玩,最后思来想去,决定了一个比较靠普的语言,c#,这个目前写软件还是比较流行的,用的人很多,例子也很多,关键是类似vb,但是以c为基础的。所以很适合我。下面是通过了1天艰苦奋斗,写的一个破串口通讯软件 

  
 

调试的截屏,有点傻,不过基本功能还是可以的,计数,发送,接受,串口,波特率设置,都是可以设置的,不过校验目前还没有,第一步算是搞定了,以后慢慢完善。

发现这东西,其实也不太难。很多东西都用函数封装起来了,直接调用就行,貌似比c语言方便。

创建项目就不说了,写com代码事,需要加一些类似的头文件的声明。

using System.IO.Ports;      

在界面初始化时,初始化串口

private SerialPort comm = new SerialPort();    //具体干啥的,我也不知道 貌似是将comm变成串口结构

这个语句很有意思,我局的很神奇,就是搜索串口号,然后将其复制在ports数组中。

string[] ports = SerialPort.GetPortNames();     //获取串口号,将其存入一个一维字符串数组

这样的话,一下子,就可以知道目前哪个串口是处于可工作的状态。

Array.Sort(ports);                              //对一个一维数组进行排列

这个函数也挺有意思,他可以对字符串数组进行排列,一句话就搞定了,如果是c的话,费了劲了,首先要将字符串变成数据,然后再对数据进行排列,至于怎么样排列,我也不知道,没做过,可是这个,一句就可以了,不错不错

labelTXdata.Text = "发送数据:" + send_count.ToString();

上面这句,可以使文字控件按照你的意思显示变量,类似在c语言中,让1602显示数据一样。

void comm_DataReceived(object sender, SerialDataReceivedEventArgs e)

这个貌似就是串口接受函数,类似c口中断,接受到数据后,进入这个函数来处理

//依次的拼接出16进制字符串
foreach (byte b in buf)
{
    builder.Append(b.ToString("X2") + " ");
 }

//转换列表为数组后发送
comm.Write(buf.ToArray(), 0, buf.Count);

在这句话的前面还有那么几句

//我们不管规则了。如果写错了一些,我们允许的,只用正则得到有效的十六进制数
MatchCollection mc = Regex.Matches(SENDBOX.Text, @"(?i)[da-f]{2}");
List buf = new List();//填充到这个临时列表中
//依次添加到列表中
foreach (Match m in mc)
{
buf.Add(byte.Parse(m.Value, System.Globalization.NumberStyles.HexNumber));
}
//具体干啥用的,我也不知道

//打开串口

comm.Open();

剩下的就是零零碎碎不重要的东西了,下面是全部代码:有兴趣的大小盆友看一下

反正第一次写软件,喜乐糊涂的,不管对c

 

 

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.IO.Ports;
using System.Windows.Forms;
using System.Text.RegularExpressions;

namespace com
{
    public partial class Form1 : Form
    {

        private SerialPort comm = new SerialPort();
        private StringBuilder builder = new StringBuilder();//避免在事件处理方法中反复的创建,定义到外面。
        private long received_count = 1000;//接收计数
        private long send_count = 1000;//发送计数


        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string[] ports = SerialPort.GetPortNames();     //获取串口号,将其存入一个一维字符串数组
            string[] Baudrate = { "4800", "9600", "192000" };
            Array.Sort(ports);                              //对一个一维数组进行排列
            cobportname.Items.AddRange(ports);                //向combobox下拉列表中添加数据,数据为串口号
            cobBaudrate.Items.AddRange(Baudrate);
            cobportname.SelectedIndex = cobportname.Items.Count > 0 ? 0 : -1;             //首选项目
            cobBaudrate.SelectedIndex = cobBaudrate.Items.IndexOf("9600");                //首选项为字符串时
            comm.NewLine = " ";
            comm.RtsEnable = true;//根据实际情况吧。

            //添加事件注册
            labelTXdata.Text = "发送数据:" + send_count.ToString();
            labelRXdata.Text = "接受数据:" + received_count.ToString();
            comm.DataReceived += comm_DataReceived;
           
        }[page]
        void comm_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            int n = comm.BytesToRead;//先记录下来,避免某种原因,人为的原因,操作几次之间时间长,缓存不一致
            byte[] buf = new byte[n];//声明一个临时数组存储当前来的串口数据
            received_count += n;//增加接收计数
            comm.Read(buf, 0, n);//读取缓冲数据
            builder.Remove(0, builder.Length);//清除字符串构造器的内容
            this.Invoke((EventHandler)(delegate
            {
                //判断是否是显示为16禁止
                if(HEXRX.Checked)
                {
                    //依次的拼接出16进制字符串
                    foreach (byte b in buf)
                    {
                        builder.Append(b.ToString("X2") + " ");
                    }
                }
                else
                {
                    //直接按ASCII规则转换成字符串
                    builder.Append(Encoding.ASCII.GetString(buf));
                }
                //追加的形式添加到文本框末端,并滚动到最后。
                this.GETRX.AppendText(builder.ToString());
                //修改接收计数
                labelTXdata.Text = "发送数据:" + send_count.ToString();
                labelRXdata.Text = "接受数据:" + received_count.ToString();
               
            }));
        }
        private void buttonTX_Click(object sender, EventArgs e)
        {
            //定义一个变量,记录发送了几个字节
            int n = 0;
            //16进制发送
            if (HEXTX.Checked)
            {
                //我们不管规则了。如果写错了一些,我们允许的,只用正则得到有效的十六进制数
                MatchCollection mc = Regex.Matches(SENDBOX.Text, @"(?i)[da-f]{2}");
                List buf = new List();//填充到这个临时列表中
                //依次添加到列表中
                foreach (Match m in mc)
                {
                    buf.Add(byte.Parse(m.Value, System.Globalization.NumberStyles.HexNumber));
                }
                //转换列表为数组后发送
                comm.Write(buf.ToArray(), 0, buf.Count);
                //记录发送的字节数
                n = buf.Count;
            }
            else//ascii编码直接发送
            {
               
                    comm.WriteLine(SENDBOX.Text);
                    n = SENDBOX.Text.Length + 2;
               
            }
            send_count += n;//累加发送字节数
            labelTXdata.Text = "Send:" + send_count.ToString();//更新界面
        }

        private void groupBox1_Enter(object sender, EventArgs e)
        {

        }

        private void button2_Click(object sender, EventArgs e)
        {
            //复位接受和发送的字节数计数器并更新界面。
            send_count = received_count = 0;
            labelTXdata.Text = "发送数据:" + send_count.ToString();
            labelRXdata.Text = "接受数据:" + received_count.ToString();
        }

        private void bottoncom_Click(object sender, EventArgs e)
        {
            //根据当前串口对象,来判断操作
            if (comm.IsOpen)
            {
                //打开时点击,则关闭串口
                comm.Close();
            }
            else
            {
                //关闭时点击,则设置好端口,波特率后打开
                comm.PortName = cobportname.Text;
                comm.BaudRate = int.Parse(cobBaudrate.Text);
                try
                {
                    comm.Open();
                }
                catch (Exception ex)
                {
                    //捕获到异常信息,创建一个新的comm对象,之前的不能用了。
                    comm = new SerialPort();
                    //现实异常信息给客户。
                    MessageBox.Show(ex.Message);
                }
            }
            //设置按钮的状态
            bottoncom.Text = comm.IsOpen ? "关闭" : "打开";
            //buttonSend.Enabled = comm.IsOpen;
        }
    }
}

关键字:串口通讯  软件设计 引用地址:c#串口通讯软件设计

上一篇:LWIP程序OPT.h头文件的各种定义
下一篇:高压电源之研发计划方案与问题

推荐阅读最新更新时间:2024-03-16 14:03

I2C操作笔记——以 AT24C04为例
1.前言 对于大多数工程师而言,I2C永远是一个头疼的问题。相比UART和SPI而言,I2C的时序要复杂一些,I2C组合变化也丰富一些。在这里以AT24C04为例说明I2C使用过程中的一些注意点。 2.AT24C04操作示意图 图 AT24C04操作示意图 示意图说明:示意图分阐述了4种不同的操作方式,例如写单个存储单元,写多个存储单元,读单个存储单元和写单个存储单元。对于单个操作而言,上部为MCU通过I2C输出的相关指令,下部为I2C设备的响应。例如写单个存储单元操作时,MCU发出I2C启动,设备地址,写标志位等,而I2C设备输出多个ACK。 (勘误说明,图AT24C04操作示意图中,两处R标志位之后分别缺少一个A应
[单片机]
STC89C52RC特点及引脚介绍
STC89C52RC是由宏晶公司推出的一种小型单片机,是 电子工程师 常用器件。其主要特点为采用Flash存贮器技术,降低了制造成本,其软件、硬件与MCS-51完全兼容,且采用高密度非易失存储器制造技术制造,将多功能8位CPU和闪烁存储器组合在单个芯片中,可以很快被中国广大用户接受。其程序的电可擦写特性,使得开发与试验比较容易,为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。 STC89C52RC的特点 STC89C52RC有很宽的工作电源电压,可为2.7~6V,当工作在3V时,电流相当于6V工作时的1/4。STC89C52RC工作于12Hz时,动态电流为5.5mA,空闲态为1mA,掉电状态仅为20nA。这样小的功耗很适
[单片机]
I2C总线上电压失常故障的分析与检修
    采用I2C总线控制技术的电视机,微处理器(CPU)仅通过数据线SDA和时钟线SOL两根传输线(以下将SDA、SOL简称总线)与所有的被控集成电路(IC)、存储器相连接。常见I2C总线控制电路如图1所示。CPU 的总线输出端通过上拉电阻RP接+5V电源,为CPU的I2C总线输出端口内电路供电。被控电路与总线之间接有隔离电阻R。为保证总线安全可靠的工作,总线上有的还接有防止高压损坏总线电路的 稳压保护二极管D,滤除干扰脉冲的高频电容C。一般常见彩电只有一对总线,根据机型和电路结构的不同,有的彩电采用两对或三对总线。每对总线根据需要,最少挂接一只被控IC,也可挂接多只被控 IC。 图1 常见I2C总线控制电路图   综观
[嵌入式]
stm32 各头文件或C文件功能
stm32f10x_con.h 配置文件:加载哪个外设、使能assert 对参数进行检查,如果使能了assert 需要在main文件中添加 _assert_faild 函数。 使能assert会增大编译出执行文件的大小,调试完后可以将assert 屏蔽。 stm32f10x.h头文件中包含了stm32f10x_conf.h 。 stm32f10x.h 1、对所有的外设的地址进行映射,映射到存储区,即定义某外设结构体变量,因为结构体是连续存储的只要将外设的基地址强制转换为结构体类型的指针,那么该外设的寄存器就可以通过指针进行访问,以GPIO为例: 定义外设的结构体,结构体变量都
[单片机]
C-V2X行业研究:20余款乘用车前装量产C-V2X,渗透率超过0.5%
20余款乘用车量产搭载C-V2X,渗透率持续提升 据佐思汽研统计,2022年1-6月,搭载C-V2X技术的量产乘用车约4.6万辆,装配率约0.5%,预计2026年装配率可达10%,装配量可超过200万。佐思基于以下三点进行装配率增长预测: 考量因素一 《智能汽车创新发展战略》指出到2025年,车用无线通信网络(LTE-V2X等)实现区域覆盖,新一代车用无线通信网络(5G+C-V2X)在部分城市、高速公路逐步开展应用。这可能是车企近两年不断增加C-V2X模块搭载的原因之一,后续可以根据车用无线通信网络的覆盖面的增加,再通过OTA直接实现V2X功能的升级。 此外,国家对自动驾驶的渗透率也有一定的规划,5G+C-V2X是自
[汽车电子]
<font color='red'>C</font>-V2X行业研究:20余款乘用车前装量产<font color='red'>C</font>-V2X,渗透率超过0.5%
arduino+STC89C52RC+nRF24L01制作远程测温系统
断断续续使用3天的时间,终于弄明白nRF24L01无线传输芯片的原理,可以让两块不同型号的芯片进行远程数据交换. 下面的这幅图片使用这个芯片进行温度传输.其中89C52RC+DS18B20作温度采集终端,由nRF24L01发送至arduino最后传送到PC和processing交互.. 最后尝试使用电池盒作为电源,发现在距离20米开外的地方也能保证数据传输的准确性,说明这块无线芯片确实性能不错. 以下是其发送和接受的源代码,供有意向的人使用: STC89C52RC发送代码 #include reg52.h #include intrins.h typedef unsigned char uchar; typede
[单片机]
arduino+STC89<font color='red'>C</font>52RC+nRF24L01制作远程测温系统
基于SJA1000的CAN总线和AT89C51单片机实现运动控制系统的设计
1、引言 运动控制系统是以机械运动的驱动设备—电动机为控制对象, 以控制器为核心, 以电力电子、功率变换装置为执行机构, 在自动控制理论指导下组成的电气传动控制系统。在电气时代, 电动机一直在现代化的生产和生活中起着十分重要的作用。在近年来, 由于半导体制造设备等相关的电子制造设备市场大幅成长, 而使得机器设备上的运动控制系统出现了以下几点技术需求: ( 1) 多轴运动控制。机器设备因自动化程度提高而使得单一机器上所需要的轴数增多, 一台设备上十几轴是常见的事情。在轴数变多后, 如何协调各轴动作就是一个重要的课题。 ( 2) 体积要小。由于厂房空间的限制, 机器的体积要求越小越好, 机器内控制器的体积也就被要求愈来愈小, 相对
[单片机]
基于SJA1000的CAN总线和AT89<font color='red'>C</font>51单片机实现运动控制系统的设计
BQ24721C - 具有 SMBus 与系统电源选择器、出色软启动的智能电池充电器
bq24721 是一款适用于便携式应用的高效率、高集成度同步电池组充电器。该器件实现了高性能模拟前端,能够通过类似 SBS 的简便 SMBus 接口连接至系统电源管理微控制器。 其动态电源管理 (DPM) 功能可根据系统负载状况改变充电电流,从而避免交流适配器出现过载。 高精度电流感应放大器能够准确测量充电电流或交流适配器电流,从而可以端接非智能电池组并监控整个系统电源。 通过使用 bq24721 提供的控制信号,可以旁路适配器隔离二极管或完全由外部 MOSFET 替代,从而降低总体功耗。 除了电池组与系统保护功能外,诸如充电器软启动、充电过流保护以及 IC 温度监控等集成功能还可提供更多保护。 特性 §具有用户可选的 300
[新品]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved