门户网站开发多少钱,wordpress主题文章页面不显示,工业设计研究生院校排名,个人博客网站搭建文章目录 前言一、基础知识快速理解1.1 理解CAN标识符:1.2 过滤器的工作原理:1.3 如何配置过滤器: 二、过滤器模式的选择#xff08;监听多个ID#xff09;2.1 使用掩码模式多个过滤器匹配多标准ID:2.2 使用掩码来匹配多个ID:#xff08;待写#xff09;2.3 使用列表模式来… 文章目录 前言一、基础知识快速理解1.1 理解CAN标识符:1.2 过滤器的工作原理:1.3 如何配置过滤器: 二、过滤器模式的选择监听多个ID2.1 使用掩码模式多个过滤器匹配多标准ID:2.2 使用掩码来匹配多个ID:待写2.3 使用列表模式来匹配多个标准ID: 三、相关代码测试3.1 测试列表模式__标准ID3.2 测试掩码模式__标准ID3.3 测试回调函数接收到的ID 总结 前言
stm32 cubemx can通讯1回环模式
过滤器可以说是can中最重要的东西我也认为这个是一个相当复杂的一个东西。 一个刚刚学习的小白以下文字只是自我学习的笔记若有写错或不明确的地方请大佬指正。 CAN过滤器是一个非常重要的功能它允许你只接收你关心的CAN消息从而提高效率和性能。 一、基础知识快速理解
1.1 理解CAN标识符:
在CAN总线上每个消息都有一个唯一的标识符(ID)。这个ID可以是11位(标准ID)或29位(扩展ID)。ID不仅仅是用来标识消息来源而且还决定了消息的优先级ID小的消息优先级更高。
1.2 过滤器的工作原理:
过滤器的工作原理是将传入的ID与预设的ID进行比较然后决定是否接收这个消息。过滤器可以工作在两种模式下
列表模式 (Identifier List mode): 在这种模式下你可以为每个过滤器指定一个或多个ID。只有与这些ID匹配的消息才会被接收。掩码模式 (Identifier Mask mode): 在这种模式下你为每个过滤器指定一个ID和一个掩码。只有与这个ID匹配的消息才会被接收。掩码允许你定义哪些位是重要的(即需要匹配的)和哪些位可以忽略。例如一个掩码0xFF0表示你只关心ID的高8位而不关心低4位。
1.3 如何配置过滤器:
下面只要知道大致流程就行不要知道sFilterConfig这些东西是啥后面会说
1.3节都是基于标准ID 首先, 我们考虑一个例子我们只希望接收ID为0x123的消息其他消息都忽略。
设置选择的过滤器: sFilterConfig.FilterBank 0; // 使用过滤器0
设置过滤器模式为掩码模式: sFilterConfig.FilterMode CAN_FILTERMODE_IDMASK;
使用32位模式: 这使得我们可以处理标准ID和扩展ID。 sFilterConfig.FilterScale CAN_FILTERSCALE_32BIT;
指定我们关心的ID和掩码: 因为0x123是一个标准ID我们可以这样配置
sFilterConfig.FilterIdHigh 0x123 5; // 11位ID需要左移5位
sFilterConfig.FilterIdLow 0x0000;
sFilterConfig.FilterMaskIdHigh 0xFFFF; // 只关心高16位
sFilterConfig.FilterMaskIdLow 0x0000; 这样的配置意味着我们只接收高16位是0x123低16位可以是任何值的消息。由于标准ID只有11位低16位永远是0所以这正是我们想要的。 为什么左移5位 STM32的CAN过滤器使用了一种特殊的方式来处理标准11位和扩展29位的ID。为了在32位寄存器中放入11位的标准ID我们需要将其左移5位。这是硬件的要求不是我们随便决定的。 所以如果你有一个标准ID0x123其二进制形式是 100100011 为了将它放入STM32的过滤器寄存器你需要将它左移5位 100100011 00000 这就是为什么我们使用 5。 为什么只关心高16位 当我们说“只关心高16位”其实是指在32位的掩码或ID中我们只设置或匹配高16位。STM32的CAN过滤器将32位分为了两个16位的部分FilterIdHigh和FilterIdLow。在我们的例子中由于我们只处理一个11位的标准ID所以我们只需要在FilterIdHigh部分设置它而将FilterIdLow部分设置为0。 关于11位与16位的区别: 实际上我们并不真的关心整个16位只关心其中的高11位。但由于简化和兼容性的考虑我们通常设置整个16位。 如果我们想要严格限制为只匹配高11位并且确保其他位不匹配我们可以使用0xF800作为掩码。这表示我们关心高11位1111 1000 0000 0000而不关心低5位。 总之为了简化操作我们通常使用0xFFFF作为掩码来接收所有与指定ID匹配的标准CAN消息。但如果你想要更精确的匹配你可以调整掩码以只匹配高11位。 设置FIFO: sFilterConfig.FilterFIFOAssignment CAN_FILTER_FIFO0; 这意味着匹配的消息将被放入FIFO0。
二、过滤器模式的选择监听多个ID
当想要监听多个标准ID的时候有几种方法可以实现 简而言之掩码告诉硬件哪些位是我们关心的而过滤器则告诉硬件我们希望这些位的值是什么。如果接收到的消息与过滤器匹配只在我们关心的位上那么消息将被接受。 2.1 使用掩码模式多个过滤器匹配多标准ID:
STM32的CAN控制器提供了多个过滤器具体数量取决于具体的STM32型号。每个过滤器可以配置为匹配一个或多个ID。 例如你想要监听两个标准ID0x123和0x456。你可以设置两个过滤器每个过滤器匹配一个ID。
// 过滤器0匹配0x123
sFilterConfig.FilterBank 0; // 使用过滤器0
sFilterConfig.FilterIdHigh 0x123 5;
sFilterConfig.FilterMaskIdHigh 0xFFFF;
HAL_CAN_ConfigFilter(hcan, sFilterConfig);
// 过滤器1匹配0x456
sFilterConfig.FilterBank 1; // 使用过滤器1
sFilterConfig.FilterIdHigh 0x456 5;
sFilterConfig.FilterMaskIdHigh 0xFFFF;
HAL_CAN_ConfigFilter(hcan, sFilterConfig);2.2 使用掩码来匹配多个ID:待写
这种方法取决于你想要监听的ID的特性。如果这些ID有一定的位集合你可以使用掩码来匹配它们。
2.3 使用列表模式来匹配多个标准ID: 在列表模式下过滤器会尝试匹配你所列举的任何ID。对于标准ID一个过滤器可以匹配两个ID。对于扩展ID过滤器只能匹配一个ID。 这里是一个如何使用列表模式来匹配四个标准ID0x1, 0x2, 0x3, 0x4的示例
// 过滤器1匹配0x1和0x2
sFilterConfig.FilterBank 0;
sFilterConfig.FilterMode CAN_FILTERMODE_IDLIST;
sFilterConfig.FilterScale CAN_FILTERSCALE_16BIT; // 16-bit列表模式用于标准IDsFilterConfig.FilterIdHigh 0x1 5; // ID1
sFilterConfig.FilterIdLow 0x2 5; // ID2HAL_CAN_ConfigFilter(hcan, sFilterConfig);// 过滤器2匹配0x3和0x4
sFilterConfig.FilterBank 1;
sFilterConfig.FilterIdHigh 0x3 5; // ID3
sFilterConfig.FilterIdLow 0x4 5; // ID4HAL_CAN_ConfigFilter(hcan, sFilterConfig);为什么使用 CAN_FILTERSCALE_16BIT 而不是 CAN_FILTERSCALE_32BIT? 当我们使用标准ID11位并希望用单个过滤器同时匹配多个ID时CAN_FILTERSCALE_16BIT 是有意义的。STM32的CAN硬件允许我们在16位过滤模式下为两个标准ID设置单个过滤器。因此每个32位寄存器可以分为两个16位部分每部分用于一个标准ID。这使得硬件更加高效地匹配两个不同的ID而不需要额外的过滤器。 关于 sFilterConfig.FilterIdHigh 和 sFilterConfig.FilterIdLow 的顺序: 过滤器的初始化顺序是可以互换的。你可以首先设置 FilterIdLow然后再设置 FilterIdHigh。硬件只是看这两个值和接收的消息ID进行比较不关心你是如何设置这两个值的。 sFilterConfig.FilterIdLow 0x1 5; sFilterConfig.FilterIdHigh 0x2 5; 这也是有效的它将会匹配ID为 0x1 和 0x2 的消息。 三、相关代码测试
我们接着使用回环模式类似的代码 这时候由于使用到了usb_can调试器所以你要有一个这个东西。emm 然后cubemx里面的回环模式给位normal模式就行。 把发送函数改成这样改动的地方在于。现在使用的是标准id由于标准id最大支持11位所以就要求最大不要超过0x7ff并把ide改为id_std
void CAN_senddata(CAN_HandleTypeDef *hcan)
{TXHeader.StdId0x7ff;//0X7FF因为标准id最大11位TXHeader.ExtId0x0000000;TXHeader.DLC8;TXHeader.IDECAN_ID_STD;TXHeader.RTRCAN_RTR_DATA;TXHeader.TransmitGlobalTime DISABLE;HAL_CAN_AddTxMessage(hcan,TXHeader,TXmessage,pTxMailbox);
}3.1 测试列表模式__标准ID
只需要这些代码在can_init的位置就可以了。 当使用01 和 02进行发送的时候可以产生中断。其他的不行 /* USER CODE BEGIN CAN_Init 2 */CAN_FilterTypeDef sFilterConfig;sFilterConfig.FilterActivation ENABLE;sFilterConfig.FilterBank 0;sFilterConfig.FilterMode CAN_FILTERMODE_IDLIST;sFilterConfig.FilterScale CAN_FILTERSCALE_16BIT; // 16-bit列表模式用于标准IDsFilterConfig.FilterFIFOAssignment CAN_FILTER_FIFO0;//采用FIFO0sFilterConfig.FilterIdHigh 0x1 5; // ID1sFilterConfig.FilterIdLow 0x2 5; // ID2if(HAL_CAN_ConfigFilter(hcan,sFilterConfig) ! HAL_OK)//初始化过滤器{Error_Handler();}if(HAL_CAN_Start(hcan) ! HAL_OK)//打开can{Error_Handler();}if(HAL_CAN_ActivateNotification(hcan,CAN_IT_RX_FIFO0_MSG_PENDING) ! HAL_OK)//开启接受邮箱0挂起中断{Error_Handler();}/* USER CODE END CAN_Init 2 */3.2 测试掩码模式__标准ID
只需要这些代码在can_init的位置就可以了。 当使用01 和 02进行发送的时候可以产生中断。其他的不行 CAN_FilterTypeDef sFilterConfig;sFilterConfig.FilterActivation ENABLE;sFilterConfig.FilterScale CAN_FILTERSCALE_32BIT; // 16-bit列表模式用于标准IDsFilterConfig.FilterFIFOAssignment CAN_FILTER_FIFO0;//采用FIFO0
// 过滤器匹配0x1sFilterConfig.FilterBank 0;sFilterConfig.FilterMode CAN_FILTERMODE_IDMASK; sFilterConfig.FilterIdHigh 0x1 5;sFilterConfig.FilterMaskIdHigh 0xFFFF;if(HAL_CAN_ConfigFilter(hcan,sFilterConfig) ! HAL_OK)//初始化过滤器{Error_Handler();}
// 过滤器匹配0x1sFilterConfig.FilterBank 1;sFilterConfig.FilterMode CAN_FILTERMODE_IDMASK; sFilterConfig.FilterIdHigh 0x2 5;sFilterConfig.FilterMaskIdHigh 0xFFFF;if(HAL_CAN_ConfigFilter(hcan,sFilterConfig) ! HAL_OK)//初始化过滤器{Error_Handler();}
3.3 测试回调函数接收到的ID
int cc 0;
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)//接受邮箱0挂起中断回调函数
{if(hcan-Instance CAN1){// 获取数据HAL_CAN_GetRxMessage(hcan, CAN_FILTER_FIFO0, RXHeader, RXmessage);// 根据接收到的ID进行处理switch (RXHeader.StdId){case 0x1:// 对于ID 0x1的处理代码cc1;break;case 0x2:// 对于ID 0x2的处理代码cc2;break;default:// 其他未知ID的处理如果需要break;}}
}总结