STM32 CAN filter analysis summary

Publisher:BlissfulHeartLatest update time:2017-09-25 Source: eefocusKeywords:STM32  CAN  Filter Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Recently I looked at STM32 CAN communication and found that the setting of identifier filter is very particular. Especially when you want to use ST library functions, when the filter works in shield mode and you set the shield bit to 1, that is, the corresponding bits of the identifier must all match in order to pass, you must be especially careful.


For example, the filter length is 32 bits, the mode is mask mode, and if the identifier I want to send is 0x1314; then the filter settings are as follows

1. The filter is completely invalid and all received identifiers are passed

   0x1314 binary code: 0000 0000 0000 0000 0001 0011 0001 0100 

   CAN_Filter xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx 

   CAN_FilterMask 0000 0000 0000 0000 0000 0000 0000 0000

Because all bits of the CAN_FilterMask register are 0, the corresponding identifiers are all "don't care", that is, the ID (identifier) ​​of the received data does not need to match any bit of the CAN_Filter register. 

2. The filter is fully effective. The received identifier is compared with the bits that need to be matched according to the MASK register. 

  Partial Match

   0x1314 binary code: 0000 0000 0000 0000 0001 0011 0001 0100 

   CAN_Filter xxxx xxxx xxxx xxxx xxxx xxx1 xxxx xxxx 

   CAN_FilterMask 0000 0000 0000 0000 0000 0001 0000 0000

The CAN_FilterMask  register specifies that the received identifier must match the 8th bit, and the other bits are ignored. That is, the 8th bit of the received identifier must be 1, otherwise the message will be discarded.

  Match all

   0x1314 binary code: 0000 0000 0000 0000 0001 0011 0001 0100 

   CAN_Filter 0000 0000 0000 0000 0000 0011 0001 0100 

   CAN_FilterMask 1111 1111 1111 1111 1111 1111 1111 1111

This is the most stringent case. Every bit of the received identifier must match every bit of the identifier in the filter. If one bit is wrong, the message will be discarded. (This identifier matching work is automatically completed by the internal hardware of the CAN module)

3. Using ST library to configure CAN filter

Similarly, the data identifiers of both   the sender and receiver are 0x1314

The first type: the filter is invalid, all pass

  static void CAN_Filter_Config(void)
{
   CAN_FilterInitTypeDef CAN_FilterInitStructure;

 
 CAN_FilterInitStructure.CAN_FilterNumber=0; //Filter group 0
    CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //Work in identifier mask bit mode
 CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //The filter bit width is a single 32-bit.
 

    CAN_FilterInitStructure.CAN_FilterIdHigh= 0x0000; //High bit of ID to be filteredCAN_FilterInitStructure.CAN_FilterIdLow
    = 0x0000; //Low bit of ID to be filteredCAN_FilterInitStructure.CAN_FilterMaskIdHigh= 0x0000; //No need to match each of the high 16 bits of the filterCAN_FilterInitStructure.CAN_FilterMaskIdLow= 0x0000
    ; //No need to match each of the low 16 bits of the filterCAN_FilterInitStructure.CAN_FilterFIFOAssignment
 =CAN_Filter_FIFO0; //Filter is associated with FIFO0
 CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //Enable filterCAN_FilterInit
 (&CAN_FilterInitStructure);
 
 CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
}

 

Second: Every bit of the filter must match

static void CAN_Filter_Config(void)
{
   CAN_FilterInitTypeDef CAN_FilterInitStructure;

 
 CAN_FilterInitStructure.CAN_FilterNumber=0; //Filter group 0
    CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //Work in identifier mask bit mode
 CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; // The filter bit width is a single 32-bit.
 

    CAN_FilterInitStructure.CAN_FilterIdHigh= (((u32)0x1314<<3)&0xFFFF0000)>>16; //High bit of ID to be filteredCAN_FilterInitStructure.CAN_FilterIdLow
    = (((u32)0x1314<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF; //Low bit of ID to be filteredCAN_FilterInitStructure.CAN_FilterMaskIdHigh
    = 0xFFFF; //Every bit of the high 16 bits of the filter must matchCAN_FilterInitStructure.CAN_FilterMaskIdLow
    = 0xFFFF; //Every bit of the low 16 bits of the filter must matchCAN_FilterInitStructure.CAN_FilterFIFOAssignment
 =CAN_Filter_FIFO0; //The filter is associated with FIFO0
 CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //Enable filter
 CAN_FilterInit(&CAN_FilterInitStructure);
 
 CAN_ITConfig(CAN1, CAN_IT_FMP0, ENABLE);
}

Here comes the point

Why does 0x1314 in CAN_FilterIdHigh need to be shifted 3 bits to the left and then bitwise ANDed with 0xFFFF0000? Why does 0x1314 in CAN_FilterIdLow need to be shifted 3 bits to the left and then bitwise ORed with CAN_ID_EXT CAN_RTR_DATA? In practice, when I send data, I set the ID identifier to 0x1314, as shown in the following code:

void CAN_SetMsg(void)
{  
  //TxMessage.StdId=0x00;      
  TxMessage.ExtId=0x1314; //Extended ID identifier 0x1314 is used
  TxMessage.IDE=CAN_ID_EXT; //Extended mode
  TxMessage.RTR=CAN_RTR_DATA; //Data is sent
  TxMessage.DLC=2; // Data length is 2 bytes
  TxMessage.Data[0]=0xDC;
  TxMessage.Data[1]=0xBA;
}

Then the identifier in your filter should also be 0x1314. According to the above code for configuring the identifier, the value in the filter identifier register is definitely not 0x1314. The reason is as follows: we used the ST library and processed it when sending the identifier.

uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage)
{
  uint8_t transmit_mailbox = 0;
 
  assert_param(IS_CAN_ALL_PERIPH(CANx));
  assert_param(IS_CAN_IDTYPE(TxMessage->IDE));
  assert_param(IS_CAN_RTR(TxMessage->RTR));
  assert_param(IS_CAN_ DLC (TxMessage->DLC));

 
  if ((CANx->TSR&CAN_TSR_TME0) == CAN_TSR_TME0)
  {
    transmit_mailbox = 0;
  }
  else if ((CANx->TSR&CAN_TSR_TME1) == CAN_TSR_TME1)
  {
    transmit_mailbox = 1;
  }
  else if ((CANx->TSR&CAN_TSR_TME2) == CAN_TSR_TME2)
  {
    transmit_mailbox = 2;
  }
  else
  {
    transmit_mailbox = CAN_TxStatus_NoMailBox;
  }

  if (transmit_mailbox != CAN_TxStatus_NoMailBox)
  {
   
    CANx->sTxMailBox[transmit_mailbox].TIR &= TMIDxR_TXRQ;
    if (TxMessage->IDE == CAN_Id_Standard)
    {
      assert_param(IS_CAN_STDID(TxMessage->StdId)); 
      CANx->sTxMailBox[transmit_mailbox] .TIR |= ((TxMessage->StdId << 21) | \
                                                  TxMessage->RTR);
    }
    else
    {
      assert_param(IS_CAN_EXTID(TxMessage->ExtId));
      CANx->sTxMailBox[transmit_mailbox].TIR |= ((TxMessage ->ExtId << 3) | \
                                                  TxMessage->IDE | \
                                                  TxMessage->RTR);
    }

 

This is the processing of the identifier when sending. When sending 16 bits, just shift it left by 21 bits, and then do a bitwise OR with TxMessage->RTR (data frame). When sending 32 bits, the processing is more. After shifting left by 3 bits, it is first bitwise ORed with TxMessage->IDE and then bitwise ORed with TxMessage->RTR (data frame). This is why we have such a statement when setting the receive filter :

CAN_FilterInitStructure.CAN_FilterIdLow= (((u32)0x1314<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF; //The low bit of the ID to be filtered

 Since the identifier is processed when sending, it is also restored when receiving:

void CAN_Receive(CAN_TypeDef* CANx, uint8_t FIFONumber, CanRxMsg* RxMessage)
{
 
  assert_param(IS_CAN_ALL_PERIPH(CANx));
  assert_param(IS_CAN_FIFO(FIFONumber));
 
  RxMessage->IDE = (uint8_t)0x04 & CANx->sFIFOMailBox[FIFONumber].RIR ;
  if (RxMessage->IDE == CAN_Id_Standard)
  {
    RxMessage->StdId = (uint32_t)0x000007FF & (CANx->sFIFOMailBox[FIFONumber].RIR >> 21);
  }
  else
  {
    RxMessage->ExtId = (uint32_t)0x1FFFFFFF & (CANx->sFIFOMailBox[FIFONumber].RIR >> 3);
  } // I don't understand why the received identifier is only shifted right by three digits when restored without any other processing. When it is sent, it looks like this:

      CANx->sTxMailBox[transmit_mailbox].TIR |= ((TxMessage->ExtId << 3) | \
                                                  TxMessage->IDE | \
                                                  TxMessage->RTR);
TxMessage->RTR is the data frame value bit 0, but TxMessage->IDE is the extended identifier value 0x00000004. After 0x1314 is shifted 3 bits to the left, the value will definitely change. However, I just figured out this problem. The binary code of 0x4 is 0100. After 0x1314 is shifted 3 bits to the left, it becomes 100. It must be attached to a value, but this value is directly processed by a right shift of three bits when receiving. It is really smart. RTR is a data frame with a value of 0. It has no effect on it when it is ANDed with another number.

 It’s too long to write so much, but I still figured out some things. If you don’t figure these out when the mask mode is effective, your receiver filter will probably be configured incorrectly, and it will be a tragedy to debug... Of course, if your mask bit doesn’t work, it doesn’t matter. You can configure the filter identifier value at will, as long as the filter mask register value is 0, it’s OK...


Keywords:STM32  CAN  Filter Reference address:STM32 CAN filter analysis summary

Previous article:Analysis of STM32 big-endian mode, stack and its growth direction
Next article:Porting ucGUI touch screen on STM32

Recommended ReadingLatest update time:2024-11-16 12:50

stm32 library function learning chapter general timer input capture function
Function: PA8 can drive the LED light to flash with random delay, and connect PA8 to PA7 port with Dupont line. PA7 is the 2nd channel of general timer TIM3. In the TIM3_CH2 trigger interrupt program, the LED light connected to PD2 port is inverted to indicate the interrupt program is running, and the polarity of trigg
[Microcontroller]
stm32 library function learning chapter general timer input capture function
Solution to STM32 serial port interruption
Today, I encountered some problems while using the USART module and solved them, so I posted them to share. Problem description: When using USART for serial communication, I only turned on the receive interrupt and set the preemption priority to the lowest level. The previous priority of the receive interrupt handles
[Microcontroller]
Solution to STM32 serial port interruption
The power-on program does not run due to NVIC_Init in STM32
Recently, I encountered a strange problem when running multitasking on STM32 using ucosii. I used 4 serial ports. As the program grew larger, it did not run after power-on. I used an LED flashing to indicate the running, and there was no problem using STLINK for debugging, but it did not work after powering on again,
[Microcontroller]
stm32 simulates output of multiple PWM channels through IO port
This is mainly used to control the servo. TIM1 is used to simulate 5-channel 50Hz PWM signal, and only the duty cycle is adjusted to control the servo angle. There is no specific test on the maximum number of channels that can be simulated. Disadvantages: Because it is a timer interrupt simulation (interruptions are m
[Microcontroller]
STMicroelectronics is working with AWS and Microsoft to help STM32U5 enable more secure IoT development
STMicroelectronics is strengthening its collaboration with Amazon (AWS) and Microsoft to expand the Internet of Things. On AWS, ST provides a reference that makes it easier and more secure to connect IoT (Internet of Things) devices (STM32U5) to the AWS cloud. At the same time, STMicroelectronics is working with Micro
[Microcontroller]
STM32 uses IO port to control the simple program of stepper motor
Practice IO port library function operations.   //Phase sequence   uint16_t phasecw ={0x2000,0x0001,0x0004,0x0008};//DCBA   uint16_t phaseccw ={0x0008,0x0004,0x0001,0x2000};//ABCD       // Initialize the stepper motor related IO ports   // IN4: PC13   // IN3: PC0   // IN2: PC2   // IN1:
[Microcontroller]
Output Compare of stm32 timer
STM32F103VB sends a logic signal to MOC3020 to control the on and off of the BTA16 thyristor. When a zero-crossing signal is detected, the output is 1 after a delay of x milliseconds; the output is turned off after a delay of y milliseconds. This can realize phase-controlled speed regulation of induction motors (low p
[Microcontroller]
Output Compare of stm32 timer
STM32 hardware structure learning
stm32 hardware learning account ---- power supply Classification: 1. Working power 2. Backup domain power 3. ADC power supply reference power Working power supply 2-3.6v The backup domain power supply is used for RTC clock module and backup domain register preservation ADC power supply reference power supply
[Microcontroller]
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号