STM32 CAN bus learning summary

Publisher:BlissfulCharmLatest update time:2018-09-02 Source: eefocusKeywords:STM32 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

1. First, read the documentation about CAN in the manual carefully.

STM32F10xxx Reference Manual Rev7V3.pdf

The two chapters that require careful reading are RCC and CAN.

Why do we need to study RCC carefully? Because we will learn how to set the baud rate of CAN and will use the settings of RCC, so it is recommended that you review several clocks in this part first.

 

A brief introduction to STM32's CAN bus

bxCAN is the abbreviation of Basic Extended CAN, which supports CAN protocol 2.0A and 2.0B. Its design goal is to efficiently process a large number of received messages with minimal CPU load. It also supports priority requirements for message sending (priority characteristics can be configured by software).

For safety-critical applications, bxCAN provides all the hardware functions required to support time-triggered communication mode.


main feature

Support CAN protocol 2.0A and 2.0B active mode

Baud rates up to 1 Mbit/s

Support time-triggered communication function


send

·3 email addresses

· The priority of sending messages can be configured by software

Record the timestamp of when SOF is sent


take over

· 2 receive FIFOs with 3 levels of depth

14 variable width filter banks – shared by the entire CAN

Identifier list

FIFO overflow handling is configurable

Record the timestamp of the moment when SOF is received


Support time-triggered communication mode

Disable automatic retransmission mode

16-bit free-running timer

Configurable timer resolution

Ability to send timestamp in the last 2 data bytes


manage

Interrupts can be masked

· The mailbox occupies a separate address space, which is convenient for improving software efficiency

 

 

2. The working modes of STM32FVBT6 can are divided into

 

#define CAN_Mode_Normal ((u8)0x00) 

#define CAN_Mode_LoopBack ((u8)0x01) 

#define CAN_Mode_Silent ((u8)0x02) 

#define CAN_Mode_Silent_LoopBack ((u8)0x03) 

In this chapter of our Doupi tutorial we will use two modes: CAN_Mode_LoopBack and CAN_Mode_Normal.

The first step we will do is to run a self-test in CAN_Mode_LoopBack.

In the reference manual, CAN_Mode_LoopBack (loopback mode) is defined as follows:

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.

Therefore, it is more suitable to test the CAN part BSP program of STM32 when we only have one board.

 

3. The physical pin positions of CAN in STM32FVBT6 can be set to three modes: default mode, redefine address 1 mode, and redefine address 2 mode.

In our Doupi, we use the redefinition address 2 mode, that is, CANRX and CANTX are redefined to the PD0 and PD1 pins respectively.

Therefore, the first step in our software is to redefine the operation:

 

-------------------------------------------------- -----------------------

 

 //GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;

 //GPIO_InitStructure.GPIO_Speed ​​= GPIO_Speed_50MHz;

 //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

 //GPIO_Init(GPIOB, &GPIO_InitStructure);

 

 

 //GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

 //GPIO_InitStructure.GPIO_Speed ​​= GPIO_Speed_50MHz;

 //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

 //GPIO_Init(GPIOB, &GPIO_InitStructure);

 

 

 //GPIO_PinRemapConfig(GPIO_Remap1_CAN, ENABLE);

-------------------------------------------------- ----------------------- 

 

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;

 GPIO_InitStructure.GPIO_Speed ​​= GPIO_Speed_50MHz;

 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

 GPIO_Init(GPIOD, &GPIO_InitStructure);

 

 

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;

 GPIO_InitStructure.GPIO_Speed ​​= GPIO_Speed_50MHz;

 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

 GPIO_Init(GPIOD, &GPIO_InitStructure);

 

 

 GPIO_PinRemapConfig(GPIO_Remap2_CAN, ENABLE); 

-------------------------------------------------- -----------------------

 

 //GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;

 //GPIO_InitStructure.GPIO_Speed ​​= GPIO_Speed_50MHz;

 //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

 //GPIO_Init(GPIOA, &GPIO_InitStructure);

 

 

 //GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;

 //GPIO_InitStructure.GPIO_Speed ​​= GPIO_Speed_50MHz;

 //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

 //GPIO_Init(GPIOA, &GPIO_InitStructure); 

-------------------------------------------------- -----------------------

 

After setting the CAN pin, you also need to turn on the CAN clock:

  

 RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE);

4. We need to understand the setting of CAN baud rate. This chapter is also one of the most important parts of using CAN, because in practical applications we need to choose the CAN baud rate according to our actual situation.

Generally speaking, the data can be transmitted reliably within a distance of 40 meters at a rate of 1M bps.

At baud rates below 50K, data can generally be transmitted reliably over distances of several kilometers.

 

For the baud rate setting, you need to study the explanation of the corresponding part of the reference manual in detail. When debugging the software, we can use an oscilloscope to test the baud rate of the waveform on the CANTX pin, which can achieve twice the result with half the effort and greatly shorten the debugging learning time.

  //************************************************ ***************

 // BaudRate = 1/NominalBitTime

 // NominalBitTime = 1tq+tBS1+tBS2

 // tq = (BRP[9:0] + 1) xtPCLK

 // tPCLK = CAN's clock =APB1's clock

  //************************************************ ****************

That is, BaudRate = APB1/((BS1 + BS2 + 1)*Prescaler)

What needs attention here is the location of the adoption point, that is, the setting of BS1 and BS2. I have also found some information here and copied it down for everyone. It is the recommended setting in the CANopen protocol.

 At 1Mbps, the location of the adoption point is at 6tq, BS1=5, BS2=2

 At 500kbps, the point of adoption is at 8tq, BS1=7, BS2=3

 At 250kbps, the point of adoption is at 14tq, BS1=13, BS2=2

 The adoption point positions of 125k, 100k, 50k, 20k, and 10k are the same as those of 250K.

 

Therefore, we need to pay attention to the following parts of the software:

 

   //Set AHB clock (HCLK)

   //RCC_SYSCLK_Div1 AHB clock = system clock

   RCC_HCLKConfig(RCC_SYSCLK_Div8);

 

 

   //Set low speed AHB clock (PCLK1)

   //RCC_HCLK_Div2 APB1 clock = HCLK / 2

   RCC_PCLK1Config(RCC_HCLK_Div2);

 

   //PLLCLK = 8MHz * 8 = 64MHz

   //Set PLL clock source and frequency multiplication factor

   RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_8);

 

The clock of PCLK1 is needed in CAN baud rate setting.

 

 

 CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;

 CAN_InitStructure.CAN_SJW=CAN_SJW_1tq;

 CAN_InitStructure.CAN_BS1=CAN_BS1_8tq;

 CAN_InitStructure.CAN_BS2=CAN_BS2_7tq;

 CAN_InitStructure.CAN_Prescaler=5;

 

Through the clock settings in the above part, we can already calculate our baud rate

CAN_bps = PCLK1 / ((1 + 7 + 8) * 5) = 25Kbps

 

You can also modify the clock value in actual testing to test whether the baud rate we need is correct through an oscilloscope. For example, reduce the PLLCLK setting by half:

   //PLLCLK = 8MHz * 4 = 32MHz

   //Set PLL clock source and frequency multiplication factor

   RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_4);

Then the CAN_bps we get will also be reduced by half.

Next, you can also modify HCLK and PCLK1. In fact, these division and multiplication values ​​ultimately affect PCLK1.

 

After several experiments, I believe everyone should be able to easily master the baud rate setting.

 

After setting the baud rate, we directly test the function: TestStatus CAN_Polling(void)

 

       // CAN transmit at 25Kb/s and receive by polling in loopback mode

       TestRx = CAN_Polling();

       

       

       if (TestRx == FAILED)

       {

           // Turn on led connected to PC.08 pin (LED4)

           // For DP-STM32F use LED4 connected to PC.12

           GPIO_ResetBits(GPIOC, GPIO_Pin_12);

       }

       else

       {

           // Turn on led connected to PC.06 pin (LED2)

           // For DP-STM32F use LED2 connected to PC.11

           GPIO_ResetBits(GPIOC, GPIO_Pin_11);

       }

 

You can simulate the program. When Test in the program is equal to Passed, it means that the Loopback mode test has passed.

At this point, if you only have one CAN module, your study can come to an end. However, this does not mean that you have mastered CAN. To really master it, you still need to read a lot of information on CAN. The reference manual is not enough. There are several books on the market that specifically introduce fieldbus and CAN bus. I recommend you to buy them and read them frequently so that you can be like a duck in water when you need practical application.

 

5. After completing the loopback mode test of the single board, the next thing we need to learn is multi-machine communication. Of course, if you only have one Doupi development board, you can't do this part of the experiment. You can only look at the program and tutorial of this part first.

Here we need to prepare two PCB boards, use three wires to directly connect CANH, CANL, and GND. Of course, we need to jump the jumper F to the terminal resistor. After both boards are jumped, we use a multimeter to measure whether the resistance between CANH and CANL is 60 ohms (about 62 ohms on PCB).

 

Normal Mode

After initialization is completed, the software should let the hardware enter normal mode in order to receive and send messages normally. The software can request to enter normal mode from initialization mode by clearing the INRQ bit of the CAN_MCR register to '0', and then wait for the hardware to confirm that the INAK position of the CAN_MSR register is '1'. After synchronizing with the CAN bus, that is, after 11 consecutive recessive bits (equivalent to bus idle) are detected on the CANRX pin, bxCAN can receive and send messages normally.

The filter initialization value does not need to be set in the initialization mode, but it must be done in the inactive state (the corresponding FACT bit is 0). The setting of the filter bit width and mode must be done in the initialization mode before entering the normal mode.

 

After the preparation work is done, we need to set up the software to allow one doupi board to send and one to receive.

       / CAN transmit at 100Kb/s and receive by interrupt in normal mode

       TestRx = CAN_Interrupt();

       

       if (TestRx == FAILED)

       {

           // Turn on led connected to PC.09 pin (LED3)

           // For DP-STM32F use LED3 connected to PC.10

           GPIO_ResetBits(GPIOC, GPIO_Pin_10);

       }

       else

       {

           // Turn on led connected to PC.07 pin (LED8)

           // For DP-STM32F use LED8 connected to PD.05

           GPIO_ResetBits(GPIOD, GPIO_Pin_5);

       }


STM32 CAN bus transmits data

Operating mode

bxCAN has 3 main operating modes: initialization, normal and sleep modes.


Initialization Mode

*The software requests bxCAN to enter initialization mode by setting the INRQ bit of the CAN_MCR register to 1, and then waits for hardware to confirm by setting the INAK bit of the CAN_MSR register to 1.

*The software requests bxCAN to exit the initialization mode by clearing the INRQ bit of the CAN_MCR register to 0. The hardware confirms the exit of the initialization mode when the INAK bit of the CAN_MSR register is cleared to 0.

*When bxCAN is in initialization mode, both the reception and transmission of messages are disabled, and the CANTX pin outputs a recessive bit (high level). To initialize the CAN controller, the software must set the CAN_BTR and CAN_MCR registers.


Normal Mode

After initialization is completed, the software should let the hardware enter normal mode and synchronize the CAN bus to receive and send messages normally. The software requests to enter normal mode from initialization mode by clearing the INRQ bit to 0, and then waits for the hardware to clear the INAK bit to confirm. After synchronizing with the CAN bus, that is, monitoring 11 consecutive recessive bits (equivalent to bus idle) on the CANRX pin, bxCAN can receive and send messages normally.

The filter initial value does not need to be set in the initialization mode, but must be completed in the inactive state (the corresponding FACT bit is 0). The setting of the filter bit width and mode must be completed before entering the normal mode, that is, in the initialization mode.


Sleep mode (low power consumption)

*Software requests to enter this mode by setting the SLEEP position of the CAN_MCR register to 1. In this mode, the clock of bxCAN is stopped, but the software can still access the mailbox register.

*When bxCAN is in sleep mode, if the software wants to enter the initialization mode by setting the INRQ bit of the CAN_MCR register to 1, the software must also clear the SLEEP bit to 0.

* There are 2 ways to wake up (exit sleep mode) bxCAN: clear the SLEEP bit to 0 by software, or detect CAN bus activity by hardware.

 

work process

 

So how does CAN send messages?

 

The process of sending a message is as follows: the application selects an empty send mailbox; sets the identifier, data length, and data to be sent; then sets the TXRQ position of the CAN_TIxR register to 1 to request sending. After the TXRQ position is set to 1, the mailbox is no longer an empty mailbox; and once the mailbox is no longer empty, the software no longer has write permission to the mailbox register. After the TXRQ position is set to 1, the mailbox immediately enters the registered state and waits to become the highest priority mailbox, see Send Priority. Once the mailbox becomes the highest priority mailbox, its state changes to the scheduled send state. When the CAN bus enters the idle state, the message in the scheduled send mailbox is immediately sent (enters the send state). After the message in the mailbox is successfully sent, it immediately becomes an empty mailbox, and the hardware accordingly sets the RQCP and TXOK positions of the CAN_TSR register to 1 to indicate a successful send.

If the transmission fails, the ALST position of the CAN_TSR register is set to 1 due to arbitration, and the TERR position is set to 1 due to a transmission error.

 

The priority of sending can be determined by identifier or by the order of sending requests:

Determined by the identifier. When there are more than one mailboxes registered for sending, the order of sending is determined by the identifier of the message in the mailbox. According to the CAN protocol, the message with the lowest identifier value has the highest priority. If the identifier values ​​are equal, the message with the smaller mailbox number is sent first.

Determined by the order of the transmit requests. By setting the TXFP position of the CAN_MCR register to 1, the transmit mailbox can be configured as a transmit FIFO. In this mode, the priority of the transmit is determined by the order of the transmit requests. This mode is useful for segmented transmission.

 

Time-triggered communication mode:

In this mode, the internal timer of the CAN hardware is activated and used to generate timestamps, which are stored in the CAN_RDTxR/CAN_TDTxR registers respectively. The internal timer is sampled at the sampling point of the start bit of the received and transmitted frame and generates a timestamp.

 

Then how to receive the message?

 

Receiving Management

The received messages are stored in a 3-level mailbox-depth FIFO. The FIFO is completely managed by hardware, which saves CPU processing load, simplifies software and ensures data consistency. The application can only read the first received message in the FIFO by reading the FIFO output mailbox. According to the CAN protocol, when a message is received correctly (there is no error until the last bit of the EOF field) and passes the identifier filter, the message is considered a valid message.

Receive related interrupt conditions

* Once a message is stored in the FIFO, the hardware will update the FMP[1:0] bits, and if the FMPIE bit in the CAN_IER register is 1, an interrupt request will be generated.

* When the FIFO becomes full (i.e. the third message is stored), the FULL bit of the CAN_RFxR register is set to 1, and if the FFIE bit of the CAN_IER register is 1, a full interrupt request is generated.

* In case of overflow, the FOVR bit is set to 1 and if the FOVIE bit of the CAN_IER register is 1, an overflow interrupt request is generated.

 

Identifier filtering

In the CAN protocol, the identifier of the message does not represent the address of the node, but is related to the content of the message. Therefore, the sender sends the message to all receivers in the form of broadcast. When receiving the message, the node decides whether it needs the message based on the value of the identifier; if it does, it copies it to the SRAM; if it does not, the message is discarded without software intervention.

To meet this requirement, bxCAN provides 14 variable-width, configurable filter groups (13~0) for the application to receive only those messages required by the software. Hardware filtering saves CPU overhead, otherwise it must be filtered by software, which will occupy a certain amount of CPU overhead. Each filter group x consists of two 32-bit registers CAN_FxR0 and CAN_FxR1.

 

Filter mode settings:

By setting the FBMx bits of CAN_FM0R, the filter group can be configured as identifier list mode or mask bit mode.

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.

 

Filter priority rules:

Filters with a bit width of 32 bits have higher priority than filters with a bit width of 16 bits;

For filters with the same bit width, the identifier list pattern takes precedence over the mask bit pattern;

For filters with the same bit width and mode, the priority is determined by the filter number, and the smaller the filter number, the higher the priority.

 

Receiving mailbox (FIFO)

After receiving a message, the software can access the output mailbox of the receive FIFO to read it. Once the software processes the message (such as reading it out), the software should set the RFOM bit of the CAN_RFxR register to 1 to release the message to leave storage space for the message received later.

 

Interrupt

bxCAN occupies 4 dedicated interrupt vectors. Each interrupt source can be enabled and disabled individually by setting the CAN interrupt enable register CAN_IER.

(1) A transmit interrupt can be generated by the following events:

─ Transmit mailbox 0 becomes empty and the RQCP0 bit in the CAN_TSR register is set to 1.

─ Transmit mailbox 1 becomes empty and the RQCP1 bit in the CAN_TSR register is set to 1.

─ Transmit mailbox 2 becomes empty and the RQCP2 bit in the CAN_TSR register is set to 1.

(2) FIFO0 interrupt can be generated by the following events:

─ FIFO0 receives a new message and the FMP0 bit in the CAN_RF0R register is no longer '00'.

─ When FIFO0 becomes full, the FULL0 bit in the CAN_RF0R register is set to 1.

─ When FIFO0 overflows, the FOVR0 bit in the CAN_RF0R register is set to 1.

(3) FIFO1 interrupt can be generated by the following events:

─ FIFO1 receives a new message and the FMP1 bit in the CAN_RF1R register is no longer '00'.

─ In case FIFO1 becomes full, the FULL1 bit in the CAN_RF1R register is set to 1.

─ If FIFO1 overflows, the FOVR1 bit in the CAN_RF1R register is set to 1.

(4) Error and status change interrupts can be generated by the following events:

─ Error conditions. For detailed information about error conditions, please refer to the CAN Error Status Register (CAN_ESR).

─ Wake-up condition, Start of Frame (SOF) is monitored on the CAN receive pin.

─ CAN enters sleep mode.

 

The workflow is roughly like this. Then there are a lot of annoying CAN registers. After reading them once, I finally have a general understanding. Besides, it is impossible to remember all these registers at once. According to past experience, as long as you use them a few times, you can remember the functions of the registers.

 

OK, it's time to read the specific experimental program. At this time, of course, you have to open the "STM32 library function" information, because it contains explanations of the STM32 packaged library functions, which is very helpful for reading the program.

 

Here is the main program:

int main(void)

{

// int press_count = 0;

char data = '0';

int sent = FALSE;

#ifdef DEBUG

debug();

#endif

RCC_Configuration();

NVIC_Configuration();

GPIO_Configuration();

USART_Configuration();

CAN_Configuration();

 

Serial_PutString("\r\nWeiyan Technology http://www.gzweiyan.com\r\n");

Serial_PutString("CAN test\r\n");

 

while(1)

{

if(GPIO_Keypress(GPIO_KEY, BUT_RIGHT))

{

GPIO_SetBits(GPIO_LED, GPIO_LD1); //Detect button press

if(sent == TRUE)

continue;

sent = TRUE;

data++;

if(data > 'z')

data = '0';

CAN_TxData(data);

}

else //Release the button

{

GPIO_ResetBits(GPIO_LED, GPIO_LD1);

sent = FALSE;

}

}

}

 

The previous RCC, NVIC, GPIO, and USART configurations are similar to the previous experiments. The key is to analyze CAN_Configuration()

The function is as follows:

void CAN_Configuration(void) //CAN configuration function

{

CAN_InitTypeDef CAN_InitStructure;

CAN_FilterInitTypeDef CAN_FilterInitStructure;

CAN_DeInit();

// CAN_StructInit(&CAN_InitStructure);

CAN_InitStructure.CAN_TTCM=DISABLE; //Disable time-triggered communication mode

CAN_InitStructure.CAN_ABOM=DISABLE; //The software sets the INRQ bit of the CAN_MCR register to 1 and then clears it to 0. Once the hardware detects

//When 128 consecutive 11-bit recessive bits are reached, the system exits the offline state.

CAN_InitStructure.CAN_AWUM=DISABLE; //Sleep mode is awakened by software by clearing the SLEEP bit of the CAN_MCR register

 

CAN_InitStructure.CAN_NART=ENABLE; //DISABLE; CAN message is sent only once, regardless of the result of the transmission (success, error or arbitration loss)

CAN_InitStructure.CAN_RFLM=DISABLE; //FIFO is not locked when receiving overflow. When the message in the receiving FIFO is not read out, the next received message will overwrite the original message.

CAN_InitStructure.CAN_TXFP=DISABLE; //The transmit FIFO priority is determined by the message identifier

 

// CAN_InitStructure.CAN_Mode=CAN_Mode_LoopBack;

CAN_InitStructure.CAN_Mode=CAN_Mode_Normal; //CAN hardware works in normal mode

CAN_InitStructure.CAN_SJW=CAN_SJW_1tq; //Resynchronization jump width 1 time unit

CAN_InitStructure.CAN_BS1=CAN_BS1_8tq; //Time period 1 is 8 time units

CAN_InitStructure.CAN_BS2=CAN_BS2_7tq; //Time period 2 is 7 time units

CAN_InitStructure.CAN_Prescaler = 9; //(pclk1/((1+8+7)*9)) = 36Mhz/16/9 = 250Kbits sets the length of a time unit 9

CAN_Init(&CAN_InitStructure);

 

 

CAN_FilterInitStructure.CAN_FilterNumber=0; //Specifies the filter 0 to be initialized

CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //Specifies the mode identifier mask bit pattern that the filter will be initialized to

CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //The filter width is given as 1 32-bit filter

 

CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000; //Used to set the filter identifier (the high bit for 32-bit width and the first bit for 16-bit width)

CAN_FilterInitStructure.CAN_FilterIdLow=0x0000; //Used to set the filter identifier (low bit for 32-bit width, second bit for 16-bit width)

CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000; //Used to set the filter mask identifier or filter identifier (the high bit for 32-bit width and the first bit for 16-bit width)

 

CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000; //Used to set the filter mask identifier or filter identifier (low bit for 32-bit width, second bit for 16-bit width)

 

CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_FIFO0; //Sets FIFO0 pointing to the filter

 

CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //Enable filter

CAN_FilterInit(&CAN_FilterInitStructure);

 

 

CAN_ITConfig(CAN_IT_FMP0, ENABLE); //Enable the specified CAN interrupt

}

 

 

Let’s look at the sending program:

TestStatus CAN_TxData(char data)

{

CanTxMsg TxMessage;

 

u32 i = 0;

u8 TransmitMailbox = 0;

 

 

TxMessage.StdId=0x00; // Set the standard identifier

TxMessage.ExtId=0x1234; // Set the extended identifier

TxMessage.IDE=CAN_ID_EXT; // Set the type of message identifier

TxMessage.RTR=CAN_RTR_DATA; // Set the frame type of the message to be transmitted

 

TxMessage.DLC= 1; //Set the frame length of the message to be transmitted

TxMessage.Data[0] = data; // contains the data to be transmitted

 

TransmitMailbox = CAN_Transmit(&TxMessage); //Start a message transmission

 

i = 0;

while((CAN_TransmitStatus(TransmitMailbox)!=

Keywords:STM32 Reference address:STM32 CAN bus learning summary

Previous article:STM32 CAN---Transmission Management Analysis
Next article:STM32--CAN simple receiving and sending

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
Guess you like

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号