英创信息技术新CAN驱动接口调用方法及说明

网友投稿 286 2022-11-10

英创信息技术新CAN驱动接口调用方法及说明

注册表设置项说明

主要配置参数项:

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

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

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

CAN打开及关闭

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

调用示例如下:

//打开CAN1

HANDLE hCan;

//关闭CAN

CloseHandle(hCan);

CAN波特率设置

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

BOOLSetBaud(HANDLE hCan, DWORD dwBaud)

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

参数dwBaud:波特率,单位bps

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

调用示例如下:

//设置波特率250bps CAN

SetBaud(m_hCan, 250000);

CAN过滤设置

调用方法

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

BOOLSetFilter(HANDLE hCan, PCAN_FILTER pFilter, DWORD num)

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

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

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

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

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

CAN_FILTER过滤器结构体定义

typedefstruct_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例程,封装好的函数定义。

DWORD dwLen;

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

returndwLen/sizeof(CAN_FRAME);

}

DWORD dwLen;

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

returndwLen/sizeof(CAN_FRAME);

}

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

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

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

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

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

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

CAN_FRAME数据帧结构体定义

typedefstruct{

unsignedintid:29;

unsignedinterror:1;

unsignedintremote:1;

unsignedintextended:1;

}CAN_ID;

typedefstruct_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数据接收。

BOOLWaitCANEvent( 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

{

}

}

}

return0;

}

错误帧定义

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

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

if(Frame.can_id.error){

//错误帧

}

else{

//数据帧;

}

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

精简掉的接口

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

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

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

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

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:springboot整合redis实现发送邮箱并验证
下一篇:Linux系统中Shell编程之case循环、for循环及While循环的实际使用
相关文章

 发表评论

暂时没有评论,来抢沙发吧~