摘 要:CAN总线是控制器局域网总线(Controller Area Network)的简称。属于现场总线的范畴,是一种有效支持分布式控制或实时控制的串行通信网络。CAN总线是一种多主方式的串行通讯总线,是国际上应用最广泛的现场总线之一,现已被应用到各个自动化控制系统中,从高速的网络到低价位的多路接线都可以使用CAN总线。本文重点就CAN总线通信设计的实现进行介绍,利用PC机对通过CAN控制器以及CAN收发器上传上来的数据进行监控并通过CAN将PC机的命令下发给单片机或者其他硬件设备,实现类似于PC机与下位机的CAN通讯。
关键词:CAN通信;波特率;C#
中图分类号:TP311.1 文献标识码:A 文章编号:1674-7712 (2013) 10-0027-01
一、CAN通信简介
CAN是一种多主方式的串行通讯总线,基本设计规范要求有高的位速率、抗电磁干扰性,而且要能够检测出总线的任何错误。当信号传输距离达10km时,CAN仍可提供高达50kbps的数据传输速率。CAN具有十分优越的特点:(1)较低的成本与极高的总线利用率;(2)数据传输距离可长达10km,传输速率可高达1Mbps[7];(3)可靠的错误处理和检错机制,发送的信息遭到破坏后可自动重发;(4)节点在错误严重的情况下具有自动退出总线的功能;(5)报文不包含源地址或目标地址,仅用标志符来指示功能信息和优先级信息。基于以上特点,CAN通讯越来越多的应用于工业控制上,尤其是电动汽车的监管上。
二、常用的API函数
实现CAN通讯首先要对CAN通讯卡的API函数进行了解,不同公司的CAN通信卡API不尽相同,以ZLG的USBCAN-2A为例,阐述在CAN通讯的实现与应用中,几个重要的API函数:(1)“VCI_OpenDevice”:该函数是用来创建一组设备,如CAN通信卡。该函数有两个参数,设备类型和设备索引号;(2)“VCI_CloseDevice”:该函数是用来关闭设备,即与设备断开。(3)“VCI_InitCAN”:该函数是用来初始化CAN通信卡。包括四个参数,设备类型、设备索引号、波特率和第几路CAN;(4)“VCI_StartCAN”:该函数是用来启动CAN控制器。包括三个参数,设备类型、设备索引号和第几路CAN;(5)“VCI_ResetCAN”:该函数是用来复位设备,进而系统重新初始化。包括三个参数,设备类型、设备索引号和第几路CAN;(6)“VCI_Transmit”:该函数是用来发送一帧或一组CAN信息。包括五个参数,设备类型、设备索引号、需要发送的数据、需要发送的数据长度和第几路CAN;(7)“VCI_Receive”:该函数是用来接收一帧或一组CAN信息。包括五个参数,设备类型、设备索引号、需要接收的数据、每次接收的数据长度、每次接收数据的时间和第几路CAN。
在创建一个新项目的时候,我们首先要初始化API函数,以"VCI_OpenDevice"为例,C#初始化API函数代码如下:
[DllImport(“ControlCAN.dll”,EntryPoint =“VCI_OpenDevice”,CharSet=CharSet.Ansi,CallingConvention = CallingConvention.StdCall)]
public static extern uint VCI_OpenDevice(uint DeviceType,uint DeviceInd,uint Reserved);
然后我们给他做个封装:
public bool OpenDevice()
{return VCI_OpenDevice(CommunicationControler.deviceType,
CommunicationControler.deviceIndex,CommunicationControler.deviceReserved) == 1 ? true : false;}
添加个类名ControlCAN,这样在应用时可以直接调用了,例如打开设备的代码为:
ControlCAN.OpenDevice();
三、初始化CAN并打开CAN卡
CAN的主要参数有波特率、滤波方式、工作方式、屏蔽码、验收码,我们把它们封装在InitDevice中,代码如下:
public bool InitDevice(String CheckCode,String MaskCode,String FilterMode,String WorkMode,String BraudRate)
{VCI_INIT_CONFIG InitConfig = new VCI_INIT_CONFIG();
InitConfig.AccCode=Convert.ToUInt32(“0x”+CheckCode,16);
InitConfig.AccMask=Convert.ToUInt32(“0x”+MaskCode,16);
InitConfig.Filter=Convert.ToByte(FilterMode==“双滤波”?0:1);
InitConfig.Mode=Convert.ToByte(WorkMode==“正常模式”?0:1);
switch(BraudRate)
{case “100KBPS”:
InitConfig.Timing0=0x04;
InitConfig.Timing1=0x1C;
break; …
return VCI_InitCAN(ControlCAN.deviceType,ControlCAN.deviceIndex,ControlCAN.deviceNumber,ref InitConfig)==1?true:false;}}
在初始化CAN之前首先要打开设备,然后初始化CAN的代码为InitDevice(“00000000”,“FFFFFFFFF”,“双滤波”,“正常模式”,“9600”);初始化完成后,打开CAN卡,代码为:
if(ControlCAN.OpenDevice()==true)
{if(ControlCAN.InitDevice()==true)
{if ControlCAN(.Start()true)
{Text=“CAN卡状态:启动成功!”;}}}
四、数据的接收与发送
CAN通信的数据主要包括参数有:ID,Data.Length,Data,当发送数据时,我们首先要定义好数据的ID、数据长度Data.Length、数据Data再进行发送ControlCAN.Transmit (frameInfo)。主要代码为:
private static void Transmit(VCI_CAN_OBJ[]frameInfo)
{uint len=VCI_Transmit(ControlCAN.deviceType,ControlCAN.deviceIndex,ControlCAN.deviceNumber,ref frameInfo[0],(uint)frameInfo.Length);
if(lenframeInfo.Length)
{CanBoardWriteResult(CanOperationDescription+“成功.”);}}
数据接收是CAN通信中最为重要的环节,如果接收不及时和接收错误则会产生致命的问题。接收数据主要代码为:
public void Receive()
{recevieLen =VCI_Receive(ControlCAN.deviceType,ControlCAN.deviceIndex,ControlCAN.deviceNumber,ref frameInfos[0],1,200);…}
对接收到的数据放入RecivedData函数进行处理。
五、关闭CAN
当使用CAN完毕后,关闭CAN并关闭设备,该函数为:ControlCAN.CloseDevice()。
通过以上三个步骤,就可以实现最简单的CAN通信。
六、结束语
本文以VS为开发工具,C#为开发语言对周立功的CANII的通信进行了简单的介绍,可以看出在VS2008中使用ControlCAN.dll的API函数进行通讯是很高效快捷的,可以很方便地实现简单的任务。
CAN通讯在VS2008中的实现与应用
最新推荐文章于 2024-06-25 10:08:55 发布