C#做一个简单的进行串口通信的上位机
C#做一个简单的进行串口通信的上位机
乱世中的单纯 发布于 1年前,共有 10 条评论
1、上位机与下位机
上位机相当于一个软件系统,可以用于接收数据、控制数据。即可以对接收到的数据直接发送操控命令来操作数据。上位机可以接收下位机的信号。下位机是一个控制器,是直接控制设备获取设备状况的计算机。上位机发出的命令首先给下位机,下位机再根据此命令解释成相应时序信号直接控制相应设备。下位机不时读取设备状态数据(一般为模拟量),转换成数字信号反馈给上位机。上位机不可以单独使用,而下位机可以单独使用。
2、串口通信
串口相当于硬件类型的接口。比如无线传感节点发送信号到汇聚节点,汇聚节点通过串口将数据传到计算机中的上位机中,上位机接收信息,并处理。
串口是按位(bit)发送和接收字节。串口通信最重要的参数是波特率、数据位、停止位和奇偶校验。对于两个进行通信的端口,这些参数必须匹配。
a,波特率:这是一个衡量符号传输速率的参数。
b,数据位:这是衡量通信中实际数据位的参数。
c,停止位:用于表示单个包的最后一位。典型的值为1,1.5和2位。
d,奇偶校验位:在串口通信中一种简单的检错方式。
3、C#代码
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.IO.Ports; using System.Diagnostics; namespace serial2 {public partial class Form1 : Form{SerialPort s = new SerialPort(); //实例化一个串口对象,在前端控件中可以直接拖过来,但最好是在后端代码中写代码,这样复制到其他地方不会出错。s是一个串口的句柄public Form1(){InitializeComponent();Control.CheckForIllegalCrossThreadCalls = false; //防止跨线程访问出错,好多地方会用到button1.Text = "打开串口";int[] item = { 9600,115200}; //定义一个Item数组,遍历item中每一个变量a,增加到comboBox2的列表中foreach (int a in item){comboBox2.Items.Add(a.ToString());}comboBox2.SelectedItem = comboBox2.Items[1]; //默认为列表第二个变量}private void Form1_Load(object sender, EventArgs e) //窗体事件要先配置端口信息。{string[] ports = SerialPort.GetPortNames();comboBox1.Items.AddRange(ports);comboBox1.SelectedItem=comboBox1.Items[0];//Array.Sort(ports);}private void button1_Click(object sender, EventArgs e) //下面讲解中差不多已经讲清楚了{try{if (!s.IsOpen){s.PortName = comboBox1.SelectedItem.ToString();s.BaudRate = Convert.ToInt32(comboBox2.SelectedItem.ToString());s.Open();s.DataReceived += s_DataReceived;button1.Text = "关闭串口";//MessageBox.Show("串口已打开");}else{s.Close();s.DataReceived -= s_DataReceived;button1.Text = "打开串口";}}catch (Exception ee){MessageBox.Show(ee.ToString());}}void s_DataReceived(object sender, SerialDataReceivedEventArgs e) //数据接收事件,读到数据的长度赋值给count,如果是8位(节点内部编程规定好的),就申请一个byte类型的buff数组,s句柄来读数据{int count =s.BytesToRead; string str=null ;if (count == 8){byte[] buff = new byte[count];s.Read(buff, 0, count);foreach (byte item in buff) //读取Buff中存的数据,转换成显示的十六进制数{str += item.ToString("X2")+" ";}richTextBox1.Text =System.DateTime.Now.ToString()+": "+ str + "\n" + richTextBox1.Text; //这是跨线程访问richtextbox,原程序和DataReceived事件是两个不同的线程同时在执行if (buff[0] == 0x04) //如果节点是04发来的数据{ID.Text = buff[0].ToString(); //这下面是上位机右边那一段,用来显示处理好的数据的温度、湿度、光照、灰尘、ID信息的。buff【0】中存的是数据的ID信息,显示在ID的Label上面switch (buff[2]) //判断数据类型 buff【0】和buff【1】代表ID的低位和高位,同理2和3代表数据类型的低位和高位,当2和3的值为1时,4和5代表温度,6和7代表湿度;{ case 0x01: //当2和3的值为1,4和5是温度,6和7是湿度{Tem.Text = (buff[5] * 4 + buff[4] * 0.05 - 30).ToString();Hum.Text = (buff[6] + buff[7]).ToString();break;}case 0x02://6和7是光照{Light.Text = (buff[6] + buff[7]).ToString();break;}case 0x04://6和7是灰尘{Dust.Text = (buff[6] + buff[7]).ToString();break;}default:break;}}}}private void button3_Click(object sender, EventArgs e) //每次发一个字节{string[] sendbuff = richTextBox2.Text.Split(); //分割输入的字符串,判断有多少个字节需要发送Debug.WriteLine("发送字节数:"+sendbuff.Length);foreach (string item in sendbuff){int count = 1;byte[] buff = new byte[count];buff[0] = byte.Parse(item, System.Globalization.NumberStyles.HexNumber);//格式化字符串为十六进制数值s.Write(buff, 0, count);}}private void button2_Click(object sender, EventArgs e)//刷新右边的数值{int count = 1;byte[] buff = new byte[count];buff[0] = byte.Parse("04", System.Globalization.NumberStyles.HexNumber);//这里只显示04节点的信息s.Write(buff, 0, count);}} }
(以上规则均是本实验室节点内部自定义规则,测试的,外面的相应要改)
4、结果
5、补充四点知识
1)在程序可能会遇到错误的地方,用try+两个Tab键,将代码写入try中。比如本例子中的代码:
private void button1_Click(object sender, EventArgs e){try{if (!s.IsOpen){s.PortName = comboBox1.SelectedItem.ToString();s.BaudRate = Convert.ToInt32(comboBox2.SelectedItem.ToString());s.Open();s.DataReceived += s_DataReceived;button1.Text = "关闭串口";//MessageBox.Show("串口已打开");}else{s.Close();s.DataReceived -= s_DataReceived;button1.Text = "打开串口";}}catch (Exception ee){MessageBox.Show(ee.ToString());}}
如果代码没有写入try中,则可能出现的一种情况是比如有两个上位机,同时占用同一个串口,则就会冲突,会出错。程序就会终止,整个进程结束。而如果写入try中,并且把抛出异常的catch代码实例化,即捕获异常要实例化一个句柄,这样程序遇到error就不会终止,而会出现报错的原因。如下图,我的这个上位机和网上下载的一个上位机同时占用COM3串口(网上下载的先占用COM3),这时我的上位机在打开串口时会出现报错。
2)就我这个上位机而言,需要有打开串口和关闭串口两个button按钮,但是考虑到占地方,当然最重要的还是如果用两个按钮来表示,当你按下打开串口,如果忘了是否打开,则是看不出来是不是打开的,所以可以合并为一个button控件。(代码还是用上面那一段的代码)。(感觉很神奇啊)。在button1_Click事件中,先点击button,如果串口是关闭的,则打开串口,然后把button1.Text的值赋值为“关闭串口”,如果串口本来是关闭的,则点击按钮会把button1.Text的值赋值为“打开串口”,同时把接收的数据清空。感觉这个方法真的很不错!嘿嘿
3)当输入一个变量或方法什么的,它所有有的会自动出现在一个列表,这时,“正方体”代表“方法”,“小钳子”代表“变量”,“闪电”代表“事件”。
4) 产生对象的事件时
比如输入s.自动会出现DataReceived事件,再输入“+=”就会有如上图提示,按Tab键。然后又会如下图提示
再次按tab键,就会自动生成DataReceived事件处理函数。
C#做一个简单的进行串口通信的上位机相关推荐
- C#实现串口通信的上位机开发
目录 上位机 串口通信 C#串口通信:SerialPort类 列出所有的串口 C#串口通信:读写数据 写数据: 读数据: DataReceived事件: 数据发送不同步问题: 界面设计 波形显示(ch ...
- 使用C#进行串口通信开发上位机软件
因为工作需要 曾使用C#开发一款上位机软件,当时工期很赶,开发联调测试交付后就转向其他工作.一直念叨着要记录一下,这次五一终于如愿. 软件开发环境:操作系统windows64位,开发工具:VisioS ...
- matlab写的串口通信图像上位机,MATLAB的串口通信
属性 BaudRate Specify the rate at which bits are transmitted BreakInterruptFcn Specify t ...
- “Xilinx ZYNQ+TCP通信+Python上位机”实现实时视频传输系统
笔者在CSDN的第一篇万字长文,请多多支持. 本文是笔者的公众号 IC设计者笔记 文章的转载.很多优质原创内容都会第一时间发布在公众号,欢迎关注公众号,一起交流学习.公众号后台回复"ZYNQ ...
- 做一个简单的“远程”开关 ESP8266 + APP
简单的远程开关制作(纯代码.无解析版.UDP通信) 引言 本篇文章,我们将做一个超级简单的开关,当你学会该操作后,就可以自己进行一些简单的添加.修改从而实现一些自定义的功能.你可以做一个简单的远程开关 ...
- 用RC522与arduino做一个简单的门禁系统
用RC522与arduino做一个简单的门禁系统 插本成功要去新学校了,结果发现新学校宿舍没有电梯没有电子门(虽然海景房很香).这对于住惯养老院的我属实难受所所以打算自己也整一个IC卡的门禁系统.然后 ...
- 程序猿修仙之路--数据结构之你是否真的懂数组? c#socket TCP同步网络通信 用lambda表达式树替代反射 ASP.NET MVC如何做一个简单的非法登录拦截...
程序猿修仙之路--数据结构之你是否真的懂数组? 数据结构 但凡IT江湖侠士,算法与数据结构为必修之课.早有前辈已经明确指出:程序=算法+数据结构 .要想在之后的江湖历练中通关,数据结构必不可少.数据 ...
- 动手做一个简单的智能小车
动手做一个简单的智能小车 来到CNDN一年了,看到了许多大佬的杰出作品.也该写点什么来回馈给大家了前不久接触了单片机,想提前进行实践一下所以有想法做一个实体出来,想来想去难的怕自己搞不定,但是还好找到 ...
- pygame做一个简单的打字游戏
pygame做一个简单的打字游戏 1.基本代码 下面的代码完成了每一秒在界面的顶部随机生成一个新的字母 # -*- coding=utf-8 -*- import pygame from pygame ...
最新文章
- python中国地图热力图是什么意思_python实现输入的数据在地图上生成热力图效果...
- linux docker 限制容器可用的 cpu
- git svn 一个疯(傻)子的想法
- mysql back blog_mysql的备份Xtrabackup
- 数据库面试系列之二:视图
- char转成string_真没想到,一个小小的String居然还有这么多窍门?
- 11.使用ForwardAction实现页面屏蔽。
- 2021 最流行的十大项目,新项目居榜首,总有长江后浪推前浪!
- 文献学习(part30)--Clustering of temporal gene expression data by regularized spline regression and...
- 光纤收发器在使用过程中有哪些需要注意的事项?
- 跳过堡垒机,一键登陆
- mysql yum安装与配置文件_MySQL 8.0 yum安装和配置
- 梦幻群侠传5帮派修炼_梦幻封妖传5门派技能介绍 | 手游网游页游攻略大全
- 软件著作权申请流程(自助申请免费登记)
- php随机给用户抽奖,PHP随机按百分比抽奖
- 重磅!100位校高校教师晒工资,详细晒,全国各地!要进高校的博士们参考
- QQ、微博、陌陌:社交难逃社交命
- 台式机显示屏作为笔记本显示屏的设置
- 系统聚类算法并绘制谱系图
- 多台路由器,不同网段的设备之间如何互访?
热门文章
- WIN TO GO (WTG):windows装入U盘 WTG安装+拔出U盘强制关机蓝屏处理(win10)
- python pygame实现五子棋双人联机(简约版)
- html加入音乐没有声音,怎样为视频加音乐 视频添加背景音乐后输出没声音,给视频配音的方法...
- 鸿蒙不支持nas,群晖Video Station不支持dts eac3的解决方案
- jieba+wordcloud 分词+词频可视化 问题总结
- 音频:听声识曲,音乐均衡器与傅立叶变换算法,双音多频(DTMF)
- opencl 加速 c语言程序_在AlveoU200加速卡上实现简单手写数字识别
- 支付宝与微信新年红包战之我见
- Django实战(9)——为人脸识别系统添加随机抽签功能
- Mac 下QQ截图不能使用