CAN总线接头(接线端子)都有哪些种类。

CAN总线是广泛应用在汽车控制和工业自动化控制领域里的现场总线,具有广阔的发展前景。基于CAN总线,工程师们开发出了各种各样的相关设备,比如USBCAN分析仪以及CAN转换网关等等。不知道你是否注意过,这些CAN总线设备的CAN接口都是什么样子的。下面,我们简单的来盘点一下:

1、多P凤凰端子类型,是最为常见的CAN接口类型,通用性好。

2、DP9接头。

3、OBD接头。

当然,只要是能够引出CAN高CAN低两根接线的,都可以充当CAN的接头,不要纠结于其外在的形象。

 

OBD
直观的从名称上来说是英文On-Board Diagnostics的缩写,中文翻译为“车载诊断系统”。书面上的解释就是处理汽车相关故障的诊断系统。对于硬件接口如下图

针对不同车型,汽车上的OBD接口位置会有所不同

而目前对于OBD接口的商用一般是作为GPS tracker即gps定位器,在汽车OBD上主要引出的接口包含了12V的电源、CAN总线、K线,L线等等如下图所示

对于实现与汽车内部诊断系统通信,就是通过这几条总线进行通信。我所理解的OBD从嵌入式的角度来说的话就是:外部器件与汽车内部系统通信的接口。

从何开始学习OBD
当我们认识了OBD相关概念之后,可是对于毫无经验的开发者来说,到底该如何下手,该先学习什么内容。我们要了解汽车内部的数据系统,那必须要学习的就是怎么和汽车进行通信,这时候就很明确了,那就是通过OBD接口的通信总线来打通外部与汽车内部的数据通信,而OBD包含的通信接口包含有CAN总线、K线以及L线,我这里主要是讲解CAN相关应用。

stm32的CAN总线
如果学习过单片机的朋友,谈到CAN总线相比OBD应该会更熟悉一些,对于CAN总线现在都是集成到芯片内部的,比较常用的就是stm32,对于使用者来说,不用太关心CAN总线的电路实现,我们只要能通过配置CAN总线进行通信就行了。在连接CAN总线通信的时候需要注意的是,在通信回路中需要并一个120欧的电阻,至于为什么需要电阻可以参考这篇博文:CAN总线为什么要有两个120Ω的终端电阻。关于CAN总线的理论基础,在网上都有很好的总结大家可以自行查找。我这里直接讨论在STM32中该如何配置CAN总线。首先调试CAN总线,可以先配置成回环模式进行调试,通过是否通信来判断can总线的相关初始化是否正确。对于can的初始化的流程,
1、配置CAN的IO口,在stm32中一般CAN的IO口是复用的,所以这里在配置的时候需要注意一下。
2、打开CAN总线的时钟,同时开始i配置CAN相关的寄存器数据,在这里很重要的一点就是要配置通信模式和波特率,这会关系到CAN的通信。
3、在初始化完之后,还需要配置CAN的滤波器,配置滤波器的目的是因为在汽车通信中,由于部分汽车是没有做网关的,当你通过CAN总线去通信的时候,会返回很多无用的消息,这个时候通过配置滤波器,直接过滤掉无用的,只接收特定的想要的数据。在滤波器中包含16位的滤波器和32位的滤波器配置,这个可以根据需要配置相应的滤波器。
网上有很多相关can初始化的配置,因为我这边使用的是stm32f042的芯片,可供大家参考一下

/****************************************************************************************
**函数信息(information):void CAN_GPIOConfig(void)
**功能描述(description):CAN所用IO引脚配置
**输入参数(Arguments)  :None
**输出参数(Returns)    :None
**调用提示(reference)  :    
*****************************************************************************************/
void CAN_GPIOConfig(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA ,ENABLE);    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE); //使能SYSCFG,
    
    GPIO_PinAFConfig(GPIOA,GPIO_PinSource11 ,GPIO_AF_4);    
    GPIO_PinAFConfig(GPIOA,GPIO_PinSource12,GPIO_AF_4);            //复用CAN功能
    
    SYSCFG->CFGR1 |= PA11_PA12_RMP;            //配置打开PA11_PA12功能
    
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_11;           
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;        
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;

    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_12;           
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AF;        
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
    
    GPIO_Init(GPIOA, &GPIO_InitStructure);    
}
/****************************************************************************************
**函数信息(information):void CAN1_Config32BitFilter(u32 id1, u32 id2, u32 mid1, u32 mid2)
**功能描述(description):CAN扩展帧滤波器设置
**输入参数(Arguments)  :id1,id2 校验码   mid1,mid2 屏蔽码
**输出参数(Returns)    :None
**调用提示(reference)  :    
*****************************************************************************************/
void CAN1_Config32BitFilter(u32 id1, u32 id2, u32 mid1, u32 mid2)
{
    CAN_FilterInitTypeDef  CAN_FilterInitStructure;
    NVIC_InitTypeDef  NVIC_InitStructure;
    
    CAN_FilterInitStructure.CAN_FilterNumber = 0;
    CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask;
    CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit;  
    CAN_FilterInitStructure.CAN_FilterIdHigh = id1>>13;
    CAN_FilterInitStructure.CAN_FilterIdLow = (id1<<3)|4;
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh = mid1>>13;
    CAN_FilterInitStructure.CAN_FilterMaskIdLow = (mid1<<3)|4;
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0;
    CAN_FilterInitStructure.CAN_FilterActivation = ENABLE;
    CAN_FilterInit(&CAN_FilterInitStructure);
    CAN_FilterInitStructure.CAN_FilterNumber = 1;
    CAN_FilterInitStructure.CAN_FilterIdHigh = id2>>13;
    CAN_FilterInitStructure.CAN_FilterIdLow = (id2<<3)|4;
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh = mid2>>13;
    CAN_FilterInitStructure.CAN_FilterMaskIdLow = (mid2<<3)|4;
    CAN_FilterInit(&CAN_FilterInitStructure);

    //中断优先级NVIC设置
    NVIC_InitStructure.NVIC_IRQChannel         = CEC_CAN_IRQn;  //CAN中断
    NVIC_InitStructure.NVIC_IRQChannelPriority = 0;          //先占优先级0级
    NVIC_InitStructure.NVIC_IRQChannelCmd      = ENABLE;     //IRQ通道被使能
    NVIC_Init(&NVIC_InitStructure);   
    
    CAN_ITConfig(CAN, CAN_IT_FMP0, ENABLE);       

}
/****************************************************************************************
**函数信息(information):void CAN1_Config16BitFilter(u16 id1, u16 id2, u16 mid1, u16 mid2)
**功能描述(description):CAN标准帧滤波器设置
**输入参数(Arguments)  :id1,id2 校验码   mid1,mid2 屏蔽码
**输出参数(Returns)    :None
**调用提示(reference)  :    
*****************************************************************************************/
void CAN1_Config16BitFilter(u16 id1, u16 id2, u16 mid1, u16 mid2)                                                                             
{                                                                                                                         
    CAN_FilterInitTypeDef  CAN_FilterInitStructure;                                                                       
    NVIC_InitTypeDef  NVIC_InitStructure;
    
    CAN_FilterInitStructure.CAN_FilterNumber=1;                                                                           
    CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;                                                         
    CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;                                                        
    CAN_FilterInitStructure.CAN_FilterIdHigh=id1<<5;                                                                      
    CAN_FilterInitStructure.CAN_FilterIdLow=id2<<5;                                                                       
    CAN_FilterInitStructure.CAN_FilterMaskIdHigh=mid1<<5;                                                                  
    CAN_FilterInitStructure.CAN_FilterMaskIdLow=mid2<<5;                                                                   
    CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0;                                                           
    CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;                                                                                                                                                                                       
    CAN_FilterInit(&CAN_FilterInitStructure);
    
    //中断优先级NVIC设置
    NVIC_InitStructure.NVIC_IRQChannel         = CEC_CAN_IRQn;  //CAN中断
    NVIC_InitStructure.NVIC_IRQChannelPriority = 0;          //先占优先级0级
    NVIC_InitStructure.NVIC_IRQChannelCmd      = ENABLE;     //IRQ通道被使能
    NVIC_Init(&NVIC_InitStructure);   
    
    CAN_ITConfig(CAN, CAN_IT_FMP0, ENABLE);       
}

/****************************************************************************************
**函数信息(information):u8* Send_CANFrame(CanTxMsg* TxMessage,u8 CANStype,ErrorStatus* err)
**功能描述(description):发送一帧CAN数据
**输入参数(Arguments)  :
**输出参数(Returns)    :None
**调用提示(reference)  :    
*****************************************************************************************/
__IO ErrorStatus RxFlay;
void Send_CANFrame(CanTxMsg* TxMessage,u8 CANStype,ErrorStatus* err)
{
    u32 i;
    RxFlay = ERROR;
    TxMessage->IDE = CANStype;
    TxMessage->DLC = 8;
//    USARTx_SendMData(&(TxMessage->Data[0]),9);
    CAN_Transmit(CAN, TxMessage);

    for (i = 0;i < 1500;i++)    
    {
        delay_ms(1);
        if (RxFlay == SUCCESS) 
            break;
    }
    *err = RxFlay;
}
//can口接收数据查询
//buf:数据缓存区;     
//返回值:0,无数据被收到;
//         其他,接收的数据长度;
u8 CAN1_Receive_Msg(u8 *buf)
{                      
     u32 i;
    CanRxMsg RxMessage;
    if( CAN_MessagePending(CAN,CAN_FIFO0)==0)return 0;        //没有接收到数据,直接退出 
    CAN_Receive(CAN, CAN_FIFO0, &RxMessage);//读取数据    
    for(i=0;i<RxMessage.DLC;i++)
    buf[i]=RxMessage.Data[i];  
    return RxMessage.DLC;    
}
/****************************************************************************************
**函数信息(information):void CEC_CAN_IRQHandler(void)
**功能描述(description):CAN中断接收函数
**输入参数(Arguments)  :
**输出参数(Returns)    :None
**调用提示(reference)  :    
*****************************************************************************************/
void CEC_CAN_IRQHandler(void)
{
    u8 data[8],i,j;
    u32 tmp;
    CanRxMsg   RbufMege;                      //CAN  receive message
    memset(&RbufMege,0,sizeof(CanRxMsg)); //先清空CAN数据接收缓存区
    CAN_Receive(CAN, CAN_FIFO0, &RbufMege);
}

需要注意的是如果CAN数据要中断接收的话,需要打开CAN的中断。

OBD的标准协议
要进行OBD数据的通信,那么必须要知道通信的通信协议,简而言之就是要获取数据的数据报文是什么,我发一条报文下去,它会返回相应的数据,我们对数据进行解析就可以获得我们最终的数据。而到底发送什么数据报文通信才会返回相应的数据,这就需要了解OBD协议的,而在OBD的通信协议中包含了不同总线的通信协议,也是世界通用的标准协议。
1、故障码标准ISO-15031。
2、通讯协议标准ISO-941,ISO-14230,ISO-15765,SAEJ1850
我这边主要讨论CAN总线在OBD中的协议ISO-15765。
首先我们必须要熟悉OBD通信的应用层,我们只需要看ISO-15031-5就行了,里面包含了OBD通信中的9种模式,每种模式需要获取的数据不一样如下:
Mode 1: 请求动力系当前数据

Mode 2: 请求冻结祯数据

Mode 3: 请求排放相关的动力系诊断故障码

Mode 4: 清除/复位排放相关的诊断信息

Mode 5: 请求氧传感器监测测试结果

Mode 6: 请求非连续监测系统OBD测试结果

Mode 7: 请求连续监测系统OBD测试结果

Mode 8: 请求控制车载系统,测试或者部件

Mode 9: 读车辆和标定识别号
其次,我们还需要ISO-15765-3里面包含了标准帧和扩展帧的使用方式和具体的数据流。通过这两个的组合我们就可以知道我们要发什么样的数据流去获取数据。
下面具体的数据流是什么,我推荐可以看一下这篇博文:ISO 15765 学习笔记

1.請求支持PID01-20
7DF 02 01 00 00 00 00 00 00------Tools To ECU 01 00:01表示SIDRQ,請求當前動力診斷信息;00表示PID((是否支持PID01-20))
7E8 07 41 00 FF FF FF FF FF------ECU To Tools (ECU #1(ECM)回覆的,41表示SIDPR,如果是表示肯定回答,00表示支持PID01到20;FF爲全支持)

2.請求支持PID21-40
7DF 02 01 20 00 00 00 00 00------Tools To ECU 01 20:01表示SIDRQ,請求當前動力診斷信息;20表示PID((是否支持PID21-40))
7E8 07 41 20 FF FF FF FF FF------ECU To Tools (ECU #1(ECM)回覆的,41表示SIDPR,如果是表示肯定回答,20表示PID((是否支持PID21-40));FF爲全支持)

3.請求支持PID41-60
7DF 02 01 40 00 00 00 00 00------Tools To ECU 01 40:01表示SIDRQ,請求當前動力診斷信息;40表示PID((是否支持PID41-60))
7E8 07 41 40 FF FF FF FF FF------ECU To Tools (ECU #1(ECM)回覆的,41表示SIDPR,如果是表示肯定回答,40表示PID((是否支持PID40-60));FF爲全支持)

4.外部測試設備向汽車請求後續的PID
7DF 02 01 01 00 00 00 00 00------Tools To ECU 01 01:第一個01表示SIDRQ,請求當前動力診斷信息;第二個01表示PID,向外發送DTC和MIL狀態數目。
7E8 07 41 01 33 44 55 66 77------ECU To Tools (// ECU #1(ECM)回覆的。41表示SIDPR;01表示PID;33表示不能發動,燃料系統,全面監控;…)

7DF 02 09 02 00 00 00 00 00------Tools To ECU 09 02:09表示SIDRQ;02表示信息類型:VIN碼
7E8 10 14 49 02 01 31 32 33------ECU To Tools(10:目前不知什麼意思, 14:表示迴應爲20字節 49:表示肯定響應 02:表示信息類型 VIN碼 01:表示第一個響應消息 31 32 33:VIN碼)
7E0 30 00 05 00 00 00 00 00------Tools To ECU (目前不知什麼意思,懷疑是連續包之類的)
7E8 21 34 35 36 37 38 39 41------ECU To Tools (21:目前不知什麼意思, 34~41:VIN碼)
7E8 22 42 43 44 45 46 47 48------ECU To Tools (22:目前不知什麼意思, 42~48: VIN碼;VIN碼全部加起來爲17字節)
知道了具体的数据流后可以根据相应9种模式到车上或者模拟器去实测一下,在国内对于CAN总线的实施是在2009年以后才开始的,所以有些老车不支持CAN总线,这个要去实测一下才知道

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/645662.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

结合Tensuns管理prometheus的blackbox与告警设置

场景说明&#xff1a; 因为业务服务器已经完成了三级等保&#xff0c;禁止在业务服务器上部署任何应用&#xff0c;遂选择一台新的服务器部署prometheus&#xff0c;采用blackbox_exporter监控业务服务器的端口与域名状态。 Tensuns项目介绍 https://github.com/starsliao/T…

链表--24. 两两交换链表中的节点/medium 理解度C

24. 两两交换链表中的节点 1、题目2、题目分析3、复杂度最优解代码示例4、适用场景 1、题目 给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&…

forEach()方法跳出循环

forEach方法如何跳出循环_foreach跳出循环-CSDN博客 forEach方法遍历数组&#xff0c;每次遍历都根据条件判断&#xff0c;当条件符合时&#xff0c;就跳出整个遍历&#xff0c;不再继续遍历后面的元素 forEach()方法跳出整个循环遍历 forEach方法一般用抛出异常的方式跳出整…

【JAVA语言-第15话】集合框架(二)——List、ArrayList、LinkedList、Vector集合

目录 List集合 1.1 概述 1.2 特点 1.3 常用方法 1.4 ArrayList集合 1.4.1 概述 1.4.2 练习 1.5 LinkedList集合 1.5.1 概述 1.5.2 特点 1.5.3 常用方法 1.5.4 练习 1.6 Vector类 1.6.1 概述 1.6.2 练习 1.7 List实现类的异同点 List集合 1.1 概述 java.util…

函数式接口

文章目录 函数式接口函数式接口当做方法的参数函数式接口作为返回值生产者接口 - Supplier消费者接口 - Consumer使用方式&#xff1a;案例&#xff1a;字符串拆分 判断接口 - Predicate使用方式应用场景 加工接口 - Function 函数式接口 只有一个抽象方法的接口&#xff0c;转…

(菜鸟自学)漏洞利用——MS11-080

&#xff08;菜鸟自学&#xff09;漏洞利用——MS11-080 漏洞简介利用漏洞对系统进行提权查看漏洞利用代码和工具将py脚本转换为exe程序渗透攻击验证 漏洞简介 MS11-080 是指微软于 2011 年发布的一个安全公告&#xff08;MS11-080&#xff09;&#xff0c;其中包含了关于 Win…

自动化网络故障管理

故障管理是网络管理的组成部分&#xff0c;涉及检测、隔离和解决问题&#xff0c;如果实施得当&#xff0c;网络故障管理可以使连接、应用程序和服务保持在最佳水平&#xff0c;提供容错能力并最大限度地减少停机时间&#xff0c;专门为此目的设计的平台或工具称为故障管理系统…

【并发编程】顺序控制交替输出abc

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;并发编程⛺️稳重求进&#xff0c;晒太阳 必须先2后1打印 用synchronized package aaa;public class Test2 {static Boolean hasExecutorfalse;public static void main(String[] args) …

1 - 搭建Redis数据库服务器|LNP+Redis

搭建Redis数据库服务器&#xff5c;LNPRedis 搭建Redis数据库服务器相关概念Redis介绍安装RedisRedis服务常用管理命令命令set 、 mset 、 get 、 mget命令keys 、 type 、 exists 、 del命令ttl 、 expire 、 move 、 flushdb 、flushall 、save、shutdown 配置文件解析 LNP …

Wordpress seo优化该怎么做?

Wordpress作为开源管理系统&#xff0c;目前已然是世界上最流行的cms之一&#xff0c;这不仅仅因为他开源&#xff0c;对用户友好&#xff0c;让任何人都能轻而易举的制作网站&#xff0c;更是因为这套程序对于搜索引擎非常友好&#xff0c;是做谷歌seo的不二之选 Wordpress作为…

【腾讯云服务器】幻兽帕鲁私服服务器部署保姆级教程

在帕鲁的世界&#xff0c;你可以选择与神奇的生物「帕鲁」一同享受悠闲的生活&#xff0c;也可以投身于与偷猎者进行生死搏斗的冒险。帕鲁可以进行战斗、繁殖、协助你做农活&#xff0c;也可以为你在工厂工作。你也可以将它们进行售卖&#xff0c;或分解后食用。 想要部署属于自…

【服务器Midjourney】Midjourney网站0基础搭建

目录 🌺【前言】 🌺【准备】 🌺【宝塔搭建MJ】 🌼1. 给服务器添加端口 🌼2. 使用Xshell连接服务器 🌼3. 安装docker 🌼4. 安装Midjourney程序 🌼5. 绑定域名+申请SSL证书 🌼6. 更新网站

两数之和[中等]

一、题目 给你一个下标从1开始的整数数组numbers&#xff0c;该数组已按非递减顺序排列&#xff0c;请你从数组中找出满足相加之和等于目标数target的两个数。如果设这两个数分别是numbers[index1]和numbers[index2]&#xff0c;则1 < index1 < index2 < numbers.len…

【AI】深度学习与图像描述生成——看图说话(1)

还记得我闲来无事&#xff0c;用大模型来“洗图”吗&#xff0c;就是想抄袭别人的图&#xff0c;但是又要装作原创的样子。因为洗稿大家都熟悉&#xff0c;洗图其实也是一样的。 【AIGC】今天想用AI“洗个图”&#xff0c;失败了&#xff0c;进来看我怎么做的-CSDN博客 【AIG…

哈夫曼树(Huffman)

哈夫曼树 Huffman 编码问题 问题引入 什么是编码&#xff1f; 简单说就是建立【字符】到【数字】的对应关系&#xff0c;如下面大家熟知的 ASC II 编码表&#xff0c;例如&#xff0c;可以查表得知字符【a】对应的数字是十六进制数【0x61】 \000102030405060708090a0b0c0d…

php下curl发送cookie

目录 一&#xff1a;使用 CURLOPT_COOKIE 选项 二&#xff1a;CURLOPT_COOKIEFILE 三&#xff1a;CURLOPT_HTTPHEADER php curl发送cookie的几种方式,下面来介绍下 一&#xff1a;使用 CURLOPT_COOKIE 选项 通过设置 CURLOPT_COOKIE 选项&#xff0c;你可以将 cookie 字符…

用ChatGPT创作留学文书三阶玩法详解!

最近人工智能聊天工具Chagpt火爆全网&#xff0c;从闲聊到编程&#xff0c;文学到菜谱&#xff0c;似乎以一种无所不能的姿态推翻了早期“人工智障”的屈辱招牌&#xff0c;正逐步进入并改变我们生产生活方式。作为文字处理大师&#xff0c;如果让人工智能来执笔大学申请文书会…

Linux 下查看端口以及释放端口

目录 一、查看端口是否被占用 1、使用 netstat 命令 2、使用 lsof 命令 二、释放端口 1、使用kill命令 2、使用 fuser 命令 三、netstat 四、lsof 五、fuser 一、查看端口是否被占用 在 Linux 系统上&#xff0c;你可以使用 netstat 或 lsof 命令来查看端口是否被占用。…

串口WiFi模块简介、工作原理、工作方式等8大知识点

WiFi模块又名串口WiFi模块&#xff0c;属于物联网传输层&#xff0c;功能是将串口或TTL电平转为符合WiFi无线网络通信标准的嵌入式模块&#xff0c;内置无线网络协议IEEE802.11b.g.n协议栈以及TCP/IP协议栈。串口WIFI模块&#xff0c;体积小&#xff0c;功耗低&#xff0c;采用…

springboot124中药实验管理系统设计与实现

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的中药实验管理系统设计与实现 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章…