STM32之CAN接收

本文介绍了STM32使用CAN通信的配置步骤,包括STM32CubeMX的设置,如波特率、中断选择等。同时,讨论了CAN报文接收模型,详细讲解了过滤器的工作原理和配置,并指出在接收中断和无限循环等待中的常见错误及其解决方案。最后,提到了通过更新tlc文件解决Simulink代码生成问题。
AI助手已提取文章相关产品:

想学习单片机的同学可以关注、私信我或者在评论区回复我要入门。要想使用CAN报文接收模块首先要完成相关的配置。

35381f824a430eb298f4180fde88fbf9.png

1 STM32CubeMX配置

使能CAN通讯:PA11配置为CAN_RX;PA12配置为CAN_TX

6c5f2359c11d001e6fc5f2fb9989bbc9.png

CAN通讯中断选择:USB low priority or CAN RX0 interrupts

49770b9c81d90c02c555ea2628611b93.png

APB1外设时钟设置为36MHz,通过配置CAN Bit Timings Parameters,将波特率设置为1Mbps:

·Prescaler : 4

·Time Quanta in Bit Segment 1 : 5

·Time Quanta in Bit Segment 2 : 3

·ReSynchronization Jump Width : 1

36000000(APB1的时钟)/(4(分频系数)/(5(TQ1)+3(TQ2)+1(同步段时间1tq))=1000k

8f7566595693da796ffb1e7c5704f0ef.png

·Time Triggered Communication选择disable:选择非时间触发通讯模式

·Automatic Bus-Off Management选择disable(可以enable):表示Bus Off后无法自恢复

·Automatic Wake-Up Mode选择disable(可以enable):表示不开启自动唤醒

·No-Automatic Retransmission选择enable:表示允许报文自动重传

·Receive Fifo Locked Mode接收FIFO锁定模式,选择disable,表示报文不锁定,新的覆盖旧的

·Transmit Fifo Priority发送FIFO优先级选择disable,表示优先级由报文标识符决定

Operating Mode选择正常模式

·Normal CAN硬件工作在正常模式

·silent CAN硬件工作在静默模式

·LoopBack环回模式(如果调试配置参数,可以选择环回模式)

·Silent_LoopBack静默环回模式

4cdca6ba341f35c92274306ce71002c1.png

2建模

CAN报文的接收模型主要包括以下四个模块:

模块

简介

CAN_Filter

CAN报文过滤

CAN_Receive

CAN报文接收

CAN_IT

CAN报文中断

CAN_Read_Data

CAN报文读取

08d7b2ae2470ce89e2e8d0d86412cfba.pngCAN报文接收模型75e93b0e55c8f244add11cf3ca3e3719.pngCAN Data Read SubSystem

can接收时,即使不需要过滤,也需要添加一个过滤器(选择mask模式,32位,MASK ID HIGH LOW,ID HIGH LOW都填0,过滤器选择FIFO0,其他默认就好)。can过滤器,有两种模式,一种mask模式(掩码模式),一种list模式(列表模式),有两种位选择,一种32位,一种16位:

检查 STDID[10:0]、 EXTID[17:0]、 IDE和 RTR位,一共 31位

检查 STDID[10:0]、 RTR、 IDE和 EXTID[17:15],一共 16位

列表模式:32位宽的列表模式,可以精确筛选两个ID(扩展帧和标准帧都可以),对于16位宽的列表模式,可以精确筛选4个标准帧ID,如果将IDE位置1,则可以筛选ID的高11位数据,无法精确筛选扩展帧ID。

掩码模式:类似屏蔽码和验证码,屏蔽码用来指定需要确定的位,验证码用来指定确定的位的值,两者一起用来过滤部分ID。

32位的掩码模式:Filter Id High与Filter Id Low合在一起表示CAN_FxR1寄存器,用来存放验证码,而Filter Mask Id High与Filter Mask Id Low合在一起表示CAN_FxR2寄存器,用来存放屏蔽码

16位的掩码模式:CAN_FxR1的低16位是作为验证码,对应的16位屏蔽码为CAN_FxR1的高16位,同样的,CAN_FxR2的低16位是作为验证码,对应与CAN_FxR2的高16位为屏蔽码

32位的列表模式:

·标准帧:将ID左移5位,然后转化为十进制,填入Filter Mask ID High;Filter Mask ID Low需要把IDE置为标准帧(值为0),数据帧RTR(值为0),所以计算值为0。

·扩展帧:将ID左移3位,再把ID右移16位,和0xffff做与运算,再转换为十进制,得到Filter ID High的值;Filter ID Low需要把先ID左移3位,和0xffff做与运算,再将IDE为置为扩展帧,数据帧RTR(值为0),再转换为十进制值。

对于STM32F103只有一个can,filter slave start bank没有作用,若是两路can,尽量设置为14。filter bank默认即可。

0a3edfcc5509495db319569f13c7e7c3.png

将接收到的报文存入CAN_FIFO0:

1f90b04ef5b479f2f8929913288b7416.png

在STMCubeMX配置好后,默认选择RX中断:

1dbd8dc7cc01696b04112579357ccf92.png

CAN数据读取模块输出的数据类型可以进行选择:

·输出CAN_MESSAGE类型,CAN_MESSAGE类型数据可以使用CAN Unpack模块进行解析

·输出CAN报文各段信号

CAN结构

简介

Std/Ext(0/1)

标准帧/扩展帧

IDE

CAN ID

D/R(0/1)

数据帧/远程帧

NbD

数据段长度

Data

数据段

d381844ec4780b411b8b4761c7c31451.png

3 BugFix

3.1 CAN中断Bug

无法进入CAN接收中断,通过排查发现代码中并未开启中断,原代码如下:

/* Activate CAN Error notifications. */

{

constuint32_tactiveITs=CAN_IT_ERROR_WARNING|CAN_IT_ERROR_PASSIVE|

CAN_IT_LAST_ERROR_CODE|CAN_IT_ERROR;

if(HAL_CAN_ActivateNotification(&hcan,activeITs)!=HAL_OK){

Error_Handler();

}

}

原代码中仅仅使能了CAN Error中断,并没有使能CAN接收中断,因此加入“CAN_IT_RX_FIFO0_MSG_PENDING”更新代码如下:

/* Activate CAN Error notifications. */

{

  const uint32_t activeITs = CAN_IT_ERROR_WARNING|CAN_IT_ERROR_PASSIVE|

    CAN_IT_LAST_ERROR_CODE| CAN_IT_ERROR |CAN_IT_RX_FIFO0_MSG_PENDING;

  if (HAL_CAN_ActivateNotification(&hcan, activeITs) != HAL_OK) {

    Error_Handler();

  }

}

3.2 CAN接收Bug

CAN接收模块CAN_Receive在运行过程中会进入无限循环的等待:

/* Polling case. *//* Wait for reception, at least something available in FIFO. */while(HAL_CAN_GetRxFifoFillLevel(&hcan,CAN_RX_FIFO0)==0);

为了能够使主逻辑正常运行,需要对无线循环进行限制:

/* Polling case. */

/* Wait for reception, at least something available in FIFO. */

int temp_wait = 1;

while (HAL_CAN_GetRxFifoFillLevel(&hcan, CAN_RX_FIFO0) == 0)

{

   temp_wait++;

   if (temp_wait > 100)break;

}

在Keil5中直接更新代码后,如若simulink代码再次生成代码,手动修改的内容将不会被保存。为了一次性解决问题,需要更新硬件驱动该库文件[2]——tlc文件。需要修改对应的tlc文件(STM32-MAT的安装目录\STM32\blks\mex\tlc_c文件夹)。

另外从网友分享信息中,通过unpack模块进行扩展帧的接收会出现新的问题:

标准帧可以接收到数据,正常转发,而扩展帧中的数据接收不到。通过STlink调试发现,生成的代码中unpack模块判断扩展帧是为1,而接收的ID信息在赋值时,STM32定义的扩展帧表示为4。为了解决问题也需要对can_read_data.tlc进行更新

f221607500cce615a01d870a243ba37f.png

本期先分享到这里,想要进群学习单片机编程的同学可以私信我,回复“我要入门”,与我们一起成长,喜欢的可以点个赞关注我们!

cf6ad08d57202a7a883fbca2d4bff651.png85b9a3c3554008dcfff38ec64e834659.png

您可能感兴趣的与本文相关内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值