C#初入串口通信(串行通信)总结

时间:2022-09-01 20:17:27

使用WinFrom来实现:

首先要知道串口通信协议以及原理

原理大概提一下:要自己翻阅看。(http://book.51cto.com/art/200911/162532.htm或者http://hi.baidu.com/fly514/item/54aeb9d731ddedb932db9006

代码部分:

实现串口通信有很多种办法,有COM组件(收费),有.net的serialPort串行端口控件等等,这里实现的方法是使用.NET提供的一个很方便的类:SerialPort。(这个类中一般简单的功能都可以实现,如果要实现的功能很变态的话,就另请高明吧)

实现的功能很简单(就是发送数据和接收数据而已),这是我初学者的入门总结。

C#初入串口通信(串行通信)总结

首先,先将这些下拉空的值手动添加进去(第一个串行端口是程序实现的,也可以手动添加COM1等等)

停止位:One    OnePointFive    Two

C#初入串口通信(串行通信)总结

数据位:8   7   6

C#初入串口通信(串行通信)总结

校验位:Even  Mark  None   Odd    Space
C#初入串口通信(串行通信)总结

波特率:300  600  1200  2400  4800  9600  19200  38400  43000  56000  57600  115200

(还有其他数字的波特率,看实际情况而定了,这应该是常用的波特率了)

C#初入串口通信(串行通信)总结

这个类是在using System.IO.Ports命名空间下的类。

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

namespace MyComm
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
            //如果不写,当你接收数据并且把数据显示到文本框上的时候会直接报错的。
            //因为这是对 Windows 窗体控件进行线程安全调用
            //访问 Windows 窗体控件本质上不是线程安全的。
            //如果有两个或多个线程操作某一控件的状态,则可能会迫使该控件进入一种不一致的状态。
            //还可能出现其他与线程相关的 bug,包括争用情况和死锁。确保以线程安全方式访问控件非常重要。
            //.NET Framework 有助于在以非线程安全方式访问控件时检测到这一问题。
            //在调试器中运行应用程序时,如果创建某控件的线程之外的其他线程试图调用该控件,
            //则调试器会引发一个 InvalidOperationException,并提示消息:“从不是创建控件 control name 的线程访问它。”
            Form.CheckForIllegalCrossThreadCalls = false;
        }
        //定义SerialPort类
        SerialPort Myport = null;

///
        /// 窗体加载完成触发
        ///
        ///
        ///
        private void Form2_Load(object sender, EventArgs e)
        {
            //实例化
            Myport = new SerialPort();
            //这里需要添加引用Microsoft.VisualBasic的引用,提供操作计算机组件(如:音频,时钟,键盘文件系统等)的属性
            Microsoft.VisualBasic.Devices.Computer pc = new Microsoft.VisualBasic.Devices.Computer();
            //循环该计算机上所有串行端口的集合
            foreach (string s in pc.Ports.SerialPortNames)
            {
                //串口名称添加到cbxPortName下拉框上
                //一般计算机上是有COM1和COM2串口的,如果没有自己在cbxPortName下拉框里写COM1 和 COM2的字符串(如:this.cbxPortName.Items.Add("COM2"))
                this.cbxPortName.Items.Add(s);
            }
            //防止报错,万一计算机上没有串口,就不走这一步
            if (pc.Ports.SerialPortNames.Count > 0)
            {
                cbxPortName.SelectedIndex = 0;
            }
            cmbbaud.SelectedIndex = 0;
            cmbParity.SelectedIndex = 0;
            cmbBits.SelectedIndex = 0;
            cmbStop.SelectedIndex = 0;
        }

///
        /// 打开串口按钮
        ///
        ///
        ///
        private void btnOpen_Click(object sender, EventArgs e)
        {
            //设置串口端口
            Myport.PortName = cbxPortName.Text;
            //设置比特率
            Myport.BaudRate = Convert.ToInt32(cmbbaud.Text);
            //设置数据位
            Myport.DataBits = Convert.ToInt32(cmbBits.Text);
            //根据选择的数据,设置停止位
            //if (cmbStop.SelectedIndex == 0)
            //    Myport.StopBits = StopBits.None;
            if (cmbStop.SelectedIndex == 1)
                Myport.StopBits = StopBits.One;
            if (cmbStop.SelectedIndex == 2)
                Myport.StopBits = StopBits.OnePointFive;
            if (cmbStop.SelectedIndex == 3)
                Myport.StopBits = StopBits.Two;

//根据选择的数据,设置奇偶校验位
            if (cmbParity.SelectedIndex == 0)
                Myport.Parity = Parity.Even;
            if (cmbParity.SelectedIndex == 1)
                Myport.Parity = Parity.Mark;
            if (cmbParity.SelectedIndex == 2)
                Myport.Parity = Parity.None;
            if (cmbParity.SelectedIndex == 3)
                Myport.Parity = Parity.Odd;
            if (cmbParity.SelectedIndex == 4)
                Myport.Parity = Parity.Space;

//此委托应该是异步获取数据的触发事件,即是:当有串口有数据传过来时触发
            Myport.DataReceived += new SerialDataReceivedEventHandler(port1_DataReceived);//DataReceived事件委托
            //打开串口的方法
            try
            {
                Myport.Open();
                if (Myport.IsOpen)
                {
                    MessageBox.Show("the port is opened!");
                }
                else
                {
                    MessageBox.Show("failure to open the port!");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("failure to open the port!"+ex.ToString());
            }
        }

///
        /// 关闭串口的方法
        ///
        public void ClosePort()
        {
            Myport.Close();
            if (!Myport.IsOpen)
            {
                Console.WriteLine("the port is already closed!");
            }
        }

///
        /// 发送按钮
        ///
        ///
        ///
        private void btnNotAutoSend_Click(object sender, EventArgs e)
        {
            //向串口发送数据的方法
            SendCommand(txtSend.Text.Trim());
        }

///
        /// 向串口发送数据的方法
        ///
        ///
        public void SendCommand(string CommandString)
        {
            //转换
            //串口只能读取ASCII码或者进制数(1,2,3.....的进制,一般是16进制)
            byte[] WriteBuffer = Encoding.ASCII.GetBytes(CommandString);
            //将数据缓冲区的数据写入到串口端口
            Myport.Write(WriteBuffer, 0, WriteBuffer.Length);
        }

///
        /// DataReceived事件委托的方法
        ///
        ///
        ///
        private void port1_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                string currentline = "";
                //循环接收串口中的数据
                while (Myport.BytesToRead > 0)
                {
                    char ch = (char)Myport.ReadByte();
                    currentline += ch.ToString();
                }
                //在这里对接收到的数据进行显示
                //如果不在窗体加载的事件里写上:Form.CheckForIllegalCrossThreadCalls = false; 就会报错)
                this.txtReceive.Text = currentline;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message.ToString());
            }
        }

}
}

配合上“VSPM虚拟串口”用就很方便   :(根据http://blog.csdn.net/redhaste/article/details/4097863http://blog.csdn.net/gaojing007/article/details/5399503写的文章)

附件下载(VSPM虚拟串口,C#中串口通信编程.doc,SerialPort程序例子):

http://yunpan.cn/Q7Yi7geX988MY   提取码 167e

在编程的过程中用到了几个工具:串口助手,VSPM虚拟串口,Configure Virtual Serial Port Driver。

C#初入串口通信(串行通信)总结的更多相关文章

  1. Linux与Windows串口通信

    串口是常用的计算机与外部串行设备之间的数据传输通道,由于串行通信方便易行,所以应用广泛.现在国际上不断有串口新技术及新规格推出,结合社会各方面需要,串口通信发展的空间庞大.串口通讯技术因其自身的优势和 ...

  2. 串口通信-MSComm控件使用详解

    串口通信-MSComm控件使用详解 2012年11月13日 09:35:45 他山之石可以攻玉 阅读数:37952更多 个人分类: 控件编程Delphi编程   MSComm 控件通过串行端口传输和接 ...

  3. .NET 串口通信

    这段时间做了一个和硬件设备通信的小项目,涉及到扫描头.输送线.称重机.贴标机等硬件.和各设备之间通信使用的是串口或网络(Socket)的方式.扫描头和贴标机使用的网络通信,输送线和称重机使用的是串口通 ...

  4. STC12C5A60S2 双串口通信

    STC12C5A60S2单片机是一款功能比较强大的单片机,它拥有两个全双工串行通信接口,串口1的功能及操作与传统51单片机串行口相同:特殊的是STC12C5A60S2单片机内部有一个独立波特率发生器, ...

  5. mfc 调用Windows的API函数实现同步异步串口通信(源码)

    在工业控制中,工控机(一般都基于Windows平台)经常需要与智能仪表通过串口进行通信.串口通信方便易行,应用广泛. 一般情况下,工控机和各智能仪表通过RS485总线进行通信.RS485的通信方式是半 ...

  6. VS2008基于对话框的MFC上位机串口通信(C++实现)简单例程

    首先,在 vs2008 环境下创建 MFC 运用程序 设置项目名称为 ComTest(这个地方随意命名,根据个人习惯),点击确定后,点击下一步 出现如下界面 选择"基于对话框"模式 ...

  7. 【C51】UART串口通信

    我们常需要单片机和其他模块进行通信,数据传输,常用的方式就是串口通信技术. 常用来 单片机<-->电脑,  单片机<-->单片机之间通信. 串行通信 versus 并行通信 并 ...

  8. LabVIEW串口通信

    Instrument I/O 利用LabVIEW内置的驱动程序库和具有工业标准的设备驱动软件,可对 GPIB(通用接口总线).Ethernet(以太网)接口.RS-232(标准串行接口总线)/RS-4 ...

  9. ARM学习笔记15——串口通信基本原理【转】

    计算机串口基本理论 1.什么是串口? 2,什么是RS-232? 3,什么是RS-422? 4,什么是RS-485? 5,什么是握手? 1,什么是串口? 串口是计算机上一种非常通用的设备通信的协议(不要 ...

随机推荐

  1. Docker 容器部署 Consul 集群

    Docker 容器部署 Consul 集群 一.docker安装与启动1.1安装docker[root@localhost /]# yum -y install docker-io 1.2更改配置文件 ...

  2. javascript 设计模式-----工厂模式

    所谓的工厂模式,顾名思义就是成批量地生产模式.它的核心作用也是和现实中的工厂一样利用重复的代码最大化地产生效益.在javascript中,它常常用来生产许许多多相同的实例对象,在代码上做到最大的利用. ...

  3. wamp 2&period;5 开放访问权限和设置虚拟域名

    开放访问权限 D:\wamp\bin\apache\apache2.4.9\conf  里的 httpd.conf 搜索www   把 Require local 改为 Require all gra ...

  4. &lbrack;Code&colon;&colon;Blocks&rsqb; Install wxWidgets &amp&semi; openCV

    The open source, cross platform, free C++ IDE. Code::Blocks is a free C++ IDE built to meet the most ...

  5. gcc选项-g与-rdynamic的异同&lowbar;转

    转自:http://www.tuicool.com/articles/EvIzUn gcc 的 -g ,应该没有人不知道它是一个调试选项,因此在一般需要进行程序调试的场景下,我们都会加上该选项,并且根 ...

  6. Shell 基础

    1.结构        #!指定执行脚本的shell  #!/bin/sh        # 注释行        命令和控制结构    2.修改权限        chmod +x ...    3 ...

  7. CSS3滤镜&lpar;filter--CSS3技术

    filter 属性定义了元素(通常是<img>)的可视效果,例如图片的模糊.饱和度.灰度等……个人感觉功能很强大 1.filter的语法 filter: none | blur() | b ...

  8. zigbee 中ZDO的理解

    ---恢复内容开始--- ZigBee     物理层:主要进行无线数据的收发,同时定义了无线传输的信道以及频率.      MAC层:使用CSMA-CA机制接入到无线信道,负责传输信标帧,保持同步和 ...

  9. C&num;获取类库&lpar;DLL&rpar;的绝对路径

    C#中当我们在写公共的类库的时候难免会调用一些xml配置文件,而这个配置文件的路径则非常重要,常用的方式就是写在web.config中,而我们也可以将配置文件直接放在dll的同级目录,那么怎么获得当前 ...

  10. 【linux】使用swap文件恢复非正常关闭的文件

    前言 使用vim的时候,文件编辑过程中可能会出现bug,导致非正常关闭.为了保存刚刚修改的内容,需要对文件进行恢复. 操作过程 1.查看目录文件 zrj@zrj-ThinkPad-E470:~/wor ...