C#电源串口调试

目的
记录串口调试的遇到的一些问题以及相应的解决方法
1.串口定义:串口是计算机与其他硬件传输数据的通道,在计算机与外设通信时起到重要作用
2.串口通信的基础知识

  1. C#中的串口通信类
    C#使用串口通信类是SerialPort(),该类使用方法是
    new 一个 SerialPort对象
    为SerialPort对象准备参数
   _serialPort = new SerialPort(portName);_serialPort.BaudRate = bauRate;_serialPort.Parity = parity;_serialPort.DataBits = dataBits;_serialPort.StopBits = stopBits;_serialPort.Handshake = Handshake.None;_serialPort.ReadTimeout = 500;_serialPort.WriteTimeout = 500;

接下来就是打开串口并且绑定事件

  try{ErrorMessage = "";_serialPort.Open();if (_serialPort.IsOpen){_serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);return true;}else{Log.Debug($"Truth_Power.SerialPortHelper.Open().Return [{false.ToString()}]");return false;}}catch(Exception ex){ErrorMessage = ex.Message;Log.Error($"Truth_Power.SerialPortHelper.Open().Error [{ex.Message}]");return false;}

2.从串口读取数据
串口的性质不同于网络,网络发一个HTTP会返回一个完整的数据。例如请求一个网页,服务端就会返回完整的网页代码。
但是串口不同,串口不一定一次返回完整的数据,可能会分批次返回
例如我已知串口返回来的数据是10个字节但是第一次触发数据接收事件时可能返回5个,第二次再触发事件时返回剩下的5个。这样串口需要一个数据合并的代码,实例代码如下:

    private  void DataReceivedHandler(object sender,SerialDataReceivedEventArgs args){//端口缓冲区字节数,本次数据到达的字节数int n = _serialPort.BytesToRead;//  Console.WriteLine(n);//将端口缓冲区数据存入字节数组byte[] byteRev = new byte[n];_serialPort.Read(byteRev, 0, n);//将字节数组存入程序缓冲区string data = BitConverter.ToString(byteRev);// RecieveBuffer += data;         if (IsRead){ReadBuffer += "-"+data;   //拼接返回的数据}//if(ReadBuffer.Length == 20)                            //如果数据长度合格,则可以发出事件   这个事件不应该在回调中发出而是应该在writeRead函数中发出//{//    ReceivedDataFromPort.Invoke(command, byteRev, n);  //读出完整数据后再发出事件//}}
    public bool WriteAndRead(byte[] sendBytes, out string recieved, int timeOut = 1000, int stepTime = 20){IsRead = true;ReadBuffer = "";//公共变量recieved = "";//clearInput();      //清空串口if (Write(sendBytes)){int times = timeOut / stepTime;for (int i = 0; i < times; i++){recieved = ReadBuffer;         //获取截止到当前串口返回的数据Thread.Sleep(stepTime);        //这个延时一定要放在recived = ReadBuffer之后,如果20ms后ReadBuffer被更新,那么received!=ReadBuffer,这时就不会跳出循环if (recieved == "")           //如果这次读到是空先跳过,等下次再读{continue;}if (recieved == ReadBuffer)    //当某次达到满数据后可以直接跳出循。跳出后判断i的值,如果i达到times那么说明超时;如果小于times那么没有超时{break;}}clearOutput();IsRead = false;return true;}IsRead = false;Log.Debug($"Truth_Power.SerialPortHelper.WriteAndRead().Return [{false.ToString()}]");return false;}

3.C#跨线程访问
C#跨线程访问需要特殊的处理

  private void sendDataThread(){string fileName = "testdata.txt";StreamWriter sr;sr = new StreamWriter(fileName);const  int length = 10; ;//发送与返回的字节长度int timeOut = 1000;      //超时时间int stepTime = 20;       //时间间隔int n = 0;            //当前接收的数据长度string hexString;//现在的问题就是数据没有写入string dataRev;byte[] dataRecv = new byte[length];while (true){if (killed)                      //如果需要结束线程,那么用break跳出循环{sr.Close();break;}lock (Lock_Port){this.Dispatcher.Invoke(new Action(delegate{//你想要做的操作    ControlMode mode = ((MainWindowViewModel)this.DataContext).CurrentSelectedMode;int electric = ((MainWindowViewModel)this.DataContext).Electricity;int magetic = ((MainWindowViewModel)this.DataContext).Magnetic;int voltage = ((MainWindowViewModel)this.DataContext).Voltage;byte[] command;List<byte> data = new List<byte>();switch (mode){case ControlMode.Voltage:SerialPortCommand.SetVoltage(voltage, Sign.PositiveSign, out command);//这里可能要先清空_serialPortControl.command = command;_serialPortControl.Write(command.ToArray());_serialPortControl.WriteAndRead(command, out dataRev);timestamp = DateTime.Now.ToString();hexString = BitConverter.ToString(command);timestamp = DateTime.Now.ToString();sr.WriteLine("接收时间");sr.WriteLine(timestamp);sr.WriteLine("发送数据");sr.WriteLine(hexString);// hexString = BitConverter.ToString(receive);sr.WriteLine("接收数据");sr.WriteLine(dataRev);sr.WriteLine("接收数据长度");sr.WriteLine(dataRev.Length.ToString());sr.WriteLine("\n");break;case ControlMode.Magnetic:SerialPortCommand.SetMagetic(magetic);break;case ControlMode.Electricity:SerialPortCommand.SetElectric(electric, Sign.PositiveSign, out command);_serialPortControl.command = command;_serialPortControl.WriteAndRead(command, out dataRev);timestamp = DateTime.Now.ToString();hexString = BitConverter.ToString(command);timestamp = DateTime.Now.ToString();sr.WriteLine("接收时间");sr.WriteLine(timestamp);sr.WriteLine("发送数据");sr.WriteLine(hexString);// hexString = BitConverter.ToString(receive);sr.WriteLine("接收数据");sr.WriteLine(dataRev);sr.WriteLine("接收数据长度");sr.WriteLine(dataRev.Length.ToString());sr.WriteLine("\n");break;}}));}Thread.Sleep(1000);                                         //延时1秒,保证电源有时间响应}

4.串口指令生成
写串口实质上是向串口写入数据
数据本质上一串字节型数据,一般有固定的格式。帧头-命令字-数据部分-帧尾,值得关注就是数据部分。
在这里插入图片描述

以这个图片为例,取出32位Int型数据的某八位可以用>>(移位)和&(且)
如果取出高第二个字节

(byte)((dataLength >> 16) & 0xFF)

如果取出Int型数据的低8位

(byte)(dataLength & 0xFF)

5.关于combox selectedChange事件 运行程序立即执行的问题
解决这个bug需要在切换事件中判断串口是否打开,如果未打开则事件立即返回。代码如下:

   //选中的改变之后,根据当前的选中值更新//核心获取改变之后的值if (!_isOpenForPort){MessageBox.Show("串口未打开");return;}

6.返回重复数据的bug的原因
换成新的WriteAndRead函数后没有把原来的函数Write删掉
在这里插入图片描述
删掉这行代码之后串口接收到的数据就正常了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/238375.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C语言】自定义类型:结构体深入解析(二)结构体内存对齐宏offsetof计算偏移量结构体传参

文章目录 &#x1f4dd;前言&#x1f320; 结构体内存对齐&#x1f309;内存对齐包含结构体的计算&#x1f320;宏offsetof计算偏移量&#x1f309;为什么存在内存对⻬?&#x1f320; 结构体传参&#x1f6a9;总结 &#x1f4dd;前言 本小节&#xff0c;我们学习结构的内存对…

R语言【cli】——通过cli_abort用 cli 格式的内容显示错误、警告或信息,内部调用cli_bullets和inline-makeup

cli_abort(message,...,call .envir,.envir parent.frame(),.frame .envir ) 先从那些不需要下大力气理解的参数入手&#xff1a; 参数【.envir】&#xff1a;进行万能表达式编译的环境。 参数【.frame】&#xff1a;抛出上下文。默认用于参数【.trace_bottom】&#xff…

Redis实现日榜|直播间榜单|排行榜|Redis实现日榜01

前言 直播间贡献榜是一种常见的直播平台功能&#xff0c;用于展示观众在直播过程中的贡献情况。它可以根据观众的互动行为和贡献值进行排名&#xff0c;并实时更新&#xff0c;以鼓励观众积极参与直播活动。 在直播间贡献榜中&#xff0c;每个观众都有一个对应的贡献值&#…

力扣日记12.21【二叉树篇】98. 验证二叉搜索树

力扣日记&#xff1a;【二叉树篇】98. 验证二叉搜索树 日期&#xff1a;2023.12.21 参考&#xff1a;代码随想录、力扣 98. 验证二叉搜索树 题目描述 难度&#xff1a;中等 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义…

啥?你还不道数据库?赶紧进来看吧!

操作系统&#xff1a; windows&#xff1a;win10、win11、win7、windows Server2016 Linux/Unix &#xff1a;红帽&#xff08;RedHat&#xff09;、Bebian、SUSE MacOS Linux系统&#xff1a;CantOS&#xff08;yum、dnf&#xff09;、Ubuntu&#xff08;apt、apt—get&am…

Ubuntu 常用命令之 df 命令用法介绍

&#x1f4d1;Linux/Ubuntu 常用命令归类整理 在Ubuntu系统下&#xff0c;df命令是用来查看文件系统的磁盘空间占用情况的。df是disk free的缩写&#xff0c;这个命令可以获取硬盘被占用了多少空间&#xff0c;还有多少空间是可用的&#xff0c;硬盘的挂载点等信息。 df命令的…

【Python】matplotlib画图_饼状图

柱状图主要使用pie()函数&#xff0c;基本格式如下&#xff1a; plt.pie(x,explodeNone,labelsNone,colorsNone,autopctsNone,pctdistance0.6,shadowFalse,labeldistance1.1,staatangleNone,radiusNone,counterclockTrue,wedgepropsNone,textpropsNone,center(0,0),frameFalse…

PIC单片机项目(7)——基于PIC16F877A的智能灯光设计

1.功能设计 使用PIC16F877A单片机&#xff0c;检测环境关照&#xff0c;当光照比阈值低的时候&#xff0c;开灯。光照阈值可以通过按键进行设置&#xff0c;同时阈值可以保存在EEPROM中&#xff0c;断电不丢失。使用LCD1602进行显示&#xff0c;第一行显示测到的实时光照强度&a…

代码随想录算法训练营Day7 | 344.反转字符串、541.反转字符串||、替换数字、151.反转字符串中的单词、右旋字符串

LeetCode 344 反转字符串 本题思路&#xff1a;反转字符串比较简单&#xff0c;定义两个指针&#xff0c;一个 i 0, 一个 j s.length-1。然后定义一个临时变量 tmp&#xff0c;进行交换 s[i] 和 s[j]。 class Solution {public void reverseString(char[] s) {int i 0;int …

华为二层交换机与防火墙配置实例

二层交换机与防火墙对接上网配置示例 组网图形 图1 二层交换机与防火墙对接上网组网图 二层交换机简介配置注意事项组网需求配置思路操作步骤配置文件相关信息 二层交换机简介 二层交换机指的是仅能够进行二层转发&#xff0c;不能进行三层转发的交换机。也就是说仅支持二层…

OceanMind海睿思入选中国信通院首批“高质量智能审计工具目录”,获多项认证

近日&#xff0c;由中国信息通信研究院&#xff08;以下简称“中国信通院”&#xff09;、中国通信标准化协会支持的“2023 GOLF IT新治理领导力论坛”在北京顺利举行。 中新赛克海睿思作为国内领先的审计数字化代表企业受邀参会。 在内部审计数字化转型走深向实以及智能化演进…

【Spring Boot】面试题汇总,带答案的那种

继上次的文章【MySQL连环炮&#xff0c;你抗的住嘛&#xff1f;】爆火之后&#xff0c;越来越多的小伙伴后台留言&#xff0c;要求阿Q总结下其他的“连环炮”知识点&#xff0c;想在金九银十的面试黄金期轻松对线面试官。 同样为了节省大家的时间&#xff0c;阿Q最近对【Sprin…

性能优化之资源优化

性能优化之资源优化 资源优化性能关键检测流程。浅析一下基于Unity3D 美术规则约束一、模型层面二、贴图层面三、动画层面四、声音层面&#xff1a;&#xff08;音频通用设置&#xff09;五、UI层面&#xff1a; 题外点&#xff1a;诚然在优化中&#xff0c;美术占比是很重要的…

搭建接口自动化测试框架python+requests+pytest

安装python&#xff08;最好是比较新比较稳定的版本&#xff09;&#xff0c;然后是python的解释器或者叫编译器pycharm安装后新建一个项目&#xff0c;以此项目为基础&#xff0c;安装依赖搭建框架。打开pycharm&#xff0c;点击左上角的File->New project->弹出如下界面…

通过navcat的ssh连接 将一个服务器当作跳板连接远程mysql

文章目录 通过ssh连接一个服务器当作跳板连接远程mysql 通过ssh连接一个服务器当作跳板连接远程mysql 简单来说 一共三台机器 windows Linux&#xff08;入口&#xff09; Linux&#xff08;mysql&#xff09; windows 可以通过ssh 私钥连接Linux&#xff08;入口&#xff09;…

开发模型和测试模型

1. 开发模型 1.1 瀑布模型 瀑布模型是其他模型的基础框架 start—>需求分析---->计划----->设计----->编码----->测试----->End&#xff08;其实就是软件开发的生命周期&#xff09; 特点&#xff1a;线性的开发流程 缺陷&#xff1a;测试被后置。①风险往…

OpenCV-Python(18):图像梯度

目录 背景介绍及应用 学习目标 原理 Sobel算子和Scharr算子 Laplacian 算子 代码示例 重要提醒 背景介绍及应用 图像的梯度是指图像中每个像素点的强度变化情况。计算图像的梯度可以帮助我们了解图像中物体的边界和纹理等信息。梯度在计算机视觉和图像处理领域有着广泛…

超分辨数据集:Set5 Set14 BSD100 Urban100 Manga109

DIV2K数据集官网上很好找到&#xff0c;但是网上流传的Set5 14 BSD100,Urban100 Manga109都是私人进行处理过的版本&#xff0c;各个处理方式都不同&#xff0c;为了统一方式写了这篇文章。 官方的DIV2K x2、x3、x4的LR图片使用下面matlab代码生成&#xff08;已经经过测试最后…

基于单片机设计的指纹锁(读取、录入、验证指纹)

一、前言 指纹识别技术是一种常见的生物识别技术&#xff0c;利用每个人指纹的唯一性进行身份认证。相比于传统的密码锁或者钥匙锁&#xff0c;指纹锁具有更高的安全性和便利性&#xff0c;以及防止钥匙丢失或密码泄露的优势。 基于单片机设计的指纹锁项目是利用STC89C52作为…

ARM GIC(三) gicv2架构

ARM的cpu,特别是cortex-A系列的CPU,目前都是多core的cpu,因此对于多core的cpu的中断管理,就不能像单core那样简单去管理,由此arm定义了GICv2架构,来支持多核cpu的中断管理 一、gicv2架构 GICv2,支持最大8个core。其框图如下图所示: 在gicv2中,gic由两个大模块组成: …