STM32H750XB_RT-THREAD/40-CAN通信实验/CAN—双机通讯/User/can/bsp_can.c

200 lines
5.5 KiB
C
Raw Normal View History

2025-07-21 06:34:29 +00:00
/**
******************************************************************************
* @file bsp_can.c
* @author fire
* @version V1.0
* @date 2016-xx-xx
* @brief can<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ػ<EFBFBD>ģʽ<EFBFBD><EFBFBD>
******************************************************************************
* @attention
*
* ʵ<EFBFBD><EFBFBD>ƽ̨:Ұ<EFBFBD><EFBFBD>STM32 H743<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD>̳ :http://www.firebbs.cn
* <EFBFBD>Ա<EFBFBD> :http://firestm32.taobao.com
*
******************************************************************************
*/
#include "./can/bsp_can.h"
FDCAN_HandleTypeDef hfdcan;
uint8_t TxData0[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
/*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>CAN_GPIO_Config
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD>CAN<EFBFBD><EFBFBD>GPIO <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> : <EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
static void CAN_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit;
/* ʹ<><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1> */
CAN_TX_GPIO_CLK_ENABLE();
CAN_RX_GPIO_CLK_ENABLE();
/* Select PLL1Q as source of FDCANx clock */
RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_FDCAN;
RCC_PeriphClkInit.FdcanClockSelection = RCC_FDCANCLKSOURCE_PLL;
HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);
/* <20><><EFBFBD><EFBFBD>CAN<41><4E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
GPIO_InitStructure.Pin = CAN_TX_PIN;
GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStructure.Pull = GPIO_PULLUP;
GPIO_InitStructure.Alternate = GPIO_AF9_FDCAN1;
HAL_GPIO_Init(CAN_TX_GPIO_PORT, &GPIO_InitStructure);
/* <20><><EFBFBD><EFBFBD>CAN<41><4E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
GPIO_InitStructure.Pin = CAN_RX_PIN ;
HAL_GPIO_Init(CAN_RX_GPIO_PORT, &GPIO_InitStructure);
}
/*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>CAN_NVIC_Config
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD>CAN<EFBFBD><EFBFBD>NVIC <EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<EFBFBD><EFBFBD>1<EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><EFBFBD>0<EFBFBD><EFBFBD>0<EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> : <EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
static void CAN_NVIC_Config(void)
{
/* NVIC for FDCANx */
HAL_NVIC_SetPriority(FDCANx_IT0_IRQn, 0, 1);
HAL_NVIC_SetPriority(FDCANx_IT1_IRQn, 0, 1);
HAL_NVIC_SetPriority(FDCAN_CAL_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(FDCANx_IT0_IRQn);
HAL_NVIC_EnableIRQ(FDCANx_IT1_IRQn);
HAL_NVIC_EnableIRQ(FDCAN_CAL_IRQn);
}
/*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>CAN_Mode_Config
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD>CAN<EFBFBD><EFBFBD>ģʽ <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> : <EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
static void CAN_Mode_Config(void)
{
/************************CANͨ<4E>Ų<EFBFBD><C5B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>**********************************/
/* ʹ<><CAB9>CANʱ<4E><CAB1> */
CAN_CLK_ENABLE();
/* <20><>ʼ<EFBFBD><CABC>FDCAN<41><4E><EFBFBD><EFBFBD><E8B9A4><EFBFBD>ڻ<EFBFBD><DABB><EFBFBD>ģʽ */
hfdcan.Instance = CANx;
hfdcan.Init.FrameFormat = FDCAN_FRAME_CLASSIC;
hfdcan.Init.Mode = FDCAN_MODE_NORMAL;
hfdcan.Init.AutoRetransmission = ENABLE;
hfdcan.Init.TransmitPause = DISABLE;
hfdcan.Init.ProtocolException = ENABLE;
/* λʱ<CEBB><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>:
************************
λʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | Nominal | Data
----------------------|--------------|----------------
CAN<EFBFBD><EFBFBD>ϵͳ<EFBFBD>ں<EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | 40 MHz | 40 MHz
ʱ<EFBFBD><EFBFBD><EFBFBD> (tq) | 25 ns | 25 ns
ͬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | 1 tq | 1 tq
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> | 23 tq | 23 tq
<EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD>1 | 8 tq | 8 tq
<EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD>2 | 8 tq | 8 tq
ͬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | 8 tq | 8 tq
λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | 40 tq = 1 us | 40 tq = 1 us
λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> | 1 MBit/s | 1 MBit/s
*/
hfdcan.Init.NominalPrescaler = 1; /* tq = NominalPrescaler x (1/40MHz) */
hfdcan.Init.NominalSyncJumpWidth = 0x8;
hfdcan.Init.NominalTimeSeg1 = 0x1F; /* NominalTimeSeg1 = <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> + <20><>λ<EFBFBD><CEBB>1 */
hfdcan.Init.NominalTimeSeg2 = 8;
hfdcan.Init.MessageRAMOffset = 0;
hfdcan.Init.StdFiltersNbr = 1;
hfdcan.Init.ExtFiltersNbr = 1;
hfdcan.Init.RxFifo0ElmtsNbr = 1;
hfdcan.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;
hfdcan.Init.RxFifo1ElmtsNbr = 2;
hfdcan.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8;
hfdcan.Init.RxBuffersNbr = 1;
hfdcan.Init.RxBufferSize = FDCAN_DATA_BYTES_8;
hfdcan.Init.TxEventsNbr = 2;
hfdcan.Init.TxBuffersNbr = 1;
hfdcan.Init.TxFifoQueueElmtsNbr = 2;
hfdcan.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
hfdcan.Init.TxElmtSize = FDCAN_DATA_BYTES_8;
HAL_FDCAN_Init(&hfdcan);
/* <20><><EFBFBD><EFBFBD>FDCANģ<4E><C4A3> */
HAL_FDCAN_Start(&hfdcan);
}
/*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>CAN_Filter_Config
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD>CAN<EFBFBD>Ĺ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> : <EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
static void CAN_Filter_Config(void)
{
FDCAN_FilterTypeDef sFilterConfig;
/* <20><><EFBFBD>ñ<EFBFBD>׼ID<49><44><EFBFBD>չ<EFBFBD><D5B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Rx<52><78><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0 */
sFilterConfig.IdType = FDCAN_EXTENDED_ID;
sFilterConfig.FilterIndex = 0;
sFilterConfig.FilterType = FDCAN_FILTER_DUAL;
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXBUFFER;
sFilterConfig.FilterID1 = 0x1314;
sFilterConfig.FilterID2 = 0x2568;
sFilterConfig.RxBufferIndex = 0;
HAL_FDCAN_ConfigFilter(&hfdcan, &sFilterConfig);
}
/*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>CAN_Config
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>CAN<EFBFBD>Ĺ<EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> : <EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>ⲿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void CAN_Config(void)
{
CAN_GPIO_Config();
CAN_NVIC_Config();
CAN_Mode_Config();
CAN_Filter_Config();
}
/*
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>CAN_SetMsg
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD>CANͨ<EFBFBD>ű<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>,<EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ0-7<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݰ<EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͱ<EFBFBD><EFBFBD>Ľ<EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> : <EFBFBD><EFBFBD>
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD>ⲿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
void CAN_SetMsg(void)
{
FDCAN_TxHeaderTypeDef TxHeader;
/* <20><><EFBFBD><EFBFBD>Tx<54><78><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ */
TxHeader.Identifier = 0x1314;
TxHeader.IdType = FDCAN_EXTENDED_ID;
TxHeader.TxFrameType = FDCAN_DATA_FRAME;
TxHeader.DataLength = FDCAN_DLC_BYTES_8;
TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
TxHeader.BitRateSwitch = FDCAN_BRS_OFF;
TxHeader.FDFormat = FDCAN_FD_CAN;
TxHeader.TxEventFifoControl = FDCAN_STORE_TX_EVENTS;
TxHeader.MessageMarker = 0x01;
HAL_FDCAN_AddMessageToTxBuffer(&hfdcan, &TxHeader, TxData0, FDCAN_TX_BUFFER0);
/* <20><><EFBFBD>ͻ<EFBFBD><CDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ */
HAL_FDCAN_EnableTxBufferRequest(&hfdcan, FDCAN_TX_BUFFER0);
}
/**************************END OF FILE************************************/