CAN总线介绍及在ZYNQ 7020中的应用

一、CAN总线协议介绍

1.CAN是 Controller Area Network 的缩写(以下称为 CAN ),是 ISO 国际标准化的串行通信协议。可以用来满足“多总线通信时,线束的数量过多”、“通过多个 LAN ,进行大量数据的高速通信”的需要。它的出现为分布式控制系统实现各节点之间实时、可靠的数据通信提供了强有力的技术支持。

2.CAN总线通常由两根线组成。这两根线分别是CAN-High(CAN-H)和CAN-Low(CAN-L),它们共同实现CAN网络的通信。总线电平分为显性电平和隐性电平,二者必居其一。发送方通过使总线电平发生变化,将消息发送给接收方。利用两根线的差分电压来进行数据的传输。

3.CAN协议具有以下特点:

(1)CAN总线是一种多主总线,总线上任意节点可在任意时刻主动地向网络上其他节点发送信息而不分主次,因此可在各节点之间实现自由通信。

(2)CAN总线采用非破坏性总线仲裁技术。当多个节点同时向总线发送信息时,优先级低的节点会主动退出发送,而最高优先级的节点可以不受影响地继续传输数据,从而大大节省总线冲突的仲裁时间。即使在网络负载很重的情况下也不会发生网络瘫痪情况。

(3)CAN总线的通信介质可以是双绞线、同轴电缆或光导纤维,选择灵活。

(4)CAN总线的通信速率可达 1Mbit/s(此时通信距离最长为 40 米),通信距离最远可达 10km(速率在 5kbit/s 以下)。

(5)CAN总线上的节点信息分成不同的优先级,可以满足不同级别的实时要求,高优先级的数据可以在 134μs 内得到传输。

(6)CAN总线通过报文滤波即可实现点对点、一点对多点及全局广播等几种方式传送数据,无需专门的调度。

(7)CAN总线的数据采用短帧结构,传输时间短,受干扰概率低,具有极好的检错效果。

(8)CAN总线采用 CRC 检验并可提供相应的错误处理功能,保证了数据通信的可靠性。

(9)CAN总线上的器件可被置于无任何内部活动的睡眠方式,相当于未连接到总线上,可以有效降低系统功耗。

4.CAN总线采用差分信号传输,通常情况下只需要两根信号线就可以进行正常的通信。在差分信号中,逻辑0和逻辑1是用两根差分信号线的电压差来表示。

当处于逻辑1,CAN_H和CAN_L的电压差小于0.5V,称为隐性电平(Recessive);当处于逻辑0,CAN_H和CAN_L的电压差大于0.9V,称为显性电平(Dominant)。

5.CAN有四种帧类型:

◆ 数据帧:发送单元向接收单元传送数据的帧

◆ 远程帧:总线单元发出远程帧,请求发送具有同一识别符的数据帧

◆ 错误帧:由检测到错误的任何节点发送的帧

◆ 过载帧:在数据或远程帧之间注入延迟的帧

数据帧是唯一实际传输数据的帧,结构上由7个段组成,其中根据仲裁段ID码长度的不同,分为标准帧(CAN2.0A)和扩展帧(CAN2.0B):

◆ 标准帧格式:具有11个标识符位

◆ 扩展帧格式:具有29个标识符位

标准数据帧的构成如下图所示:

                 

6.数据帧一般由7个段构成,即:

(1)帧起始:表示数据帧开始的段。

(2)仲裁段:表示该帧优先级的段。

(3)控制段:表示数据的字节数及保留位的段。

(4)数据段:数据的内容,一帧可发送0~8个字节的数据标准数据帧的有效数据长度为0到8字节,而扩展数据帧的有效数据长度为0到64字节

(5)CRC段:检查帧的传输错误的段。

(6)ACK段:表示确认正常接收的段。

(7)帧结束:表示数据帧结束的段。

(详细的CAN介绍可以参看 CAN介绍.pdf)

二.工作原理

1.CAN控制器的工作原理

CAN核心模块:收到一个报文时,该模块根据CAN规范将穿行位流转换成用于接收的并行数据,发送相反。

发送缓冲器:存储一个完整的报文。

验收滤波器:根据用户设定,过滤掉无须接收的报文。

接收FIFO:存储从CAN总线上接收的所有报文。

三.应用代码

1.CAN 总线中数据在传输时使用了大端模式,即对于长度超过 1 字节的数据,先传输低字节,再传输高字节。

2.示例:

#include "xcanps.h"

#include "xparameters.h"

#include "xil_printf.h"

/************************** Constant Definitions *****************************/

#define CAN_DEVICE_ID XPAR_XCANPS_0_DEVICE_ID

#define XCANPS_MAX_FRAME_SIZE_IN_WORDS (XCANPS_MAX_FRAME_SIZE / sizeof(u32))

#define FRAME_DATA_LENGTH 8  /* Frame Data field length */

#define TEST_MESSAGE_ID 2000

#define TEST_BTR_SYNCJUMPWIDTH 3

#define TEST_BTR_SECOND_TIMESEGMENT 2

#define TEST_BTR_FIRST_TIMESEGMENT 15

#define TEST_BRPR_BAUD_PRESCALAR 29

/************************** Function Prototypes ******************************/

int CanPsPolledExample(u16 DeviceId);

static int SendFrame(XCanPs *InstancePtr);

static int RecvFrame(XCanPs *InstancePtr);

/************************** Variable Definitions *****************************/

static u32 TxFrame[XCANPS_MAX_FRAME_SIZE_IN_WORDS];

static u32 RxFrame[XCANPS_MAX_FRAME_SIZE_IN_WORDS];

/* Driver instance */

static XCanPs Can;

/****************************************************************************/

int main(void)

{

int Status;

Status = CanPsPolledExample(CAN_DEVICE_ID);

if (Status != XST_SUCCESS) {

xil_printf("CAN Polled Mode Example Test Failed\r\n");

return XST_FAILURE;

}

Status = SendFrame(&Can);

if (Status != XST_SUCCESS) {

return Status;

}

return XST_SUCCESS;

}

/*****************************************************************************/

int CanPsPolledExample(u16 DeviceId)

{

int Status;

XCanPs *CanInstPtr = &Can;

XCanPs_Config *ConfigPtr;

/*

 * Initialize the Can device.

 */

ConfigPtr = XCanPs_LookupConfig(DeviceId);

if (CanInstPtr == NULL) {

return XST_FAILURE;

}

Status = XCanPs_CfgInitialize(CanInstPtr,

ConfigPtr,

ConfigPtr->BaseAddr);

if (Status != XST_SUCCESS) {

return XST_FAILURE;

}

/*

 * Run self-test on the device, which verifies basic sanity of the

 * device and the driver.

 */

Status = XCanPs_SelfTest(CanInstPtr);

if (Status != XST_SUCCESS) {

return XST_FAILURE;

}

/*

 * Enter Configuration Mode so we can setup Baud Rate Prescaler

 * Register (BRPR) and Bit Timing Register (BTR).

 */

XCanPs_EnterMode(CanInstPtr, XCANPS_MODE_CONFIG);

while(XCanPs_GetMode(CanInstPtr) != XCANPS_MODE_CONFIG);

/*

 * Setup Baud Rate Prescaler Register (BRPR) and

 * Bit Timing Register (BTR).

 */

XCanPs_SetBaudRatePrescaler(CanInstPtr, TEST_BRPR_BAUD_PRESCALAR);

XCanPs_SetBitTiming(CanInstPtr, TEST_BTR_SYNCJUMPWIDTH,

TEST_BTR_SECOND_TIMESEGMENT,

TEST_BTR_FIRST_TIMESEGMENT);

/*

 * Enter Loop Back Mode.

 */

XCanPs_EnterMode(CanInstPtr, XCANPS_MODE_LOOPBACK);

while(XCanPs_GetMode(CanInstPtr) != XCANPS_MODE_LOOPBACK);

/*

 * Send a frame, receive the frame via the loop back and verify its

 * contents.

 */

Status = SendFrame(CanInstPtr);

if (Status != XST_SUCCESS) {

return Status;

}

Status = RecvFrame(CanInstPtr);

return Status;

}

/*****************************************************************************/

static int SendFrame(XCanPs *InstancePtr)

{

u8 *FramePtr;

int Index;

int Status;

/*

 * Create correct values for Identifier and Data Length Code Register.

 */

TxFrame[0] = (u32)XCanPs_CreateIdValue((u32)TEST_MESSAGE_ID, 0, 0, 0, 0);

TxFrame[1] = (u32)XCanPs_CreateDlcValue((u32)FRAME_DATA_LENGTH);

/*

 * Now fill in the data field with known values so we can verify them

 * on receive.

 */

FramePtr = (u8 *)(&TxFrame[2]);

for (Index = 0; Index < FRAME_DATA_LENGTH; Index++) {

*FramePtr++ = (u8)Index;

}

/*

 * Wait until TX FIFO has room.

 */

while (XCanPs_IsTxFifoFull(InstancePtr) == TRUE);

/*

 * Now send the frame.

 *

 * Another way to send a frame is keep calling XCanPs_Send() until it

 * returns XST_SUCCESS. No check on if TX FIFO is full is needed anymore

 * in that case.

 */

Status = XCanPs_Send(InstancePtr, TxFrame);

return Status;

}

/*****************************************************************************/

static int RecvFrame(XCanPs *InstancePtr)

{

u8 *FramePtr;

int Status;

int Index;

/*

 * Wait until a frame is received.

 */

while (XCanPs_IsRxEmpty(InstancePtr) == TRUE);

/*

 * Receive a frame and verify its contents.

 */

Status = XCanPs_Recv(InstancePtr, RxFrame);

if (Status == XST_SUCCESS) {

/*

 * Verify Identifier and Data Length Code.

 */

if (RxFrame[0] !=

(u32)XCanPs_CreateIdValue((u32)TEST_MESSAGE_ID, 0, 0, 0, 0))

return XST_LOOPBACK_ERROR;

if ((RxFrame[1] & ~XCANPS_DLCR_TIMESTAMP_MASK) != TxFrame[1])

return XST_LOOPBACK_ERROR;

/*

 * Verify Data field contents.

 */

FramePtr = (u8 *)(&RxFrame[2]);

for (Index = 0; Index < FRAME_DATA_LENGTH; Index++) {

if (*FramePtr++ != (u8)Index) {

return XST_LOOPBACK_ERROR;

}

}

}

return Status;

}

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

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

相关文章

FIFO Generate IP核使用——Native接口Basic页配置

Xilinx FIFO Generator IP核是一个经过全面验证的先入先出&#xff08;FIFO&#xff09;内存队列&#xff0c;专为需要按顺序存储和检索的应用而设计。该IP核为所有FIFO配置提供了优化解决方案&#xff0c;并在利用最小资源的同时实现最大性能&#xff08;高达500MHz&#xff0…

《Python编程从入门到实践》day19

#昨日知识点回顾 使用unittest模块测试单元和类 #今日知识点学习 第12章 武装飞船 12.1 规划项目 游戏《外星人入侵》 12.2 安装pygame 终端管理器执行 pip install pygame 12.3 开始游戏项目 12.3.1 创建Pygame窗口及响应用户输入 import sysimport pygameclass…

Android4.4真机移植过程笔记(三)

如果文章字体看得不是很清楚&#xff0c;大家可以下载pdf文档查看&#xff0c;文档已上传&#xff5e;oo&#xff5e; 7、安装加密APK 需要修改文件如下&#xff1a; 相对Android4.2改动还是蛮大的&#xff0c;有些文件连路径都变了: //Android4.2 1、frameworks/native/libs…

tableau基础学习——添加标靶图、甘特图、瀑布图

标靶图 添加参考线 添加参考分布 甘特图 创建新的字段 如设置延迟天数****计划交货日期-实际交货日期 为正代表提前交货&#xff0c;负则代表延迟交货 步骤&#xff1a;创建——计算新字段 把延迟天数放在颜色、大小里面就可以 瀑布图 两个表按照地区连接 先做个条形图&…

Linux的vim下制作进度条

目录 前言&#xff1a; 回车和换行有区别吗&#xff1f; 回车和换行的区别展示&#xff08;这个我在Linux下演示&#xff09; 为什么会消失呢? 回车和换行的区别 为什么\r和\n产生的效果不同&#xff1f; 打印进度条&#xff1a; &#xff08;1&#xff09;打印字符串 …

Anomalib:用于异常检测的深度学习库!

大家好,今天给大家介绍了一个用于无监督异常检测和定位的新型库:anomalib,Github链接:https://github.com/openvinotoolkit/anomalib 简介 考虑到可重复性和模块化,这个开源库提供了文献中的算法和一组工具,以通过即插即用的方法设计自定义异常检测算法。 Anomalib 包…

【STM32】快速使用F407通用定时器输出可变PWM

网上的文章太啰嗦&#xff0c;这里直接开始。 使用的是STM32CubeIDE&#xff0c;HAL。以通用定时器TIM12在 通道2上输出1KHz的PWM为例。 要确定输出的引脚、定时器连接在哪里。 TIM2、3、4、5、12、13、14在APB1上&#xff0c;最大计数频率84M。 TIM1、8、9、10、11在APB2…

RS0102YH8功能和参数介绍及如何计算热耗散

RS0102YH8功能和参数介绍-公司新闻-配芯易-深圳市亚泰盈科电子有限公司 RS0102YH8 是一款电平转换芯片&#xff0c;由润石&#xff08;RUNIC&#xff09;公司生产。以下是关于RS0102YH8的一些功能和参数的介绍&#xff1a; 电平转换功能&#xff1a; RS0102YH8旨在提供电平转换…

Web APIs 学习归纳5--- BOM浏览器对象

前面几节主要针对DOM进行了学习&#xff0c;现在开始新的内容的学习---DOM浏览器对象。 DOM是更注重页面&#xff08;document&#xff09;内容的设计&#xff0c;但是BOM不仅限于页面&#xff08;document&#xff09;的设计&#xff0c;而是更加全面包括页面的刷新&#xff0…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-8.2-链接脚本

前言&#xff1a; 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM&#xff08;MX6U&#xff09;裸机篇”视频的学习笔记&#xff0c;在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

C++入门基础(二)

目录 缺省参数缺省参数概念缺省参数分类全缺省参数半缺省参数声明与定义分离 缺省参数的应用 函数重载函数重载概念例子1 参数类型不同例子2 参数的个数不同例子3 参数的顺序不同 C支持函数重载的原理--名字修饰(name Mangling) 感谢各位大佬对我的支持,如果我的文章对你有用,欢…

傲软录屏(ApowerREC)一款简单好用的录屏软件,中文破姐版 v1.6.9.6(240501)

软件介绍 傲软录屏&#xff0c;是由ApowerREC开发的一款高级录屏软件&#xff0c;兼容多个操作系统平台&#xff0c;包括Windows、Mac以及基于安卓和iOS的设备。这款专业工具具备捕捉各类屏幕活动的能力&#xff0c;确保音视频同步&#xff0c;无论用户是进行电脑桌面操作、参…

算法入门<二>:分治算法之汉诺塔问题及递归造成的栈溢出

1、分治算法 分治&#xff08;divide and conquer&#xff09;&#xff0c;全称分而治之&#xff0c;是一种非常重要且常见的算法策略。分治通常基于递归实现&#xff0c;包括“分”和“治”两个步骤。 分&#xff08;划分阶段&#xff09;&#xff1a;递归地将原问题分解为两…

ARM学习(27)链接库依赖学习(二)dlopen failed:library xxxx.so

笔者继续学习一下链接的依赖库。 1、起因 Android下面需要需要一个日志解码库&#xff0c;所以笔者就编译了一个parse.so来进行解码&#xff0c; 编译器&#xff1a;Clang&#xff0c;基于llvm后端的编译器平台&#xff1a;交叉编译&#xff0c;linux -> aarch64 linux An…

Angular中的管道(Pipe)

Angular中的管道(Pipe) 文章目录 Angular中的管道(Pipe)前言一、内置管道1. date管道格式化日期2. currency管道格式化货币3. uppercase和lowercase管道转换字符串大小写4. 小数位数5. JavaScript 对象序列化6. slice7. 管道链 二、自定义管道 前言 Angular中的管道&#xff0…

【Qt之OpenGL】01创建OpenGL窗口

1.创建子类继承QOpenGLWidget 2.重写三个虚函数 /** 设置OpenGL的资源和状态,最先调用且调用一次* brief initializeGL*/ virtual void initializeGL() override; /** 设置OpenGL视口、投影等&#xff0c;当widget调整大小(或首次显示)时调用* brief resizeGL* param w* para…

四、线段、矩形、圆、椭圆、自定义多边形、边缘轮廓和文本绘制(OpenCvSharp)

功能实现&#xff1a; 对指定图片上进行绘制线段、矩形、圆、椭圆、自定义多边形、边缘轮廓以及自定义文本 一、布局 用到了一个pictureBox和八个button 二、引入命名空间 using System; using System.Collections.Generic; using System.Drawing; using System.Windows.F…

【MySQL | 第九篇】重新认识MySQL锁

文章目录 9.重新认识MySQL锁9.1MySQL锁概述9.2锁分类9.2.1锁的粒度9.2.2锁的区间9.2.3锁的性能9.2.4锁的级别 9.3拓展&#xff1a;意向锁9.3.1意向锁概述9.3.2意向锁分类9.3.3意向锁作用&#xff08;1&#xff09;意向锁的兼容互斥性&#xff08;2&#xff09;例子1&#xff08…

【Flutter】极光推送配置流程(小米厂商通道) 章二

前言 继【Flutter】极光推送配置流程(极光通道/华为厂商/IOS) 章一 并且&#xff0c;我大概率不会去修改第一篇文章的内容。 随着我自己在配置公司的项目的同时&#xff0c;我希望一直更新这个推送系列文章。 在章一配置完后&#xff0c;也是出现了一些问题&#xff0c;所以本…

PHP算命源码_最新测算塔罗源码_可以运营

众筹商城源码 众筹商品平台 商城加共识元富之路 网上商城众筹 前端是编译后的&#xff0c;后端PHP&#xff0c;带商城 运行截图 源码贡献 https://githubs.xyz/boot?app39 部分数据库表 CREATE TABLE ti_shopro_store (id int(11) NOT NULL AUTO_INCREMENT COMMENT ID,nam…