工控网首页
>

应用设计

>

英创新CAN驱动接口调用方法及说明

英创新CAN驱动接口调用方法及说明

  用户可从英创开发光盘中或联系英创工程师获得CAN例程源码。参考例程使用英创已经封装好的.h及.cpp库文件可以使开发更方便。

注册表设置项说明

  CAN驱动设置参数位于注册表[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\CAN1]及[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\CAN2]下

  主要配置参数项:

  TxTimeout :发送超时时间,单位ms。

  BusErrorReport :错误帧上报标记,0:不上报,1:上报错误帧

  设置程序可以连接英创工程师获得。

CAN打开及关闭

  打开关闭采用标准的流式设备驱动接口CreateFile及CloseHandle,设备名为”CAN1:”及”CAN2:”

  调用示例如下:

  //打开CAN1

  HANDLE hCan;

  hCan = CreateFile( L”CAN1:”, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

  //关闭CAN

  CloseHandle(hCan);

CAN波特率设置

  参考CAN例程,对驱动的DeviceIoCon trol操作已封装在SetBaud函数中。

  BOOL SetBaud(HANDLE hCan, DWORD dwBaud)

  参数hCan:CreateFile打开CAN返回的设备句柄

  参数dwBaud:波特率,单位bps

  返回值:TRUE 设置成功,FALSE 设置失败

  调用示例如下:

  //设置波特率250bps CAN

  SetBaud(m_hCan, 250000);

CAN过滤设置

  调用方法

  参考CAN例程,对驱动的DeviceIoCon trol操作已封装在SetFilter函数中。

  BOOL SetFilter(HANDLE hCan, PCAN_FILTER pFilter, DWORD num)

  参数hCan:CreateFile打开CAN返回的设备句柄

  参数pFilter:过滤器结构体数组指针

  参数num:过滤器结构体数组长度,最大为4

  返回值:TRUE 设置成功,FALSE 设置失败

  注:此函数如果重复调用,生效的为最后一次调用设置值。

CAN_FILTER过滤器结构体定义

  typedef struct _can_filter

  {

    CAN_ID can_id;

    CAN_ID can_mask;

  } CAN_FILTER, *PCAN_FILTER

  过滤器由id和mask组成,设置的过滤器组数最大4个。CAN包能满足其中一组过滤器以下条件才能接收

  CAN包id & 过滤器mask = 过滤器id

  即,2进制中,过滤MASK为1的对应位需和过滤ID值一致,示例表

  调用示例如下

  //设置一组寄存器

  CAN_FILTER      Filter[4];

  memzero(Filter, sizeof(CAN_FILTER));

  Filter[0].can_id.id = 5;

  Filter[0].can_mask.id = 22;

  SetFilter(m_hCan, Filter, 1);

CAN发送/接收

  发送接收同样采用标准的流式设备驱动接口ReadFile及WriteFile

  调用方法

  参考CAN例程,封装好的函数定义。

  int     WriteCAN(HANDLE hCan, PCAN_FRAME pFrame, DWORD num){

      DWORD dwLen;

      if(!WriteFile( hCan, (char *)pFrame, num*sizeof(CAN_FRAME), &dwLen, 0 )) return 0;

      return dwLen/sizeof(CAN_FRAME);

  }

  int     ReadCAN(HANDLE hCan, PCAN_FRAME pFrame, DWORD num){

      DWORD dwLen;

      if(!ReadFile( hCan, (char *)pFrame, num*sizeof(CAN_FRAME), &dwLen, 0 )) return 0;

      return dwLen/sizeof(CAN_FRAME);

  }

  参数hCan:CreateFile打开CAN返回的设备句柄

  参数pFrame:帧结构体数组指针

  参数num:帧结构体数组长度,默认值1,可空

  返回值:发送/接收的数据包个数

  注:发送函数为阻塞函数,超时时间可以在注册表中设置,默认1000ms。

    发送失败后,应用程序应当自行判断是否需要重新发送。

  接收函数应当单独开一个接收线程,并配合WaitCANEvent函数使用,参考下一节。

CAN_FRAME数据帧结构体定义

  typedef struct{

       unsigned int id:29;

       unsigned int error:1;      

       unsigned int remote:1;

       unsigned int extended:1;

  }CAN_ID;

  typedef struct _can_frame

  {

      CAN_ID   can_id;        /* 32 bit CAN_ID + EFF/RTR/ERR flags */

      BYTE    can_dlc;     /* frame payload length in byte (0 ..CAN_MAX_DLEN) */

      BYTE    data[CAN_MAX_DLEN];

  } CAN_FRAME, *PCAN_FRAME;

  调用示例如下:

  DWORD dwNum;

  //发送

  CAN_FRAME Sendframe;

  memzero(Sendframe, sizeof(CAN_FRAME));

  Sendframe.can_id.id = 6;

  m_Sendframe.data[0] = 0x01;

  m_Sendframe.can_dlc = 1;

   dwNum = WriteCAN(hCan, &Sendframe);

  //接收

  CAN_FRAME   Revframe[MAX_ARRAY];

  dwNum = ReadCAN(hCan, Revframe, MAX_ARRAY);

WaitCANEvent函数使用

  如果轮询方式接收CAN包,系统负荷会过高,采用事件方式事半功

  WaitCANEvent为等待CAN接收事件的阻塞函数,通过返回值可以判断是否有CAN数据接收。

  BOOL WaitCANEvent( HANDLE hDevice, LPDWORD lpEvtMask, DWORD dwTimeout )

  参数hDevice:CreateFile打开CAN返回的设备句柄

  参数lpEvtMask:返回事件类型,新驱动目前恒为0

  参数dwTimeout:超时时间

  返回值:FALSE 等待超时,TRUE 有数据帧收到

  接收线程调用示例

  //主线程中开启接收线程

  m_hRecvThread = CreateThread(0, 0, RecvTread, this, 0, NULL);

  //接收线程函数定义

  DWORD Ctest_can_v2Dlg::RecvTread(LPVOID lparam)

  {

      Ctest_can_v2Dlg* pDlg = (Ctest_can_v2Dlg*)lparam;

      DWORD       dwEvtMask;

      int         num;

      CAN_FRAME   rbuf[MAX_ARRAY];

     while(!pDlg->m_bThreadStop)

      {

          if(WaitCANEvent(pDlg->m_hCan, &dwEvtMask, 200))

          {

              if( dwEvtMask == 0 )      // 接收到数据包

              {

                  num = ReadCAN(pDlg->m_hCan, rbuf, MAX_ARRAY);

                  while( num )

                  {

                      OnRecv(pDlg, rbuf, num);        //调用回调函数处理数据

                      num = ReadCAN(pDlg->m_hCan, rbuf, MAX_ARRAY);

                  }

              }

              else        //258

              {

            }

        }

    }

      return 0;

  }

错误帧定义

  当设置注册表选项,允许接收错误帧后,CAN总线上的出错信息将以帧的形式上报上来。

  错误帧的帧结构体中,值为1,可通过该值判断是接收到的数据帧还是驱动上报的错误帧。

  if(Frame.can_id.error){

    //错误帧

  }

  else{

    //数据帧;

  }

  错误帧详细定义,请参数手册《CAN错误帧定义》。

精简掉的接口

  新CAN驱动能够自动复位CAN总线,不需要再手动复位,所以之前ResetCAN,StartCAN,StopCAN精简掉了。

  

  SetCANLoop功能实用性不大,故精简掉。

  

  但是为了兼容老驱动,这些函数依然可以正常调用。

  相关测试例程可以联系英创工程师获得。

  成都英创信息技术有限公司

  http://www.emtronix.com

投诉建议

提交

查看更多评论
其他资讯

查看更多

Windows下STM32单片机eclipse编译环境搭建

Android Studio应用开发简介

WinCE工控主板WiFi解决方案

敬请关注成都英创微信公众号

WinCE工控主板通过PPI协议连接西门子PLC