CAN communication debugging under STM32

CAN communication debugging under STM32

 

CAN is an abbreviation of Controller Area Network (hereinafter referred to as CAN), is an ISO international standard serial communication protocol. In the current automotive industry, for the sake of safety, comfort, convenience, low pollution, low-cost requirements, various electronic control system is developed it. Since the data types used for communication between these systems and the reliability requirements vary, the number of bus configuration where a plurality of lot, the wire harness also increases. To meet the need to "reduce the number of harness," "through multiple LAN, a large number of high-speed data communications," the 1986 German electrical supplier Bosch has developed a car-oriented CAN communication protocol. Thereafter, CAN was standardized by ISO11898 and ISO11519, now in Europe is a standard protocol for automotive networks.

Now, CAN high performance and reliability have been recognized, widely used in industrial automation, marine, medical equipment, industrial equipment and so on. Fieldbus is today one of the hot field of automation technology, computer local area network known as the field of automation. It appears as a distributed control system in real time between the nodes, reliable data communication provides a strong support.

The potential difference between two CAN controller determines the bus line level. Bus level is divided into dominant level and recessive level, it must be one. The sender is changed by bus level, it sends the message to the recipient.

STM32 comes with a bxCAN, namely, the basic extended CAN. It supports CAN protocol 2.0A and 2.0B. Its design goal is to minimize the load on the CPU to efficiently process large number of packets received. It also supports the priority requirements (software configurable priority properties) packet sent. For safety critical applications, bxCAN provide all the support required for time-triggered communication mode hardware capabilities.

The main features of the STM32 bxCAN are:

l support CAN protocol 2.0A and 2.0B active mode

l baud rates up to 1Mbps

l supports time-triggered communication

l having three transmission mailboxes

l has a depth of three two receive FIFO

l variable filter set (up to 28)

In the STM32 Connectivity products, with two CAN controllers, and STM32F103ZET6 belong enhanced, not interconnected type, only one CAN controller

STM32 identifier is a complex filter stuff, its presence reduces the overhead of CPU processing CAN communication. STM32 set up to filter 28 (network type), but only 14 STM32F103ZET6 (Enhanced), x each filter bank 32 is composed of two registers, CAN_FxR1 and CAN_FxR2 composition.

STM32 bit width of each filter group is independently configurable to meet different application requirements. According to different bit-widths, each filter set can be provided:

CAN configuration initialization step, firmware and library functions defined in the document profile associated CAN stm32f10x_can.c stm32f10x_can.h file and the header file.

1) configured the associated pin multiplexing function, to enable clock CAN.

We use the CAN, the first step is to be able to clock a CAN. Second, we must set the multiplexed CAN associated output pin, where we need to pull PA11 set input (the CAN_RX pin) is multiplexed with an output of PA12 (the CAN_TX pin), a clock enable port PA. CAN1 clock enable function is:

RCC_APB1PeriphClockCmd (RCC_APB1Periph_CAN1, ENABLE); // enable clock CAN1

2) set the baud rate and CAN operation mode.

This first step by setting INRQ bit CAN_MCR register, so CAN enter initialization mode, then set the other control bits CAN_MCR. Then set the baud rate and the operating mode (normal mode / loop back mode) information CAN_BTR. INRQ last set to 0, the initialization mode is exited.

In a library function, a function CAN_Init () to initialize the operation mode and the baud rate of CAN, CAN_Init () function in the body, prior to initialization, the register is set to 1 INRQ CAN_MCR allowed initialization mode is entered, then initialization after CAN_MCR CRN_BTR registers and registers of register sets CAN_MCR 0 INRQ allowed to exit the initialization mode. So we call this function before and after no further initialization mode setting. Let's look at the definition CAN_Init () function:

uint8_t CAN_Init(CAN_TypeDef* CANx, CAN_InitTypeDef* CAN_InitStruct);

The first parameter is the CAN labels, here we have only one chip CAN, it is CAN1.

The second parameter is initialized CAN structure pointer, type of structure is CAN_InitTypeDef, let's look at the definition of this structure:

typedef struct

{

uint16_t CAN_Prescaler;

uint8_t CAN_Mode;

uint8_t CAN_SJW;

uint8_t CAN_BS1;

uint8_t CAN_BS2;

FunctionalState CAN_TTCM;

FunctionalState CAN_ABOM;

FunctionalState CAN_AWUM;

FunctionalState CAN_NART;

FunctionalState CAN_RFLM;

FunctionalState CAN_TXFP;

} CAN_InitTypeDef;

This structure looks more member variables, in fact, parameters can be divided into two categories. The foregoing five parameters are used to set the CAN_BTR registers, used to set the baud rate mode and associated parameters, parameter setting mode is CAN_Mode, used in our experiments CAN_Mode_LoopBack loopback mode and a normal mode CAN_Mode_Normal, you can also select a silent mode, and silent loopback test mode. Other parameters related to the baud rate setting CAN_Prescaler, CAN_SJW, CAN_BS1 are used to set the baud rate and CAN_BS2 divider resynchronization hop count period and the time width of 1 unit and the time period occupied by 2. 6 back member to set the variable register CAN_MCR, CAN communication is provided associated control bits.

Initialization Examples are:

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

CAN_InitStructure.CAN_ABOM = DISABLE; // automatic offline management software

CAN_InitStructure.CAN_AWUM = DISABLE; // wake-sleep mode via software

CAN_InitStructure.CAN_NART = ENABLE; // prohibit automatic transmission packets

CAN_InitStructure.CAN_RFLM = DISABLE; // message is not locked, the new over the old one

CAN_InitStructure.CAN_TXFP = DISABLE; // priority is determined by the packet identifier

CAN_InitStructure.CAN_Mode = CAN_Mode_LoopBack; // Set Mode: 1, loopback mode;

// set the baud rate

CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; // skip width resynchronization time units

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

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

CAN_InitStructure.CAN_Prescaler = 5; // division factor (Fdiv)

CAN_Init (CAN1, & CAN_InitStructure); // initialize CAN

3) setting of the filter.

We will use a filter bank 0, and 32-bit identifier in the working mask bit pattern. FINIT CAN_FMR first set of bits, so that the filter group working in the initialization mode, and then set the operating mode of the filter bank 0 and the identifier ID and the mask bits. Finally activate the filter and exit filter initialization mode.

In a library function, a function CAN_FilterInit () to initialize CAN filter parameters, CAN_Init () function in the body, prior to initialization, sets INRQ CAN_FMR INIT register is allowed to enter the initialization mode, then initialize CAN Filter after RELATED registers of register sets CAN_FMR 0 FINIT is allowed to exit the initialization mode. So we call this function before and after no further initialization mode setting. Let's look at the definition CAN_FilterInit () function:

void CAN_FilterInit(CAN_FilterInitTypeDef* CAN_FilterInitStruct);

This function is only one inlet CAN filter initialization parameters structure pointer, the structure type is CAN_FilterInitTypeDef, let's look at the type definition:

typedef struct

{

uint16_t CAN_FilterIdHigh;

uint16_t CAN_FilterIdLow;

uint16_t CAN_FilterMaskIdHigh;

uint16_t CAN_FilterMaskIdLow;

uint16_t CAN_FilterFIFOAssignment;

uint8_t CAN_FilterNumber;

uint8_t CAN_FilterMode;

uint8_t CAN_FilterScale;

FunctionalState CAN_FilterActivation;

} CAN_FilterInitTypeDef;

A total of nine structural body member variable, 1st to 4th is used to set a filter 32 and a 32-bit mask id id, are combined by two 16-bit

CAN_FilterFIFOAssignment fifth member variable to set the association FIFO and filters, our experiments are related to FIFO0 filter 0, the value CAN_Filter_FIFO0.

A sixth member provided to initialize variables CAN_FilterNumber filter group, in the range of 0 to 13.

FilterMode seventh mode for setting a member variable filter set, a value of the identifier and the identifier list mode CAN_FilterMode_IdList mask bit pattern CAN_FilterMode_IdMask.

FilterScale eighth member variable to set the bit width of the filter 2 16-bit or a 32-bit CAN_FilterScale_16bit CAN_FilterScale_32bit.

9th member variables CAN_FilterActivation very clear, and to activate the filter.

Reference Example Filter Initialization Code:

CAN_FilterInitStructure.CAN_FilterNumber = 0; // 0 Filter

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 the filter 0

CAN_FilterInit (& CAN_FilterInitStructure); // initialize filter

So far, CAN can begin working. If you use interrupts, you also need to interrupt the relevant configuration

4) sends an acceptance message

After initializing the CAN and the filter parameters, the next step is to send and receive messages. Providing the library function and a function of transmitting accept message. Function message is sent:

uint8_t CAN_Transmit(CAN_TypeDef* CANx, CanTxMsg* TxMessage);

This function is better understood, the first parameter is CAN numbers, we use CAN1. The second parameter is related to the message structure CanTxMsg pointer type member variable CanTxMsg structure to set the standard identifier, extension identifier, message type and frame length information.

Function takes the message is:

void CAN_Receive(CAN_TypeDef* CANx, uint8_t FIFONumber, CanRxMsg* RxMessage);

The first two parameters are better appreciated, CAN numerals and FIFO numbers. RxMessage second parameter is used to store received message information.

Structures and structure CanTxMsg CanRxMsg close, respectively, to define and describe accept message to send messages,

5) CAN status acquisition

Sending status messages for the CAN, the like number of messages pending transmission state information, library functions provides functions, including in CAN_TransmitStatus () function, CAN_MessagePending () function, CAN_GetFlagStatus () function, etc., we can You need to call.

Click (here) folded or unfolded

// CAN initialization

// tsjw: resynchronization means jump time range: 1 ~ 3; CAN_SJW_1tq CAN_SJW_2tq CAN_SJW_3tq CAN_SJW_4tq.

// tbs2: period means the time range of 2: 1 to 8;.

. // tbs1: unit period of time a range of 1: 1 ~ 16; CAN_BS1_1tq ~ CAN_BS1_16tq

// brp: baud rate prescaler range: 1 to 1024; (add 1 to the actual, i.e. 1 ~ 1024) tq = (brp) * tpclk1

// Note that any one of the above parameters can not be set to 0, otherwise it will be chaos.

// baud rate = Fpclk1 / ((tsjw + tbs1 + tbs2) * brp);

// mode: 0, normal mode; 1, loopback mode;

// Fpclk1 36M clock set at initialization, if provided CAN_Normal_Init (1,8,7,5,1);

// the baud rate: 36M / ((1 + 8 + 7) * 5) = 450Kbps

// Return value: 0, the OK initialization;

// other 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 clock PORTA

 

RCC_APB1PeriphClockCmd (RCC_APB1Periph_CAN1, ENABLE); // enable clock CAN1

 

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; // multiplexing pull

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; // // management software automatically offline

CAN_InitStructure.CAN_AWUM = DISABLE; // wake-sleep mode via software (Clear CAN-> SLEEP bit in MCR) //

CAN_InitStructure.CAN_NART = ENABLE; // // prohibit messages automatically sent

CAN_InitStructure.CAN_RFLM = DISABLE; // message is not locked, the new over the old one //

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

CAN_InitStructure.CAN_Mode = mode; // set mode: 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; // division factor (Fdiv) of brp + 1 //

CAN_Init (CAN1, & CAN_InitStructure); // initialize CAN1

 

CAN_FilterInitStructure.CAN_FilterNumber = 0; // 0 Filter

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; // 0 filter associated FIFO0

CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; // activate the filter 0

 

CAN_FilterInit (& CAN_FilterInitStructure); // initialize filter

#if CAN_RX0_INT_ENABLE

CAN_ITConfig (CAN1, CAN_IT_FMP0, ENABLE); // FIFO0 message interrupt enable register.

NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // master priority 1

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 0 times priority

NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

NVIC_Init(&NVIC_InitStructure);

#endif

return 0;

}

 

#if CAN_RX0_INT_ENABLE // enable interrupt RX0

// interrupt service routine

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, a data frame)

// len: data length (maximum of 8)

// msg: data pointer, a maximum of 8 bytes.

// Return: 0, successfully;

// other, failed;

u8 Can_Send_Msg(u8* msg,u8 len)

{

u8 mbox;

u16 i=0;

CanTxMsg TxMessage;

TxMessage.StdId = 0x12; // standard identifier 0

TxMessage.ExtId = 0x12; // set identifier extension (29)

TxMessage.IDE = 0; // Extended Identifier

TxMessage.RTR = 0; // message type is a data frame, an 8

TxMessage.DLC = len; // send two information

for(i=0;i<len;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 transmission end

if(i>=0XFFF)return 1;

return 0;

 

}

 

 

// can port to receive data query

// buf: data buffer;

// Return Value: 0, no data is received;

// other, the received data length;

u8 Can_Receive_Msg(u8 *buf)

{

u32 i;

CanRxMsg RxMessage;

if (CAN_MessagePending (CAN1, CAN_FIFO0) == 0) return 0; // no data is received, exit

CAN_Receive (CAN1, CAN_FIFO0, & RxMessage); // read data

for(i=0;i<8;i++)

buf[i]=RxMessage.Data[i];

return RxMessage.DLC;

}

Released nine original articles · won praise 0 · Views 176

Guess you like

Origin blog.csdn.net/Wang_XB_3434/article/details/104355834