[STM32F4] stm32f103can总线过滤器配置

[复制链接]
 楼主| 为你转身 发表于 2022-5-31 13:53 | 显示全部楼层 |阅读模式
CAN过滤器的配置(f103 hal1.8 系列)

can的过滤器的配置是对can接收到的报文进行过滤的配置,在STM32芯片中,可以对can的报文进行过滤,从而省略cpu的处理过程。

can的过滤模式

f103中为应用程序提供了14个位宽可变、可配置的过滤器组,每个过滤器组由2个32位寄存器,CAN_FxR0和CAN_FxR1组成。
每个过滤器组的位宽都可以单独设置,以满足应用程序的不同需求。根据位宽的不同,可以配置为1个32位过滤器和2个16位过滤器。
can过滤器还可以分为屏蔽位模式和标识符列表模式。

 楼主| 为你转身 发表于 2022-5-31 13:53 | 显示全部楼层
其中:

标识符屏蔽位模式:FxR0为标识符匹配值,FxR1为屏蔽码。解释为FxR1中某一位为1,FxR0中相应的位置必须与收到的帧的标识符中的相应位置吻合才能通过过滤器。FxR1中为0的位表示FxR0的相应位可不必与收到的帧进行匹配。例如:标识符寄存器的bit15=0,屏蔽位寄存器的bit15=1,那么接受的Message里面的标识符的bit15必须为0才可能被硬件接受。如果屏蔽位寄存器的bit15=0,Message里面的标识符的bit15无论为什么值,bit15都能匹配通过,当bit0~31位都能通过的时候,这个报文就会被接受;
 楼主| 为你转身 发表于 2022-5-31 13:54 | 显示全部楼层
标识符列表模式:FR1和FR2都是要匹配的标识符,收到的帧的标识符必须与其中一个吻合才能通过过滤器;
所有的过滤器都是并联的,一个报文只要能通过一个过滤器就算是有效的。
 楼主| 为你转身 发表于 2022-5-31 13:54 | 显示全部楼层
hal中的解释
在can的过滤器的配置的时候,需要用到结构体中FilterIdHigh,FilterIdLow,FilterMaskIdHigh,FilterMaskIdLow,这几个配置。在标识符列表模式下:ID和maskID在32位模式和16位模式的过滤器中都是代表着一个意思。在屏蔽位模式下,ID代表着标准值,而maskID代表着需要关心ID中的哪些位。其中高对应着高,低对应着低。
 楼主| 为你转身 发表于 2022-5-31 13:55 | 显示全部楼层
677636295adb2bdc9c.png
其中IDE = 0为标准ID,IDE为1为扩展ID,RTR = 0为代表数据帧,RTR = 1代表远程帧,MASK设置屏蔽码,ID设置标准帧。
 楼主| 为你转身 发表于 2022-5-31 14:18 | 显示全部楼层
使用cube生成代码过程:
1、进行can配置
286516295b33fb8d5b.png
 楼主| 为你转身 发表于 2022-5-31 14:42 | 显示全部楼层
上图主要的配置是进行can总线波特率的配置,波特率由p、tq1、tq2这三个数值进行确定。
 楼主| 为你转身 发表于 2022-5-31 14:53 | 显示全部楼层
 楼主| 为你转身 发表于 2022-5-31 14:54 | 显示全部楼层
使用HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxMessage, RxData);可以读取CAN数据(RxMessage 的定义:CAN_RxHeaderTypeDef RxMessage;)
 楼主| 为你转身 发表于 2022-5-31 14:54 | 显示全部楼层
3、生成工程后进行添加过滤器的配置
进行32位过滤器屏蔽位模式设置
  1. HAL_StatusTypeDef CAN_User_Init(CAN_HandleTypeDef *h_can)
  2. {
  3.   CAN_FilterTypeDef sFilterConfig;

  4.   sFilterConfig.FilterBank = 0;   //chenal 0
  5.   sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;   //屏蔽模式
  6.   sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;  //设置为32位模式
  7.   sFilterConfig.FilterIdHigh = 0xC020; //代表着设置的参考ID为0x601
  8.   sFilterConfig.FilterIdLow = 0x0000;//代表着标准ID,而且是数据帧
  9.   //MASK bit 0 means don't care,bit 0 means match
  10.   sFilterConfig.FilterMaskIdHigh = 0xFFFF;
  11.   sFilterConfig.FilterMaskIdLow = 0xFFFF;//代表着需要符合上述所有的需求才能进行出传递报文
  12.   sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0; //FIFO0的中断和FIFO1的中断是不一样的,这里是把接收到的报文放入到FIFO0中
  13.   sFilterConfig.FilterActivation = CAN_FILTER_ENABLE;   //enable filter
  14.   sFilterConfig.SlaveStartFilterBank = 0;    //为从属can选择开始的过滤库,对于单个CAN实例,这个参数没有意义
  15. }
 楼主| 为你转身 发表于 2022-5-31 14:55 | 显示全部楼层
进行16位过滤器屏蔽位模式配置
  1. HAL_StatusTypeDef CAN_User_Init(CAN_HandleTypeDef *h_can)
  2. {
  3.   CAN_FilterTypeDef sFilterConfig;

  4.   sFilterConfig.FilterBank = 0;   //chenal 0
  5.   sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;   //屏蔽模式
  6.   sFilterConfig.FilterScale = CAN_FILTERSCALE_16BIT;  //设置为32位模式
  7.   sFilterConfig.FilterIdHigh = 0xC020; //代表着设置的参考ID为0x601,标准ID,数据帧
  8.   sFilterConfig.FilterIdLow = 0xD020;//代表着设置的参考ID为0x681,标准ID,数据帧
  9.   //MASK bit 0 means don't care,bit 0 means match
  10.   sFilterConfig.FilterMaskIdHigh = 0xFFFF;//代表着需要是0x601的标准数据帧才能进行通过
  11.   sFilterConfig.FilterMaskIdLow = 0xFFDF;//代表着需要是0x68x的标准数据帧才能通过。
  12.   sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0; //FIFO0的中断和FIFO1的中断是不一样的,这里是把接收到的报文放入到FIFO0中
  13.   sFilterConfig.FilterActivation = CAN_FILTER_ENABLE;   //enable filter
  14.   sFilterConfig.SlaveStartFilterBank = 0;    //为从属can选择开始的过滤库,对于单个CAN实例,这个参数没有意义
  15. }
 楼主| 为你转身 发表于 2022-5-31 14:56 | 显示全部楼层
注意以上只是一个过滤器的配置过程,f103可以进行14组过滤器的配置。
 楼主| 为你转身 发表于 2022-5-31 14:57 | 显示全部楼层
4、发送数据:
  1. /*使用can总线发送数据*/
  2. uint8_t CANx_SendNormalData(CAN_TxHeaderTypeDef TxHeader,uint32_t std_id ,uint8_t *TxData ,uint16_t lengh)
  3. {
  4.     uint32_t TxMailbox;
  5.         uint8_t  FreeTxNum=0;//用来表示邮箱是否空闲
  6.                
  7.     TxHeader.RTR = CAN_RTR_DATA;
  8.     TxHeader.IDE = CAN_ID_STD;            
  9.     TxHeader.StdId = std_id;
  10.     TxHeader.TransmitGlobalTime = DISABLE;
  11.     TxHeader.DLC = lengh;
  12.                
  13.     FreeTxNum = HAL_CAN_GetTxMailboxesFreeLevel(&hcan);
  14.                 while(0==FreeTxNum)
  15.                 {
  16.                         FreeTxNum=HAL_CAN_GetTxMailboxesFreeLevel(&hcan);
  17.                 }
  18.                
  19.     if (HAL_CAN_AddTxMessage(&hcan, &TxHeader, TxData, &TxMailbox) != HAL_OK)
  20.     {
  21.        /* Transmission request Error */
  22.        Error_Handler();
  23.     }
  24.                 return 1;
  25. }
 楼主| 为你转身 发表于 2022-5-31 14:58 | 显示全部楼层
5、接收中断
  1. /*采用接收中断函数*/
  2. void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *h_can)
  3. {
  4.   uint8_t Data[8] = {0};
  5.         uint16_t nodeid = 0;
  6.         HAL_StatusTypeDef        HAL_RetVal;
  7.         uint8_t cmd = 0x2F;
  8. //        uint16_t control_Mode = 0x6060;
  9.        
  10.   if (h_can == &hcan)
  11.   {
  12.     //retrive data by calling HAL_CAN_GetRxMessage
  13.     HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &RxMessage, Data);
  14.                 nodeid = RxMessage.StdId;
  15.                 //对can1的速度进行接收
  16.                 if((nodeid&0x581) == 0x581)
  17.                 {
  18.                         if(Data[0] == cmd)
  19.                         {
  20.                                 if(Data[1] == 0x60)
  21.                                 {
  22.                                         if(Data[2] == 0x60)
  23.                                         {
  24.                                                 Real_Speed  =(int32_t)((uint32_t)(Data[4]&0xFF)|(uint32_t)((Data[5]<<8)&0xFFFF)|(uint32_t)((Data[6]<<16)&0xFFFF)|(uint32_t)((Data[7]<<24)&0xFFFF));
  25.                                         }
  26.                                 }
  27.                         }
  28.                 }
  29.                 if((nodeid&0x582) == 0x582)
  30.                 {
  31.                         //对can2的速度进行接收
  32.                         if(Data[0] == cmd)
  33.                         {
  34.                                 if(Data[1] == 0x60)
  35.                                 {
  36.                                         if(Data[2] == 0x60)
  37.                                         {
  38.                                                 Real_Speed  =(int32_t)((uint32_t)(Data[4]&0xFF)|(uint32_t)((Data[5]<<8)&0xFFFF)|(uint32_t)((Data[6]<<16)&0xFFFF)|(uint32_t)((Data[7]<<24)&0xFFFF));
  39.                                         }
  40.                                 }
  41.                         }
  42.                 }
  43.   }
  44. }
Bblythe 发表于 2022-10-6 09:06 | 显示全部楼层

图像由前景和背景组成,在灰度直方图上,前景和背景会形成高峰,在双峰之间的最低谷处就是阈值。
Pulitzer 发表于 2022-10-6 12:05 | 显示全部楼层

根据色彩的变化记录每一行的颜色跳变点,由此识别出车牌区域。
Uriah 发表于 2022-10-6 16:07 | 显示全部楼层

在内存中开辟七个长为车牌长的七分之一和宽为车牌宽的区域
帛灿灿 发表于 2023-5-1 08:03 | 显示全部楼层

不同的代码逻辑就代表了不同的策略
Bblythe 发表于 2023-5-1 09:06 | 显示全部楼层

对于优秀程序员来说,这不是好代码
童雨竹 发表于 2023-5-1 11:02 | 显示全部楼层

会以switch-case的方式出现
您需要登录后才可以回帖 登录 | 注册

本版积分规则

82

主题

740

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部

82

主题

740

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部