EM9170嵌入式主板CAN通讯接口使用说明

 2011-10-27          [nemail]    
[lablebox]

        英创公司推出的基于WinCE 6.0操作系统的嵌入式工控板卡EM9170,板上带有2路独立的CAN总线接口,均为FlexCAN模块。FlexCAN完全支持CAN 2.0B协议,支持对于标准帧和扩展帧的收发,同时FlexCAN还支持高优先级的报文优先发送的机制,可有效改善实时控制的相应时间。EM9170板上输出的两路CAN收发信号均为TTL电平,在实际使用时需要在外围电路中加上CAN驱动芯片,具体可以参考英创公司提供的“EM9170开发底板评估手册”。EM9170内核操作系统中已经实现FlexCAN底层驱动,系统一旦上电系统,将自动加载两路FlexCAN的驱动程序,客户在基于EM9170上编写CAN应用程序时,均可按照WinCE流式设备,打开关闭文件的方式对CAN接口进行操作,本文将着重介绍基于EM9170上FlexCAN的使用方法。

 

数据结构

        EM9170的CAN通讯提供了两种数据结构,定义在flex_can.h文件中。一个是CAN通讯数据包的结构,一个是CAN通讯中对于滤波器的设置结构。

 

        CAN数据包结构的定义如下:

 

typedef struct
{
        // 定义数据帧的类型:0 - 标准帧;1 - 扩展帧
        DWORD dwType;
        // 标准帧或扩展帧的CAN ID。
        // bit 0-28: CAN identifier (11/29 bit),其中标准帧11bit,扩展帧29bit
        DWORD dwID;
        // = 0:数据帧;= 1:远程帧
        DWORD dwRTR;
        // 发送优先级= 0 - 7,为最高优先级,对接收数据包无意义
        DWORD dwPrio;
        // 数据长度= 0 - 8
        DWORD dwDatLen;
        // 数据字节
        UCHAR ucDat[8]; 
}CAN_PACKET, *PCAN_PACKET;

 

        CAN滤波器数据结构的定义如下:

 

typedef struct
{
        // 组号,恒为0
        DWORD dwGroup;
        // 定义数据帧的类型:0 - 标准帧;1 - 扩展帧
        DWORD dwType;
        // 定义标准帧或扩展帧需要比较过滤的CAN ID。
        // bit 0-28: CAN identifier (11/29 bit),其中标准帧11bit,扩展帧29bit
        DWORD dwID;
        // = 0:数据帧;= 1:远程帧
        DWORD dwRTR;
        // 定义和dwID对应的需要检查或不检查的Mask位
        // bit 0-28: (11/29 bit),其中标准帧11bit,扩展帧29bit
        // = 0:该位不检查;= 1:该位须检查
        DWORD dwMask;
}CAN_FILTER, *PCAN_FILTER;

 

        滤波器数据结构设置距离如下:

 

CAN_FILTER Filter;

Filter.dwGroup = 0; // 保留,恒为0
Filter.dwType = CAN_PACKET_TYPE_STANDARD; // 标准帧
Filter.dwID = 0x00000002; // 设定的接收ID
Filter.dwMask = 0x00000003; // 检查接收报文ID的低2位
Filter.dwRTR = 0; // 数据帧

 

        设置的Filter结构,表明对于接收到的CAN标准帧报文只检查报文CAN ID的低两位的值,这两位的值应该和Filter.dwID所设定的值相符合,即:

        CAN_ID & Filter.dwMask = Filter.dwID

 

        因此在上例中,所接收的CAN报文的ID的低两位必须为0x02。

 

CAN_API函数

        英创公司提供的CAN通讯接口的驱动程序采用标准的驱动程序,和串口操作类似用户可以用标准的打开文件CreateFile( )、关闭文件CloseHandle( )的方式,来打开该CAN设备,数据的收发可调用ReadFile() WrtieFile( ),另外的一些对CAN操作通讯相关参数的设置可以通过调用DeviceIOCTL( )来实现。为了方便客户的使用,在CAN驱动程序的基础上,以源码的形式为客户封装了一套简单实用的API函数。各个函数的定义在can_api.h文件下,在该头文件中对于各个API函数均有相应的中文说明。

 

// 功能描述:启动CAN设备端口。
// 输入参数hDevice: 已创建CAN流式设备的句柄。
// 返回值= TRUE: 启动CAN设备端口成功。
// = FALSE: 启动CAN设备端口失败。

BOOL CAN_StartChip(HANDLE hDevice);

 

// 功能描述:停止CAN设备端口。
// 输入参数hDevice: 已创建CAN流式设备的句柄。
// 返回值= TRUE: 停止CAN设备端口成功。
// = FALSE: 停止CAN设备端口失败。

BOOL CAN_StopChip(HANDLE hDevice);

 

// 功能描述: 软件复位CAN设备端口。
// 输入参数hDevice: 已创建CAN流式设备的句柄。
// 返回值 = TRUE: 复位CAN设备端口成功。
// = FALSE: 复位CAN设备端口失败。

BOOL CAN_SoftReset(HANDLE hDevice);

 

// 功能描述:设置CAN设备通讯的波特率。
// 输入参数hDevice: 已创建CAN流式设备的句柄。
// CAN_TIMING_10K : 10Kbps
// CAN_TIMING_20K : 20Kbps
// CAN_TIMING_50K : 50bps
// CAN_TIMING_60K : 60bps
// CAN_TIMING_100K : 100bps
// CAN_TIMING_125K : 125Kbps
// CAN_TIMING_250K : 250Kbps
// CAN_TIMING_500K : 500bps
// CAN_TIMING_1000K: 1Mbps
// 返回值= TRUE: 波特率设置成功。
// = FALSE: 波特率设置失败。

BOOL CAN_SetBaudRate(HANDLE hDevice, DWORD dwBaudRate );

 

// 功能描述: 设置CAN设备通讯接收过滤器配置。
// 输入参数hDevice: 已创建CAN流式设备的句柄。
// pFilter: 根据通讯报文格式定义过滤器的配置。
// 返回值= TRUE: 配置设置成功。
// = FALSE: 配置设置失败。

BOOL CAN_SetFilter( HANDLE hDevice, PCAN_FILTER pFilter );

 

// 功能描述: 获取CAN设备通讯事件
// 输入参数hDevice: 已创建CAN流式设备的句柄。
// dwTimeout: 超时时间,单位为ms
// 输出参数
// lpEvtMask: 得到的CAN事件类型= 1:接收到CAN数据包
// = 2:CAN错误事件
// 返回值= TRUE: 调用成功。
// = FALSE: 调用失败。
BOOL WaitCANEvent( HANDLE hDevice, LPDWORD lpEvtMask, DWORD dwTimeout );

 

// 功能描述: 清空CAN设备通讯接收、发送BUFFER。
// 输入参数hDevice: 已创建CAN流式设备的句柄。
// 返回值= TRUE: 设置成功。

BOOL CAN_Purge( HANDLE hDevice );

 

CAN出错处理

        在CAN实际应用数据通讯过程中,可能会遇到CAN通讯出错的情况,调用API函数WaitCANEvent( HANDLE hDevice, LPDWORD lpEvtMask, DWORD dwTimeout )可以获取到CAN通讯出错的事件,对CAN的错误事件的处理可采用重启CAN设备的操作。

 

if( WaitCANEvent( pCAN->m_hCAN, &dwEvtMask, 2000 ) )
{
        …..
        if( dwEvtMask & 0x02 ) // 错误事件
        {
                CAN_StopChip( pCAN->m_hCAN );
                CAN_StartChip( pCAN->m_hCAN );
        }
}

 

        在英创公司提供的应用光盘中有具体CAN接口的测试代码,可供客户参考测试。

[lablebox]