2025年can通讯入门(can通信入门)

can通讯入门(can通信入门)using Kvaser CanLib using System Text namespace CanDemo https blog csdn net supposing article details D Program FilesKvaserC etstandard2 0Kvaser CanLib dll class KvaserApi int hnd 0 Kvaser 通道句柄



using Kvaser.CanLib;
using System.Text;

namespace CanDemo
{
    // https://blog.csdn.net/supposing962464/article/details/124387781
    // D:Program FilesKvaserCanlibdotnetx64
etstandard2.0Kvaser.CanLib.dll
    class KvaserApi
    {
        int hnd = 0;//Kvaser通道句柄
        bool CanState = false;//CAN状态
        Thread readCANThread;   //创建数据监听控制线程
                                //
        public class CanMsg//定义CanMsg包
        {
            public int ID;
            public byte[] Data;
            public string DataType;
            public long 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;
            //创建Kvaser状态句柄
            Canlib.canStatus stat = new Canlib.canStatus();
            //Kvaser软件库初始化
            Canlib.canInitializeLibrary();
            //打开CAN通道;其中第一个参数为通道号,从0开始,如有多CAN卡或多通道,则依次为2、3...;第二个参数为canOPEN_xxx标志,一般默认为0;返回值为通道句柄
            hnd = Canlib.canOpenChannel(0, Canlib.canOPEN_ACCEPT_VIRTUAL);// Canlib.canOPEN_EXCLUSIVE
            //设置CAN参数;第一个参数为CAN通道句柄,第二个参数为波特率对应参数,其他参数默认为0即可;返回值为0则代表设置成功,否则设置失败
            stat = Canlib.canSetBusParams(hnd, freq, 0, 0, 0, 0, 0);
            if (stat == Canlib.canStatus.canOK)//如果打开成功,则CAN状态更新为true
                CanState = true;
            //启动CAN BUS总线
            Canlib.canBusOn(hnd);
            //重置CAN BUS总线
            Canlib.canResetBus(hnd);
            //清空缓存区
            Canlib.canFlushReceiveQueue(hnd);
            if (CanState == false)//如果CAN卡打开失败,则弹出错误提示信息
            {
                Console.WriteLine("CAN启动失败!请连接CAN卡或重新插拔CAN卡!");
                return;
            }

            canWrite(hnd, 111, new byte[] { 1, 1, 1, 1, 1 }, "标准帧");
            //canWrite(hnd, 222, new byte[] { 1, 1, 1, 1, 1 }, "扩展帧");

            //如打开成功,启动CAN信号读取线程
            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; //CAN状态更新为false
            if (readCANThread != null)
                readCANThread.Abort();//退出监听线程
        }

        //写入CAN数据
        public bool canWrite(int hnd, int ID, byte[] data, string dataType)
        {
            bool writeResult = false;//发送是否成功标识
            Canlib.canStatus stat = Canlib.canStatus.canERR_NOMSG;//Kvaser状态句柄
                                                                  //canWrite输入5个参数。第一个为通道句柄,为canOpenChannel的返回值;第二个参数为CAN报文的ID;第三个参数为报文数据;
                                                                  //第四个参数为报文长度;第五个参数为报文类型(扩展帧或标准帧)
            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)//如果写入返回值为canOK,说明写入成功
                writeResult = true;
            return writeResult;
        }

        //读取CAN数据
        public void canRead(int hnd, int filterID)
        { 
            int dlc, flags;//定义数据长度及数据标识
            byte[] msg = new byte[8];//定义数据数组
            int IDReceive = filterID;//定义过滤ID
            long time;//定义时间戳
            Canlib.canStatus stat;//Kvaser状态句柄
                                  //canRead第一个参数为通道句柄,为canOpenChannel的返回值;第二个参数为过滤的ID,如果为-1,则全部接受;否则为待接收的ID;
                                  //第三个参数为报文数据;第四个参数为报文长度;第五个参数为报文类型(扩展帧或标准帧);第六个参数为报文时间戳
            if (filterID == -1)
                stat = Canlib.canRead(hnd, out IDReceive, msg, out dlc, out flags, out time);//如果全部接收,则使用canRead函数
            else
                stat = Canlib.canReadSpecific(hnd, filterID, msg, out dlc, out flags, out time);//如果定义了过滤ID,则使用canReadSpecific函数

            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)
            {
                //读取CAN报文
                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[i].ToString("X2") + strFill);
                }
                hexString = strB.ToString();
            }

            hexString = hexString.Trim();

            return hexString;
        }
    }
}
编程小号
上一篇 2025-02-06 14:01
下一篇 2025-02-23 09:17

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ri-ji/43409.html