Filtering analysis of CAN communication receiving filter of STM32

Posted by millercj on Fri, 21 Jan 2022 23:50:48 +0100

1, Foreword

After learning CAN communication, the bottom Dongdong CAN controller has finished processing for you, that is, the CAN communication protocol has been completed. You CAN throw data to the corresponding bit according to the protocol format. Therefore, when using CAN communication, we only need to care about formulating the protocol between the transmitted data, that is, adding an identifier to each data. As shown in the figure below, for the data frame of data sent by CAN communication, the Arbitration Field is the identification ID with priority, and the Data Field is the data to be sent. The Arbitration Field and Data Field are the focus of our attention, because these sent identification IDS in the CAN communication protocol do not represent the address of the node, and the data is sent in the form of broadcast, Each node CAN receive. Is the received data desired? You need to filter and filter the ID of these identifiers, and then extract the data.

2, Analysis of CAN communication receiving filter

First, let's look at the structure of sending data to be configured, as shown below. The Arbitration Field ID we sent is cantxmsg Stdid, after receiving, the ID will be filtered first, and then the sent cantxmsg will be extracted Data. If it is not the set ID, the receiver will not read the data. How does the receiver filter the data.

typedef struct
{
  uint32_t StdId;    //11 bit standard frame ID, i.e. Arbitration Field
  uint32_t ExtId;    //29 bit extended frame ID
  uint8_t IDE;       //1-bit O: standard frame, 1: extended frame
  uint8_t RTR;       //1 bit 0: data frame, 1: remote frame
  uint8_t DLC;       //Length of 4-bit transmitted data
  uint8_t Data[8];   //The data sent by 8 bits is Data Field
} CanTxMsg;

In non internet products, STM32 CAN controller provides 14 variable bit width and configurable filter groups (13 ~ 0). Each filter group x consists of two 32-bit registers, CAN_FxR0 and CAN_FxR1, and the bit width setting of one filter bank CAN be divided into four working modes. The working mode depends on the setting of two registers FBMx and FSCx, as shown in the following figure:


See the four working modes of the filter, including identifier masking and list mode. How to understand, for example, if we send the ID idcantxmsg Stdid is 0x000~0x00f. The ID of the ID is filtered by the identifier mask mode before receiving filtering, as shown below:

 ID  :     000 0000 0000 xxxx              
 shield :     111 1111 1111 0000 
  

X means that 0 or 1 can pass through any combination of 0000 to 1111, so that the data of 0x000~0x00f can be filtered. Therefore, shielding means that the identifier ID of a range can pass through, so as to filter out a group of identifiers. Then, if you want to filter out a data 0x003, use the identifier masking mode, and the implementation method is as follows,

 ID  :     000 0000 0000 0011              
 shield :     111 1111 1111 1111 
  

If the receiving filter uses the identifier list mode to filter the ID, as shown below,

 ID  :    000 0000 0001 
 ID  :    000 0000 0010

This mode can only filter out two IDS, namely 0x001 and 0x002, so the list means to list the desired ID followed by the sent cantxmsg Stdid is used for proofreading. If yes, the data will be received. If not, the data will be filtered out. The purpose of identifier list mode is to filter out an identifier ID.

3, Program configuration of four working modes of CAN receiving filter

1. 32-bit identifier masking mode


If the identifier to be sent is idcantxmsg Stdid ranges from 0x010 to 0x01f

ID      :  0000 001x xxx0 0000 0000 0000 0000 0000  //Corresponding to can respectively_ FXR1 high 16 bit, CAN_FxR1 low 16 bits
 shield    :  1111 1110 0001 1111 1111 1111 1111 1111  //Corresponding to can respectively_ Fxr2 high 16 bit, CAN_FxR2 low 16 bits

The program configuration is as follows:

CAN_RxFilerconfig(0,CANRX32IDMASK);                                      //32-bit identifier mask mode
void CAN_RxFilerconfig(u8 FilterNum,u8 FilterMode)
{
  CAN_FilterInitTypeDef  	CAN_FilterInitStructure;
   
   CAN_FilterInitStructure.CAN_FilterNumber=FilterNum;	               //Filter No. 0 ~ 13 optional
   if(FilterMode==CANRX32IDMASK)
   {
     CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; 	   //Identifier mask mode
     CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;    //32-bit wide 
   }
   else if(FilterMode==CANRX32IDLIST)
   {
     CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList; 	   //Identifier list mode
     CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;    //32-bit wide 
   }
   else if(FilterMode==CANRX16IDMASK)
   {
     CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; 	   //Identifier mask mode
     CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;    //16 bit wide 
   }
   else if(FilterMode==CANRX16IDLIST)
   {
     CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList; 	   //Identifier list mode
     CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;    //16 bit wide
   }
    //Identifier register FxR1
   CAN_FilterInitStructure.CAN_FilterIdHigh=0x010<<5;                  //32-bit ID, 16 bits high
   CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;                     //Lower 16 bits
   //Mask register FxR2
   CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xfe1f;                //32-bit MASK, 16 bits high
   CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xffff;                 //Lower 16 bits
	
   CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;  //Filter 0 is associated to FIFO0
   CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;                //Activate filter 0

   CAN_FilterInit(&CAN_FilterInitStructure);			               //Filter initialization
} 

2. 32-bit identifier list mode


If the identifier to be sent is idcantxmsg Stdid is 0x011 and 0x012.

ID      :  0000 0010 0010 0000 0000 0000 0000 0000  //Corresponding to can respectively_ FXR1 high 16 bit, CAN_FxR1 low 16 bit / / 0x011
 shield    :  0000 0010 0100 1111 1111 1111 1111 1111  //Corresponding to can respectively_ Fxr2 high 16 bit, CAN_FxR2 low 16 bit / / 0x012

The program configuration is as follows:

CAN_RxFilerconfig(0,CANRX32IDLIST);                                      //32-bit identifier list mode
void CAN_RxFilerconfig(u8 FilterNum,u8 FilterMode)
{
  CAN_FilterInitTypeDef  	CAN_FilterInitStructure;
   
   CAN_FilterInitStructure.CAN_FilterNumber=FilterNum;	               //Filter No. 0 ~ 13 optional
   if(FilterMode==CANRX32IDMASK)
   {
     CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; 	   //Identifier mask mode
     CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;    //32-bit wide 
   }
   else if(FilterMode==CANRX32IDLIST)
   {
     CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList; 	   //Identifier list mode
     CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;    //32-bit wide 
   }
   else if(FilterMode==CANRX16IDMASK)
   {
     CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; 	   //Identifier mask mode
     CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;    //16 bit wide 
   }
   else if(FilterMode==CANRX16IDLIST)
   {
     CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList; 	   //Identifier list mode
     CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;    //16 bit wide
   }
    //Identifier register FxR1
   CAN_FilterInitStructure.CAN_FilterIdHigh=0x011<<5;                  //32-bit ID, 16 bits high
   CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;                     //Lower 16 bits
   //Mask register FxR2
   CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x012<<5;              //32-bit MASK, 16 bits high
   CAN_FilterInitStructure.CAN_FilterMaskIdLow=0xffff;                 //Lower 16 bits
	
   CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;  //Filter 0 is associated to FIFO0
   CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;                //Activate filter 0

   CAN_FilterInit(&CAN_FilterInitStructure);			               //Filter initialization
} 

3. 16 bit identifier mask mode


If the identifier to be sent is idcantxmsg Stdid range is 0x0100x01f, 0x0000x00f.

ID      :  0000 001x xxx0 0000  //Corresponding to can respectively_ FXR1 low 16 bit CAN_FilterIdLow
 shield    :  1111 1110 0001 1111  //Corresponding to can respectively_ FXR1 high 16 bit CAN_FilterIdHigh

ID      :  0000 000x xxx0 0000  //Corresponding to can respectively_ Fxr2 low 16 bit CAN_FilterMaskIdLow
 shield    :  1111 1110 0001 1111  //Corresponding to can respectively_ Fxr2 high 16 bit CAN_FilterMaskIdHigh

The program configuration is as follows:

CAN_RxFilerconfig(0,CANRX16IDMASK);                                      //16 bit identifier mask mode
void CAN_RxFilerconfig(u8 FilterNum,u8 FilterMode)
{
  CAN_FilterInitTypeDef  	CAN_FilterInitStructure;
   
   CAN_FilterInitStructure.CAN_FilterNumber=FilterNum;	               //Filter No. 0 ~ 13 optional
   if(FilterMode==CANRX32IDMASK)
   {
     CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; 	   //Identifier mask mode
     CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;    //32-bit wide 
   }
   else if(FilterMode==CANRX32IDLIST)
   {
     CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList; 	   //Identifier list mode
     CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;    //32-bit wide 
   }
   else if(FilterMode==CANRX16IDMASK)
   {
     CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; 	   //Identifier mask mode
     CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;    //16 bit wide 
   }
   else if(FilterMode==CANRX16IDLIST)
   {
     CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList; 	   //Identifier list mode
     CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;    //16 bit wide
   }
    //Identifier register FxR1
   CAN_FilterInitStructure.CAN_FilterIdHigh=0xfe1f;                    //32-bit ID, 16 bits high
   CAN_FilterInitStructure.CAN_FilterIdLow=0x010<<5;                   //Lower 16 bits
   //Mask register FxR2
   CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0xfe1f;                //32-bit MASK, 16 bits high
   CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x000<<5;               //Lower 16 bits
	
   CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;  //Filter 0 is associated to FIFO0
   CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;                //Activate filter 0

   CAN_FilterInit(&CAN_FilterInitStructure);			               //Filter initialization
} 

4. 16 bit identifier list mode


If the identifier to be sent is idcantxmsg There are four stdids: 0x010,0x01f, 0x001,0x00f.

ID      :  0000 0010 0000 0000  //Corresponding to can respectively_ FXR1 low 16 bit CAN_FilterIdLow  //0x010
ID      :  0000 0011 1110 0000  //Corresponding to can respectively_ FXR1 high 16 bit CAN_FilterIdHigh //0x01f

ID      :  0000 0000 0010 0000  //Corresponding to can respectively_ Fxr2 low 16 bit CAN_FilterMaskIdLow //0x001
ID      :  0000 0001 1110 0000  //Corresponding to can respectively_ Fxr2 high 16 bit CAN_FilterMaskIdHigh //0x00f

The program configuration is as follows:

CAN_RxFilerconfig(0,CANRX16IDLIST);                                      //16 bit identifier list mode
void CAN_RxFilerconfig(u8 FilterNum,u8 FilterMode)
{
  CAN_FilterInitTypeDef  	CAN_FilterInitStructure;
   
   CAN_FilterInitStructure.CAN_FilterNumber=FilterNum;	               //Filter No. 0 ~ 13 optional
   if(FilterMode==CANRX32IDMASK)
   {
     CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; 	   //Identifier mask mode
     CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;    //32-bit wide 
   }
   else if(FilterMode==CANRX32IDLIST)
   {
     CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList; 	   //Identifier list mode
     CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;    //32-bit wide 
   }
   else if(FilterMode==CANRX16IDMASK)
   {
     CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; 	   //Identifier mask mode
     CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;    //16 bit wide 
   }
   else if(FilterMode==CANRX16IDLIST)
   {
     CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdList; 	   //Identifier list mode
     CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_16bit;    //16 bit wide
   }
    //Identifier register FxR1
   CAN_FilterInitStructure.CAN_FilterIdHigh=0x01f<<5;                  //32-bit ID, 16 bits high
   CAN_FilterInitStructure.CAN_FilterIdLow=0x010<<5;                   //Lower 16 bits
   //Mask register FxR2
   CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x00f<<5;              //32-bit MASK, 16 bits high
   CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x001<<5;               //Lower 16 bits
	
   CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;  //Filter 0 is associated to FIFO0
   CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;                //Activate filter 0

   CAN_FilterInit(&CAN_FilterInitStructure);			               //Filter initialization
} 

Topics: network