1. Turn on the STM32 CAN system working clock
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA
| RCC_APB2Periph_AFIO,
ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1,
ENABLE);
2. Open system interruption, select according to actual situation
NVIC_InitStructure.NVIC_IRQChannel
=
USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority
=
0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority
=
0;
NVIC_InitStructure.NVIC_IRQChannelCmd
=
ENABLE;
NVIC_Init(&NVIC_InitStructure);
// NVIC_InitStructure.NVIC_IRQChannel
=
CAN1_RX1_IRQn;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority
=
5;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority
=
0;
// NVIC_InitStructure.NVIC_IRQChannelCmd
=
ENABLE;
// NVIC_Init(&NVIC_InitStructure);
//NVIC_InitStructure.NVIC_IRQChannel
=
CAN1_SCE_IRQn;
//NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority
=
3;
//NVIC_InitStructure.NVIC_IRQChannelSubPriority
=
0;
//NVIC_InitStructure.NVIC_IRQChannelCmd
=
ENABLE;
//NVIC_Init(&NVIC_InitStructure);
// NVIC_InitStructure.NVIC_IRQChannel
=
USB_HP_CAN1_TX_IRQn;
// NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority
=
4;
// NVIC_InitStructure.NVIC_IRQChannelSubPriority
=
0;
// NVIC_InitStructure.NVIC_IRQChannelCmd
=
ENABLE;
// NVIC_Init(&NVIC_InitStructure);
3. Port Configuration
//初始化MCU_CAN_RXD---PA11
GPIO_InitStructure.GPIO_Pin
=
GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode
= GPIO_Mode_IPU;
GPIO_Init(GPIOA,
&GPIO_InitStructure);
//初始化MCU_CAN_TXD---PA12
GPIO_InitStructure.GPIO_Pin
=
GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode
=
GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed
= GPIO_Speed_50MHz;
GPIO_Init(GPIOA,
&GPIO_InitStructure);
4. CAN initialization
void
CAN_Configuration(void)
{
CAN_InitTypeDef CAN_InitStructure;
CAN_FilterInitTypeDef CAN_FilterInitStructure;
CAN_DeInit(CAN1);
CAN_StructInit(&CAN_InitStructure);
CAN_InitStructure.CAN_TTCM
= DISABLE;
CAN_InitStructure.CAN_ABOM
= DISABLE;
CAN_InitStructure.CAN_AWUM
= DISABLE;
CAN_InitStructure.CAN_NART
= ENABLE;
CAN_InitStructure.CAN_RFLM =
DISABLE;
CAN_InitStructure.CAN_TXFP =
ENABLE;
//CAN_InitStructure.CAN_Mode
=
CAN_Mode_LoopBack;
CAN_InitStructure.CAN_Mode
=
CAN_Mode_Normal;
CAN_InitStructure.CAN_SJW
=
CAN_SJW_1tq;
CAN_InitStructure.CAN_BS1
=
CAN_BS1_9tq;
CAN_InitStructure.CAN_BS2
=
CAN_BS2_8tq;
CAN_InitStructure.CAN_Prescaler
=
200;
//Here Tseg1+1 = CAN_BS1_8tp
if
(CAN_Init(CAN1,&CAN_InitStructure) == CANINITFAILED)
{
}
CAN_FilterInitStructure.CAN_FilterNumber=0;
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=0;
CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
CAN_FilterInitStructure.CAN_FilterNumber=1;
CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;
CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;
CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;
CAN_FilterInitStructure.CAN_FilterIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;
CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;
CAN_FilterInitStructure.CAN_FilterFIFOAssignment=1;
//CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
CAN_FilterInit(&CAN_FilterInitStructure);
CAN_ITConfig(CAN1,CAN_IT_FMP0,
ENABLE);
CAN_ITConfig(CAN2,
CAN_IT_TME,
ENABLE); //打开发送中断
CAN_ITConfig(CAN2,
CAN_IT_FMP1, ENABLE); //打开接收中断
CAN_ITConfig(CAN2,
CAN_IT_EWG|CAN_IT_EPV|CAN_IT_BOF|CAN_IT_LEC|CAN_IT_ERR,
ENABLE);//打开错误中断
//CAN_ITConfig(CAN1,CAN_IT_FMP0,
ENABLE); //FIFO0
消息挂号中断屏蔽
//CAN_ITConfig(CAN1,CAN_IT_TME,
ENABLE); //发送邮箱空中断屏蔽
//CAN_ITConfig(CAN1,CAN_IT_BOF,
ENABLE); //离线中断允许
}
5. Send data function
void CanWriteData(uint16_t CanAddress,uint8_t SendData[8])
{
CanTxMsg TxMessage; //Define data structure type variable
u8 TransmitMailbox = 0;
u16 i = 0;
TxMessage.StdId = CanAddress;
TxMessage.ExtId=0x00; //tempId is the address of the receiving board, which needs to be shifted left by 13 bits during application
TxMessage.IDE=CAN_ID_STD; //Use standard id
TxMessage.RTR=CAN_RTR_DATA; //Send data frame
TxMessage.DLC= 8; //Set the length of the data to be sent
TxMessage.Data[0] = SendData[0]; //Assign value to be sent
TxMessage.Data[1] = SendData[1]; //Assign value to be sent
TxMessage.Data[2] = SendData[2]; //Assign value to be sent
TxMessage.Data[3] = SendData[3];//Assign value to be sentTxMessage.Data
[4] = SendData[4];//Assign value to be
sentTxMessage.Data[5] = SendData[5];//Assign value to be
sentTxMessage.Data[6] = SendData[6];//Assign value to be
sentTxMessage.Data[7] = SendData[7];//Assign value to be
sentTransmitMailbox = CAN_Transmit(CAN1,&TxMessage);//Start sending datai
= 0;
//Confirm whether the transmission is successful by checking the CANTXOK bitwhile
((CAN_TransmitStatus(CAN1,TransmitMailbox) != CANTXOK) && (i != 0xFF))
{
i++;
}
i = 0;
while((CAN_MessagePending(CAN1,CAN_FIFO0) < 1) && (i != 0xFF)) //Return whether the number of pending messages is 0
{
i++;
}
}
void
SEND_CAN_TQ_COMMAND(u8 device_add,u8 GFB_flag,u8 TQ_A_flag,u8
TQ_B_flag)
{
u16
Send_add,num;
u8 Send_Data[8];
if(device_add
==
0)
{
switch(GFB_flag)
{
case
90:
if(TQ_A_flag
==
0x22)
{
TQ_CON_A
=
1;
TQ_CON_B
=
1;
TQ_CON_C
=
1;
JDQ_A_Flag
=
0x07;
Net_Node_CapA[0]
=
Net_Node_CapA[0]|0x07;
}
else
if(TQ_A_flag ==
0x11)
{
TQ_CON_A
=
0;
TQ_CON_B
=
0;
TQ_CON_C
=
0;
JDQ_A_Flag
=
0x00;
Net_Node_CapA[0]
=
Net_Node_CapA[0]&0x00;
}
if(TQ_B_flag
==
0x22)
{
TQ_CON_2A
=
1;
TQ_CON_2B
=
1;
TQ_CON_2C
=
1;
JDQ_B_Flag
=
0x07;
Net_Node_CapB[0]
=
Net_Node_CapB[0]|0x07;
}
else
if(TQ_B_flag ==
0x11)
{
TQ_CON_2A
=
0;
TQ_CON_2B
=
0;
TQ_CON_2C
=
0;
JDQ_B_Flag
=
0x00;
Net_Node_CapB[0]
=
Net_Node_CapB[0]&0x00;
}
break;
case
91:
if(TQ_A_flag
==
0x22)
{
TQ_CON_A
=
1;
JDQ_A_Flag
|=
0x04;
Net_Node_CapA[0]
=
Net_Node_CapA[0]|0x04;
}
else
if(TQ_A_flag ==
0x11)
{
TQ_CON_A
=
0;
JDQ_A_Flag
&=
0xFB;
Net_Node_CapA[0]
=
Net_Node_CapA[0]&0xFB;
}
break;
case
92:
if(TQ_A_flag
==
0x22)
{
TQ_CON_A
=
1;
JDQ_A_Flag
|=
0x02;
Net_Node_CapA[0]
=
Net_Node_CapA[0]|0x02;
}
else
if(TQ_A_flag ==
0x11)
{
TQ_CON_A
=
0;
JDQ_A_Flag
&=
0xFD;
Net_Node_CapA[0]
=
Net_Node_CapA[0]&0xFD;
}
break;
case
93:
if(TQ_A_flag
==
0x22)
{
TQ_CON_A
=
1;
JDQ_A_Flag
|=
0x01;
Net_Node_CapA[0]
=
Net_Node_CapA[0]|0x01;
}
else
if(TQ_A_flag ==
0x11)
{
TQ_CON_A
=
0;
JDQ_A_Flag
&=
0xFE;
Net_Node_CapA[0]
=
Net_Node_CapA[0]&0xFE;
}
break;
}
}
else
{
Send_add
= 0x100 +
device_add;
Send_Data[0]
=
0x55;
Send_Data[1]
=
0x01;
Send_Data[2]
=
device_add; //从机地址
Send_Data[3]
=
GFB_flag; //共补投入控制指令
Send_Data[4]
=
TQ_A_flag;
Send_Data[5]
=
TQ_B_flag;
num
= Send_Data[1] + Send_Data[2] + Send_Data[3] + Send_Data[4] +
Send_Data[5];
Send_Data[6]
=
num&0xFF;
Send_Data[7]
=
0xAA;
CanWriteData(Send_add,Send_Data);
switch(GFB_flag)
{
case
90:
if(TQ_A_flag
==
0x22)
{
Net_Node_CapA[device_add]
=
Net_Node_CapA[device_add]|0x07;
}
else
if(TQ_A_flag ==
0x11)
{
Net_Node_CapA[device_add]
=
Net_Node_CapA[device_add]&0x00;
}
if(TQ_B_flag
==
0x22)
{
Net_Node_CapB[device_add]
=
Net_Node_CapB[device_add]|0x07;
}
else
if(TQ_B_flag ==
0x11)
{
Net_Node_CapB[device_add]
=
Net_Node_CapB[device_add]&0x00;
}
break;
case
91:
if(TQ_A_flag
==
0x22)
{
Net_Node_CapA[device_add]
=
Net_Node_CapA[device_add]|0x04;
}
else
if(TQ_A_flag ==
0x11)
{
Net_Node_CapA[device_add]
=
Net_Node_CapA[device_add]&0xFB;
}
break;
case
92:
if(TQ_A_flag
==
0x22)
{
Net_Node_CapA[device_add]
=
Net_Node_CapA[device_add]|0x02;
}
else
if(TQ_A_flag ==
0x11)
{
Net_Node_CapA[device_add]
=
Net_Node_CapA[device_add]&0xFD;
}
break;
case
93:
if(TQ_A_flag
==
0x22)
{
Net_Node_CapA[device_add]
=
Net_Node_CapA[device_add]|0x01;
}
else
if(TQ_A_flag ==
0x11)
{
Net_Node_CapA[device_add]
=
Net_Node_CapA[device_add]&0xFE;
}
break;
}
}
}
6. Interrupt receiving function
void USB_LP_CAN1_RX0_IRQHandler(void) //CAN interrupt function
{
CanRxMsg RxMessage;
u8 i;
RxMessage.StdId=0x00; //Initialize the receive data pool
RxMessage.ExtId=0x00;
RxMessage.IDE=0;
RxMessage.DLC=0;
RxMessage.FMI =0;
RxMessage.Data[0]=0x00;
RxMessage.Data[1]=0x00;
RxMessage.Data[2]=0x00;
RxMessage.Data[3]=0x00;
RxMessage.Data[4]=0x00
; Data[5]=0x00;
RxMessage.Data[6]=0x00;
RxMessage.Data[7]=0x00;
//while(CAN_IT_FF0==0);
for(i=0;i<8;i++)
{
if(Can_Receive_Flag[i] == 0)
{
if(CAN_IT_FF0 > 0)
{
CAN_Receive(CAN1, CAN_FIFO0, &RxMessage); //Receive messages from CAN1 port buffer FIFO 0 to RxMessage
CAN_Receive_data[i][0] = ( RxMessage.StdId>>8)&0xff;
CAN_Receive_data[i][1] = (RxMessage.StdId)&0xff;
CAN_Receive_data[i][2] = RxMessage.Data[0];
CAN_Receive_data[i][3] = RxMessage.Data [1];
CAN_Receive_data[i][4] = RxMessage.Data[2];
CAN_Receive_data[i][5] = RxMessage.Data[3];
CAN_Receive_data[i][6] = RxMessage.Data[4];
CAN_Receive_data [i][7] = RxMessage.Data[5];
CAN_Receive_data[i][8] = RxMessage.Data[6];
CAN_Receive_data[i][9] = RxMessage.Data[7];
CAN_Receive_data[i][10] = 0xff;
Can_Receive_Flag[i ] = 1;
break;
}
if(CAN_IT_FF1 > 0)
{
CAN_Receive(CAN1, CAN_FIFO1, &RxMessage); //Receive messages from CAN1 port buffer FIFO 0 to RxMessage
CAN_Receive_data[i][0] = (RxMessage.StdId> >8)&0xff;
CAN_Receive_data[i][1] = (RxMessage.StdId)&0xff;
CAN_Receive_data[i][2] = RxMessage.Data[0];
CAN_Receive_data[i][3] = RxMessage.Data[1];
CAN_Receive_data[i][4] = RxMessage.Data[2];
CAN_Receive_data[i][5] = RxMessage.Data[3];
CAN_Receive_data[i][6] = RxMessage.Data[4];
CAN_Receive_data[i][7] = RxMessage.Data[ 5];
CAN_Receive_data[i][8] = RxMessage.Data[6];
CAN_Receive_data[i][9] = RxMessage.Data[7];
CAN_Receive_data[i][10] = 0xff;
Can_Receive_Flag[i] = 1;
break;
}
}
}
CAN_ClearITPendingBit(CAN1,
CAN_IT_FMP0);
}
附录:
The receiving and sending functions are test program codes in the current project and can be adjusted according to actual conditions.
Previous article:STM32 small package PD0, PD1 have no external interrupt function
Next article:STM32 CAN filtering principle
Recommended ReadingLatest update time:2024-11-17 09:57
- 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
- New breakthrough! Ultra-fast memory accelerates Intel Xeon 6-core processors
- New breakthrough! Ultra-fast memory accelerates Intel Xeon 6-core processors
- Consolidating vRAN sites onto a single server helps operators reduce total cost of ownership
- Consolidating vRAN sites onto a single server helps operators reduce total cost of ownership
- 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!
- Kalman filter and UKF
- Unboxing and testing the SparkRoad FPGA development board gives me a bad feeling
- Hardware Design for Analog Isolation
- LED Control
- I am a great detective: Finding the lost TI power supply puzzle (Reply with a screenshot of this post)
- Set-top box chip STI8036, low ripple, low noise
- Overvoltage and overcurrent protection circuit of power supply
- Design of high-speed communication between digital signal processor and PC
- msp430f149 communicates with mobile phone via Bluetooth HC-05
- Inventory of brain-burning remedial measures after PCB back drilling leakage