1、CAN模块结构

5744CAN模块主要由CHI(Control Host Interface)、PE(Protocol Engine)和MBs三个部分组成,其中CHI负责发送仲裁和接收匹配,PE负责时钟等的配置,MBs进行消息的存储。结构如下图所示:

2、MB(Message Buffer)结构

5744含有多达64个MB(Mailbox)进行数据的收发,通过配置对应MB的C/S寄存器来进行数据发送或接收。其结构如下:

  • CODE 缓存器码,是进行缓存器匹配和仲裁过程的一部分,编码如下所示:
    0b0000 MB用于接收且未激活
    0b0100 MB用于发送、激活并且为空,准备接收数据
    0b0010 MB用于接收且为满
    0b0110 MB用于接收且为OVERRUN,并且被overwrite
    0b1010 MB接收到一个远程帧数据并发送一帧数据作为回应
    0bxxx1 MB用于接收且正在更新MB的内容,此时CPU禁止范围MB。
    0b1000 MB为用于发送且未激活
    0b1001 MB用于发送且被中止
    0b1100 MB用于发送,当RTR为0时内部消息为数据帧,当 RTR为1时,内部消息为远程帧
    0b1110 MB用于发送,为进入的远程请求帧发送一帧数据作为回应

  • SRR 替代远程请求 固定为隐形,该位发送时必须被设置为1,若接收到时不为1,则仲裁丢失

  • IDE ID标识位 1:MB内为扩展帧 0:MB内为标准帧

  • RTR 远程传输请求 1 :当前MB有一个远程请求帧要传输 0:当前MB有一个数据帧要传输

  • DLC 当前MB内数据的字节长度

  • TIMESTAMP 自由运行时间戳

  • PRIO 本地优先级,使能情况下,对于发送信箱有意义,参与发送仲裁过程

  • ID 帧ID

  • DATA BYTE0-7 数据域

3、模块配置

1、波特率设置
CAN时钟可选择外设时钟或晶振时钟作为时钟源,再时钟源选定以后可进行波特率的配置。公式如下:

其中Time Quanta的组成如下:
则可通过配置PRESDIV、PSEG1、PSEG2、PROPSEG的值配置不同的波特率,综合上述两个式子波特率计算公式为:

Bit Rate=
fcanclk/([1 + (PSEG1 + 1) + (PSEG2 + 1) + (PROPSEG + 1)] x (PRESDIV + 1))

其中各个值的范围和彼此的限制关系如下:
由于CAN模块具有较多的MB,在进行发送仲裁的时候需要耗费一定的时间,为了给发送仲裁留充足的时间,外设时钟(控制CHI的时钟)和比特率需要保证一定的比率,也就是在处理每CAN bit的外设时钟数要足够大,计算公式如下:
fsys为系统时钟,即是外设桥时钟,NCCP就是每CAN bit 耗费的外设时钟数,随着采用MB的数目的增加应调整NCCP的值,对应关系如下:
2、CAN模块配置过程
1)多路复用功能选择
2)运行模式选择
3)进行时钟源的选择(需要先失能CAN模块然后再打开);
4)使能Frzee模式并进入Frzee模式以进行波特率配置;
5)进行波特率的配置
6)退出Frzee模式并确认
3、示例代码

/******************************************* 名称         CAN_CAN0_Init* 说明         进行CAN0的初始化* 输入参数     无* 返回值       无* 示例         CAN_CAN0_Init();//进行CAN0的初始化*******************************************/
void CAN_CAN0_Init()
{uint8_t i=0;SIUL2.MSCR[16].B.SSS=1;    //PB0复用为CAN0_TXSIUL2.MSCR[16].B.OBE=1;SIUL2.MSCR[16].B.SRC=3;SIUL2.MSCR[17].B.IBE=1;    //PB1复用为CAN0_RXSIUL2.IMCR[32].B.SSS=2;MC_ME.PCTL79.B.RUN_CFG=0;  //选择运行模式0CAN_0.MCR.B.MDIS=1;        //关闭CAN模块CAN_0.CTRL1.B.CLKSRC=0;    //选择晶振作为CAN时钟源CAN_0.MCR.B.MDIS=0;        //开启CAN模块CAN_0.MCR.B.FRZ=1;         //允许进入Frzee 模式CAN_0.MCR.B.HALT=1;        //请求进入Frzee 模式while(!CAN_0.MCR.B.FRZACK);//确认进入frzee 模式CAN_0.CTRL1.B.PRESDIV=9;   //bit rate=fcanclk/([1+(PSEG1+1)+(PSEG2+1)+(PROPSEG+1)]x(PRESDIV+1))CAN_0.CTRL1.B.PSEG1=3;     //=40MHz/((1+4+4+7)*10)=1/4MHz=250kHzCAN_0.CTRL1.B.PSEG2=3;CAN_0.CTRL1.B.PROPSEG=6;CAN_0.CTRL1.B.RJW=3;       //配置 Resync Jump Width为3+1=4for(i=0;i<64;i++)          //复位MBs为失活状态{CAN_0.MB[0].CS.B.CODE=0;}CAN_0.MCR.B.MAXMB=63;       //选择最大可以数据缓存为默认,默认为63CAN_0.MCR.B.HALT=0;         //退出 Frzee模式while(CAN_0.MCR.B.FRZACK & CAN_0.MCR.B.NOTRDY);  //等待退出Frzee模式
}

4、缓存器配置
在进行CAN模块的配置后,在使用CAN收发之前,还需要对所需的缓冲器进行配置,具体函数及实现如下:

/********************************************************** 名称         CAN_CAN0_TMB_Config* 说明         将制定MB配置为发送缓存器* 输入参数*             CAN_MBx*               配置为发送的MB x可为0-63* 返回值      无* 示例        CAN_CAN0_TMB_Config(CAN_MB0);//配置MB0为发送缓存器*/
void CAN_CAN0_TMB_Config(uint8_t CAN_MBx)
{CAN_0.MB[CAN_MBx].CS.B.CODE=0;            //设置CAN_MBx为失活CAN_0.MB[CAN_MBx].CS.B.CODE=8;            //设置CAN_MBx为发送激活
}/********************************************************** 名称         CAN_CAN0_RMB_Config* 说明         将指定MB配置为接收缓冲器 并设置接收ID和接收中断优先级* 输入参数*             CAN_MBx*               所指定的MB x可为0~63*             id*               所指定的MB可接收的CAN帧ID*             prio*               所指定MB接收数据的优先级* 返回值      无* 示例        CAN_CAN0_RMB_Config(CAN_MB7,0x18FF9400,11);//配置MB7接收帧ID为0x18FF9400的数据,且设置其接收中断优先级为11*/
void CAN_CAN0_RMB_Config(uint8_t CAN_MBx,uint32_t id,uint8_t prio)
{CAN_0.MB[CAN_MBx].CS.B.CODE=0;           //将CAN_MBx设为失活CAN_0.MB[CAN_MBx].CS.B.IDE=1;            //设置CAN_MBx接收扩展帧CAN_0.MB[CAN_MBx].ID.R=id;               //设置CAN_MBx能接收的数据帧的IDif(CAN_MBx <= 31)                        //打开CAN_MBx的接收中断{CAN_0.IMASK1.R |=(1<<CAN_MBx);}else{CAN_0.IMASK2.R |=(1<<(CAN_MBx-32));}INTC_0.PSR[522+CAN_MBx/4].R=0x8000|prio; //设置CAN_MBx的接收中断优先级CAN_0.MB[CAN_MBx].CS.B.CODE=4;
}

4、传输过程

1、发送过程
1)检测对应标志位是否被置位并清除;
2)如果要使用的MB为激活状态,则写入中止码(0b1001)中止传输过程(或直接写入失活码(0b1000)失活对应MB);
3)写入ID、数据字节、数据长度,设置SRR、RTR、IDE等;
4)写入激活码激活MB参与发送仲裁进行传输。
2、示例代码

/******************************************************** 名称         CAN_CAN0_Send* 说明         采用CAN0发送指定数据* 输入参数*             can_msg*             要发送的CAN信息* 返回值       无* 示例         CAN_CAN0_Send(can_msg);//发送CAN信息can_msg********************************************************/
void CAN_CAN0_Send(uint8_t CAN_MBx,const CAN_Msg_Struct can_msg)
{uint8_t i=0;CAN_0.MB[CAN_MBx].CS.B.CODE=0b1000;             //失活MB0CAN_0.MB[CAN_MBx].ID.R=can_msg.id;              //设置IDfor(i=0;i<8;i++)CAN_0.MB[CAN_MBx].DATA.B[i]=can_msg.data[i];//设置数据CAN_0.MB[CAN_MBx].CS.B.DLC=can_msg.len;         //设置数据长度CAN_0.MB[CAN_MBx].CS.B.SRR=1;                   //设置SRR 强制为1CAN_0.MB[CAN_MBx].CS.B.IDE=1;                   //发送帧为扩展帧CAN_0.MB[CAN_MBx].CS.B.RTR=0;                   //非请求帧CAN_0.MB[CAN_MBx].CS.B.CODE=0b1100;             //设置MB0为发送激活 参与发送仲裁进行发送
}

3、接收过程
接收过程一般采用中断,本文只介绍CAN接收过程,具体中断配置参见PIT模块的介绍。
1)为保证数据完整新,先读取MB的C/S寄存器上锁MB;
2)读取ID、数据长度、数据等;
3)读取自由运行定时器解锁MB;
4)清零对应标志位;
4、示例代码

/************************************** 名称         CAN_CAN0_Msg_Set* 说明         将CAN_MBx内的数据加载入对应的数据帧内* 输入参数*        p_can_msg*          对应数据帧的指针*        CAN_MBx*          要赋值的数据帧对应的MB* 返回值      无*/
void CAN_CAN0_Msg_Set(CAN_Msg_Struct* p_can_msg,uint8_t CAN_MBx)
{uint8_t i=0;uint32_t dummy=0;dummy=CAN_0.MB[CAN_MBx].CS.R;p_can_msg->id=CAN_0.MB[CAN_MBx].ID.R;    //用于测试p_can_msg->len=CAN_0.MB[CAN_MBx].CS.B.DLC;for(i=0;i<p_can_msg->len;i++){p_can_msg->data[i]=CAN_0.MB[CAN_MBx].DATA.B[i];}dummy=CAN_0.TIMER.R;
}
/**************************************** 函数名        CAN_CAN0_Rx4_7_Isr* 功能            CAN_0 MB4-7中断接收函数* 输入参数    无* 返回值        无****************************************/
void CAN_CAN0_Rx4_7_Isr()
{uint32_t flags=0;flags=CAN_0.IFLAG1.R;if((flags&0x000000F0)== CAN_MB4_FLAG){CAN_CAN0_Msg_Set(&GL_Can_Msg,CAN_MB4);CAN_0.IFLAG1.R |= (1<<CAN_MB4);}else if((flags&0x000000F0)== CAN_MB5_FLAG){//GPIO_ToggleBit(GPIO_PORTC,GPIO_PIN12);CAN_CAN0_Msg_Set(&GL_Can_Msg,CAN_MB5);CAN_0.IFLAG1.R |= (1<<CAN_MB5);}else if((flags&0x000000F0)== CAN_MB6_FLAG){CAN_CAN0_Msg_Set(&GL_Can_Msg,CAN_MB6);CAN_0.IFLAG1.R |= (1<<CAN_MB6);}else{CAN_CAN0_Msg_Set(&GL_Can_Msg,CAN_MB7);CAN_0.IFLAG1.R |= (1<<CAN_MB7);}
}

MPC5744P-CAN模块相关推荐

  1. 【MPC5744P】劳特巴赫调试器Trace32的使用方法

    对于大部分MCU来说,官方IDE一般都带有调试功能,配合JTAG接口使用即可,也支持变量查看.断点等功能.绝大多数工业开发的中小型程序,使用自带调试器即可,价格便宜,几十到几千不等. 在某些特殊领域( ...

  2. MPC5744P-DMA模块及SPI DMA发送

    1.MPC5744P 主从机模块 mpc5744含有z4d_0 core.z4d_0 core Nexus.DMA.SIPI.FlexRay五个主机模块和FLASH CTRL.PRAM CTRL.PB ...

  3. MBD for MPC5744P

    MBD for MPC5744P 前言 一. 安装 二. 运行第一个模型 三. 可能遇到的问题 前言 经过了一番折腾,终于能正常创建模型.烧录程序及使用Freemaster进行监控了,在此记录一下,方 ...

  4. MPC5744P-SIUL2模块(GPIO和多路复用功能)

    MPC5744的SIUL2可用于GPIO.多路复用和中断/DMA请求,这里只涉及GPIO和多路复用功能. 1.GPIO功能 SIUL2能够控制芯片引脚的电特性,包括:1)自旋率.2)驱动能力.3)上拉 ...

  5. etcd 笔记(05)— etcd 代码结构、各模块功能、整体架构、各模块之间的交互、请求和应答流程

    1. etcd 项目结构和功能 etcd 项目代码的目录结构如下: $ tree ├── auth ├── build ├── client ├── clientv3 ├── contrib ├── ...

  6. OpenCV 笔记(01)— OpenCV 概念、整体架构、各模块主要功能

    1. OpenCV 概念 图像处理( Image Processing )是用计算机对图像进行分析, 以达到所需结果的技术, 又称影像处理. 图像处理技术一般包括图像压缩, 增强和复原, 匹配.描述和 ...

  7. Python 多线程总结(1)- thread 模块

    thread 模块 1. 单线程 首先看下单线程程序运行的例子,如下所示, import timedef loop0():print 'start loop0 begin', time.ctime() ...

  8. 关于python导入模块和package的一些深度思考

    背景 在python中有导入模块和导入package一说,这篇文章主要介绍导入模块和package的一些思考. 首先什么是模块?什么是package? 模块:用来从逻辑上组织python代码(变量,函 ...

  9. Python Re 模块超全解读!详细

    内行必看!Python Re 模块超全解读! 2019.08.08 18:59:45字数 953阅读 121 re模块下的函数 compile(pattern):创建模式对象 > import ...

  10. python性能分析之line_profiler模块-耗时,效率 时间

    20210203 直接用pycharm 自带的 20201215 直接装不上的情况下 先下载安装文件 再安装 line_profiler使用装饰器(@profile)标记需要调试的函数.用kernpr ...

最新文章

  1. python csv模块 一次读多行_python中csv模块读取reader只能读取一次
  2. Java回调函数的理解
  3. 浅谈Angular网络请求
  4. [Java网络编程基础]端口,协议
  5. Android之WebView学习
  6. linux权限介绍,Linux的权限介绍
  7. 【Kafka】kafka This may indicate that authentication failed due to invalid credentials
  8. linux ubuntu 获取ip,linux系统(ubuntu)怎么查看ip地址
  9. 小米2s Android pie,Android 9 Pie什么时候升级?小米MIX 2S抢先体验!
  10. app dcloud 打包公用证书
  11. 最小二乘法曲线拟合程序matlab,最小二乘法曲线拟合_原理及matlab实现.doc
  12. Kalman Filter— Priori/Posteriori Error Covariance Matrix
  13. Lonlife-ACM 1014 - Absolute Defeat [差分]
  14. 不同火车车型的座位分布图
  15. android dpi计算器,安卓多功能计算器 One++ Calculator 1.7.5 中文多语免费版
  16. 微软的Framework导致该内存不能为written或read的错误?
  17. Hadoop分布式集群搭建以及案例运行-fs操作
  18. 快速排序,归并排序的递归实现(c++)
  19. 蓝桥杯刷题013——小猪存钱罐(并查集)
  20. 后台缓存收回进程无法释放上下文[/BUSINESS的缓存的[10]%-请考虑增加缓存的最大大小

热门文章

  1. 百度地图在设置中心时,背景变白
  2. 异常Unable to create schema compiler处理办法
  3. 西部世界科普时间:FIL将从4月15日开始减产? 谣言!
  4. word显示隐藏格式清除残留格式
  5. 【车载以太网】【测试】架构及测试工具
  6. 宏基因组单个样本数据处理流程笔记
  7. 图计算思维与实践 (一)概览
  8. 百信社区-社区服务一体化
  9. Maya获取材质ShadingEngine信息
  10. qt 打印 刻度尺 曲线 复杂图像