本教程将帮助你从零开始学习C#编程,并使用C#构建上位机应用程序,本教程将以经典的串口工具开发为Demo,讲述一个项目如何去实现,因为粉丝朋友的要求本章决定先更新数据的收发处理。在上一章串口数据的收发处理我们讲到了3个比较重要的内容
1、异步线程更新UI:this.Invoke()
2、List<byte>数据缓存区的建立
3、字符编码格式的处理
this.Invoke():涉及到了委托,委托是C#的一大特色,从字面意思理解,委托就是一种代理,类似于房屋中介,由租房人委托中介为其租赁房屋,委托是一种引用类型,虽然在定义委托与方法类似, 但不能称其方法,对于委托我们将专门开一个章节讲解,这里不再展开。
List<T>:是在C#中,一种通用的动态数组(也称为可变大小数组),它可以存储特定类型(T)的元素。List<T>类是System.Collections.Generic命名空间中的一部分,它提供了一组用于操作和管理元素的方法和属性。
以下是List<T>的一些常用特性和用法:
动态大小:List<T>可以根据需要自动调整大小,可以动态地添加或删除元素。
类型安全:List<T>是类型安全的,因为它只能存储指定类型(T)的元素。这意味着在编译时会进行类型检查,避免了在运行时出现类型错误。
索引访问:可以通过索引来访问和修改List<T>中的元素。索引从0开始,例如list[0]表示第一个元素。
常用方法:List<T>提供了一系列常用的方法,例如Add(添加元素到列表末尾)、Remove(从列表中删除指定元素)、Contains(检查列表是否包含指定元素)等。
遍历:可以使用foreach循环遍历List<T>中的元素。
以下是一个示例代码,展示了如何创建、添加和遍历一个List<int>:
using System;
using System.Collections.Generic;
class Program
{
static void Main()
{
List<int> numbers = new List<int>();
numbers.Add(10);
numbers.Add(20);
numbers.Add(30);
foreach (int number in numbers)
{
Console.WriteLine(number);
}
}
}
List<T>是C#中常用的数据结构之一,可以方便地进行元素的添加、删除和访问,非常适用于需要动态管理元素的场景。
以上是我们对上节收发处理重要内容的回顾,接下来我们描述下串口数据发送的具体处理逻辑:
建立发送缓存区,以及发送计数器
建立焦点leave事件,当鼠标离开发送区时,根据16进制checkbox的状态处理发送区的数据并转换成指定的编码格式后添加至发送缓存区
调用数据发送方法,发送计数器计数
public partial class Form1 : Form
{
private bool portOpenFlag = false;
private bool isReceive = true;
//接收计数
private int receiveCount = 0;
//发送计数
private int sendCount = 0;
//接收缓存区
private List<byte> receiveBuffer = new List<byte>();
//发送缓存区
private List<byte > sendBuffer = new List<byte>();
建立焦点leave事件
新建一个leave事件的方法
/// <summary>
/// 判断checkbox的状态,根据状态处理相应内容
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void sendDataTB_Leave(object sender, EventArgs e)
{
if (hexSendCB.CheckState == CheckState.Checked)
{
if (DataEncoding.IsHexString(sendDataTB.Text.Replace(" ", "")))
{
sendBuffer.Clear();
sendBuffer.AddRange(Transform.ToBytes(sendDataTB.Text.Replace(" ", "")));
}
else
{
MessageBox.Show("请输入正确的十六进制数据!!");
sendDataTB.Select();
}
}
else
{
sendBuffer.Clear();
sendBuffer.AddRange(Encoding.GetEncoding("gb2312").GetBytes(sendDataTB.Text));
}
}
当发送区的16进制CheckBox被选中时调用下面的方法
// <summary>
/// 发送区16进制转换处理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void hexSendCB_CheckedChanged(object sender, EventArgs e)
{
if (sendDataTB.Text == " ") return;
if (hexSendCB.Checked )
{
sendDataTB.Text = Transform.ToHexString(sendBuffer.ToArray(), " ");
}
else
{
sendDataTB.Text = Encoding.GetEncoding("gb2312").GetString(sendBuffer.ToArray()).Replace("\0", "\\0");
}
}
Encoding.GetEncoding("gb2312"):获取指定编码(此处为GB2312)的编码器,用于将字节数组解码为字符串。
sendBuffer.ToArray():将sendBuffer集合转换为字节数组。ToArray()方法用于将集合中的元素复制到新的数组中。
GetString(sendBuffer.ToArray()):使用指定的编码器将字节数组解码为字符串。
Replace("\0", "\\0"):将字符串中的空字符(\0)替换为\0,并返回替换后的字符串。
sendDataTB.Text = ...:将转换后的字符串赋值给sendDataTB文本框的Text属性,即更新文本框中的显示内容。
新建一个数据发送的方法
/// <summary>
/// 数据发送方法,并将发送计数
/// </summary>
private void SendData()
{
serialPort1.Write(sendBuffer.ToArray(),0,sendBuffer.Count);
sendCount += sendBuffer.Count;
sendCountData.Text = sendCount.ToString();
}
在手动发送按钮的click事件中调用数据发送的方法
/// <summary>
/// 调用数据发送方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ManualSendBtn_Click(object sender, EventArgs e)
{
if (this.sendDataTB.Text != " " && serialPort1.IsOpen)
{
Console.WriteLine(Transform.ToHexString(sendBuffer.ToArray()));
SendData();
}
else
{
MessageBox.Show("请输入数据和检查串口是否打开");
}
}
版权所有:江苏和讯自动化设备有限公司所有 备案号:苏ICP备2022010314号-1
技术支持: 易动力网络