想学习单片机的同学可以关注、私信我或者在评论区回复我要入门。要想使用CAN报文接收模块首先要完成相关的配置。
1 STM32CubeMX配置
使能CAN通讯:PA11配置为CAN_RX;PA12配置为CAN_TX
CAN通讯中断选择:USB low priority or CAN RX0 interrupts
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
·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静默环回模式
2建模
CAN报文的接收模型主要包括以下四个模块:
模块
简介
CAN_Filter
CAN报文过滤
CAN_Receive
CAN报文接收
CAN_IT
CAN报文中断
CAN_Read_Data
CAN报文读取
CAN报文接收模型
CAN 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默认即可。
将接收到的报文存入CAN_FIFO0:
在STMCubeMX配置好后,默认选择RX中断:
CAN数据读取模块输出的数据类型可以进行选择:
·输出CAN_MESSAGE类型,CAN_MESSAGE类型数据可以使用CAN Unpack模块进行解析
·输出CAN报文各段信号
CAN结构
简介
Std/Ext(0/1)
标准帧/扩展帧
IDE
CAN ID
D/R(0/1)
数据帧/远程帧
NbD
数据段长度
Data
数据段
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进行更新
本期先分享到这里,想要进群学习单片机编程的同学可以私信我,回复“我要入门”,与我们一起成长,喜欢的可以点个赞关注我们!
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.