Introduction:
CAN is the abbreviation of Controller Area Network (hereinafter referred to as CAN), which is an ISO internationally standardized serial communication protocol. It was first proposed by German electrical company Bosch in 1986. Since then, CAN has been standardized through ISO11898 and ISO11519. It is now the standard protocol for automotive networks in Europe.
After being standardized by ISO, the CAN protocol has two standards: ISO11898 and ISO11519-2. ISO11898 is a high-speed communication standard for communication rates of 125Kbps to 1Mbps, while ISO11519-2 is a low-speed communication standard for communication rates below 125Kbps.
CAN has high reliability and is widely used in automotive electronics, industrial automation, ships, medical equipment, industrial equipment, etc.
Features:
Multi-master control. When the bus is idle, all units can send messages. When two or more units start sending messages at the same time, the priority is determined by the identifier (ID, not the address). When two or more units start sending messages at the same time, each bit of each message ID is arbitrated and compared one by one. The unit that wins the arbitration (highest priority) can continue to send messages, and the unit that loses the arbitration immediately stops sending and starts receiving.
System flexibility. The units connected to the bus do not have information such as "addresses". Therefore, when adding units to the bus, the software, hardware and application layers of other connected units do not need to be changed.
Fast speed and long distance. Up to 1Mbps (distance <40M), up to 10KM (rate <5Kbps).
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).
Fault containment 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.
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. However, in practice, 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.
Physical Features:
Bus level = CAN_H voltage - CAN_L voltage
Dominant level corresponds to logic 0 = bus level is about 2V
Recessive level corresponds to logic 0 = bus level is 0V
The dominant level has priority. As long as one unit outputs the dominant level, the bus will be at the dominant level. The invisible level has an inclusive meaning. Only when all units output the recessive level will the bus be 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.
Frame type introduction:
Frame type | Frame function |
---|---|
Data Frame | Frame used for transmitting data from the sending unit to the receiving unit |
Remote Control Frame | Frame used by a receiving unit to request data from a sending unit with the same ID |
Error frame | A frame used to notify other units of an error when an error is detected. |
Overload Frame | Frame used by the receiving unit to notify that it is not ready to receive. |
Interval Frame | Frame used to separate data frames and remote control frames from previous frames |
Note: 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.
STM32 CAN controller introduction:
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 groups (also called filter groups, up to 28, F1 usually has 14, interconnect and F4 have 28, in addition, F4 has two cans, F1 has only one)
3 modes:
Working mode:
Initialization mode (INRQ=1, SLEEP=0)
Normal mode (INRQ=0, SLEEP=0)
Sleep mode (SLEEP=1)
Test Mode:
Silent mode (LBKM=0, SILM=1)
Loopback mode (LBKM=1, SILM=0)
Loopback Silent Mode (LBKM=1, SILM=1)
Debug mode (not often used)
STM32 CAN filter bit width and mode configuration:
The CAN identifier does not indicate the destination address but the sending priority. The receiving node decides whether to receive the corresponding message based on the value of the identifier.
Identifier masking mode: filter a group of identifiers
Identifier list mode: filter a single identifier
Example: Set filter group 0 to work in: 1 32-bit filter-identifier mask mode, then set CAN_F0R1=0XFFFF0000, CAN_F0R2=0XFF00FF00. The value stored in CAN_F0R1 is the ID expected to be received, that is, (STID+EXTID+IDE+RTR) is preferably: 0XFFFF0000. And 0XFF00FF00 is to set the ID that we must care about, indicating that the received image, 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 image must be 0XFFxx00xx to be correct (x means don't care).
Baud rate setting:
STM32F103, set TS1=8, TS2=7, BRP=3, baud rate=36000/[(9+8+1)*4]=500Kbps.
STM32F407, set TS1=6, TS2=5, BRP=5, baud rate=42000/[(7+6+1)*6]=500Kbps.
register:
CAN Master Control Register (CAN_MCR)
In this register, we only introduce the INRQ bit, which is used to control the initialization request.
Setting INRQ=0 can make CAN enter normal working mode from initialization mode.
Setting INRQ=1 can make CAN enter initialization mode from normal working mode.
When CAN is initialized, first set INRQ=1 to enter the initialization mode and perform initialization (especially the setting of CAN_BTR, which must be set before CAN works normally), then set INRQ=0 to enter the normal working mode.
CAN Bit Timing Register (CAN_BTR) sets the baud rate
CAN receive FIFO register (CAN_RF0R/CAN_RF1R)
CAN send mailbox identifier register (CAN_TIxR) (x=0~2)
CAN send mailbox data length and timestamp register (CAN_TDTxR) (x=0~2)
The lower 4 bits are used to set how many bytes to send, up to 8 bytes
CAN send mailbox data register (CAN_TDLxR/CAN_TDHxR) (x=0~2)
CAN Receive FIFO Mailbox Identifier Register (CAN_RIxR) (x=0/1)
CAN receive FIFO mailbox data length and timestamp register (CAN_RDTxR) (x=0/1)
CAN receive FIFO mailbox mailbox data register (CAN_RDLxR/CAN_RDHxR) (x=0/1)
CAN filter mode register (CAN_FM1R) (0 identifier mask, 1 identifier list)
CAN filter standard register (CAN_FS1R) (0 double 16 bits, 1 single 32 bits)
CAN filter FIFO associated register (CAN_FFA1R) (0 filter is assigned to FIFO0, 1 filter is assigned to FIFO1)
CAN filter activation register (CAN_FA1R) (0 is not activated, 1 is activated)
CAN filter group i register x (CAN_FiRx) (i=0~27, x=1/2) (F103 filter has only 14)
Configuration steps:
①Configure the multiplexing function of related pins and enable CAN clock.
The clock of N is set by the 25th bit of APB1ENR. Secondly, we need to set the relevant pins of CAN to multiplexed output. Here we need to set PA11 to pull-up input (CAN_RX pin) and PA12 to multiplexed output (CAN_TX pin), and enable the clock of PA port (CAN_TX pin).
②Set CAN working mode and baud rate, etc.
First, set the INRQ bit of the CAN_MCR register to let CAN enter the initialization mode, and then set other related control bits of CAN_MCR. Then set the baud rate and working mode (normal mode/loopback mode) and other information through CAN_BTR. Finally, set INRQ to 0 to exit the initialization mode.
③Set the filter.
In this example, we will use filter group 0 and work in 32-bit identifier mask bit mode. First, set the FINIT bit of CAN_FMR to enter the 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 initialization mode.
CODE:
//can.c
#include "can.h"
#include "led.h"
#include "delay.h"
#include "usart.h"
//CAN initialization
//tsjw: resynchronize jump time unit. Range: CAN_SJW_1tq~ CAN_SJW_4tq
//tbs2: time unit of time period 2. Range: CAN_BS2_1tq~CAN_BS2_8tq;
//tbs1: time unit of time period 1. Range: CAN_BS1_1tq ~CAN_BS1_16tq
//brp: baud rate divider. Range: 1~1024; tq=(brp)*tpclk1
//Baud rate = Fpclk1/((tbs1+1+tbs2+1+1)*brp);
//mode:CAN_Mode_Normal, normal mode;CAN_Mode_LoopBack, loopback mode;
//The clock of Fpclk1 is set to 36M during initialization. If CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_8tq,CAN_BS1_9tq,4,CAN_Mode_LoopBack) is set;
//The baud rate is: 36M/((8+9+1)*4)=500Kbps
//Return value: 0, initialization OK;
//Others, initialization failed;
u8 CAN_Mode_Init(u8 tsjw,u8 tbs2,u8 tbs1,u16 brp,u8 mode)
{
GPIO_InitTypeDef GPIO_InitStructure;
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
#if CAN_RX0_INT_ENABLE
NVIC_InitTypeDef NVIC_InitStructure;
#endif
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //Enable PORTA clock
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); //Enable CAN1 clock
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //Multiplex push-pull
GPIO_Init(GPIOA, &GPIO_InitStructure); //Initialize IO
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //Pull-up input
GPIO_Init(GPIOA, &GPIO_InitStructure); //Initialize IO
//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 by 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: mode: 0, normal mode; 1, loopback mode;
//Set the baud rate
CAN_InitStructure.CAN_SJW=tsjw; //Resynchronization jump width (Tsjw) is tsjw+1 time unit CAN_SJW_1tq CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq
CAN_InitStructure.CAN_BS1=tbs1; //Tbs1=tbs1+1 time unit CAN_BS1_1tq ~CAN_BS1_16tq
CAN_InitStructure.CAN_BS2=tbs2; //Tbs2=tbs2+1 time unit 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
CAN_FilterInitStructure.CAN_FilterNumber=0; //Filter 0
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; //mask bit mode
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; //32 bits wide
CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000; //32-bit ID
CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32-bit 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
#if CAN_RX0_INT_ENABLE
CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE); //FIFO0 message registration interrupt is enabled.
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_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;
}
#if CAN_RX0_INT_ENABLE //Enable RX0 interrupt
//Interrupt service function
void USB_LP_CAN1_RX0_IRQHandler(void)
{
CanRxMsg RxMessage;
int i=0;
CAN_Receive(CAN1, 0, &RxMessage);
for(i=0;i<8;i++)
printf("rxbuf[%d]:%d\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;
u8 Can_Send_Msg(u8* msg,u8 len)
{
u8 mbox;
u16 i=0;
CanTxMsg TxMessage;
TxMessage.StdId=0x12; // Standard identifier
TxMessage.ExtId=0x12; // Set the extended identifier
TxMessage.IDE=CAN_Id_Standard; // Standard frame
TxMessage.RTR=CAN_RTR_Data; // Data frame
TxMessage.DLC=len; // Length of data to be sent
for(i=0;i TxMessage.Data[i]=msg[i]; 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; u8 Can_Receive_Msg(u8 *buf) { u32 i; 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<8;i++) buf[i]=RxMessage.Data[i]; return RxMessage.DLC; } main.c #include "led.h" #include "delay.h" #include "key.h" #include "sys.h" #include "lcd.h" #include "usart.h" #include "can.h" int main(void) { u8 key; u8 i=0,t=0; u8 cnt=0; u8 canbuf[8]; u8 res; u8 mode=CAN_Mode_LoopBack; //CAN working mode; CAN_Mode_Normal (0): normal mode, CAN_Mode_LoopBack (1): loopback mode delay_init(); //delay function initialization NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //Set the interrupt priority group to group 2: 2-bit preemption priority, 2-bit response priority uart_init(115200); //Serial port initialized to 115200 LED_Init(); //Initialize the hardware interface connected to the LED LCD_Init(); //Initialize LCD KEY_Init(); //Key initialization CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_8tq,CAN_BS1_9tq,4,CAN_Mode_LoopBack); //CAN initializes loopback mode, baud rate 500Kbps POINT_COLOR=RED; //Set the font to red LCD_ShowString(60,50,200,16,16,"WarShip STM32"); LCD_ShowString(60,70,200,16,16,"CAN TEST"); LCD_ShowString(60,90,200,16,16,"ATOM@ALIENTEK"); LCD_ShowString(60,110,200,16,16,"2015/1/15"); LCD_ShowString(60,130,200,16,16,"LoopBack Mode"); LCD_ShowString(60,150,200,16,16,"KEY0:Send WK_UP:Mode");//Display prompt information POINT_COLOR=BLUE; //Set the font to blue LCD_ShowString(60,170,200,16,16,"Count:"); //Display the current count value LCD_ShowString(60,190,200,16,16,"Send Data:"); //Prompt the data to be sent LCD_ShowString(60,250,200,16,16,"Receive Data:"); //Prompt received data while(1) { key=KEY_Scan(0); if(key==KEY0_PRES)//KEY0 is pressed, data is sent once { for(i=0;i<8;i++) { canbuf[i]=cnt+i; //Fill the send buffer if(i<4)LCD_ShowxNum(60+i*32,210,canbuf[i],3,16,0X80); //display data else LCD_ShowxNum(60+(i-4)*32,230,canbuf[i],3,16,0X80); //Display data } res=Can_Send_Msg(canbuf,8); //Send 8 bytes if(res)LCD_ShowString(60+80,190,200,16,16,"Failed"); //Prompt that the sending failed else LCD_ShowString(60+80,190,200,16,16,"OK"); //Prompt that the message was sent successfully }else if(key==WKUP_PRES)//WK_UP is pressed to change the working mode of CAN { mode=!mode; CAN_Mode_Init(CAN_SJW_1tq,CAN_BS2_8tq,CAN_BS1_9tq,4,mode); //CAN normal mode initialization, baud rate 500Kbps POINT_COLOR=RED; //Set the font to red if(mode==0)//Normal mode, requires 2 development boards { LCD_ShowString(60,130,200,16,16,"Nnormal Mode "); }else //Loopback mode, one development board can be tested. { LCD_ShowString(60,130,200,16,16,"LoopBack Mode"); } POINT_COLOR=BLUE; //Set the font to blue } key=Can_Receive_Msg(canbuf); if(key) //Received data { LCD_Fill(60,270,130,310,WHITE); //Clear the previous display for(i=0;i { if(i<4)LCD_ShowxNum(60+i*32,270,canbuf[i],3,16,0X80); //display data else LCD_ShowxNum(60+(i-4)*32,290,canbuf[i],3,16,0X80); //display data } } t++; delay_ms(10); if(t==20) { LED0=!LED0; //Prompt that the system is running t=0; cnt++; LCD_ShowxNum(60+48,170,cnt,3,16,0X80); //Display data } } }
Previous article:STM32 Core Coupled Memory (CCM)
Next article:Embedded Learning--step4 STM32F4 bus architecture
- Popular Resources
- Popular amplifiers
- Learn ARM development(16)
- Learn ARM development(17)
- Learn ARM development(18)
- Embedded system debugging simulation tool
- A small question that has been bothering me recently has finally been solved~~
- Learn ARM development (1)
- Learn ARM development (2)
- Learn ARM development (4)
- Learn ARM development (6)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Analysis of the application of several common contact parts in high-voltage connectors of new energy vehicles
- Wiring harness durability test and contact voltage drop test method
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- From probes to power supplies, Tektronix is leading the way in comprehensive innovation in power electronics testing
- Sn-doped CuO nanostructure-based ethanol gas sensor for real-time drunk driving detection in vehicles
- Design considerations for automotive battery wiring harness
- Do you know all the various motors commonly used in automotive electronics?
- What are the functions of the Internet of Vehicles? What are the uses and benefits of the Internet of Vehicles?
- Power Inverter - A critical safety system for electric vehicles
- Analysis of the information security mechanism of AUTOSAR, the automotive embedded software framework
- Broadcom Wi-Fi 6E technology makes the Galaxy S21 Ultra shine
- Simulation Problems with Strobe Display
- dsp28335 phase shift full bridge easy to understand program
- Optimizing DSP Power Budget by Adjusting Voltage Regulators
- [Erha Image Recognition Artificial Intelligence Vision Sensor] Review 3: Firmware Upgrade via HUSKYLENS Uploader
- [Portable programmable meter] Ready to start soldering the board
- TMS320VC5509A development board hardware LED indicators and buttons
- EEWORLD University ---- Wide input DC-DC converters that meet low quiescent current requirements in industrial applications
- Is Python worth learning? Is it easy to learn?
- TMP112 read timing is incorrect, can produce results, 9 more clocks