|
由于H7的教程需要,特此将函数做了详细注释:
- /*
- *********************************************************************************************************
- * 函 数 名: bsp_InitCan1
- * 功能说明: 初始CAN1
- * 形 参: 无
- * 返 回 值: 无
- *********************************************************************************************************
- */
- void bsp_InitCan1(void)
- {
- /* 位时间特性配置
- Bit time parameter | Nominal | Data
- ---------------------------|--------------|----------------
- fdcan_ker_ck | 20 MHz | 20 MHz
- Time_quantum (tq) | 50 ns | 50 ns
- Synchronization_segment | 1 tq | 1 tq
- Propagation_segment | 23 tq | 1 tq
- Phase_segment_1 | 8 tq | 4 tq
- Phase_segment_2 | 8 tq | 4 tq
- Synchronization_Jump_width | 8 tq | 4 tq
- Bit_length | 40 tq = 2us | 10 tq = 0.5us
- Bit_rate | 0.5 MBit/s | 2 MBit/s
- */
- hfdcan1.Instance = FDCAN1; /* 配置FDCAN1 */
- hfdcan1.Init.FrameFormat = FDCAN_FRAME_FD_BRS; /* 配置使用FDCAN可变波特率 */
- hfdcan1.Init.Mode = FDCAN_MODE_NORMAL; /* 配置使用正常模式 */
- hfdcan1.Init.AutoRetransmission = ENABLE; /*使能自动重发 */
- hfdcan1.Init.TransmitPause = DISABLE; /* 配置禁止传输暂停特性 */
- hfdcan1.Init.ProtocolException = ENABLE; /* 协议异常处理使能 */
-
- /*
- 配置仲裁阶段波特率
- CAN时钟20MHz时,仲裁阶段的波特率就是
- CAN FD Freq / (Sync_Seg + Pro_Seg + Phase_Seg1 + Phase_Seg2) = 20MHz / (1+0x1F + 8) = 0.5Mbps
-
- 其中Sync_Seg是固定值 = 1 , Pro_Seg + Phase_Seg1 = NominalTimeSeg1, Phase_Seg2 = NominalTimeSeg2
- */
- hfdcan1.Init.NominalPrescaler = 0x01; /* CAN时钟分配设置,一般设置为1即可,全部由PLL配置好,tq = NominalPrescaler x (1/ fdcan_ker_ck) */
- hfdcan1.Init.NominalSyncJumpWidth = 0x08; /* 用于动态调节 Phase_Seg1和 Phase_Seg1,所以不可以比Phase_Seg1和 Phase_Seg1大 */
- hfdcan1.Init.NominalTimeSeg1 = 0x1F; /* 特别注意这里的Seg1,这里是两个参数之和,对应位时间特性图的 Pro_Seg + Phase_Seg1 */
- hfdcan1.Init.NominalTimeSeg2 = 0x08; /* 对应位时间特性图的 Phase_Seg2 */
- /*
- 配置数据阶段波特率
- CAN时钟20MHz时,数据阶段的波特率就是
- CAN FD Freq / (Sync_Seg + Pro_Seg + Phase_Seg1 + Phase_Seg2) = 20MHz / (1+5+ 4) = 2Mbps
-
- 其中Sync_Seg是固定值 = 1 , Pro_Seg + Phase_Seg1 = DataTimeSeg1, Phase_Seg2 = DataTimeSeg2
- */
- hfdcan1.Init.DataPrescaler = 0x01; /* CAN时钟分配设置,一般设置为1即可,全部由PLL配置好,tq = NominalPrescaler x (1/ fdcan_ker_ck),范围1-32 */
- hfdcan1.Init.DataSyncJumpWidth = 0x04; /* 用于动态调节 Phase_Seg1和 Phase_Seg1,所以不可以比Phase_Seg1和 Phase_Seg1大,范围1-16 */
- hfdcan1.Init.DataTimeSeg1 = 0x05; /* 特别注意这里的Seg1,这里是两个参数之和,对应位时间特性图的 Pro_Seg + Phase_Seg1,范围 */
- hfdcan1.Init.DataTimeSeg2 = 0x04; /* 对应位时间特性图的 Phase_Seg2 */
-
-
- hfdcan1.Init.MessageRAMOffset = 0; /* CAN1和CAN2共享2560个字, 这里CAN1分配前1280字 */
-
-
- hfdcan1.Init.StdFiltersNbr = 1; /* 设置标准ID过滤器个数,范围0-128 */
- hfdcan1.Init.ExtFiltersNbr = 0; /* 设置扩展ID过滤器个数,范围0-64 */
- hfdcan1.Init.RxFifo0ElmtsNbr = 2; /* 设置Rx FIFO0的元素个数,范围0-64 */
- hfdcan1.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8; /* 设置Rx FIFO0中每个元素大小,支持8,12,16,20,24,32,48或者64字节 */
- hfdcan1.Init.RxFifo1ElmtsNbr = 0; /* 设置Rx FIFO1的元素个数,范围0-64 */
- hfdcan1.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8; /* 设置Rx FIFO1中每个元素大小,支持8,12,16,20,24,32,48或者64字节 */
- hfdcan1.Init.RxBuffersNbr = 0; /* 设置Rx Buffer个数,范围0-64 */
- hfdcan1.Init.RxBufferSize = 0; /* 设置Rx Buffer中每个元素大小,支持8,12,16,20,24,32,48或者64字节 */
- hfdcan1.Init.TxEventsNbr = 0; /* 设置Tx Event FIFO中元素个数,范围0-32 */
- hfdcan1.Init.TxBuffersNbr = 0; /* 设置Tx Buffer中元素个数,范围0-32 */
- hfdcan1.Init.TxFifoQueueElmtsNbr = 2; /* 设置用于Tx FIFO/Queue的Tx Buffers个数。范围0到32 */
- hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; /* 设置FIFO模式或者QUEUE队列模式 */
- hfdcan1.Init.TxElmtSize = FDCAN_DATA_BYTES_8; /* 设置Tx Element中的数据域大小,支持8,12,16,20,24,32,48或者64字节 */
- HAL_FDCAN_Init(&hfdcan1);
- /*
- 配置过滤器, 过滤器主要用于接收,这里采样屏蔽位模式。
- FilterID1 = filter
- FilterID2 = mask
-
- FilterID2的mask每个bit含义
- 0: 不关心,该位不用于比较;
- 1: 必须匹配,接收到的ID必须与滤波器对应的ID位相一致。
-
- 举例说明:
- FilterID1 = 0x111
- FilterID2 = 0x7FF
- 表示仅接收ID为0x111的FDCAN帧。
-
- */
- sFilterConfig1.IdType = FDCAN_STANDARD_ID; /* 设置标准ID或者扩展ID */
- sFilterConfig1.FilterIndex = 0; /* 用于过滤索引,如果是标准ID,范围0到127。如果是扩展ID,范围0到64 */
- sFilterConfig1.FilterType = FDCAN_FILTER_MASK; /* 过滤器采样屏蔽位模式 */
- sFilterConfig1.FilterConfig = FDCAN_FILTER_TO_RXFIFO0; /* 如果过滤匹配,将数据保存到Rx FIFO 0 */
- sFilterConfig1.FilterID1 = 0x111; /* 屏蔽位模式下,FilterID1是消息ID */
- sFilterConfig1.FilterID2 = 0x7FF; /* 屏蔽位模式下,FilterID2是消息屏蔽位 */
- HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig1); /* 配置过滤器 */
-
- /* 设置Rx FIFO0的wartermark为1 */
- HAL_FDCAN_ConfigFifoWatermark(&hfdcan1, FDCAN_CFG_RX_FIFO0, 1);
- /* 激活RX FIFO0的watermark通知中断,位开启Tx Buffer中断*/
- HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_WATERMARK, 0);
- /* 启动FDCAN */
- HAL_FDCAN_Start(&hfdcan1);
- }
复制代码
|
|