SAE J1939 协议源代码分析(二)-程序移植

SAE J1939 协议源代码分析(二)-程序移植预备知识1.熟悉CAN2.0B协议,及相关硬件驱动开发2.熟悉SAEJ1939协议程序移植流程CreatedwithRaphaël2.1.0将代码加载到你的工程打开配置文件J1939_Config.h明白默认地址和标识符配置规则?了解J1939支持的功能配置使用

大家好,又见面了,我是你们的朋友全栈君。

预备知识

1.熟悉CAN2.0B协议,及相关硬件驱动开发
2.熟悉SAE J1939协议<http://blog.csdn.net/xietongxueflyme/article/details/74276702/>

程序移植流程

Created with Raphaël 2.1.0 将代码加载到你的工程 打开配置文件J1939_Config.h 明白默认地址和 标识符配置规则? 了解J1939支持的 功能配置使用的功能 熟悉AN2.0B驱动编写 按J1939_Config.h文件提示说 明,移植相关的函数功能 移植完成 练习CAN2.0B扩展帧驱动编写 参考J1939-21 查阅J1939附录B( 地址和标识符分配) yes no yes no yes no

移植示例(demo)

以下示例,对德国英飞凌XMC4500(MCU)芯片自带的CAN模块上移植J1939协议源代码,代码中can驱动函数,can的驱动结构体,可供移植参考

#ifndef __J1939_Config_H 
#define __J1939_Config_H 

#include "J1939.H"

#include "../UserApp/includes.h"//用户,自己工程必要的声明头文件
/******************************J1939地址和标识符配*********************************/ //设备默认的地址(地址命名是有规定的,参考J1939的附录B 地址和标识符的分配) #define J1939_STARTING_ADDRESS 243 //如果声明不为0,表示我们的ECU(电子控制单元)支持网络中申请的任意地址,(参考J1939的网络层) #define J1939_ARBITRARY_ADDRESS 0x00 #define J1939_INDUSTRY_GROUP 0 #define J1939_VEHICLE_INSTANCE 0 #define J1939_CA_NAME7 (J1939_ARBITRARY_ADDRESS | (J1939_INDUSTRY_GROUP << 4) | J1939_VEHICLE_INSTANCE) #define J1939_VEHICLE_SYSTEM 0 #define J1939_CA_NAME6 (J1939_VEHICLE_SYSTEM << 1) #define J1939_FUNCTION 0 #define J1939_CA_NAME5 J1939_FUNCTION #define J1939_FUNCTION_INSTANCE 0 #define J1939_ECU_INSTANCE 0 #define J1939_CA_NAME4 ((J1939_FUNCTION_INSTANCE << 3) | J1939_ECU_INSTANCE) #define J1939_MANUFACTURER_CODE 0 #define J1939_IDENTITY_NUMBER 50 #define J1939_CA_NAME3 (J1939_MANUFACTURER_CODE >> 3) #define J1939_CA_NAME2 (((J1939_MANUFACTURER_CODE & 0x07) << 5) | (J1939_IDENTITY_NUMBER >> 16)) #define J1939_CA_NAME1 ((J1939_IDENTITY_NUMBER >> 8) & 0xFF) #define J1939_CA_NAME0 (J1939_IDENTITY_NUMBER & 0xFF) /******************************J1939功能配置******************************************/ //是否使用接受协议(对TP协议的支持,参考J1939-21) #define J1939_ACCEPT_CMDADD J1939_FALSE #define J1939_RX_QUEUE_SIZE 3 //当mcu来不及处理消息,接收消息列队是否允许被新的消息覆盖 #define J1939_OVERWRITE_RX_QUEUE J1939_FALSE #define J1939_TX_QUEUE_SIZE 3 //当mcu来不及处理消息,发送消息列队是否允许被新的消息覆盖 #define J1939_OVERWRITE_TX_QUEUE J1939_FALSE //是否使用轮询模式(否则使用中断模式) #define J1939_POLL_ECAN J1939_TRUE #define J1939_PRIORITIZED_INT J1939_TRUE /******************************J1939移植配置函数******************************************/ #define Port_CAN_Transmit(MsgPtr) J1939_CAN_Transmit(MsgPtr) #define Port_CAN_Receive(MsgPtr) J1939_CAN_Receive(MsgPtr) #define Port_SetAddressFilter(Address) J1939_SetAddressFilter(Address) #define Port_RXinterruptEnable() J1939_RXinterruptEnable() #define Port_RXinterruptDisable() J1939_RXinterruptDisable() #define Port_TXinterruptEnable() J1939_TXinterruptEnable() #define Port_TXinterruptDisable() J1939_TXinterruptDisable() /******************************J1939CAN驱动接口函数************************************/ void J1939_SetAddressFilter(unsigned char Ps_Address) { CAN_NODE3_DEBUG.lmobj_ptr[0]->mo_ptr->can_id_mask &=0XFFFF00FF; CAN_NODE3_DEBUG.lmobj_ptr[0]->mo_ptr->can_id_mask |= (Ps_Address<<8); CAN_NODE_MO_Init(CAN_NODE3_DEBUG.lmobj_ptr[0]); } void ChangeGroupIDofLMO(const CAN_NODE_LMO_t *lmo_ptr,J1939_MESSAGE *MsgPtr) { int _i=0; lmo_ptr->mo_ptr->can_identifier = 0; for(_i=0;_i<4;_i++) { lmo_ptr->mo_ptr->can_identifier = (lmo_ptr->mo_ptr->can_identifier << 8) + MsgPtr->Array[_i]; } // 在线修改lmo配置 CAN_NODE_MO_Init(lmo_ptr); } /*从MsgPtr加载到CAN自带的结构体中*/ void J1939_CAN_Transmit(J1939_MESSAGE *MsgPtr) { CAN_NODE_LMO_t *lmo_ptr = CAN_NODE3_DEBUG.lmobj_ptr[1]; /*加载29ID*/ ChangeGroupIDofLMO((const CAN_NODE_LMO_t * const)(CAN_NODE3_DEBUG.lmobj_ptr[1]),MsgPtr); /*加载数据长度*/ lmo_ptr->mo_ptr->can_data_length = MsgPtr->Mxe.DataLength; CAN_NODE_MO_Init(lmo_ptr); /*加载数据*/ lmo_ptr->mo_ptr->can_data_byte[0] = MsgPtr->Mxe.Data[0]; lmo_ptr->mo_ptr->can_data_byte[1] = MsgPtr->Mxe.Data[1]; lmo_ptr->mo_ptr->can_data_byte[2] = MsgPtr->Mxe.Data[2]; lmo_ptr->mo_ptr->can_data_byte[3] = MsgPtr->Mxe.Data[3]; lmo_ptr->mo_ptr->can_data_byte[4] = MsgPtr->Mxe.Data[4]; lmo_ptr->mo_ptr->can_data_byte[5] = MsgPtr->Mxe.Data[5]; lmo_ptr->mo_ptr->can_data_byte[6] = MsgPtr->Mxe.Data[6]; lmo_ptr->mo_ptr->can_data_byte[7] = MsgPtr->Mxe.Data[7]; /*加载RTR*/ //你的代码 //开始发送数据 (CAN_NODE_STATUS_t) CAN_NODE_MO_Transmit(lmo_ptr) ; } //将设备CAN中的数据取出,存入J1939_MESSAGE结构体中 int J1939_CAN_Receive(J1939_MESSAGE *MsgPtr) { uint32_t receive_status=0; uint32_t _id=0; receive_status = CAN_NODE_MO_GetStatus( ((CAN_NODE_t *)&CAN_NODE3_DEBUG)->lmobj_ptr[0]); if ( receive_status & XMC_CAN_MO_STATUS_RX_PENDING) //XMC_CAN_MO_STATUS_NEW_DATA { // 清除接受标识位 CAN_NODE_MO_ClearStatus(((CAN_NODE_t *)&CAN_NODE3_DEBUG)->lmobj_ptr[0],XMC_CAN_MO_RESET_STATUS_RX_PENDING); // 读取数据 CAN_NODE_MO_Receive( ((CAN_NODE_t *)&CAN_NODE3_DEBUG)->lmobj_ptr[0]); //将29位标志位(can_identifier)写入J1939的结构中 _id = ((CAN_NODE_t *)&CAN_NODE3_DEBUG)->lmobj_ptr[0]->mo_ptr->can_identifier; MsgPtr->Array[0] = _id>>(8*3); MsgPtr->Array[1] = _id>>(8*2); MsgPtr->Array[2] = _id>>(8*1); MsgPtr->Array[3] = _id>>(8*0); //读取数据长度 MsgPtr->Mxe.DataLength = ((CAN_NODE_t *)&CAN_NODE3_DEBUG)->lmobj_ptr[0]->mo_ptr->can_data_length; if (MsgPtr->Mxe.DataLength > 8) MsgPtr->Mxe.DataLength = 8; //读取数据 MsgPtr->Mxe.Data[0] = ((CAN_NODE_t *)&CAN_NODE3_DEBUG)->lmobj_ptr[0]->mo_ptr->can_data_byte[0]; MsgPtr->Mxe.Data[1] = ((CAN_NODE_t *)&CAN_NODE3_DEBUG)->lmobj_ptr[0]->mo_ptr->can_data_byte[1]; MsgPtr->Mxe.Data[2] = ((CAN_NODE_t *)&CAN_NODE3_DEBUG)->lmobj_ptr[0]->mo_ptr->can_data_byte[2]; MsgPtr->Mxe.Data[3] = ((CAN_NODE_t *)&CAN_NODE3_DEBUG)->lmobj_ptr[0]->mo_ptr->can_data_byte[3]; MsgPtr->Mxe.Data[4] = ((CAN_NODE_t *)&CAN_NODE3_DEBUG)->lmobj_ptr[0]->mo_ptr->can_data_byte[4]; MsgPtr->Mxe.Data[5] = ((CAN_NODE_t *)&CAN_NODE3_DEBUG)->lmobj_ptr[0]->mo_ptr->can_data_byte[5]; MsgPtr->Mxe.Data[6] = ((CAN_NODE_t *)&CAN_NODE3_DEBUG)->lmobj_ptr[0]->mo_ptr->can_data_byte[6]; MsgPtr->Mxe.Data[7] = ((CAN_NODE_t *)&CAN_NODE3_DEBUG)->lmobj_ptr[0]->mo_ptr->can_data_byte[7]; return 1; }else { return 0;//没有消息 } } void J1939_RXinterruptEnable() { INTERRUPT_Enable(&CAN_RInterrupt_DEBUG); } void J1939_RXinterruptDisable() { INTERRUPT_Disable(&CAN_RInterrupt_DEBUG); } void J1939_TXinterruptEnable() { ; } void J1939_TXinterruptDisable() { ; } #endif

备注

J1939与CAN2.0B驱动接口函数在后面,将逐一的分析。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/132771.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 二维数组初始化规则

    二维数组初始化规则二维数组初始化的形式为:  数据类型数组名[整常量表达式][整常量表达式]={初始化数据};  在{}中给出各数组元素的初值,各初值之间用逗号分开。把{}中的初值依次赋给各数组元素。  有如下几种初始化方式:  ⑴分行进行初始化  inta[2][3]={{1,2,3},{4,5,6}};  在{}内部再用{}把各行分开,第一对{}中的初值1,2,3是0行的3个元素的初值。第…

    2022年7月18日
    12
  • Ubuntu 18 安装rabbitVCS

    Ubuntu 18 安装rabbitVCSsudoadd-apt-repositoryppa:ondrej/phpsudoapt-getinstallphp5.6-opcachesudoapt-getinstallphp5.6-jsonsudoapt-getinstallphp5.6-commonsudoapt-getinstallphp5.6-devsudoapt-getinstallpk…

    2022年7月18日
    13
  • 全国大学生电子设计竞赛(七)–逆变电源设计

    全国大学生电子设计竞赛(七)–逆变电源设计  逆变电源在全国大学生电子设计竞赛电源类题目中占十分重要的地位。每一个参加全国大学生电子设计竞赛并选择电源方向的学生都需要掌握逆变电源的设计制作。与整流相反,把直流电变为交流电称为逆变。逆变电路的应用非常广泛。当需要蓄电池、干电池、太阳能电池等直流电源向交流负载供电时,就需要逆变电路。除此之外,应用非常广泛的交流电机调速用变频器、不间断电源UPS、感应加热电源等电力电子装置的核心电路就是逆变电…

    2022年6月12日
    40
  • mac goland 2021激活码(最新序列号破解)[通俗易懂]

    mac goland 2021激活码(最新序列号破解),https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月18日
    53
  • html下拉框内容新增,给html下拉框控件自动添加数据[通俗易懂]

    html下拉框内容新增,给html下拉框控件自动添加数据[通俗易懂]functionAddRow(){varmyTable=tElementById(“ctl00_ContentPlaceHolder1_zjjzzTB”);varnewRowIndex=ws.length;functionAddRow(){varmyTable=tElementById(“ctl00_ContentPlac…

    2025年5月27日
    0
  • synchronousqueue场景_谈谈SynchronousQueue

    synchronousqueue场景_谈谈SynchronousQueueSynchronousQueue是一个没有容量的队列,它的put操作和take操作之间是相互依赖的,即put操作必须在take操作准备好时才能将元素“推”过去,反之take操作也必须在put操作准备推元素的时候才能获取到元素。有人可能会说只有1个容量大小的BlockingQueue也能实现该操作,但是它们之间有着本质的不同:1、SynchronousQueue在put时,如果另一个线程没有执行ta…

    2022年6月22日
    24

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号