STM32 CAN bus description

Publisher:疯狂小马Latest update time:2018-06-07 Source: eefocusKeywords:STM32 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Introduction:

  1. 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.

  2. 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.

  3. CAN has high reliability and is widely used in automotive electronics, industrial automation, ships, medical equipment, industrial equipment, etc.

Features:

  1. 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.

  2. 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.

  3. Fast speed and long distance. Up to 1Mbps (distance <40M), up to 10KM (rate <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 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.

  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. 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 
Write the picture description here

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 typeFrame function
Data FrameFrame used for transmitting data from the sending unit to the receiving unit
Remote Control FrameFrame used by a receiving unit to request data from a sending unit with the same ID
Error frameA frame used to notify other units of an error when an error is detected.
Overload FrameFrame used by the receiving unit to notify that it is not ready to receive.
Interval FrameFrame 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:

  1. Support CAN protocol 2.0A and 2.0B active mode

  2. Baud rate up to 1Mbps

  3. Support time-triggered communication

  4. Has 3 sending mailboxes

  5. 2 receive FIFOs with 3 levels of depth

  6. 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. 
Write the picture description here

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

        }          

    }

}


Keywords:STM32 Reference address:STM32 CAN bus description

Previous article:STM32 Core Coupled Memory (CCM)
Next article:Embedded Learning--step4 STM32F4 bus architecture

Latest Microcontroller Articles
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号