RFID综合项目实训 | 基于C#的一卡通管理系统

news2025/6/2 3:36:43

目录

基于C#的一卡通管理系统

【实验目的】

【实验设备】

【实验内容】

【实验步骤】

实验准备

第一部分 界面布局设计

​第二部分 添加串口通讯函数及高频标签操作功能函数(部分代码)

第五部分 实验运行效果


基于C#的一卡通管理系统

【实验目的】

  1. 熟悉 Visual Studio 的使用
  2. 熟练掌握 C#语言 WinForm 开发
  3. 熟悉 13.56M TypeA 标签卡操作协议

【实验设备】

1、硬件:13.56M 高频 RFID 模块、ISO14443 TypeA 标签卡,miniUSB 线,PC 电脑;

2、软件: PC 机操作系统 Windows(XP、7、10) + Visual Studio 2022开发环境

【实验内容】

在Visual Studio 平台上使用C#语言Winform 开发基于 13.56M TypeA 标签卡的一卡通管理系统。

【实验步骤】

  实验准备

1、在visual Studio 2022中安装和配置C#环境

参考博客:C#学习visual Studio 2022安装与配置详细过程_vs2022怎么配置c#环境-CSDN博客

第一部分 界面布局设计

1、设计界面布局,需要设计一个主界面。通过 Visual Studio 自带的组件完成布局操作。主界面布局参考:(主要包含 Label、TextBox、ComboBox、RadioButton、GroupBox、Button、StatusStrip、ToolStripStatusLabel 组件)

2、各组件属性与事件设置

第二部分 添加串口通讯函数及高频标签操作功能函数(部分代码)

        1、在主界面代码中,添加动态获取电脑上的串口并自动添加到串口设置列表中的函数,代码如下:

private void initComComboBox()
{
    RegistryKey keyCom =         
    Registry.LocalMachine.OpenSubKey("Hardware\\DeviceMap\\SerialComm");                 
    mSerialComboBox.Items.Clear();
    if (keyCom != null)
    {
         string[] sSubKeys = keyCom.GetValueNames(); 
         foreach (string sName in sSubKeys)
         {
              string sValue = (string)keyCom.GetValue(sName); 
              mSerialComboBox.Items.Add(sValue); mSerialComboBox.SelectedIndex = 0;
         }
    }
}

        2、然后添加串口操作函数,包括打开串口,关闭串口,串口发送和串口接收,其中串口接收使用线程来完成,使用的非阻塞方式,所以间隔 50 毫秒读取一次串口数据,将串口数据存储到缓冲区 byteRecBuff 内,代码如下:

//打开串口
private void openSerial()
{
    try
    {
        SwitchCOMThread(mSerialComboBox.Text); 
        btnSerialConnect.Enabled = false;         
        btnSerialDisconnect.Enabled = true;
        showMsg("串口:连接成功!");
    }
    catch (Exception ex)
    {
        showMsg("串口:" + ex.Message);
    }
}
//关闭串口
private void closeSerial()
{
    try
    {
        if (mSerialPort.IsOpen)
        {
            mSerialPort.Close();
        }
        //清空缓冲区 
        iDataIn = 0;
        iDataOut = 0; 
        btnSerialConnect.Enabled = true; 
        btnSerialDisconnect.Enabled = false;
        showMsg("串口:断开连接!");
    }
    catch (Exception ex)
    {
        showMsg("串口:" + ex.Message);
    }
}
//串口数据发送
private bool serialSend(byte[] msg)
{
    if (mSerialPort.IsOpen)
    {
 
        try
        {

            mSerialPort.Write(msg, 0, msg.Length); 
            return true;
        }
 
        catch (Exception ex)
        {
 
            showMsg("串口:" + ex.Message); 
            return false;

        }
    }
    else
    {
  
        showMsg("串口:请先建立连接!");
    }
    return false;
}
//串口数据接收
private void serialReceive()
{
    if (mSerialPort.IsOpen)
    {
    try
    {

        int i = 0;
        int iDataLen = mSerialPort.BytesToRead; 
        if (iDataLen > 50) iDataLen = 50;
        //读取缓冲区的数据到数组
        mSerialPort.Read(bytesData, 0, iDataLen); 
        if (bLock == false)
        {
 
            bLock = true;
            if (iDataIn + iDataLen <= MaxLen)
            {
                for (i = 0; i < iDataLen; i++)
                {
                    byteRecBuff[iDataIn + i] = bytesData[i];
                }
                iDataIn += iDataLen;
            }
            else if (iDataIn + iDataLen == MaxLen)
            {
                for (i = 0; i < iDataLen; i++)
                {
                    byteRecBuff[iDataIn + i] = bytesData[i];
                }
                iDataIn = 0;
            }
            else
            {
                for (i = iDataIn; i < MaxLen; i++)
                {
 
                    byteRecBuff[i] = bytesData[i - iDataIn];
                }
                for (i = 0; i < iDataLen - MaxLen + iDataIn; i++)
                {
                    byteRecBuff[i] = bytesData[i + MaxLen - iDataIn];
                }
                iDataIn = iDataLen - MaxLen + iDataIn;
            }
            bLock = false;
        }
    }
    catch (Exception ex)
    {
        showMsg("串口:" + ex.Message);
        bLock = false;
    }
}
//接收数据线程
private void serialThreadReceive()
{
    while (bThread)
    {
        serialReceive(); Thread.Sleep(50);
    }
}
//启动接收线程
private void recvThreadStart()
{
    Thread newthread = new Thread(new ThreadStart(serialThreadReceive));     
    newthread.Start();
}
//关闭接收线程
private void recvThreadStop()
{
    bThread = false;
}

3、再添加从串口缓冲区内将数据读取并初步提取的函数,代码如下:

private void scanData()
{
    if (bLock == false)
    {
        bLock = true;
        int iValidLen, iPacketLen; 
        while (iDataIn != iDataOut)
        {
            if (byteRecBuff[dataOutAdd(0)] == (byte)0x00 && byteRecBuff[dataOutAdd(1)]== (byte)0x00 && byteRecBuff[dataOutAdd(2)] == (byte)0xFF)//判断包头
        {
            if (byteRecBuff[dataOutAdd(3)] == (byte)0x00)
            {
                iDataOut = dataOutAdd(6); 
                bLock = false;
                //包含有效数据长度
                iValidLen = validReceiveLen(); 
                if (iState == 0 && iValidLen < 8)
                {
                    HF1356MReadUid();
                }
                return;
            }
            else
            {
                //包含有效数据长度 
                iValidLen = validReceiveLen();
                if (iValidLen < 8)
                { 
                    bLock = false;
                    return;
                }
                iPacketLen = byteRecBuff[dataOutAdd(3)] + 7; 
                if (iValidLen < iPacketLen)
                {
                    bLock = false;
                    return;
                }
                // 判断数据包是否完整
                if (iPacketLen > 7 && iPacketLen < 40)
                {
                    //读出一个数据包
                    byte[] Packet = new byte[iPacketLen]; 
                    for (int i = 0; i < iPacketLen; i++)
                    {
                        Packet[i] = byteRecBuff[dataOutAdd(i)];
                    }
                    handleData(Packet);
                    iDataOut = dataOutAdd(iPacketLen);
                    bLock = false;
                    return;
                }
            }
        }
        iDataOut = dataOutAdd(1);
    }
    bLock = false;
}
//返回数据缓冲区内的有效数据长度 
private int validReceiveLen()
{
    if (iDataOut < iDataIn)
    {
        return (iDataIn - iDataOut);
    }
    else if (iDataOut > iDataIn)
    {
        return (MaxLen - iDataOut + iDataIn);
    }
    return 0;
}
//返回后面第 iNum 有效数据的位置
private int dataOutAdd(int iNum)
{
    int ret = 0;
    if (iDataOut + iNum < MaxLen)
    {
        ret = iDataOut + iNum;
    }
    else if (iDataOut + iNum > MaxLen)
    {
        ret = iDataOut + iNum - MaxLen;
    }
    return ret;
}

第五部分 实验运行效果

1、将实验箱通电,使用 MiniUSB 线连接 PC 机和 13.56M 模块,同时将模块上的拨码开关拨到右边(USB),这样才能保证模块和 PC 能够正常通讯;

2、运行程序“EcardSystem.exe”,程序运行成功后主登录界面,此时暂时无法操作扣费系统也无法操作充值系统,如下图:

3、软件中选择正确的串口号(在设备管理器当中查看 USB 转串口的串口号,如果未出现串口号,需要先安装 CP2102 USB 转串口驱动)并点击连接,此时程序会自动发送唤醒模块的指令,如果唤醒成功,扣费系统和充值系统就可以正常使用了;

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

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

相关文章

mysql如何设置update时间字段自动更新?

之前在给网站做表设计的时候时间字段都是用的datetime类型&#xff0c;初始值都是设置的CURRENT_TIMESTAMP。 由于给文章表设计的有创建时间和更新时间两个字段&#xff0c;但是更新时间字段需要在更新文章后再次更新&#xff0c;当时由于不了解mysql还可以设置自动更新时间戳…

【第4章 图像与视频】4.5 操作图像的像素

文章目录 前言示例-获取和修改图像数据图像数据的遍历方式图像滤镜负片滤镜黑白滤镜浮雕滤镜filter滤镜属性 前言 getImageData() 与 putImageData() 这两个方法分别用来获取图像的像素信息&#xff0c;以及向图像中插入像素。与此同时&#xff0c;如果有需要&#xff0c;也可…

Science Advances 上海理工大学与美国杜克大学(Duke University)共同开发了一种仿生复眼相机

编辑丨%科学家开发了一种 AI 辅助的仿生复眼相机。炎炎夏日&#xff0c;相信各位读者都有被蚊子骚扰过的恼火记忆。但往往想要清剿蚊子的时候&#xff0c;却被它灵巧地躲开&#xff0c;再难找到。诸如蚊子这种节肢动物的视觉系统已经进化了 5 亿多年&#xff0c;从寒武纪一直到…

正点原子Z20 ZYNQ ​​​开发板​​发布!板载FMC LPC、LVDS LCD和WIFI蓝牙等接口,资料丰富!

正点原子Z20 ZYNQ ​​​开发板​​发布&#xff01;板载FMC LPC、LVDS LCD和WIFI&蓝牙等接口&#xff0c;资料丰富&#xff01; 正点原子新品Z20 ZYNQ开发板来啦&#xff01;核心板全工业级设计&#xff0c;主控芯片型号是XC7Z020CLG484-2I。开发板由核心板底板组成&…

软件测评中心如何确保软件品质?需求分析与测试计划很关键

软件测评中心承担着对软件进行评估、测试和审查的任务&#xff0c;它有一套规范的流程来确保软件的品质&#xff0c;并且能够向客户和开发者提供详实的软件状况分析报告。 需求分析环节 这一环节至关重要&#xff0c;必须与客户和开发团队保持密切交流。我们需要从他们那里精…

2025LitCTF 复现

easy_file 登录界面 尝试admin 和密码1 没成功 结果尝试了弱口令 admin 用户和 password 密码就登录成功了 文件上传 新建一个空的 新建木马.txt 文件发现上传成功 然后写入一句话木马 <?php eval($_POST[a]); ?> 上传失败 说明可能是有字符被过滤了&#xff0c;猜…

使用C# 快速删除Excel表格中的重复行数据-详解

目录 简介 使用工具 C# 删除Excel工作表中的重复行 C# 删除指定Excel单元格区域中的重复行 C# 基于特定列删除重复行 RemoveDuplicates 方法快速比较 简介 重复行是指在Excel表格中完全相同的多行数据。这些冗余行的存在可能源于多种原因&#xff0c;例如&#xff1a; …

WPF-Prism学习笔记之 “导航功能和依赖注入“

新建空白模板(Prism) 新建好后会有自动创建ViewModels和Views 在"MainWindow.xaml"文件里面标题去绑定了一个属性"Title"&#xff0c;而"MainWindowViewModel.cs"里面继承一个非常重要的"BindbleBase"(prism框架里面非常重要的)。所以…

中国城市间地理距离矩阵(2024)

1825 中国城市间地理距离矩阵(2024) 数据简介 中国城市间地理距离矩阵数据集&#xff0c;通过审图号GS(2024)0650的中国城市地图在Albers投影坐标系中进行计算得出矩阵表格&#xff0c;单位为KM&#xff0c;方便大家研究使用。 中国城市地理距离矩阵数据通过计算城市中心距离…

【备战秋招】C++音视频开发经典面试题整理

1、简要介绍一下对 H.264 的了解&#xff1f; 1&#xff09;基础描述 H.264 是由国际标准组织机构&#xff08;ISO&#xff09;下属的运动图象专家组&#xff08;MPEG&#xff09;和国际电传视讯联盟远程通信标准化组织&#xff08;ITU-T&#xff09;开发的系列编码标准之一。…

《java创世手记》---java基础篇(下)

《Java 创世手记 - 基础篇&#xff08;下&#xff09;》 第五章&#xff1a;契约与规范 —— 接口 (Interfaces) 与抽象类 (Abstract Classes) 造物主&#xff0c;在你日益繁荣的世界里&#xff0c;你发现仅仅依靠“继承”来构建“物种体系”有时会遇到一些限制。比如&#x…

【MySQL】C语言连接

要使用C语言连接mysql&#xff0c;需要使用mysql官网提供的库&#xff0c;大家可以去官网下载 我们使用C接口库来进行连接 要正确使用&#xff0c;我们需要做一些准备工作: 保证mysql服务有效在官网上下载合适自己平台的mysql connect库&#xff0c;以备后用 下载开发库 s…

新能源汽车与油车销量

中国油车与新能源车销量对比&#xff08;2022-2025年&#xff09; ‌1. 市场份额演化&#xff08;2022-2025年&#xff09;‌ ‌年份‌ ‌新能源车销量 &#xff08;渗透率&#xff09;‌ ‌燃油车销量 &#xff08;渗透率&#xff09;‌ ‌关键事件‌ ‌2022‌ 688.7万辆…

基于Java,SpringBoot,Vue,UniAPP宠物洗护医疗喂养预约服务商城小程序管理系统设计

摘要 随着宠物经济的快速发展&#xff0c;宠物主对宠物服务的便捷性、专业性需求日益增长。本研究设计并实现了一套宠物洗护医疗喂养预约服务小程序系统&#xff0c;采用 Java 与 SpringBoot 构建后端服务&#xff0c;结合 Vue 开发管理后台&#xff0c;通过 UniAPP 实现多端适…

中车靶场,网络安全暑期实训营

不善攻防&#xff0c;何谈就业&#xff1f; 实训目的&#xff1a;提升实战能力&#xff0c;直通就业快道。 实训对象&#xff1a;面向计算机相关专业、有兴趣接触网络攻防、大专及以上学历的学员。 知识准备 为确保高效实训&#xff0c;学员需具备一定的实战基础。报名后&am…

2.2.2 06年T1

成功的同化机器——美国&#xff1a;2006年考研英语&#xff08;一&#xff09;Text 1精析 本文解析2006年考研英语&#xff08;一&#xff09;第一篇文章&#xff0c;揭示美国社会强大的文化同化力及其表现。 一、原文与翻译 Paragraph 1&#xff1a;美国社会的同化本质 L1: …

【第1章 基础知识】1.8 在 Canvas 中使用 HTML 元素

文章目录 前言示例-橡皮筋式选取框示例代码 前言 尽管我们可以说 Canvas 是 HTML5 之中最棒的功能&#xff0c;不过在实现网络应用程序时&#xff0c;很少会单独使用它。在绝大多数情况下&#xff0c;你都会将一个或更多的 canvas 元素与其他 HTML 控件结合起来使用&#xff0…

c++流之sstream/堆or优先队列的应用[1]

目录 c流之sstream 解释 注意事项 215.数据流的第k大 问题分析 修正代码 主要修改点 优先队列的比较规则 代码中的比较逻辑 为什么这样能维护第 k 大元素&#xff1f; 举个例子 总结 Python 实现&#xff08;使用heapq库&#xff09; Java 实现&#xff08;使用P…

SAR ADC 比较器噪声分析(二)

SAR ADC的比较器是非常重要的模块&#xff0c;需要仔细设计。主要考虑比较器的以下指标&#xff1a; 1)失调电压 2)输入共模范围 3)比较器精度 4)传输延时 5)噪声 6)功耗 这里主要讲一下动态比较器的noise。 动态比较器一般用于高速SAR ADC中&#xff0c;且精度不会超过12bit…

机器学习Day5-模型诊断

实现机器学习算法的技巧。当我们训练模型或使用模型时&#xff0c;发现预测误差很 大&#xff0c;可以考虑进行以下优化&#xff1a; &#xff08;1&#xff09;获取更多的训练样本 &#xff08;2&#xff09;使用更少的特征 &#xff08;3&#xff09;获取其他特征 &#xff…