1、开发环境
(1)KeilMDK:V5.38.0.0
(2)STM32CubeMX:V6.8.1
(3)MCU:STM32F407ZGT6
2、实现目的
(1)MCU的CAN通过CAN盒连接电脑,接收上位机发送的扩展数据帧。
(2)MCU过滤接收的扩展数据帧,通过串口打印出来作为验证。
3、原理图
(1)CAN芯片选择TJA1040。
(2)CAN_TX接PA12,CAN_RX接PA11。
4、过滤器相关介绍
(1)此实验以屏蔽位模式、32位位宽、扩展数据帧的接收过滤举例。
(2)过滤器映射图。
(3)筛选出的扩展ID为:xxx1 10xx 01xx 11xx 10xx 10xx 00xx 11xx (x为无关位)
5、主要程序
5.1、过滤器函数
/*
**功能:CAN过滤器配置
**参数:无
**返回值:无
**注:
** (1)屏蔽位模式、32位位宽、扩展数据帧的接收过滤举例
** (2)筛选出的扩展ID为: xxx1 10xx 01xx 11xx 10xx 10xx 00xx 11xx (x为无关位)
** (3)无关位填充零,相关位不变: 0001 1000 0100 1100 1000 1000 0000 1100 = 0x184C880C
** (4)无关位填充零,相关位为1: 0001 1100 1100 1100 1100 1100 1100 1100 = 0x1CCCCCCC
*/
void can_filter_config(void)
{
CAN_FilterTypeDef can_filterconfig;
// 过滤器模式:标识符掩码模式(屏蔽位模式)
can_filterconfig.FilterMode = CAN_FILTERMODE_IDMASK;
// 过滤器位宽:32位位宽
can_filterconfig.FilterScale = CAN_FILTERSCALE_32BIT;
//STID[10:3] STID[2:0] EXID[17:13] EXID[12:5] EXID[4:0] IDE RTR 0
// 扩展标识符位:决定是标准数据帧还是扩展数据帧;置1为扩展帧。
uint16_t IDE = 0x01;
// 远程发送请求位:0数据帧、1遥控帧(遥控帧没有后面的数据段);清零为数据帧
uint16_t RTR = 0x01;
// ID高字节
can_filterconfig.FilterIdHigh = (0x184C880C >> 13) & 0xffff;
// ID低字节
can_filterconfig.FilterIdLow = ((0x184C880C & 0x1FFF) << 3) \
| (IDE << 2) & (~(RTR << 1)) \
& (~ 0x01 );
printf("%.4x %.4x\r\n", can_filterconfig.FilterIdHigh, can_filterconfig.FilterIdLow);
// 掩码高字节
can_filterconfig.FilterMaskIdHigh = (0x1CCCCCCC >> 13) & 0xffff;
// 掩码低字节
can_filterconfig.FilterMaskIdLow = ((0x1CCCCCCC & 0x1FFF) << 3) \
| (IDE << 2) & (~(RTR << 1)) \
& (~ 0x01 );
printf("%.4x %.4x\r\n", can_filterconfig.FilterMaskIdHigh, \
can_filterconfig.FilterMaskIdLow);
can_filterconfig.FilterBank = 0; /* 选择过滤器组 */
can_filterconfig.FilterFIFOAssignment = CAN_FilterFIFO0; /* 过滤器关联FIFO */
can_filterconfig.FilterActivation = CAN_FILTER_ENABLE; /* 过滤器使能 */
can_filterconfig.SlaveStartFilterBank = 14;
HAL_CAN_ConfigFilter(&hcan1, &can_filterconfig);
}