HAL库进行CAN通讯的程序编写说明2

关于过滤器的设置:
1、过滤器是针对接收的,有两种方式分别为列表模式和掩码模式。每种模式下有16位位宽和32位位宽的差异。因此组合起来就有4种不同的设置。

  • 列表模式:将需要进行接收的报文ID写入过滤器,在接收时会根据列表进行接收,不在列表中的报文ID会进行过滤不接收。在列表模式下,16位位宽和32位位宽差异在于接收报文ID的数量不同。32位位宽的过滤器,在列表模式下每个过滤器只能写入两个报文ID,将希望存入的报文ID放入CAN_FxR1和CAN_FxR2这两个寄存器,而16位位宽最多可以写入4个报文ID,将CAN_FxR1和CAN_FxR2这两个寄存器进行拆分即可。
    在列表模式下,需要注意的是对应HAL库是FilterIdHigh是CAN_FxR1的高16位,FilterIdLow是CAN_FxR1的低16位。在ID填写过程中需要注意该寄存器的存放位置说明,并不是直接将ID进行赋值就行。在这里插入图片描述在这里插入图片描述

以32位为例,我们可以看到标准ID(共11bit)是被分开成两部分的,在FilterIdHigh寄存器的bit5-bit15。扩展ID(共18bit)也是被分开的,分为3部分,IDE是指标准ID还是扩展ID,RTR是数据帧还是远程帧。
一般列表模式都是针对ID数量不多的情况下进行的,能准确过滤。

  • 掩码模式:只需要设置某些位就可以。打个比方假设筛查1990—1999年出生的人,我其实可以只检查199x这三个数字就行,不需要最后一位也进行检查,此时假设我们观察的是身份证信息,那么在出生年份前面和后面其实还有很多位,我们把身份证号的其它位不需要进行检测就与0去进行与操作,需要进行检测的就是与1去进行与操作,这个与的操作就是屏蔽码的作用,而与后剩下的就是出生年份这一项,与199比较就是验证码。这个就是使用了掩码的方式,只取公共位就行,先进行大致的筛查。对应程序中也是在CAN_FxR1和CAN_FxR2这两个寄存器进行设置。我们需要设置屏蔽码和验证码这两个。其中对于32位位宽的过滤器来说CAN_FxR1就是存放验证码,CAN_FxR2存放屏蔽码。而16位位宽的就会拆分为2对验证码和屏蔽码,但此时只针对标准ID。在这里插入图片描述
    在这里插入图片描述
    掩码过滤时就按上面的寄存器标示进行设置即可。由于在列表模式下已经讲过就不再赘述。后面我们再讲讲具体的程序操作。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个基本的STM32 HAL库CAN通讯程序的示例,包含了CAN初始化、发送和接收数据的代码: ```c #include "stm32f4xx_hal.h" CAN_HandleTypeDef hcan; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_CAN1_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_CAN1_Init(); CAN_TxHeaderTypeDef TxHeader; uint8_t TxData[8] = {0, 1, 2, 3, 4, 5, 6, 7}; uint32_t TxMailbox; CAN_RxHeaderTypeDef RxHeader; uint8_t RxData[8]; while (1) { if (HAL_CAN_GetState(&hcan) == HAL_CAN_STATE_READY) { TxHeader.StdId = 0x123; TxHeader.RTR = CAN_RTR_DATA; TxHeader.IDE = CAN_ID_STD; TxHeader.DLC = 8; TxHeader.TransmitGlobalTime = DISABLE; HAL_CAN_AddTxMessage(&hcan, &TxHeader, TxData, &TxMailbox); } if (HAL_CAN_GetRxFifoFillLevel(&hcan, CAN_RX_FIFO0) != 0) { HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &RxHeader, RxData); // 处理接收到的数据 } } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; /** Initializes the CPU, AHB and APB busses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLM = 16; RCC_OscInitStruct.PLL.PLLN = 336; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4; RCC_OscInitStruct.PLL.PLLQ = 7; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB busses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK) { Error_Handler(); } PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_CAN; PeriphClkInit.CanClockSelection = RCC_CANCLKSOURCE_PLL; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { Error_Handler(); } } static void MX_CAN1_Init(void) {

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值