建云 2025-7-18 17:14:33 | 显示全部楼层 | 阅读模式
抖音粉丝群1
『7x24小时有问必答』

AI浪潮下的计算机行业——从业者现状与未来展望

前言

随着工业自动化和物联网技术的迅猛发展,CAN(Controller Area Network)总线作为一种可靠且高效的通信协议,在汽车电子、工业控制等领域得到了广泛应用。为了实现上位机与CAN总线设备之间的通信,通常需要使用专门的硬件设备和相应的软件工具。
本文将详细介绍如何通过上位机实现CAN通信,包括所需的硬件设备和软件方法,并提供一个基于C#和Kvaser CAN卡的具体示例。
正文1、硬件方法
上位机实现CAN通信通常需要借助CAN控制器或CAN总线适配器等硬件设备。
CAN控制器是一种专门用于实现CAN通信的芯片,具有CAN总线接口和处理器接口等功能。
CAN总线适配器则是一种将CAN总线信号转换为标准串行接口(如USB或PCI)的设备,可以通过串口通信实现CAN通信。
CAN总线的发展经历了多个阶段,从最初的CAN 2.0标准(发布于1991年,支持最多8字节的数据段),到2015年的CAN FD标准(支持最多64字节的数据段),再到2020年的CAN XL标准。
CAN总线采用多主通讯模式,每个CAN节点都能自主收发数据,并通过ID仲裁机制确保优先级高的数据能够实时传输。
2、软件方法
上位机实现CAN通信还需要使用相应的CAN通信软件。这些软件通常包括驱动程序、通信协议和应用程序三个主要部分:

驱动程序:用于控制CAN控制器或CAN总线适配器的工作,实现CAN通信的底层控制。

通信协议:规定了CAN通信的数据格式和传输方式,确保通信过程的标准化。

应用程序:实现了具体的CAN通信功能,如数据采集、控制指令发送等。

通过安装和配置相应的CAN通信软件,上位机可以实现与CAN总线设备的通信功能。
代码示例
以下是一个基于C#和Kvaser CAN卡实现CAN通信的示例代码:
using Kvaser.CanLib;

using System.Text;

namespaceCanDemo

{

    // https://blog.csdn.net/supposing962464/article/details/124387781

    // D:Program FilesKvaserCanlibdotnetx64netstandard2.0Kvaser.CanLib.dll

    classKvaserApi

    {

        int hnd = 0// Kvaser通道句柄

        bool CanState = false// CAN状态

        Thread readCANThread; // 创建数据监听控制线程

        publicclassCanMsg// 定义CanMsg包

        {

            publicint ID;

            publicbyte[] Data;

            publicstring DataType;

            publiclong TimeStamp;

        }

        public void InitKvaser(int BaudRate)

        {

            int freq = 0;

            if (BaudRate == 50// 波特率50K对应freq为-7

                freq = -7;

            if (BaudRate == 100// 波特率100K对应freq为-5

                freq = -5;

            if (BaudRate == 125// 波特率125K对应freq为-4

                freq = -4;

            if (BaudRate == 250// 波特率250K对应freq为-3

                freq = -3;

            if (BaudRate == 500// 波特率500K对应freq为-2

                freq = -2;

            if (BaudRate == 1000// 波特率1000K对应freq为-1

                freq = -1;

            Canlib.canStatus stat = new Canlib.canStatus();

            Canlib.canInitializeLibrary(); // Kvaser软件库初始化

            hnd = Canlib.canOpenChannel(0, Canlib.canOPEN_ACCEPT_VIRTUAL); // 打开CAN通道

            stat = Canlib.canSetBusParams(hnd, freq, 00000); // 设置CAN参数

            if (stat == Canlib.canStatus.canOK)

                CanState = true;

            Canlib.canBusOn(hnd); // 启动CAN BUS总线

            Canlib.canResetBus(hnd); // 重置CAN BUS总线

            Canlib.canFlushReceiveQueue(hnd); // 清空缓存区

            if (CanState == false)

            {

                Console.WriteLine("CAN启动失败!请连接CAN卡或重新插拔CAN卡!");

                return;

            }

            canWrite(hnd, 111newbyte[] { 11111 }, "标准帧");

            readCANThread = new Thread(new ThreadStart(DataReadCAN));

            readCANThread.IsBackground = true;

            readCANThread.Start(); // 启动CAN接收

        }

        public void CloseKvaser()

        {

            Canlib.canBusOff(hnd); // 关闭CAN总线

            Canlib.canClose(hnd); // 关闭CAN通道

            Canlib.canUnloadLibrary(); // 卸载软件库

            CanState = false;

            if (readCANThread != null)

                readCANThread.Abort(); // 退出监听线程

        }

        public bool canWrite(int hnd, int ID, byte[] data, string dataType)

        {

            bool writeResult = false;

            Canlib.canStatus stat = Canlib.canStatus.canERR_NOMSG;

            if (dataType == "标准帧")

                stat = Canlib.canWrite(hnd, ID, data, data.Length, Canlib.canMSG_STD);

            if (dataType == "扩展帧")

                stat = Canlib.canWrite(hnd, ID, data, data.Length, Canlib.canMSG_EXT);

            if (stat == Canlib.canStatus.canOK)

                writeResult = true;

            return writeResult;

        }

        public void canRead(int hnd, int filterID)

        {

            int dlc, flags;

            byte[] msg = newbyte[8];

            int IDReceive = filterID;

            long time;

            Canlib.canStatus stat;

            if (filterID == -1)

                stat = Canlib.canRead(hnd, out IDReceive, msg, out dlc, out flags, out time);

            else

                stat = Canlib.canReadSpecific(hnd, filterID, msg, out dlc, out flags, out time);

            if (stat == Canlib.canStatus.canOK)

            {

                CanMsg canmsg = new CanMsg() { TimeStamp = time };

                canmsg.ID = IDReceive;

                canmsg.Data = msg;

                if (flags == 2)

                    canmsg.DataType = "标准帧";

                if (flags == 4)

                    canmsg.DataType = "扩展帧";

                string hex = ToHexString(canmsg.Data, canmsg.Data.Length, true);

                Console.WriteLine($"recv,TimeStamp={canmsg.TimeStamp},DataType={canmsg.DataType},ID={canmsg.ID},Data={hex}");

            }

        }

        private void DataReadCAN()

        {

            while (true)

            {

                canRead(hnd, -1);

            }

        }

        public static string ToHexString(byte[] bytes, int length, bool space)

        {

            string strFill = space ? " " : "";

            string hexString = string.Empty;

            if (bytes != null)

            {

                StringBuilder strB = new StringBuilder();

                for (int i = 0; i < length; i++)

                {

                    strB.Append(bytes.ToString("X2") + strFill);

                }

                hexString = strB.ToString();

            }

            hexString = hexString.Trim();

            return hexString;

        }

    }

}

总结

本文详细介绍了上位机实现CAN通信的方法,包括硬件设备的选择和软件的配置。通过使用CAN控制器或CAN总线适配器,结合相应的驱动程序和通信协议,上位机可以轻松实现与CAN总线设备的通信。

另外,本文还提供了一个基于C#和Kvaser CAN卡的具体示例代码,展示了如何进行CAN通信的基本操作,如初始化、发送和接收数据等。
关键词

最后

如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。也可以加入微信公众号[DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!

作者:上位机李工

出处:mp.weixin.qq.com/s/dVDxqjIrlHhI9KazDSRVSw

声明:网络内容,仅供学习,尊重版权,侵权速删,歉意致谢!

END

方便大家交流、资源共享和共同成长

纯技术交流群,需要加入的小伙伴请扫码,并备注加群

推荐阅读

C# 实现三种方式的模拟按键

WinForm 跨线程操作 UI 控件封装实践

WPF + Halcon 开发的机器视觉算法平台

WinForm 开发的智能停车场管理系统(岗亭端)

WinForm + SQLite 实现轻量级库存管理系统

C# 自定义特性实现 DataGridView 全自动列生成

C# 工业开发必备:精选 4 个最强 Modbus 通信库

WPF 工业大数据采集维保平台:工业4.0时代的智能运维中枢

.NET 7.0 + Vue 3 开源跨平台图形化工作流引擎,适配多终端

告别重复造轮子!WPF 通用上位机开发框架,快速搭建工业监控系统

.NET 9 可视化工作流引擎!纯血开源,支持数十种数据库,开箱即用

基于 WinForm 的智能温控系统,运用 Modbus协议实现高效上位机控制

惊艳!这个开源框架用 HTML5/CSS3/JavaScript 轻松开发 WinForm 炫酷界面

觉得有收获?不妨分享让更多人受益
关注「DotNet技术匠」,共同提升技术实力

收藏

点赞

分享

在看


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

上一主题上一主题         下一主题下一主题
QQ手机版小黑屋粤ICP备17165530号

Copyright 2010-2015. All rights reserved. 

微信公众号二维码 抖音二维码 百家号二维码 今日头条二维码哔哩哔哩二维码