STM32MX 配置CANFD收发通讯
一、环境
MCU:STM32G0B1CEU6
CAN收发器:JIA1042
二、MX配置
配置SYS
配置canfd并开启中断,我开了两个FDCAN,配置是一样的,这里贴一下波特率的计算公式:
也就是:CAN时钟频率/预分频器/(1+TS1+TS2)
按照我这里的时钟就是:
CAN时钟频率为40MHZ,预分频器为1,TS1=5,TS2=4
所以数据段的频率为40/8/(1+5+4)=500MHZ
同时我这里开了个uart用作调试,配置完成后生成
三、滤波器配置
这里设置了ID为0x000,使用CANFD,数据长度64,滤波器在系统初始化完成后就可以进行配置了
void FDCAN1_config(void){
FDCAN_FilterTypeDef sFilterConfig;
/* Configure Rx filter */
sFilterConfig.IdType = FDCAN_STANDARD_ID;
sFilterConfig.FilterIndex = 0;
sFilterConfig.FilterType = FDCAN_FILTER_MASK;
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
sFilterConfig.FilterID1 = 0x000;
sFilterConfig.FilterID2 = 0x000;
if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
/* Configure global filter:
Filter all remote frames with STD and EXT ID
Reject non matching frames with STD ID and EXT ID */
if (HAL_FDCAN_ConfigGlobalFilter(&hfdcan1, FDCAN_REJECT, FDCAN_REJECT, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE) != HAL_OK)
{
Error_Handler();
}
/* Start the FDCAN module */
if (HAL_FDCAN_Start(&hfdcan1) != HAL_OK)
{
Error_Handler();
}
if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
{
Error_Handler();
}
TxHeader.Identifier = 0x000; // CAN ID
TxHeader.IdType = FDCAN_STANDARD_ID; // 标准ID
TxHeader.TxFrameType = FDCAN_DATA_FRAME;
TxHeader.DataLength = FDCAN_DLC_BYTES_64;
TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
TxHeader.BitRateSwitch = FDCAN_BRS_ON;
TxHeader.FDFormat = FDCAN_FD_CAN; // CANFD
TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
TxHeader.MessageMarker = 0;
}
void FDCAN2_config(void){
FDCAN_FilterTypeDef sFilterConfig;
/* Configure Rx filter */
sFilterConfig.IdType = FDCAN_STANDARD_ID;
sFilterConfig.FilterIndex = 0;
sFilterConfig.FilterType = FDCAN_FILTER_MASK;
sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
sFilterConfig.FilterID1 = 0x000;
sFilterConfig.FilterID2 = 0x000;
if (HAL_FDCAN_ConfigFilter(&hfdcan2, &sFilterConfig) != HAL_OK)
{
Error_Handler();
}
/* Configure global filter:
Filter all remote frames with STD and EXT ID
Reject non matching frames with STD ID and EXT ID */
if (HAL_FDCAN_ConfigGlobalFilter(&hfdcan2, FDCAN_REJECT, FDCAN_REJECT, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE) != HAL_OK)
{
Error_Handler();
}
/* Start the FDCAN module */
if (HAL_FDCAN_Start(&hfdcan2) != HAL_OK)
{
Error_Handler();
}
if (HAL_FDCAN_ActivateNotification(&hfdcan2, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
{
Error_Handler();
}
TxHeader.Identifier = 0x000; // CAN ID
TxHeader.IdType = FDCAN_STANDARD_ID; // 标准ID
TxHeader.TxFrameType = FDCAN_DATA_FRAME;
TxHeader.DataLength = FDCAN_DLC_BYTES_64;
TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
TxHeader.BitRateSwitch = FDCAN_BRS_ON;
TxHeader.FDFormat = FDCAN_FD_CAN; // CANFD
TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
TxHeader.MessageMarker = 0;
}
四、发送和接收函数
这里我的发送是写在while里面的,实现的功能flag标志位1时,是一个canfd1发送数据,canfd2接收后flag值为2;flag为2时,canfd2发送数据,canfd1接收将flag值等于1
HAL库发送函数为:
HAL_FDCAN_AddMessageToTxFifoQ(FDCAN_HandleTypeDef *hfdcan, const FDCAN_TxHeaderTypeDef *pTxHeader,const uint8_t *pTxData)
接收函数为:
HAL_FDCAN_GetRxMessage(FDCAN_HandleTypeDef *hfdcan, uint32_t RxLocation,FDCAN_RxHeaderTypeDef *pRxHeader, uint8_t *pRxData)
下面时我的main(发送)和中断回调函数(接收)函数:
FDCAN_RxHeaderTypeDef RxHeader;
FDCAN_TxHeaderTypeDef TxHeader;
uint8_t TXData[64]={0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
0x00};
uint8_t RxData[64]={0};
uint8_t flag=1;
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_FDCAN1_Init();
MX_FDCAN2_Init();
MX_USART3_UART_Init();
/* USER CODE BEGIN 2 */
FDCAN1_config();
FDCAN2_config();
HAL_Delay(2000);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
if(flag==0x01){
if(HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, TXData)!=HAL_OK){
Error_Handler();
}
HAL_Delay(1000);
}else{
if(HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan2, &TxHeader, TXData)!=HAL_OK){
Error_Handler();
}
HAL_Delay(1000);
}
HAL_Delay(1000);
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{
if((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != RESET)
{
if(hfdcan->Instance == FDCAN1)
{
if (HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
{
Error_Handler();
}
flag=0x01;
HAL_UART_Transmit(&huart3,&flag,1,1000);
}
if(hfdcan->Instance == FDCAN2)
{
if (HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
{
Error_Handler();
}
flag=0x02;
HAL_UART_Transmit(&huart3,&flag,1,1000);
}
}
}
五、实际使用
实际使用过程中,需要将两个CANFD建立在一个CAN网络中才能进行通讯
六、源码工程
https://download.csdn.net/download/weixin_46516921/90080900
原文地址:https://blog.csdn.net/weixin_46516921/article/details/144241465
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!