STM32配置FDCAN通讯

您所在的位置:网站首页 can通讯教程 STM32配置FDCAN通讯

STM32配置FDCAN通讯

2023-08-11 10:17| 来源: 网络整理| 查看: 265

STM32配置FDCAN通讯

由于总线上有设备不支持FDCAN,为了保持兼容性,将本机FDCAN配置为传统CAN运行。

CubeMX配置

开启SW调试接口 开启FDCAN2 开启外部时钟 在这里插入图片描述 外部晶振为12M,主频480M,FDCAN时钟来自PLL1Q 在这里插入图片描述 在这里插入图片描述 FDCAN2参数设置,参数设置的说明,在代码中有注释, 在此强调2点: 1 配置为传统CAN模式时要关闭自动重传,原子哥建议,不知为何,有待测试,CAN标准是支持自动重传的。 2 FDCAN支持仲裁段与数据段波特率不同,而传统模式二者相同,所以若配置为传统CAN时(如本例),数据段可以不配,即Data开始的4个参数可以采用默认值 波特率说明: 前面配置的FDCAN时钟频率为20MHz,Seg1+Seg2+1=40,20MHz/40=500KHz,为保持一致性,Data段配置也和仲裁段(Nominal)配成一样了。 在这里插入图片描述 开启中断 在这里插入图片描述

最后点Generate,生成工程

Keil代码

首先是定义变量

FDCAN_RxHeaderTypeDef RxHeader; FDCAN_TxHeaderTypeDef TxHeader; u8 RxData[8]; u8 TxData[8] = {'L', 'a', 'o', 'L', 'i', '1', '2', '3'};

下面这一段是CubeMX生成的CAN配置参数,我做了备注

void MX_FDCAN2_Init(void) { /* USER CODE BEGIN FDCAN2_Init 0 */ /* USER CODE END FDCAN2_Init 0 */ /* USER CODE BEGIN FDCAN2_Init 1 */ hfdcan2.Instance = FDCAN2; //用FDCAN2 hfdcan2.Init.FrameFormat = FDCAN_FRAME_CLASSIC; //配置为传统模式 hfdcan2.Init.Mode = FDCAN_MODE_NORMAL; //正常工作状态 hfdcan2.Init.AutoRetransmission = DISABLE; //关闭自动重传, 传统模式下需关闭 hfdcan2.Init.TransmitPause = DISABLE; //关闭传输暂停 hfdcan2.Init.ProtocolException = DISABLE; //关闭协议异常处理 hfdcan2.Init.NominalPrescaler = 1; //仲裁段时钟分频 FDCAN时钟基准为20MHz 传统CAN模式时只设置这一段即可 hfdcan2.Init.NominalSyncJumpWidth = 8; //同步跳转段的宽度 8 //时钟频率20M / (1 + TSG1 + TSG2) = CAN波特率 hfdcan2.Init.NominalTimeSeg1 = 31; //时间段1 31 hfdcan2.Init.NominalTimeSeg2 = 8; //时间段2 8 hfdcan2.Init.DataPrescaler = 1; //数据段时钟分频,若工作于传统模式,不需要设置数据段参数 // 若工作于FDCAN模式,允许数据段与仲裁段波特率不同 hfdcan2.Init.DataSyncJumpWidth = 8; //8 hfdcan2.Init.DataTimeSeg1 = 31; //31 hfdcan2.Init.DataTimeSeg2 = 8; //8 hfdcan2.Init.MessageRAMOffset = 0; //消息偏移 hfdcan2.Init.StdFiltersNbr = 1; //标准帧使用滤波器1 hfdcan2.Init.ExtFiltersNbr = 1; //扩展帧使用滤波器1 hfdcan2.Init.RxFifo0ElmtsNbr = 1; //接收FIFO0的元素编号1 hfdcan2.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8; //接收FIFO0的元素长度8 hfdcan2.Init.RxFifo1ElmtsNbr = 1; //接收FIFO1的元素编号1 hfdcan2.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8; //接收FIFO1的元素长度8 hfdcan2.Init.RxBuffersNbr = 1; //接收缓冲区编号1 hfdcan2.Init.RxBufferSize = FDCAN_DATA_BYTES_8; //接收缓冲区长度 hfdcan2.Init.TxEventsNbr = 2; //发送事件编号 hfdcan2.Init.TxBuffersNbr = 1; //发送缓冲区编号 hfdcan2.Init.TxFifoQueueElmtsNbr = 2; //发送FIFO队列元素编号 hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; //发送模式 先入先出 hfdcan2.Init.TxElmtSize = FDCAN_DATA_BYTES_8; //发送元素长度8 if (HAL_FDCAN_Init(&hfdcan2) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN FDCAN2_Init 2 */ /* USER CODE END FDCAN2_Init 2 */ }

CAN滤波器的设置,本函数要自己写,然后放到自己的初始化代码中,在CubeMX生成的初始化代码的后面。

void FDCAN2_Config(void) { FDCAN_FilterTypeDef sFilterConfig; HAL_FDCAN_ActivateNotification(&hfdcan2, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0); sFilterConfig.IdType = FDCAN_STANDARD_ID; // 配置为过滤标准帧 sFilterConfig.FilterIndex = 0; // 过滤器的索引号 sFilterConfig.FilterType = FDCAN_FILTER_RANGE; // 过滤方式为范围,即从FilterID1~FilterID2之间的值 sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; sFilterConfig.FilterID1 = 0x0000; sFilterConfig.FilterID2 = 0x07ff; // 标准帧为11位ID,即0x7ff,本例配置为接收所有帧 if(HAL_FDCAN_ConfigFilter(&hfdcan2, &sFilterConfig) != HAL_OK) Error_Handler(); sFilterConfig.IdType = FDCAN_EXTENDED_ID; // 配置为过滤扩展帧 sFilterConfig.FilterIndex = 0; // 过滤器的索引号 sFilterConfig.FilterType = FDCAN_FILTER_RANGE_NO_EIDM; // 过滤方式为范围,即从FilterID1~FilterID2之间的值 sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO1; sFilterConfig.FilterID1 = 0x00000000; sFilterConfig.FilterID2 = 0x01ffffff; // 扩展帧为29位ID,即0x1fffffff,本例配置为接收所有帧 HAL_FDCAN_ConfigFilter(&hfdcan2, &sFilterConfig); TxHeader.Identifier = 0x123; TxHeader.IdType = FDCAN_STANDARD_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_CLASSIC_CAN; TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS; TxHeader.MessageMarker = 0x52; HAL_FDCAN_Start(&hfdcan2); }

然后是发送代码,这个简单,即每延时200ms,发送一次数据

while (1) { HAL_Delay(200); HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan2, &TxHeader, TxData); /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ }

接收采用中断的方式,在FDCAN2_IT0中断内写入一句

void FDCAN2_IT0_IRQHandler(void) { /* USER CODE BEGIN FDCAN2_IT0_IRQn 0 */ /* USER CODE END FDCAN2_IT0_IRQn 0 */ HAL_FDCAN_IRQHandler(&hfdcan2); /* USER CODE BEGIN FDCAN2_IT0_IRQn 1 */ HAL_FDCAN_GetRxMessage(&hfdcan2, FDCAN_RX_FIFO0, &RxHeader, RxData); /* USER CODE END FDCAN2_IT0_IRQn 1 */ } 代码验证

打开CAN分析仪的界面,可以看到接收到的数据帧 在这里插入图片描述 在CAN分析仪发送数据后,可以在中断内接收到发来的数据 在这里插入图片描述 在这里插入图片描述

完整代码下载

https://download.csdn.net/download/13011803189/85054662



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3