如何使用MCP2518FD外部CAN FD控制器实现速速CAN通信

这篇具有很好参考价值的文章主要介绍了如何使用MCP2518FD外部CAN FD控制器实现速速CAN通信。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

         MCP2518FD外部CAN FD控制器具有小尺寸和SPI接口,可实现轻松连接。可将CAN FD通道轻松添加到缺少CAN FD外设或没有所需CAN FD通道的微控制器上。MCP2518FD支持经典格式 (CAN 2.0B) 和CAN灵活数据速率 (CAN FD) 格式中的CAN帧格式,符合ISO11898-1:2015标准。

mcp2518,Microchip,前端,单片机

 框图:mcp2518,Microchip,前端,单片机

本文实验板MCUSTM32F103C8T6

CAN FD控制器:MCP2518FD

CAN FD收发器:ATA6560

开发环境:Keil uVision5.28

想了解开发板更详细信息,请点击 MCP2518FD学习评估套件

MCP2518FD学习评估套件

mcp2518,Microchip,前端,单片机

电路图如下:

mcp2518,Microchip,前端,单片机

 典型应用

mcp2518,Microchip,前端,单片机

上图有两部分组成,一部分是CAN控制器mcp2518fd,另一部分就是CANFD收发器ATA6563,我们实验板上用的是ATA6560,和ATA6563 PIN to PIN

对于CAN 收发器,有两个引脚要特别注意,就是STBYNSIL引脚,这两个引脚的状态控制CAN收发器工作状态,如下图:

CAN收发器STBY接地VIONSIL)接3.3vVDD5VVSS接地。

mcp2518,Microchip,前端,单片机

 1、SPI时序

mcp2518,Microchip,前端,单片机

我们要配置寄存器,要通过SPI总线发数据过去,相对于外设就是SDI接口的数据:Command + Address + Data.

  • 第一个字节:4位命令+4位地址;
  • 第二个字节:8位地址;
  • 第三个字节及以后:都是数据;

所以往寄存器写一个字节时序可以这么写:

// write one byte

spiTransmitBuffer[0] = (uint8_t) ((CMD << 4) + ((ADDR >> 8) & 0xF));  // 4位指令码+地址高4位

spiTransmitBuffer[1] = (uint8_t) (ADDR& 0xFF);            // 地址低8位

spiTransmitBuffer[2] = txdata;                                          // 数据位

同理,写halfWord或者one Word也可以这样定义。

指令:

mcp2518,Microchip,前端,单片机

注意:只有在器件进入配置模式后才能发出RESET 指令

 2、MCP2518FD 驱动程序移植

2.1 下载驱动程序

从Microchip 官网下载此IC的驱动程序,一共包括4个文件: drv_canfdspi_api.c,drv_canfdspi_api.h,drv_canfdspi_defines.h,drv_canfdspi_register.h

mcp2518,Microchip,前端,单片机

drv_canfdspi_api.c 里面是MCP2515FD的驱动函数。

drv_canfdspi_api.h 应对.c文件函数的声明

drv_canfdspi_defines.h 寄存器的值定义,比如CAN_DLC等等

drv_canfdspi_register.h 寄存器的定义

由于这4个文件都是官方做好的,我们只管拿过来用,尽量不要去修改里面的内容。

在Keil MDK建好工程后,直接把这4个文件添加到工程中。

 2.2 编写SPI驱动程序

//SPIx 读写一个字节

//TxData:要写入的字节

//返回值:读取到的字节  SPI通信可以同进读写数据

uint8_t SPI2_ReadWriteByte(uint8_t TxData)

{

         u8 dat=0,i;

        

         for(i=0;i<8;i++)

         {

                  if(TxData & 0x80)                                       // 如果位为1,则发送1,否则发送0

                  {

                          CAN1_SPI_MOSI_HIGH();                // 发送1  

                  }

                  else{CAN1_SPI_MOSI_LOW();                // 发送0

                  }

                  TxData<<= 1;

                  dat <<= 1;

                  __NOP();

                  __NOP();

                  if(CAN1_MISO())

                  {dat += 1; }

                  CAN1_SPI_CLK_HIGH();

                  __NOP();

                  __NOP();

                  CAN1_SPI_CLK_LOW();

                  __NOP();

                  __NOP();

         }

         CAN1_SPI_MOSI_LOW();

         return dat;

}

 2.3 SPI通信

通过分析官方给的4个文件,我们真正关心的,其实就是drv_canfdspi_api.c里的驱动函数,那如何将stm32f103c8t6的SPI函数连接上里面的函数呢?

SPI 数据的读写:

//数据读写

int8_t DRV_SPI_TransferData(uint8_t spiSlaveDeviceIndex, uint8_t *SpiTxData, uint8_t *SpiRxData, uint16_t spiTransferSize);

没错,就是这个函数。

spiSlaveDeviceIndex 由于SPI总线只接1MCP2518FD,所以这个值一直定义为0

*SpiTxData:要发送的数据首地址

*SpiRxData:接收数据存放在首地址

spiTransferSize:发送数据的字节数

完整函数如下:

mcp2518,Microchip,前端,单片机

mcp2518,Microchip,前端,单片机

2.4 CAN初始化

void MCP251xFD_canfd_cfg_init(CAN_BITTIME_SETUP baud)

{

         REG_CiFLTOBJ fObj;

         REG_CiMASK mObj;

         CAN_TX_FIFO_CONFIG txConfig;

         CAN_RX_FIFO_CONFIG rxConfig;

         CAN_CONFIG config;

         // Reset device

         DRV_CANFDSPI_Reset(CANFD_CH1);   //复位MCP2518FD 所有SFR和状态机都会像上电复位期间一样复位,器件会立即进入配置模式

         // Enable ECC and initialize RAM

         DRV_CANFDSPI_EccEnable(CANFD_CH1);    //使能ECC(ECC逻辑支持单个位错误纠正和双位错误检测)

         DRV_CANFDSPI_RamInit(CANFD_CH1, 0xff);         //并将RAM空间初始化为初值0xFF

                         

         // Configure device

         DRV_CANFDSPI_ConfigureObjectReset(&config);       //MCP2518FD配置信息复位

         config.IsoCrcEnable = 1;                 // 使能CAN FD帧中的ISO CRC

         config.StoreInTEF = 0;// 不将发送的报文保存到TEF中,也就不在RAM中预留TEF空间

         config.BitRateSwitchDisable = 0;  // Depends on the BRS bit on TX msg

         //CiCON->addr:0x00-03

         DRV_CANFDSPI_Configure(CANFD_CH1, &config);     //MCP2518FD配置

         // Setup TX FIFO  发送FIFO配置

         DRV_CANFDSPI_TransmitChannelConfigureObjectReset(&txConfig);

         txConfig.FifoSize = 11;                                                              // 采用FIFO11作为发送FIFO

         txConfig.PayLoadSize = CAN_PLSIZE_64;     // 有效负载大小位64个数据字节

         txConfig.TxPriority = 1;                                                       // 使能奇偶校验位

         //CiTXQCON->addr:0x50-53 + CAN_FIFO_CHn*12

         DRV_CANFDSPI_TransmitChannelConfigure(CANFD_CH1, CAN_TX_FIFO, &txConfig);

         // Setup RX FIFO              接收FIFO配置

         DRV_CANFDSPI_ReceiveChannelConfigureObjectReset(&rxConfig);

         rxConfig.FifoSize = 15;                                                               // 采用FIFO15作为接收FIFO

         rxConfig.PayLoadSize = CAN_PLSIZE_64;     // 有效负载大小位64个数据字节

         rxConfig.RxTimeStampEnable = 1;                                   // 捕捉时间戳 (去研究下,捕捉和不捕捉的区别在哪里)

        

         //CiFIFOCON1->addr:0x50-53 + CAN_FIFO_CHn*12

         DRV_CANFDSPI_ReceiveChannelConfigure(CANFD_CH1, CAN_RX_FIFO, &rxConfig);

        

         // set time stamp

         DRV_CANFDSPI_TimeStampModeConfigure(CANFD_CH1,CAN_TS_RES);

         DRV_CANFDSPI_TimeStampPrescalerSet(CANFD_CH1,40-1);     //40 clk 140M晶体,单位1us

         DRV_CANFDSPI_TimeStampSet(CANFD_CH1,0);

         DRV_CANFDSPI_TimeStampEnable(CANFD_CH1);       //使能时间戳

         // Setup RX Filter           接收滤波器设置 ,只接收数据侦ID0x128的数据(前提是屏蔽寄存器有效)

         fObj.word = 0;

         fObj.bF.SID = 0x128;       // 接收标准标识符 11bit            

         fObj.bF.EXIDE = 0;           // 接收扩展标识符使能位 1 enable, 0 disable  1bit

         fObj.bF.EID = 0;                         // 接收扩展标识符 18bit

         //CiFLTCON0->0x1D0-0x1D3

         DRV_CANFDSPI_FilterObjectConfigure(CANFD_CH1, CAN_FILTER0, &fObj.bF);

         // Setup RX Mask                     接收屏蔽器设置 高电平有效

         mObj.word = 0;                                 // 32bit 寄存器写法,这里不用

         mObj.bF.MSID = 0x128;  // 接收标准标识符屏蔽位 如果不应用于范围控制,就设置值等于 fObj.bF.SID,一对一对应

         mObj.bF.MIDE = 1;                  // 只适用于扩展侦模式,标准侦模式时,这个位不起作用

         mObj.bF.MEID = 0;                   // 接收扩展标识符屏蔽位

        

         //CiMASK0                                                                                     

         DRV_CANFDSPI_FilterMaskConfigure(CANFD_CH1, CAN_FILTER0, &mObj.bF);

         // Link FIFO and Filter 将接收滤波器与接收屏蔽器与接收FIFO绑定,则满足接收滤波器和接收屏蔽器规则的报文会在相应的FIFO接收。

         DRV_CANFDSPI_FilterToFifoLink(CANFD_CH1, CAN_FILTER0, CAN_RX_FIFO, true);

         // Setup Bit Time 设置位时间  总线波特率 baud,这里采用自动测量发送器延时的方式实现二次采样点采集数据位

         // CiNBTCFG->0x04-0x07

         DRV_CANFDSPI_BitTimeConfigure(CANFD_CH1, baud, CAN_SSP_MODE_AUTO, CAN_SYSCLK_40M);

         // Setup Transmit and Receive Interrupts

         // IOCONN->0xE04-0xE07

         DRV_CANFDSPI_GpioModeConfigure(CANFD_CH1, GPIO_MODE_INT, GPIO_MODE_INT);

         //CiFOFICON0

         DRV_CANFDSPI_ReceiveChannelEventEnable(CANFD_CH1, CAN_RX_FIFO, CAN_RX_FIFO_NOT_EMPTY_EVENT);

         //CiINT->0x1C

         DRV_CANFDSPI_ModuleEventEnable(CANFD_CH1, CAN_RX_EVENT);

         // Select Normal Mode   

         //CiCON->0x00-0x03

         DRV_CANFDSPI_OperationModeSelect(CANFD_CH1, CAN_NORMAL_MODE);

//     DRV_CANFDSPI_OperationModeSelect(CANFD_CH1, CAN_INTERNAL_LOOPBACK_MODE);

                                                       

}

2.5 CAN收发函数

先将数据打包,然后发送

mcp2518,Microchip,前端,单片机

CAN接收数据,这里用的是查询方式,先查询MCP2518FD INT引脚状态变化,如有变化,接收数据,其实,这个方法,很容易应用中断方式来接收。

mcp2518,Microchip,前端,单片机  数据接收的过程在 int8_t MCP251XFD_canfd_rcv_poll(void) 这个函数完成。

3 移植大概思路

3.1 先从官网下载驱动代码

   工程路径:MCP2518FD_STM32F103C8T6\Driver\canfdspi

   mcp2518,Microchip,前端,单片机

3.2 编写STM32F103 SPI函数

  工程路径:MCP2518FD_STM32F103C8T6\Driver

   SPI_mcp2518fd.c 和 SPI_mcp2518fd.h

  使用IO模拟SPI,并把SPI驱动连接到 drv_canfdspi_api.c 里的函数

int8_t DRV_SPI_TransferData(uint8_t spiSlaveDeviceIndex, uint8_t *SpiTxData, uint8_t *SpiRxData, uint16_t spiTransferSize)

3.3 编写MCP2518FD 初始化程序

  工程路径:MCP2518FD_STM32F103C8T6\User

  Canfd.c 和 canfd.h

  这个文件完成对MCP2518FD初始化,时钟配置,工作模式等等,都在这个函数完成:

  void MCP251xFD_canfd_cfg_init(CAN_BITTIME_SETUP baud)

  当然这个文件其它函数也是常用的,比如

   int8_t MCP251xFD_can_transmit_msg(CANFDSPI_MODULE_ID index,CANFD_TX_MSG *tx_msg)

   这个就是数据发送的。

3.4 发送数据打包 和 接收数据过程

   打包数据:

  mcp2518,Microchip,前端,单片机

接收数据,通过查询方式接收。

mcp2518,Microchip,前端,单片机文章来源地址https://www.toymoban.com/news/detail-802505.html

到了这里,关于如何使用MCP2518FD外部CAN FD控制器实现速速CAN通信的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Autosar CAN开发11-1(CAN控制器相关参数,位时间、Tq、采样点等)

            生活不易,猫咪叹气。好久没更新,距离上次更新已经是快半年前了。毕业到现在,已经在这家公司呆了快2年了。快的话一个月,慢的话两个月,马上就是提桶的日子了。                            说回我们的正题。                 平时在工作上,对于通

    2024年02月03日
    浏览(28)
  • 控制器局域网(CAN)物理层调试的基础知识和实例分析

    控制器局域网的概念 控制器局域网是国际上应用最广泛的现场总线之一。CAN被设计作为汽车环境中的微控制器通讯,在车载各电子控制装置ECU之间交换信息,形成汽车电子控制网络。比如:发动机管理系统、变速箱控制器、仪表装备、电子主干系统中,均嵌入CAN控制装置。

    2024年02月07日
    浏览(33)
  • Autosar BSW层CAN控制器相关参数------11(物理层。位时间、Tq、采样点等)

            生活不易,猫咪叹气。好久没更新,距离上次更新已经是快半年前了。毕业到现在,已经在这家公司呆了快2年了。快的话一个月,慢的话两个月,马上就是提桶的日子了。                            说回我们的正题。                 平时在工作上,对于通

    2024年02月10日
    浏览(29)
  • 基于STM32 ARM+ FPGA 的软体机器人的 CAN总线运动控制器的设计

    针对在软体机器人控制时 , 多电机协同控制过程中难度大 、 通用性差 、 协同性差等缺点 , 设计了基于 ARM 和 FPGA 的软体机器人的控制器局域网络 ( controller area network , CAN ) 总线运动控制器 , 采用 ARMCortex-M4 为内核的 STM32F407 开发板和 AX7102 FPGA 开发板设计一种基于 C

    2024年02月13日
    浏览(38)
  • [足式机器人]Part2 Dr. CAN学习笔记-Advanced控制理论 Ch04-7 LQR控制器 Linear Quadratic Regulator

    本文仅供学习使用 本文参考: B站:DR_CAN 线性控制器设计- 轨迹跟踪(Fellow a Desired Path)

    2024年02月02日
    浏览(46)
  • k8s控制器之job--第九弹 job如何使用扩展进行并行处理

    下面是一个 Job 的模板文件: 与 pod template 不同,此处的 job template 并不是一个 Kubernetes API 对象,而仅仅是 Job 对象的 yaml 文件(其中包含一些占位符)。例子文件中的 $ITEM 对 Kubernetes 并没有任何意义,仅仅是一个占位符,必须在使用时用实际数值替换。 在此例子中,容器唯

    2024年02月10日
    浏览(28)
  • 【GD32】从零开始学GD32单片机高级篇——外部存储器控制器EXMC详解+SDRAM读写例程

    外部存储器控制器EXMC,用来访问各种片外存储器,通过配置寄存器,EXMC可以把AMBA 协议转换为专用的片外存储器通信协议,包括 SRAM,ROM,NOR Flash,NAND Flash,PC Card和SDRAM 。 EXMC的工作原理其实就是把外部储存器的地址映射到内部的特定地址上,用户想访问外部的存储器,我们

    2024年02月10日
    浏览(76)
  • 如何监控EMC VNX控制器的启动过程

    这里我们要讨论的内容基本上适用于所有的EMC VNX中端存储系统,包含老的Clariion CX3,CX4,VNX1和VNX2,其实VNXe和Unity很多内容也是一样的。当然由于VNXe和Unity 操作系统的大的变化,差异也是比较大的。 导致EMC Clarrion CX和VNX存储控制器故障的原因有很多,常见的有: 1. 控制器物

    2024年02月08日
    浏览(26)
  • 如何将电机控制器添加到您的 ROS 机器人

            如果您正在构建与 ROS/ROS2 一起使用的移动机器人,您需要做的第一件事就是集成电机控制器。电机控制器的目的是接受来自更高级别的软件(如导航堆栈)的消息,并将其转换为驱动电机的信号。它还将从电机的编码器接收信息,以计算机器人的速度和位置。 您

    2024年02月15日
    浏览(38)
  • 【云原生】kubernetes控制器deployment的使用

        目录 ​编辑 1 Controller 控制器 1.1 什么是 Controller 1.2 常见的 Controller 控制器 1.3 Controller 如何管理 Pod 2 Deployment 2.1 创建 deployment 2.2 查看 deployment 2.3 扩缩 deployment 2.4 回滚 deployment 2.5 删除 deployment 1 Controller 控制器 官网: 控制器 | Kubernetes 1.1 什么是 Controller Kubernetes 通常不会

    2024年02月13日
    浏览(25)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包