百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

开启CAN通信学习(二)——基于Kvaser的CAN通信案例

myzbx 2025-01-07 14:27 19 浏览

1 案例硬件介绍

Kvaser是瑞典的一家专门提供CAN和LIN总线分析仪及数据记录仪的公司,在CAN产品开发领域已经有近30年的经验,本案例选择的CAN通信硬件型号是Kvaser Leaf Light v2,产品如下图所示:

公众号dotNet工控上位机:thinger_swj】

为了配套该产品,还准备了一个威柏电子(Westpac)提供的模拟控制器RL78 CAN ECU来进行功能测试,如下图所示,该模拟控制器可以通过上位机控制,实现速度调节及转向灯控制。

硬件准备就绪,这个接线也比较简单,由于是已经集成好的DB9插头,所以ECU与CAN卡之间直接公头和母头对接就可以了,CAN卡通过USB接入电脑,安装好驱动后,就可以通过电脑的设备管理器中看到CAN设备了,如下图所示:

2 案例开发准备

CAN通信开发需要调用厂家提供好的一些SDK或者Lib库,而且厂家一般都是提供一些Demo,Demo中包含多种不同的语言,我们找到dotnet或者C#或者cs的字眼,然后打开相关的案例进行研究。Kvaser并没有提供类似的Demo,只是提供了一个Kvaser CANLib SDK的软件,安装之后打开包含以下内容:

接着打开dotnet >> win32 >> fw40,找到下面这些dll,我们的开发主要就是基于这个文件夹里面的dll来实现的,dotnet下面有win32和x64两个文件夹,这里根据不同的项目平台版本,选择相应的dll。

Kvaser针对CANLib库的使用,提供了一个HTML帮助手册,如下图所示,如果对于某个函数或者参数不理解,可以通过这个帮助手册来查找:!

虽然有了dll以及帮助手册,但是对于应该调用哪些方法,调用方法之间的顺序,很多时候我们仍然是一头雾水,下面的这个开发指南应该是雪中送炭。

3 案例程序开发

万事具备之后,这时候我们就可以进行程序开发了,先创建一个Windows窗体应用程序,项目名称为thinger.com.kvaserCANECU,界面初步设计如下图所示:

公众号dotNet工控上位机:thinger_swj】

(1)UI界面设计完成后,首先将canlibCLSNET.dll复制到项目中并添加引用

(2)在窗体初始化中调用canInitializeLibrary初始化并初始化波特率

        public FrmMain()        {            InitializeComponent();            //初始化CanLibrary            Canlib.canInitializeLibrary();            this.cmb_BaudRate.Items.Add("500000");            this.cmb_BaudRate.Items.Add("250000");            this.cmb_BaudRate.SelectedIndex = 1;        }

(3)刷新按钮事件下,获取所有能获取到的CAN通信信息

        private void btn_Refresh_Click(object sender, EventArgs e)        {            int count = 0;            canstatus = Canlib.canGetNumberOfChannels(out count);            if (canstatus != Canlib.canStatus.canOK)            {                HandleError("canGetNumberOfChannels", canstatus);                return;            }            this.cmb_Channel.Items.Clear();            for (int i = 0; i < count; i++)            {                string result = string.Empty;                object obj;                //获取通道                canstatus = Canlib.canGetChannelData(i, Canlib.canCHANNELDATA_CHANNEL_NAME, out obj);                HandleError("canCHANNELDATA_CHANNEL_NAME", canstatus);                result += obj.ToString();?                //获取序列号                canstatus = Canlib.canGetChannelData(i, Canlib.canCHANNELDATA_CARD_SERIAL_NO, out obj);                HandleError("canCHANNELDATA_CARD_SERIAL_NO", canstatus);                result += "   " + obj.ToString();                this.cmb_Channel.Items.Add(result);            }            if (count > 0)                this.cmb_Channel.SelectedIndex = 0;        }?        private void HandleError(string cmd, Canlib.canStatus state)        {            if (state != Canlib.canStatus.canOK)            {                string error = string.Empty;                Canlib.canGetErrorText(state, out error);                this.tssl_Info.Text = cmd + " Error:" + error;            }            else            {                this.tssl_Info.Text = "系统正常";            }        }?

(4)打开按钮事件中,实现打开CAN卡及关闭CAN卡的功能

        private void btn_Open_Click(object sender, EventArgs e)        {            if (this.btn_Open.Text == "打开")            {                //打开                handle = Canlib.canOpenChannel(this.cmb_Channel.SelectedIndex,                 Canlib.canOPEN_OVERRIDE_EXCLUSIVE + Canlib.canOPEN_ACCEPT_VIRTUAL);                //设置波特率                canstatus = Canlib.canSetBitrate(handle, Convert.ToInt32(this.cmb_BaudRate.Text));                HandleError("canSetBitrate", canstatus);                //BUS ON                canstatus = Canlib.canBusOn(handle);                if (canstatus != Canlib.canStatus.canOK)                {                    HandleError("canBusOn", canstatus);                    return;                }                else                {                    this.btn_Open.Text = "关闭";                 }            }            else            {                Canlib.canClose(handle);?                this.btn_Open.Text = "打开";            }        }

相关推荐

炫酷的计时器效果Canvas绘图与动画

-----------------------------------------华丽的分割线-----------------------------------------------------...

康托尔集合的绘制及其Python绘制(康托尔集合论的概括原则是什么)

康托尔三分集(Cantorternaryset)是数学中一个著名的分形例子,由德国数学家格奥尔格·康托尔在1883年引入。它通过不断去掉线段的中间三分之一部分,重复这个过程得到的一个分形集合。康托...

一文带你搞懂JS实现压缩图片(js 压缩图片)

作者:wuwhs转发链接:https://segmentfault.com/a/1190000023486410前言公司的移动端业务需要在用户上传图片是由前端压缩图片大小,再上传到服务器,这样可以减...

数据可视化—Echarts图表应用(数据可视化图表类型)

ECharts是一款由百度前端技术部开发的,基于Javascript的数据可视化图表库,提供直观,生动,可交互,可个性化定制的数据可视化图表。使用JavaScript实现开源的可视化库,可以流畅的...

ThreeJS中三维世界坐标转换成二维屏幕坐标

Threejs全称是“Javascript3Dlibrary”。WebGL则是openGL在浏览器上的一个实现。Threejs对WebGL进行了封装,让前端开发人员在不需要掌握很多数学知识和绘图知...

鸿蒙开源第三方件组件——加载动画库

前言基于安卓平台的加载动画库AVLoadingIndicatorView(https://github.com/81813780/AVLoadingIndicatorView),实现了鸿蒙化迁移和重构...

canvas实现下雪背景图(canvas绘制背景图)

canvas下雪背景html+css+js实现:1.定义标签:<h1>北极光之夜。</h1><divclass="bg"></...

用canvas画简单的“我的世界”人物头像

前言:花了4天半终于看完了《HeadFirstHTML5》,这本书的学习给我最大的感受就是,自己知识的浅薄,还有非常多非常棒的技术在等着我呢。[熊本表情]扶朕起来,朕还能学!H5新增标签里面最喜欢...

Manim-基础图形之点(什么叫图形基点)

制作数学演示视频时需要用到各类的集合图形,manim中内置了一些列的图形,本篇就从最简单的点讲起。点作为manim中最简单图形,也是其他所有图形的基,所有图形的绘制都是靠点来定位。manim中的点主...

一起学 WebGL:坐标系(坐标系格式)

大家好,我是前端西瓜哥,今天我们来学习WebGL。WebGL的世界坐标系是三维的。默认使用笛卡尔坐标系的右手坐标系,满足右手定则,即x轴向右,y轴向上,z轴向着观察者,原点位于画布中心。然...

漫画 欣赏 - 聖鬥士星矢 THE.LOST.CANVAS 冥王神話 24

《圣斗士星矢THELOSTCANVAS冥王神话》改编自车田正美原作的漫画《圣斗士星矢》,由车田正美原作、手代木史织作画。其外传《圣斗士星矢THELOSTCANVAS冥王神话外传》则在《...

漫画 欣赏 - 聖鬥士星矢 THE.LOST.CANVAS 冥王神話 25 - 完结篇

《圣斗士星矢THELOSTCANVAS冥王神话》改编自车田正美原作的漫画《圣斗士星矢》,由车田正美原作、手代木史织作画。其外传《圣斗士星矢THELOSTCANVAS冥王神话外传》则在《...

Eric Fischl 名画录(eric tucker画家)

艾瑞克费舍尔(EricFischl,1948——),是美国新表现主义画家,当代国际画坛一位十分活跃的人物,在国际上享有很高的知名度。作为20世纪美国第6次经济衰退时期本土第一个伟大画家艾瑞克·费舍尔...

canvas绘画板的实现(canvas画布)

新项目有一个需求:客户需要在订单确认的时候签名。第一反应就是用html的canvas实现,同事一起商量了下,canvas有三个制约:canvas必须要用鼠标,签名会很难看;手机端webapp怎么实现...

Python程序开发之简单小程序实例(9)利用Canvas绘制图形和文字

Python程序开发之简单小程序实例(9)利用Canvas绘制图形和文字一、项目功能利用Tkinter组件中的Canvas绘制图形和文字。二、项目分析要在窗体中绘制图形和文字,需先导入Tkinter组...