一、简介
RFID卡
RFID卡,即射频识别卡,英文全称为Radio Frequency Identification,是一种无线通信技术。它可以通过无线电信号识别特定目标并读写相关数据,而无需识别系统与特定目标之间建立机械或者光学接触。这种技术具有非接触式的特点,识别工作无须人工干预,并且可以工作于各种恶劣环境。
RFID卡的应用范围广泛,包括门禁保安、资产管理、物流行业、智慧医疗等多个领域。通过RFID技术,可以实现对目标对象的自动识别、跟踪和管理,提高工作效率和安全性。例如,门禁保安系统使用RFID卡可以简化出入手续,提高工作效率;在物流行业中,RFID技术可以实现货物的实时跟踪和定位,提高物流运营效率。
Visual Studio
Visual Studio是微软公司推出的一个集成开发环境(IDE),用于支持多种程序设计语言的开发,包括Visual C++(从6.0版后并入Visual Studio)。它为程序员提供了丰富的工具和功能,以便更高效地编写、调试和管理代码。此外,Visual Studio还提供了版本控制、团队协作等支持,是开发人员在开发过程中不可或缺的工具。
本文使用的Visual Studio版本为2022,可自行前往VS官网https://visualstudio.microsoft.com/zh-hans/vs/下载适合的版本
C#
C#(读作C sharp)是一种由微软公司开发的面向对象的编程语言。它是由安德斯·海尔斯伯格领导的团队在2000年首次发布的。C#是.NET框架的主要开发语言,同时也是开发Windows操作系统应用程序的首选语言。
C#结合了C++和Java的特点,去除了C++中容易引起错误的功能,并加入了Java的泛型和反射功能。这使得C#具有了类型安全、组件技术、泛型编程以及版本控制等特性。
此外,C#还具有简单易学、开发效率高、可移植性强等特点,因此受到了广泛的欢迎。
二、通过本文可实现的功能
1、使用Visual Studio和C#设计一个低频卡APP,可以通过该APP设置串口各个属性(端口号,波特率,数据位,停止位,奇偶校验位);
2、使用串口手动发送数据的方法
3、使用串口手动接收数据的方法
4、使用数据转换、调整数据
三、步骤教程
步骤1:创建项目
打开Visual Studio软件(此处使用2022版本),选择创建新项目
这里需要注意的是,这里要选择C#语言后搜索Windows窗体应用,最后选择Windows窗体应用(.NET Framework)
按自己喜好为项目进行命名
完成项目的创建后,我们就进入到了窗体的设计界面
步骤2:设置界面
我们需要在左上角的工具箱中搜索以下内容
可以根据自己的习惯,在右下角的属性中对他们的Name和Text进行修改
最终将窗体大概设计成这样:
步骤3:手动发送和接收(部分代码)
1.手动发送:
private void btSend_Click(object sender, EventArgs e) //手动发送数据
{
//发送字符串“ABCD”
byte[] ss = { 0xff, 0x55, 0x00, 0x00, 0x01, 0x01, 0x00, 0x50, 0x74 }; //创建数组变量
//byte[] xx = new byte[] { 0xff, 0x55, 0x00, 0x01, 0x01, 0x00, 0x50, 0x74 }; //创建数组对象
//COM.Write("ABCD"); //发送字符串的方式1
//COM.Write(textBox1.Text); //发送字符串的方式2
COM.Write(ss,0,ss.Length); //发送字节数组方式
}
2.手动接收:
private void btReceive_Click(object sender, EventArgs e) //手动接收
{
int len = COM.BytesToRead; //获取接收到数据的数量
byte[] rr = new byte[len]; //创建一个字节变量数组,数组长度与串口接收到的数据长度相同
COM.Read(rr,0,rr.Length); //将串口读取到的数据存放在rr字节数组中
for (int i = 0; i < len; i++)
{
txtReceive.Text += rr[i].ToString("X").PadLeft(2, '0')+" ";
}
}
3.如何将字符串“FF 55 00 00 01 01 00 50 74”转换成字节数组并保存
//<summary>
//把十六进制格式的字符串转换成字节数组
//</summary>
//<param name="pString">要转换的十六进制格式的字符串</param>
//<returns>返回字节数组。</returns>
public static byte[] getBytesFromString(String pString) //将字符串转变成字节的“方法=函数”
{
//str1="FF 55 00 00 01 01 00 50 74"
string[] str = pString.Split(' '); //将字符切成一段段的字符串/把十六进制格式的字符串按空格转换为字符串数组
byte[] bytes = new byte[str.Length]; //创建字节数组,用来接收字符串转变后的字节/定义字节数组并初始化,长度为字符串数组的长度
for(int i=0; i < str.Length;i++) //遍历字符串数组,把每个字符串转换成字节类型赋值给每个字节变量
{
bytes[i] = Convert.ToByte(Convert.ToInt32(str[i],16));
}
return bytes; //返回字节数组
}
4.如何将接收到的字节转换成字符串
//把字节数组转换为十六进制格式的字符串.
//<param name="pByte">要转换的字节数组.</param>
//<returns>返回十六进制格式的字符串.</returns>
public static string getStringFromBytes(byte[] pByte) //将字节数组转变成字符串,以便于显示
{
//byte1 = (ff,55,00,00,01......74)
string str = " "; //定义字符串类型临时变量
//遍历字节数组,把每个字节转换成十六进制字符串。
//不足两位前面添“0”,以空格分隔累加到字符串变量里
for (int i = 0; i < pByte.Length; i++) //遍历字节数组,把每个字节转换成十六进制字符串
{
str += (pByte[i].ToString("X").PadLeft(2, '0')+" ");//不足两位前面添“0”,以空格分隔累加到字符串变量里
str = str.TrimEnd(' '); //去掉字符串末尾的空格。
}
return str; //返回字符串临时变量
// str="ff 55 00 00 01......74"
}
5.如何获取CRC16最后两个校验字节
//C# CRC16校验算法
public static byte[] crc16(byte[] data, int len)
{
byte[] temdata = new byte[2];
int xda, xdapoly;
byte i, j, xdabit;
xda = 0xFFFF;
xdapoly = 0xA0001;
for (i = 0; i < data.Length; i++)
{
xda ^= data[i];
for (j = 0; j < 8; j++)
{
xdabit = (byte)(xda & 0x01);
xda >>= 1;
if (xdabit == 1)
xda ^= xdapoly;
}
}
temdata[0] = (byte)(xda & 0xFF);
temdata[1] = (byte)(xda >> 8);
return temdata;
}
6.如何发送指令获取低频卡信息
private void btnInformation_Click(object sender, EventArgs e)
{
txtSend.Text = "";
txtReceive.Text = "";
status_num = 1;
String str1 = "FF 55 00 00 01 01 00 50 74";
byte[] data = getBytesFromString(str1);
com.Write(data, 0, data.Length);
txtSend.Text = str1;
}
四、完整代码展示
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;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
SerialPort COM = new SerialPort("COM1",9600,Parity.None,8,StopBits.One);
public Form1()
{
InitializeComponent();
comboBox1.SelectedIndex = 0;
comboBox2.SelectedIndex = 0;
//comboData.SelectedIndex = 0;
//comboParity.SelectedIndex = 0;
}
//窗体加载
private void Form1_Load(object sender, EventArgs e)
{
comboBox1.SelectedIndex = 1;
//串口初始化
//byte i = 0x06;
//textBox1.Text = i.ToString("X").PadLeft(3, '0');
}
private void button1_Click(object sender, EventArgs e)
{
if (!COM.IsOpen) //假如串口没有打开,则打开串口
{
COM.PortName = comboBox1.Text;
COM.Open();
button1.Text = "关闭串口";
}
else
{
COM.Close();
button1.Text = "打开串口";
}
}
private void btSend_Click(object sender, EventArgs e) //手动发送数据
{
//发送字符串“ABCD”
byte[] ss = { 0xff, 0x55, 0x00, 0x00, 0x01, 0x01, 0x00, 0x50, 0x74 }; //创建数组变量
//byte[] xx = new byte[] { 0xff, 0x55, 0x00, 0x01, 0x01, 0x00, 0x50, 0x74 }; //创建数组对象
//COM.Write("ABCD"); //发送字符串的方式1
//COM.Write(textBox1.Text); //发送字符串的方式2
COM.Write(ss,0,ss.Length); //发送字节数组方式
}
private void btReceive_Click(object sender, EventArgs e) //手动接收
{
int len = COM.BytesToRead; //获取接收到数据的数量
byte[] rr = new byte[len]; //创建一个字节变量数组,数组长度与串口接收到的数据长度相同
COM.Read(rr,0,rr.Length); //将串口读取到的数据存放在rr字节数组中
for (int i = 0; i < len; i++)
{
txtReceive.Text += rr[i].ToString("X").PadLeft(2, '0')+" ";
}
}
//<summary>
//把十六进制格式的字符串转换成字节数组
//</summary>
//<param name="pString">要转换的十六进制格式的字符串</param>
//<returns>返回字节数组。</returns>
public static byte[] getBytesFromString(String pString) //将字符串转变成字节的“方法=函数”
{
//str1="FF 55 00 00 01 01 00 50 74"
string[] str = pString.Split(' '); //将字符切成一段段的字符串/把十六进制格式的字符串按空格转换为字符串数组
byte[] bytes = new byte[str.Length]; //创建字节数组,用来接收字符串转变后的字节/定义字节数组并初始化,长度为字符串数组的长度
for(int i=0; i < str.Length;i++) //遍历字符串数组,把每个字符串转换成字节类型赋值给每个字节变量
{
bytes[i] = Convert.ToByte(Convert.ToInt32(str[i],16));
}
return bytes; //返回字节数组
}
//把字节数组转换为十六进制格式的字符串.
//<param name="pByte">要转换的字节数组.</param>
//<returns>返回十六进制格式的字符串.</returns>
public static string getStringFromBytes(byte[] pByte) //将字节数组转变成字符串,以便于显示
{
//byte1 = (ff,55,00,00,01......74)
string str = " "; //定义字符串类型临时变量
//遍历字节数组,把每个字节转换成十六进制字符串。
//不足两位前面添“0”,以空格分隔累加到字符串变量里
for (int i = 0; i < pByte.Length; i++) //遍历字节数组,把每个字节转换成十六进制字符串
{
str += (pByte[i].ToString("X").PadLeft(2, '0')+" ");//不足两位前面添“0”,以空格分隔累加到字符串变量里
str = str.TrimEnd(' '); //去掉字符串末尾的空格。
}
return str; //返回字符串临时变量
// str="ff 55 00 00 01......74"
}
//C# CRC16校验算法
public static byte[] crc16(byte[] data, int len)
{
byte[] temdata = new byte[2];
int xda, xdapoly;
byte i, j, xdabit;
xda = 0xFFFF;
xdapoly = 0xA0001;
for (i = 0; i < data.Length; i++)
{
xda ^= data[i];
for (j = 0; j < 8; j++)
{
xdabit = (byte)(xda & 0x01);
xda >>= 1;
if (xdabit == 1)
xda ^= xdapoly;
}
}
temdata[0] = (byte)(xda & 0xFF);
temdata[1] = (byte)(xda >> 8);
return temdata;
}
}
}