1. Introduction to CAN
CAN is the abbreviation of Controller Area Network (hereinafter referred to as CAN), which is an ISO internationally standardized serial communication protocol. In the current automotive industry, various electronic control systems have been developed for the requirements of safety, comfort, convenience, low pollution and low cost. Since the data types used for communication between these systems and the requirements for reliability are different, there are many cases where multiple buses are used, and the number of wiring harnesses increases accordingly. In order to meet the needs of "reducing the number of wiring harnesses" and "high-speed communication of large amounts of data through multiple LANs", the German electrical company Bosch developed the CAN communication protocol for automobiles in 1986. Since then, CAN has been standardized through ISO11898 and ISO11519, and is now a standard protocol for automotive networks in Europe. Now, the high performance and reliability of CAN have been recognized and are widely used in industrial automation, ships, medical equipment, industrial equipment, etc. Fieldbus is one of the hot spots in the development of technology in the field of automation today, and is known as the computer local area network in the field of automation. Its emergence provides strong technical support for distributed control systems to achieve real-time and reliable data communication between nodes.
The CAN controller determines the bus level based on the potential difference between the two lines. The bus level is divided into dominant level and recessive level, and one of the two must be present. The sender sends the message to the receiver by changing the bus level.
The CAN protocol has the following characteristics:
1) Multi-master control. When the bus is idle, all units can send messages (multi-master control). When two or more units start sending messages at the same time, the priority is determined by the identifier (hereinafter referred to as ID). The ID does not indicate the destination address of the message, but the priority of the message accessing the bus.
When sending a message, each bit of each message ID is compared and arbitrated one by one. The unit that wins the arbitration (determined to have the highest priority) can continue to send messages, while the unit that loses the arbitration immediately stops sending and starts receiving.
2) System flexibility. The units connected to the bus do not have information similar to "address". Therefore, when adding units to the bus, the software, hardware and application layers of other units connected to the bus do not need to be changed.
3) Fast communication speed and long communication distance. The highest speed is 1Mbps (distance less than 40M), and the longest distance can reach 10KM (speed less than 5Kbps).
4) It has error detection, error notification and error recovery functions. All units can detect errors (error detection function). The unit that detects an error will immediately notify all other units at the same time (error notification function). Once a unit that is sending a message detects an error, it will force the current transmission to end. The unit that forcefully ends the transmission will repeatedly resend the message until it is successfully sent (error recovery function).
5) Fault isolation function. CAN can determine whether the type of error is a temporary data error on the bus (such as external noise, etc.) or a continuous data error (such as internal unit fault, driver fault, disconnection, etc.). With this function, when a continuous data error occurs on the bus, the unit causing the fault can be isolated from the bus.
6) Many connected nodes. The CAN bus is a bus that can connect multiple units at the same time. The total number of connectable units is theoretically unlimited. But in reality, the number of connectable units is limited by the time delay and electrical load on the bus. Reducing the communication speed increases the number of connectable units; increasing the communication speed reduces the number of connectable units. It is precisely because of these characteristics of the CAN protocol that CAN is particularly suitable for the interconnection of industrial process monitoring equipment. Therefore, it has been increasingly valued by the industry and has been recognized as one of the most promising field buses. After being standardized by ISO, the CAN protocol has two standards: ISO11898 standard and ISO11519-2 standard. Among them, ISO11898 is a high-speed communication standard for communication rates of 125Kbps~1Mbps, while ISO11519-2 is a low-speed communication standard for communication rates below 125Kbps.
We use a communication rate of 500Kbps and the ISO11898 standard. The physical layer characteristics of this standard are shown in the figure:
From this characteristic, we can see that the dominant level corresponds to logic 0, and the difference between CAN_H and CAN_L is about 2.5V.
The level corresponds to logic 1, and the difference between CAN_H and CAN_L is 0V. The dominant level has priority on the bus. As long as one unit outputs the dominant level, the bus is at the dominant level. The invisible level has an inclusive meaning. Only when all units output the recessive level, the bus is at the recessive level (the dominant level is stronger than the recessive level). In addition, there is a 120Ω terminal resistor at the start and end of the CAN bus for impedance matching to reduce echo reflection.
The CAN protocol is carried out through the following five types of frames:
Data Frame
Remote Control Frame
Error frame
Overload Frame
Interval Frame
In addition, data frames and remote control frames have two formats: standard format and extended format. The standard format has an 11-bit identifier (ID) and the extended format has a 29-bit ID. The uses of various frames are shown in the table
Due to space limitations, we only introduce the data frame in detail here. The data frame is generally composed of 7 segments, namely:
(1) Start of frame: Indicates the segment where the data frame starts.
(2) Arbitration segment: This segment indicates the priority of the frame.
(3) Control segment: This segment indicates the number of bytes of data and reserved bits.
(4) Data segment: Data content. One frame can send 0 to 8 bytes of data.
(5) CRC segment: This segment checks the transmission errors of the frame.
(6) ACK segment: This segment indicates the segment confirming normal reception.
(7) End of frame. This segment indicates the end of the data frame.
The structure of the data frame is shown in the figure:
In the figure, D represents the dominant level and R represents the recessive level (the same below).
Frame start, this is relatively simple, both standard frames and extended frames are indicated by a 1-bit dominant level to indicate the start of the frame.
The arbitration segment indicates the data priority segment. The standard frame and extended frame formats are different in this segment, as shown in the figure
The standard format ID has 11 bits. They are sent sequentially from ID28 to ID18. The upper 7 bits are prohibited to be recessive (prohibited setting: ID=1111111XXXX). The extended format ID has 29 bits. The basic ID is from ID28 to ID18, and the extended ID is represented by ID17 to ID0. The basic ID is the same as the standard format ID. The upper 7 bits are prohibited to be recessive (prohibited setting: basic ID=1111111XXXX). The RTR bit is used to identify whether it is a remote frame (0, data frame; 1, remote frame), the IDE bit is the identifier selection bit (0, use the standard identifier; 1, use the extended identifier), and the SRR bit is the replacement remote request bit, which is a recessive bit and replaces the RTR bit in the standard frame.
The control segment consists of 6 bits and indicates the number of bytes in the data segment. The control segments of standard frames and extended frames are slightly different, as shown in the figure:
In the figure above, r0 and r1 are reserved bits and must all be sent at dominant levels, but the receiving end can receive dominant, recessive, and any combination of levels. The DLC segment is the data length segment, with the high bit first. The valid value of the DLC segment is 0~8, but the receiver does not consider it an error when it receives 9~15. The data segment can contain 0~8 bytes of data. The output starts from the highest bit (MSB), and the definition of the standard frame and the extended frame in this segment is the same. As shown in the figure:
The calculation range of the CRC value of this segment includes: frame start, arbitration segment, control segment, and data segment. The receiver calculates the CRC value with the same algorithm and compares it. If it is inconsistent, an error will be reported.
ACK segment: This segment is used to confirm whether the message is received normally. It consists of two bits: ACK Slot and ACK Delimiter.
The format of standard frame and extended frame in this segment is the same, as shown in the figure:
The sending unit sends ACK, which is a 2-bit recessive bit, and the unit that receives the correct message is in the ACK slot.
Sending dominant bits to notify the sending unit of the normal reception end is called sending ACK/returning ACK. The unit that sends ACK is the unit that receives a normal message among all the receiving units that are neither in the bus-off state nor in the sleep state (the sending unit does not send ACK). The so-called normal message refers to a message that does not contain padding errors, format errors, or CRC errors. The end of the frame, this segment is also relatively simple. The format of the standard frame and the extended frame is the same in this segment, consisting of 7 recessive bits.
Next, let's take a look at the bit timing of CAN.
The number of bits per second sent by the sending unit in an asynchronous manner is called the bit rate. A bit can be divided into 4 segments.
Synchronization Segment (SS)
Propagation Time Segment (PTS)
Phase buffer segment 1 (PBS1)
Phase Buffer Segment 2 (PBS2)
These segments are in turn composed of the smallest time unit known as Time Quantum (hereinafter referred to as Tq).
1 bit is divided into 4 segments, each segment is composed of a number of Tq, which is called bit timing.
The bit timing can be set arbitrarily, such as how many Tqs make up 1 bit and how many Tqs make up each segment. By setting the bit timing, multiple units can be sampled at the same time, and the sampling point can be set arbitrarily. The function of each segment and the number of Tqs are shown in the table:
The structure of 1 bit is shown in the figure:
The sampling point in the figure above refers to the point where the bus level is read and the read level is used as the bit value. The position is at the end of PBS1. According to this bit timing, we can calculate the baud rate of CAN communication. We will introduce the specific calculation method later. The CAN protocol mentioned above has an arbitration function. Let's see how it is implemented.
In the bus idle state, the unit that starts sending a message first obtains the right to send.
When multiple units start to send at the same time, each sending unit starts arbitration from the first bit of the arbitration segment. The unit that continuously outputs the most dominant levels can continue to send. The implementation process is shown in the figure:
In the figure above, unit 1 and unit 2 start sending data to the bus at the same time. At the beginning, their data formats are the same.
Therefore, it is impossible to distinguish the priorities until the moment T, when unit 1 outputs a recessive level and unit 2 outputs a dominant level. At this time, unit 1 fails in arbitration and immediately switches to the receiving state, no longer competing with unit 2, while unit 2 successfully obtains the right to use the bus and continues to send its own data. This realizes arbitration, allowing the unit that continuously sends more dominant levels to obtain the right to use the bus.
2. Introduction to STM32 CAN
The STM32F4 comes with bxCAN, the basic extended CAN. It supports CAN protocols 2.0A and 2.0B. It is designed to efficiently process a large number of received messages with minimal CPU load. It also supports priority requirements for message sending (priority characteristics are software configurable). For safety-critical applications, bxCAN provides all the hardware functions required to support time-triggered communication mode.
The main features of bxCAN of STM32F4 are:
Support CAN protocol 2.0A and 2.0B active mode
Baud rate up to 1Mbps
Support time-triggered communication
Has 3 sending mailboxes
2 receive FIFOs with 3 levels of depth
Variable filter bank (28, shared by CAN1 and CAN2)
The STM32F407ZGT6 has two CAN controllers, but we only use one CAN in this chapter, namely CAN1.
The block diagram of dual CAN is shown in the figure
From the figure, we can see that both CANs have their own send mailbox and receive FIFO, but they share 28
Filter. The filter allocation method can be set by setting the CAN_FMR register.
The identifier filtering of STM32F4 is a relatively complex thing, and its existence reduces the CPU's overhead in processing CAN communications. STM32F4 has a maximum of 28 filter groups, and each filter group x consists of two 32-bit registers, CAN_FxR1 and CAN_FxR2.
The bit width of each filter group of STM32F4 can be configured independently to meet the different needs of the application. Depending on the bit width, each filter group can provide:
● 1 32-bit filter, including: STDID[10:0], EXTID[17:0], IDE and RTR bits
● 2 16-bit filters, including: STDID[10:0], IDE, RTR, and EXTID[17:15] bits
Additionally filters can be configured as mask bit patterns and identifier list patterns.
In mask bit mode, the identifier register and mask register together specify whether any bit of the message identifier should be treated as "must match" or "don't care". In identifier list mode, the mask register is also used as the identifier register. Therefore, instead of using one identifier plus one mask bit, two identifier registers are used. Every bit of the received message identifier must be the same as the filter identifier.
Through the CAN_FMR register, the bit width and working mode of the filter group can be configured, as shown in the figure
To filter out a group of identifiers, the filter group should be set to work in mask bit mode.
To filter out an identifier, the filter group should be set to work in identifier list mode.
Filter groups that are not used by your application should remain disabled.
Each filter in a filter group is numbered (called the filter number, n in Figure 32.1.11) starting from 0 to a certain maximum value - depending on the mode and bit width settings of the filter group.
For a simple example, we set filter group 0 to work in: 1 32-bit filter-identifier mask mode, and then set CAN_F0R1=0XFFFF0000, CAN_F0R2=0XFF00FF00. The value stored in CAN_F0R1 is the ID we expect to receive, that is, the ID we hope to receive (STID+EXTID+IDE+RTR) is preferably: 0XFFFF0000. And 0XFF00FF00 is to set the ID we must care about, indicating that the received ID, its 16 bits [31:24] and [15:8] must be exactly the same as the corresponding bits in CAN_F0R1, and the other 16 bits are not concerned, they can be the same or different, and are considered to be the correct ID, that is, the received ID must be 0XFFxx00xx to be correct (x means don't care).
Next, let's look at the CAN sending and receiving process of STM32F4.
CAN sending process
The CAN sending process is: the program selects an empty mailbox (TME=1) sets the identifier (ID), data length and send data sets the TXRQ bit of CAN_TIxR to 1, requests to send mailbox registration (wait to become the highest priority) scheduled to send (wait for the bus to be idle) send mailbox empty. The whole process is shown in the figure:
The above figure also includes many other processes, such as termination of transmission (ABRQ=1) and transmission failure processing. Through this flowchart, we have a general understanding of the CAN transmission process, and we basically follow this process for the subsequent data transmission.
Next, let’s take a look at the CAN receiving process.
CAN receiving process
The valid messages received by CAN are stored in a FIFO with a depth of 3 mailboxes. FIFO is completely managed by hardware, which saves CPU processing load, simplifies software and ensures data consistency. The application can only read the first message received in the FIFO by reading the FIFO output mailbox. The valid messages here are those that are correctly received (no errors until EOF) and pass the identifier filter. As we know, CAN has 2 FIFOs for reception. Each filter group can set its associated FIFO. By setting CAN_FFA1R, the filter group can be associated with FIFO0/FIFO1.
The CAN receiving process is: FIFO empty valid message received registration_1 (a mailbox stored in FIFO, this is controlled by hardware, we don’t need to care about it) valid message received registration_2 valid message received registration_3 valid message received overflow.
In this process, we did not consider the situation of reading messages from FIFO. The actual situation is: we must read at least one message before FIFO overflows, otherwise the arrival of the next message will cause FIFO overflow, resulting in message loss. Every time a message is read, the corresponding registration number is reduced by 1 until FIFO is empty. The CAN receiving process is shown in the figure:
The number of messages received by FIFO can be obtained by querying the FMP register of CAN_RFxR.
If it is not 0, we can read the received message from FIFO.
Next, let's take a brief look at the CAN bit timing characteristics of the STM32F4. The CAN bit timing characteristics of the STM32F4 are slightly different from those we introduced before. The STM32F4 merges the propagation time period and phase buffer segment 1 (STM32F4 calls it time period 1), so the STM32F4 CAN has only three segments per bit: synchronization segment (SYNC_SEG), time period 1 (BS1), and time period 2 (BS2). The BS1 segment of the STM32F4 can be set to 1~16 time units, which is exactly equal to the sum of the propagation time period and phase buffer segment 1 we introduced above. The CAN bit timing of the STM32F4 is shown in the figure:
Figure STM32F4 CAN bit timing
The figure also gives the calculation formula for the CAN baud rate. We only need to know the settings of BS1 and BS2, as well as APB1
The baud rate can be easily calculated by using the clock frequency (usually 42Mhz). For example, if TS1=6, TS2=5 and BRP=5 are set, and the APB1 frequency is 42Mhz, the baud rate of CAN communication can be obtained as 42000/[(7+6+1)*6]=500Kbps. Next, we will introduce some important registers that will be used in this chapter. First, let's look at the CAN master control register (CAN_MCR). The description of each bit of this register is shown in the figure.
Only the INRQ bit is introduced, which is used to control the initialization request.
The software clears this bit to 0, which allows the CAN to enter the normal operation mode from the initialization mode: when the CAN detects 11 consecutive recessive bits on the receive pin, the CAN is synchronized and ready to receive and send data. To this end, the hardware clears the INAK bit of the CAN_MSR register to '0' accordingly.
Software can set this position to 1 to make CAN enter initialization mode from normal working mode: once the current CAN activity (sending
When the CAN_MSR register is set to '1', the hardware sets the INAK bit of the CAN_MSR register to '1'. Therefore, when we initialize the CAN, we must first set this bit to 1, then initialize it (especially the setting of CAN_BTR, which must be set before the CAN works normally), and then set this bit to 0 to let the CAN enter the normal working mode.
Second, we introduce the CAN bit timing register (CAN_BTR), which is used to set the frequency division, Tbs1, Tbs2 and Tsjw and other very important parameters, which directly determine the baud rate of CAN. In addition, this register can also set the working mode of CAN. The description of each bit of this register is shown in the figure:
STM32F4 provides two test modes, loopback mode and silent mode. Of course, they can also be combined into loopback silent mode. Here we briefly introduce the loopback mode. In loopback mode, bxCAN treats the sent message as a received message and saves it (if it can pass the receiving filter) in the receiving mailbox. That is, the loopback mode is a self-transmitting and self-receiving mode, as shown in the figure:
Loopback mode can be used for self-testing. To avoid external influences, the CAN core ignores confirmation errors in loopback mode (does not detect whether there is a dominant bit at the confirmation bit moment of the data/remote frame). In loopback mode, bxCAN internally feeds the Tx output back to the Rx input, completely ignoring the actual state of the CANRX pin. The sent message can be detected on the CANTX pin.
Third, we introduce the CAN send mailbox identifier register (CAN_TIxR) (x=0~3), the description of each bit of this register is shown in the figure
This register is mainly used to set the identifier (including the extended identifier), and can also set the frame type, and request the mailbox to send through the TXRQ value 1. Because there are 3 sending mailboxes, there are 3 registers CAN_TIxR.
Fourth, we introduce the CAN send mailbox data length and timestamp register (CAN_TDTxR) (x=0~2). This register is only used to set the data length, that is, the lowest 4 bits. It is relatively simple and will not be introduced in detail here.
The fifth one I will introduce is the CAN send mailbox low byte data register (CAN_TDLxR) (x=0~2).
Each description is as shown in the figure:
This register is used to store the data to be sent. Only the lower 4 bytes can be stored here. There is also another register
CAN_TDHxR, this register is used to store the upper 4 bytes, so a total of 8 bytes can be stored.
The description of each bit is similar to CAN_TDLxR, so we will not introduce it separately.
Sixth, we introduce the CAN receive FIFO mailbox identifier register (CAN_RIxR) (x=0/1). The description of each bit of this register is almost exactly the same as the CAN_TIxR register, except that the lowest bit is a reserved bit. This register is used to save information such as the received message identifier. We can obtain relevant information by reading this register.
Similarly, the CAN receive FIFO mailbox data length and timestamp register (CAN_RDTxR), CAN receive FIFO mailbox low byte data register (CAN_RDLxR) and CAN receive FIFO mailbox high byte data register (CAN_RDHxR) are similar to the send mailbox: CAN_TDTxR, CAN_TDLxR and CAN_TDHxR
Seventh, we introduce the CAN filter mode register (CAN_FM1R), the description of each bit of this register is shown in Figure 32.1.20:
This register is used to set the working mode of each filter group. The working modes of the 28 filter groups can be set through this register. However, this register can only be set when the filter is in initialization mode (FINIT bit of CAN_FMR = 1).
Eighth, we introduce the CAN filter width register (CAN_FS1R), the description of each bit of this register is shown in the figure:
This register is used to set the bit width of each filter group. The bit width setting of 28 filter groups can be realized through this register. This register can also only be set when the filter is in initialization mode.
Ninth, we introduce the CAN filter FIFO associated register (CAN_FFA1R), the description of each bit of this register is shown in the figure:
This register sets the FIFO into which the message is stored after passing through the filter group. If the corresponding bit is 0, it is stored in FIFO0.
If it is 1, it is stored in FIFO1. This register can also only be configured when the filter is in initialization mode.
Tenth, we introduce the CAN filter activation register (CAN_FA1R), each bit of this register corresponds to the filter group and
The previous registers are similar and will not be listed here. If the corresponding position is 1, the corresponding filter group is turned on; if it is 0, the filter group is turned off.
Finally, we introduce the register x (CAN_FiRx) of the CAN filter group i (i=0~27; x=1/2).
Each description is as shown in the figure:
Each filter group CAN_FiRx consists of two 32-bit registers, namely: CAN_FiR1 and CAN_FiR2.
Depending on the filter bit width and mode settings, the functions of these two registers are also different. About the mapping of filters, functional descriptions and associations with mask registers
3. Use of STM32 library functions
In this example, I choose PD0, PD1 as CAN
1) Configure the multiplexing function of the relevant pins and enable the CAN clock.
If we want to use CAN, the first step is to enable the CAN clock, which is set by the 25th bit of APB1ENR. Secondly, we need to set the relevant pins of CAN to multiplex outputs. Here we need to set PD0 (CAN1_RX) and PD1 (CAN1_TX) to multiplex functions and enable the clock of the PA port. The specific configuration process is as follows:
// Enable the relevant clock
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD,ENABLE); //Enable PORTD clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,ENABLE); //Enable CAN1 clock
// Initialize GPIO
GPIO_InitStructure.GPIO_Pin= GPIO_Pin_0| GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //Multiplexing function
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //Push-pull output
GPIO_InitStructure.GPIO_Speed= GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd= GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOD,&GPIO_InitStructure); //Initialize PD0, PD1
//Pin multiplexing mapping configuration
GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_CAN1); //PD0 is multiplexed as CAN1
GPIO_PinAFConfig(GPIOA,GPIO_PinSource1,GPIO_AF_CAN1); //PD1 is multiplexed as CAN1
Here we need to remind you which IO ports the CAN sending and receiving pins are. You can find them in the pin table of the Chinese reference manual.
2) Set the CAN working mode and baud rate, etc.
In this step, the CAN is put into initialization mode by setting the INRQ bit of the CAN_MCR register, and then setting other related control bits of the CAN_MCR. Then, the baud rate and working mode (normal mode/loopback mode) and other information are set through the CAN_BTR. Finally, INRQ is set to 0 to exit the initialization mode.
In the library function, the function CAN_Init() is provided to initialize the working mode and baud rate of CAN. In the body of the CAN_Init() function, before initialization, the INRQ of the CAN_MCR register will be set to 1 to enter the initialization mode. After initializing the CAN_MCR register and the CRN_BTR register, the INRQ of the CAN_MCR register will be set to 0 to exit the initialization mode. Therefore, we do not need to set the initialization mode before and after calling this function. Let's take a look at the definition of the CAN_Init() function:
uint8_t CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct);
The first parameter is the CAN number. Our chip has only one CAN, so it is CAN1.
The second parameter is the CAN initialization structure pointer, the structure type is CAN_InitTypeDef, let's take a look at the definition of this structure:
typedefstruct
{
uint16_tCAN_Prescaler;
uint8_tCAN_Mode;
uint8_tCAN_SJW;
uint8_tCAN_BS1;
uint8_tCAN_BS2;
FunctionalStateCAN_TTCM;
FunctionalStateCAN_ABOM;
FunctionalStateCAN_AWUM;
FunctionalStateCAN_NART;
FunctionalState CAN_RFLM;
FunctionalStateCAN_TXFP;
}CAN_InitTypeDef;
This structure seems to have many member variables, but in fact the parameters can be divided into two categories. The first five parameters are used to set the register CAN_BTR, which is used to set the mode and baud rate related parameters, which have been explained before. The parameter for setting the mode is CAN_Mode. In our experiment, we used the loopback mode CAN_Mode_LoopBack and the normal mode CAN_Mode_Normal. You can also choose the silent mode and silent loopback mode test. Other parameters related to the baud rate setting CAN_Prescaler, CAN_SJW, CAN_BS1 and CAN_BS2 are used to set the baud rate divider, resynchronization jump width and the number of time units occupied by time period 1 and time period 2. The last six member variables are used to set the register CAN_MCR, that is, to set the control bits related to CAN communication. You can look up the description of these two registers in the Chinese reference manual, which is very detailed, and we have also explained it before. The initialization example is:
CAN_InitStructure.CAN_TTCM=DISABLE; //Non-time triggered communication mode
CAN_InitStructure.CAN_ABOM=DISABLE; //Software automatic offline management
CAN_InitStructure.CAN_AWUM=DISABLE; //Sleep mode wake up by software
CAN_InitStructure.CAN_NART=ENABLE; //Disable automatic message transmission
CAN_InitStructure.CAN_RFLM=DISABLE; //The message is not locked, the new one overwrites the old one
CAN_InitStructure.CAN_TXFP=DISABLE; //Priority is determined by the message identifier
CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack; //Mode setting 1, loopback mode;
CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //Resynchronization jump width is time units
CAN_InitStructure.CAN_BS1=CAN_BS1_8tq; //Time period 1 takes up 8 time units
CAN_InitStructure.CAN_BS2=CAN_BS2_7tq; //Time period 2 takes up 7 time units
CAN_InitStructure.CAN_Prescaler=5; //Frequency division factor (Fdiv)
CAN_Init(CAN1, &CAN_InitStructure); //Initialize CAN1
3) Set the filter.
In this chapter, we will use filter group 0 and work in 32-bit identifier mask bit mode. First set the FINIT bit of CAN_FMR to make the filter group work in initialization mode, then set the working mode of filter group 0 as well as the identifier ID and mask bit. Finally, activate the filter and exit the filter initialization mode.
In the library function, the function CAN_FilterInit() is provided to initialize the filter-related parameters of CAN. In the body of the CAN_Init() function, before initialization, the INRQ of the CAN_FMR register will be set to INIT to enter the initialization mode. After initializing the CAN filter-related registers, the FINIT of the CAN_FMR register will be set to 0 to exit the initialization mode. Therefore, we do not need to set the initialization mode before and after calling this function. Let's take a look at the definition of the CAN_FilterInit() function:
void CAN_FilterInit(CAN_FilterInitTypeDef* CAN_FilterInitStruct);
This function has only one entry parameter, which is the pointer to the CAN filter initialization structure. The structure type is
CAN_FilterInitTypeDef, let's look at the type definition:
typedefstruct
{
uint16_tCAN_FilterIdHigh;
uint16_tCAN_FilterIdLow;
uint16_tCAN_FilterMaskIdHigh;
uint16_tCAN_FilterMaskIdLow;
uint16_tCAN_FilterFIFOAssignment;
uint8_tCAN_FilterNumber;
uint8_t CAN_FilterMode;
uint8_tCAN_FilterScale;
FunctionalStateCAN_FilterActivation;
}CAN_FilterInitTypeDef;
The structure has a total of 9 member variables. The first to fourth ones are used to set the filter's 32-bit ID and 32-bit mask ID, which are combined by two 16-bit bits respectively. Their meanings have been explained before.
The fifth member variable CAN_FilterFIFOAssignment is used to set the association between FIFO and filter. Our experiment associates filter 0 to FIFO0, and the value is CAN_Filter_FIFO0.
The sixth member variable CAN_FilterNumber is used to set the initialized filter group, with a value range of 0 to 13.
The seventh member variable FilterMode is used to set the mode of the filter group, and its value is the identifier list mode.
CAN_FilterMode_IdList and the identifier mask bit pattern CAN_FilterMode_IdMask.
The eighth member variable FilterScale is used to set the filter bit width to 2 16-bit CAN_FilterScale_16bit or 1 32-bit CAN_FilterScale_32bit.
The ninth member variable CAN_FilterActivation is very clear and is used to activate the filter.
Filter initialization reference example code:
CAN_FilterInitStructure.CAN_FilterNumber=0; //Filter 0
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;//32位
CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;////32位ID
CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32位MASK
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//FIFO0
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //Activate filter 0
CAN_FilterInit(&CAN_FilterInitStructure); //Filter initialization
4) Send and receive messages
After initializing CAN related parameters and filters, the next step is to send and receive messages. The library function provides functions for sending and receiving messages. The function for sending messages is:
uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage);
This function is relatively easy to understand. The first parameter is the CAN number, we use CAN1. The second parameter is the pointer type of the relevant message structure CanTxMsg. The member variables of the CanTxMsg structure are used to set the standard identifier, extended identifier, message type, message frame length and other information.
The function that receives the message is:
void CAN_Receive(CAN_TypeDef* CANx, uint8_t FIFONumber,CanRxMsg* RxMessage);
The first two parameters are easy to understand, CAN number and FIFO number. The second parameter RxMessage is used to store the received message information. The structure CanRxMsg is similar to the structure CanTxMsg, which are used to define the sending message and describing the receiving message respectively. You can compare them and it is also easy to understand.
5) CAN status acquisition
For transmission status information such as the status of CAN sending messages, the number of pending messages, etc., the library function provides a series of functions, including CAN_TransmitStatus() function, CAN_MessagePending() function, CAN_GetFlagStatus() function, etc., which can be called as needed.
4. STM32 CAN source code
This source code sets CAN1 to loopback mode
Can.h
#ifndef_ADC_H_H_H
#define_ADC_H_H_H
#include"stm32f4xx_gpio.h"
#include"stm32f4xx_rcc.h"
#include"stm32f4xx_can.h"
//CAN1 receives RX0 interrupt enable
#defineCAN1_RX0_INT_ENABLE 1 //0, disable; 1, enable.
u8CAN1_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode);//CAN initialization
u8CAN1_Send_Msg(u8* msg,u8 len); //Send data
u8CAN1_Receive_Msg(u8 *buf); //Receive data
#endif
Can.c
#include "can.h"
u8CAN1_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode)
{
GPIO_InitTypeDefGPIO_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
#ifCAN1_RX0_INT_ENABLE
NVIC_InitTypeDef NVIC_InitStructure;
#endif
// Enable the relevant clock
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); //Enable PORTA clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,ENABLE); //Enable CAN1 clock
// Initialize GPIO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0| GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_AF; //Multiplexing function
GPIO_InitStructure.GPIO_OType =GPIO_OType_PP; //Push-pull output
GPIO_InitStructure.GPIO_Speed =GPIO_Speed_100MHz;//100MHz
GPIO_InitStructure.GPIO_PuPd =GPIO_PuPd_UP;//上拉
GPIO_Init(GPIOD,&GPIO_InitStructure); //Initialize PA11, PA12
//Pin multiplexing mapping configuration
GPIO_PinAFConfig(GPIOD,GPIO_PinSource1,GPIO_AF_CAN1); //GPIOA11 is multiplexed as CAN1
GPIO_PinAFConfig(GPIOD,GPIO_PinSource0,GPIO_AF_CAN1); //GPIOA12 is multiplexed as CAN1
//CAN unit settings
CAN_InitStructure.CAN_TTCM=DISABLE; //Non-time triggered communication mode
CAN_InitStructure.CAN_ABOM=DISABLE; //Software automatic offline management
CAN_InitStructure.CAN_AWUM=DISABLE; //Sleep mode wakes up through software (clear the SLEEP bit of CAN->MCR)
CAN_InitStructure.CAN_NART=ENABLE; //Disable automatic message transmission
CAN_InitStructure.CAN_RFLM=DISABLE; //The message is not locked, the new one overwrites the old one
CAN_InitStructure.CAN_TXFP=DISABLE; //Priority is determined by the message identifier
CAN_InitStructure.CAN_Mode=mode; //Mode setting
CAN_InitStructure.CAN_SJW=tsjw; //Resynchronization jump width (Tsjw) is tsjw+1 time unit CAN_SJW_1tq~CAN_SJW_4tq
CAN_InitStructure.CAN_BS1=tbs1;//Tbs1范围CAN_BS1_1tq ~CAN_BS1_16tq
CAN_InitStructure.CAN_BS2=tbs2;//Tbs2范围CAN_BS2_1tq~ CAN_BS2_8tq
CAN_InitStructure.CAN_Prescaler=brp; //Frequency division factor (Fdiv) is brp+1
CAN_Init(CAN1,&CAN_InitStructure); // Initialize CAN1
//Configure the filter
CAN_FilterInitStructure.CAN_FilterNumber=0; //Filter 0
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;//32位
CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;////32位ID
CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32位MASK
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0; //Filter 0 is associated with FIFO0
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //Activate filter 0
CAN_FilterInit(&CAN_FilterInitStructure); //Filter initialization
#ifCAN1_RX0_INT_ENABLE
CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);//FIFO0 message registration interrupt is enabled.
NVIC_InitStructure.NVIC_IRQChannel= CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // The main priority is 1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // Subpriority is 0
NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;
NVIC_Init(&NVIC_InitStructure);
#endif
return 0;
}
#ifCAN1_RX0_INT_ENABLE //Enable RX0 interrupt
//Interrupt service function
voidCAN1_RX0_IRQHandler(void)
{
CanRxMsgRxMessage;
int i=0;
CAN_Receive(CAN1, 0, &RxMessage);
for(i=0;i<8;i++)
printf("rxbuf[%d]:%c\r\n",i,RxMessage.Data[i]);
}
#endif
//can send a set of data (fixed format: ID is 0X12, standard frame, data frame)
//len: data length (maximum 8)
//msg: data pointer, maximum 8 bytes.
//Return value: 0, success;
//Other, failed;
u8CAN1_Send_Msg(u8* msg,u8 len)
{
u8 mbox;
u16 i=0;
CanTxMsg TxMessage;
TxMessage.StdId=0x12; // Standard identifier is 0
TxMessage.ExtId=0x12; // Set the extended identifier (29 bits)
TxMessage.IDE=0; // Use extended identifier
TxMessage.RTR=0; // The message type is data frame, one frame is 8 bits
TxMessage.DLC=len; // Send two frames of information
for(i=0;i TxMessage.Data[i]=msg[i]; // First frame information mbox= CAN_Transmit(CAN1,&TxMessage); i=0; while((CAN_TransmitStatus(CAN1,mbox)==CAN_TxStatus_Failed)&&(i<0XFFF))i++; //Wait for sending to end if(i>=0XFFF)return 1; return 0; } //Can port receives data query //buf: data buffer; //Return value: 0, no data is received; //Others, received data length; u8CAN1_Receive_Msg(u8 *buf) { u32i; CanRxMsg RxMessage; if(CAN_MessagePending(CAN1,CAN_FIFO0)==0)return 0; //No data received, exit directly CAN_Receive(CAN1, CAN_FIFO0,&RxMessage);//Read data for(i=0;i buf[i]=RxMessage.Data[i]; return RxMessage.DLC; } Main.c #include"led.h" #include"key.h" #include"delay.h" #include"uart.h" #include"exit.h" #include"iwdog.h" #include"pwm.h" #include"can.h" voidUser_Delay(__IO uint32_t nCount) { while(nCount--) { } } staticint count = 0; intmain(void) { u8 i = 0; u8 cnt=0; u8 canbuf[8]; u8 canrxbuf[8]; u8 only; u8 res; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); My_USART2_Init(); delay_init(168); printf("main test start\n"); CAN1_Mode_Init(CAN_SJW_1tq,CAN_BS2_6tq,CAN_BS1_7tq,6,CAN_Mode_LoopBack); //CAN initializes loopback mode, baud rate 500Kbps for(i=0;i<8;i++) { canbuf[i]='c'+i; //Fill the send buffer } while(1) { res=CAN1_Send_Msg(canbuf,8); //Send 8 bytes //len=CAN1_Receive_Msg(canrxbuf); if(len) { for(i=0;i { printf("%c",canrxbuf[i]); } } printf("\r\n"); delay_ms(1000); } }
Previous article:【stm32f407】Flash programming
Next article:【stm32f407】SPI experimental driver W25Q128
Recommended ReadingLatest update time:2024-11-17 01:47
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- Rambus Launches Industry's First HBM 4 Controller IP: What Are the Technical Details Behind It?
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- Xiaozhi Comics丨The Structure of Transistors
- Help, IP5306 charging chip short circuit problem
- MSP432 development board serial port debugging
- Let's study together. This e-book is well written in Chinese.
- Where do you go to buy components? e-Network has spot products and can receive them the next day.
- RFID related CPU card
- EEWORLD University Hall----TI Cup 2019 National College Student Electronic Design Competition Topic Analysis and Technical Exchange Seminar
- Conversion relationship of various parameters of VSWR
- High voltage inverter
- Hydrogen escape problem