这是我根据一个实际的项目,学习CAN和CANOpen之后写下的半笔记性质的文章。
阅读前提,是对CAN有一些浅显的认识,并且正在尝试理解一个现成的CAN代码。
为什么建议大家结合代码阅读呢,是因为本文最初的起源,就是我在注解前人代码的时候,写的注释集合。所以如果没有一个代码做范本,直接阅读本文,因为全是干货,而且是干的非常彻底的干货,很快你就会觉得本文极度枯燥,难以阅读。
但如果你手上正好有一个CANOpen的代码,但你又不太看得懂代码到底在干嘛,那么本文比较适合你当字典查阅,因为CANOpen在实际工作中常用的内容,你几乎都能查到。
本文着重于简洁,全面,用最短的篇幅把实际工作中用到的知识点都梳理出来。所以一些很基础的概念,本文不再逐条说明;一些实际工作中用不到的知识,也不罗列。程序员都没有时间读长篇大论,我的目的更不是把整个协议翻译一遍,够用就好。
我也是从一个对CAN几乎一无所知的小白起步的,所以有点耐心(本文的后面几篇很多内容都需要反复阅读两三遍才能看明白),你一定能吃透的(结合源代码)。
最后,本文很多图片素材来自于CSDN,所以你有似曾相识的感觉并不奇怪,但本文所有内容都是我重新消化组织的,并逐一校正了原始文章的各种错误。
源代码,这个我不提供,也不能提供,请谅解。我自己的源代码是基于GD单片机的,你会发现有些涉及硬件的内容,还是那句话,我尽量不讲代码中不涉及或者底层驱动帮你自动完成的内容,既然列出来了,肯定是对理解代码有帮助的部分。
第一部分、CAN的基础协议:
第一节、关于显性和隐性:
显性数值表示逻辑0,隐性数值表示逻辑1。仲裁的时候显性(0)优先。
典型地,CAN总线为隐性(逻辑1)时,CAN_H和CAN_L的电平都为2.5V(电位差为0V);CAN总线为显性(逻辑0)时,CAN_H和CAN_L电平分别为3.5V和1.5V(电位差为2.0V)。
Dominant是显性(0)(优先),Recessive是隐性。