返回列表 发新帖我要提问本帖赏金: 55.00元(功能说明)

[APM32F1] 基于APM32E103 SPI转CAN芯片MCP2515移植测试

[复制链接]
 楼主| Alden 发表于 2024-2-26 15:35 | 显示全部楼层 |阅读模式
<
本帖最后由 Alden 于 2024-2-26 15:35 编辑

#申请原创# #技术资源#
CAN简介:CAN 是控制器局域网络 Controller Area Network 的缩写,是 ISO 国际标准化的串行通信协议,支持 CAN 协议 2.0A 和 2.0B。在 CAN 协议中,发送者以广播形式把报文发送给所有接收者,节点在接收报文时,会经过过滤器组根据标识符决定是否需要该报文,这种设计节省了 CPU 的开销。

APM32E103系列支持CAN协议 2.0A 和 2.0B,通信波特率最大为 1Mbit/s,并且拥有双CAN接口,能适应更多的应用场合。
偶尔会有三个以上CAN接口需求或者需要在没有CAN接口的芯片上使用CAN

就可以考虑使用外接协议转换芯片,将其他通讯接口转接成CAN接口。

查找发现比较常用的就是MCP2515,带有SPI接口的独立CAN控制器。
MCP2515是独立的控制器局域网(CAN)控制器,实现CAN规范,版本2.0B。它是有能力的发送和接收标准和扩展数据和远程帧。MCP2515有两个接受掩码和六个接受过滤器被用来过滤掉不需要的消息,因此减少了主机MCU的开销。MCP2515与微控制器(mcu)的连接通过一个工业标准串行外设接口(SPI)来实现的。

在网上可以直接买到MCP2515的模块,方便直接在开发板上用杜邦线接出来测试。
1 (1).jpg
附带的资料包是基于51单片机的例程,需要修改移植到APM32的例程中。

移植基于APM32E10x_SDK_V1.2中的SPI_FullDuplex例程进行修改移植。
为了方便使用,硬件SPI和软件SPI都进行了定义初始化,通过宏定义来切换。
  1. #define SPI_S//SPI_H
软件SPI只需要初始化用到的IO引脚,硬件SPI就需要对SPI进行初始化配置。

MCP2515有一个中断脚,在总线上有CAN型号是会有下拉型号,告诉MCU需要准备进入接收状态。
所以需要在MCU上配置个外部中断引脚,用于快速响应。
  1. void MCP2515_GPIO_Init(void)
  2. {
  3.                 GPIO_Config_T GPIO_configStruct;
  4.                 EINT_Config_T     EINT_configStruct;
  5.                 RCM_EnableAPB2PeriphClock(RCM_APB2_PERIPH_GPIOA);

  6.                 GPIO_configStruct.pin = GPIO_PIN_0;
  7.                 GPIO_configStruct.mode = GPIO_MODE_IN_PU;
  8.                 GPIO_Config(GPIOA, &GPIO_configStruct);

  9.                 GPIO_ConfigEINTLine(GPIO_PORT_SOURCE_A,GPIO_PIN_SOURCE_0);

  10.                 /* Configure Button EINT line */
  11.                 EINT_configStruct.line =EINT_LINE_0;
  12.                 EINT_configStruct.mode = EINT_MODE_INTERRUPT;
  13.                 EINT_configStruct.trigger = EINT_TRIGGER_FALLING;
  14.                 EINT_configStruct.lineCmd = ENABLE;
  15.                 EINT_Config(&EINT_configStruct);
  16.                         /* Enable and set Button EINT Interrupt to the lowest priority */
  17.                 NVIC_EnableIRQRequest(EINT0_IRQn, 0x0f, 0x0f);
  18. }
SPI初始化完成后需要对MCU2515的寄存器进行初始化配置,配置CAN通讯的波特率工作模式等。
  1. void MCP2515_Init(void)
  2. {
  3.                         u16 i=0;
  4.         unsigned char temp=0;

  5.         MCP2515_Reset();        //发送复位指令软件复位MCP2515
  6.         Delay_Nms(1);                //通过软件延时约nms(不准确)

  7.         //设置波特率为250Kbps
  8.        
  9.         MCP2515_WriteByte(CNF1,CAN_250Kbps);
  10.         MCP2515_WriteByte(CNF2,0x80|PHSEG1_3TQ|PRSEG_1TQ);
  11.         MCP2515_WriteByte(CNF3,PHSEG2_3TQ);

  12.         MCP2515_WriteByte(TXB0SIDH,0xFF);//发送缓冲器0标准标识符高位
  13.         MCP2515_WriteByte(TXB0SIDL,0xE0);//发送缓冲器0标准标识符低位
  14.        
  15.         MCP2515_WriteByte(RXB0SIDH,0x00);//清空接收缓冲器0的标准标识符高位
  16.         MCP2515_WriteByte(RXB0SIDL,0x00);//清空接收缓冲器0的标准标识符低位
  17.         MCP2515_WriteByte(RXB0CTRL,0x20);//仅仅接收标准标识符的有效信息
  18.         MCP2515_WriteByte(RXB0DLC,DLC_8);//设置接收数据的长度为8个字节
  19.        
  20.         MCP2515_WriteByte(RXF0SIDH,0x00);//配置验收滤波寄存器n标准标识符高位
  21.         MCP2515_WriteByte(RXF0SIDL,0x00);//配置验收滤波寄存器n标准标识符低位
  22.         MCP2515_WriteByte(RXM0SIDH,0x00);//配置验收屏蔽寄存器n标准标识符高位
  23.         MCP2515_WriteByte(RXM0SIDL,0x000);//配置验收屏蔽寄存器n标准标识符低
  24.        
  25.         MCP2515_WriteByte(CANINTF,0x00);//清空CAN中断标志寄存器的所有位(必须由MCU清空)
  26.         MCP2515_WriteByte(CANINTE,0x01);//配置CAN中断使能寄存器的接收缓冲器0满中断使能,其它位禁止中断
  27.        
  28.         MCP2515_WriteByte(CANCTRL,REQOP_LOOPBACK|CLKOUT_ENABLED);//将MCP2515设置为环回模式,退出配置模式
  29.        
  30.         temp=MCP2515_ReadByte(CANSTAT);//读取CAN状态寄存器的值
  31.         if(OPMODE_NORMAL!=(temp && 0xE0))//判断MCP2515是否已经进入正常模式
  32.         {
  33.                 MCP2515_WriteByte(CANCTRL,REQOP_LOOPBACK|CLKOUT_ENABLED);//再次将MCP2515设置为环回模式,退出配置模式
  34.         }
  35. }
MCP2515的初始化部分基本结束,接下来就是到main中编写个收发测试。
可以看到MCP2515是配置成环回模式,也就是自发自收,方便测试SPI配置和MCP2515的配置是否正确。
  1. int main(void)
  2. {
  3.     APM_MINI_LEDInit(LED2);
  4.     APM_MINI_LEDInit(LED3);
  5.     APM_MINI_LEDOff(LED2);
  6.     APM_MINI_LEDOff(LED3);

  7.                 SPI_MCP2515_Init();
  8.                 MCP2515_Init();
  9.                 MCP2515_GPIO_Init();
  10.                 TMR5_INIT();
  11.         while(1)
  12.         {       
  13.                         //向CAN总线发送数据
  14.                                 if(timer_flag==0x01)   //定时发送
  15.                                 {
  16.                                                 timer_flag=0x00;
  17.                                                 if(++can_tx_msg.StdId>1000)can_tx_msg.StdId=0x00; //CANID每发送一条报文,自加1
  18.                                                 memcpy(can_tx_msg.Data, CAN_T_Buffer,8);          //取报文数据放入缓冲区       
  19.                                                 CAN_Send_Buffer(&can_tx_msg);
  20.                                                 APM_MINI_LEDToggle(LED2);
  21.                                 }
  22.                                
  23.                                 //接收CAN数据
  24.                                 if(can_tx_flag==0x01)  //判断中断标志位
  25.                                 {               
  26.                                                 CAN_Receive_Buffer(&can_rx_msg);
  27.                                                 can_tx_flag=0x00;
  28.                                 }
  29.         }       

  30. }
将杜邦线按照引脚配置,接好线后仿真就能测试回环模式下收发数据了。
微信图片_20240226153038.png
可以看到断点打到接收部分,可以接收到CAN数据,与发送的数据一致。

如果有其他can设备或者CAN分析仪的话,可以将工作模式改成普通模式,进行设备间的通讯。
MCP2515.pdf (1011.39 KB, 下载次数: 12) APM32E10x_SDK_V1.2-SPItocan.zip (3.85 MB, 下载次数: 20)

打赏榜单

21小跑堂 打赏了 55.00 元 2024-02-27
理由:恭喜通过原创审核!期待您更多的原创作品~(蓝v达人奖励已提升)

评论

一个简单的通过MCP2515芯片将SPI信号转CAN的实验,可用于无CAN口的MCU或CAN口不足的情况下进行CAN通信。  发表于 2024-2-27 11:12
@21小跑堂  发表于 2024-2-26 15:36
zps136631 发表于 2024-7-19 17:27 | 显示全部楼层
MCP2515直接用SIT2515代替是否可行?
 楼主| Alden 发表于 2024-7-22 09:44 | 显示全部楼层
zps136631 发表于 2024-7-19 17:27
MCP2515直接用SIT2515代替是否可行?

没试过,要对比寄存器看看能否兼容
您需要登录后才可以回帖 登录 | 注册

本版积分规则

49

主题

113

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部