硬汉嵌入式论坛

 找回密码
 立即注册
查看: 3261|回复: 2
收起左侧

[CAN/FDCAN] 分享个详细的FDCAN注释

[复制链接]

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
107049
QQ
发表于 2021-10-30 14:11:28 | 显示全部楼层 |阅读模式
由于H7的教程需要,特此将函数做了详细注释:

  1. /*
  2. *********************************************************************************************************
  3. *        函 数 名: bsp_InitCan1
  4. *        功能说明: 初始CAN1
  5. *        形    参: 无
  6. *        返 回 值: 无
  7. *********************************************************************************************************
  8. */
  9. void bsp_InitCan1(void)
  10. {         
  11.         /*                    位时间特性配置
  12.                 Bit time parameter         | Nominal      |  Data
  13.                 ---------------------------|--------------|----------------
  14.                 fdcan_ker_ck               | 20 MHz       | 20 MHz
  15.                 Time_quantum (tq)          | 50 ns        | 50 ns
  16.                 Synchronization_segment    | 1 tq         | 1 tq
  17.                 Propagation_segment        | 23 tq        | 1 tq
  18.                 Phase_segment_1            | 8 tq         | 4 tq
  19.                 Phase_segment_2            | 8 tq         | 4 tq
  20.                 Synchronization_Jump_width | 8 tq         | 4 tq
  21.                 Bit_length                 | 40 tq = 2us  | 10 tq = 0.5us
  22.                 Bit_rate                   | 0.5 MBit/s   | 2 MBit/s
  23.         */
  24.         hfdcan1.Instance = FDCAN1;                     /* 配置FDCAN1 */            
  25.         hfdcan1.Init.FrameFormat = FDCAN_FRAME_FD_BRS; /* 配置使用FDCAN可变波特率 */  
  26.         hfdcan1.Init.Mode = FDCAN_MODE_NORMAL;         /* 配置使用正常模式 */
  27.         hfdcan1.Init.AutoRetransmission = ENABLE;      /*使能自动重发 */
  28.         hfdcan1.Init.TransmitPause = DISABLE;          /* 配置禁止传输暂停特性 */
  29.         hfdcan1.Init.ProtocolException = ENABLE;       /* 协议异常处理使能 */
  30.         
  31.         /*
  32.                 配置仲裁阶段波特率
  33.                 CAN时钟20MHz时,仲裁阶段的波特率就是
  34.                 CAN FD Freq / (Sync_Seg + Pro_Seg + Phase_Seg1 + Phase_Seg2) = 20MHz / (1+0x1F + 8) = 0.5Mbps        
  35.                
  36.                 其中Sync_Seg是固定值 = 1 , Pro_Seg + Phase_Seg1 = NominalTimeSeg1, Phase_Seg2 = NominalTimeSeg2
  37.         */
  38.         hfdcan1.Init.NominalPrescaler = 0x01;           /* CAN时钟分配设置,一般设置为1即可,全部由PLL配置好,tq = NominalPrescaler x (1/ fdcan_ker_ck) */
  39.         hfdcan1.Init.NominalSyncJumpWidth = 0x08; /* 用于动态调节  Phase_Seg1和 Phase_Seg1,所以不可以比Phase_Seg1和 Phase_Seg1大 */
  40.         hfdcan1.Init.NominalTimeSeg1 = 0x1F;           /* 特别注意这里的Seg1,这里是两个参数之和,对应位时间特性图的 Pro_Seg + Phase_Seg1 */
  41.         hfdcan1.Init.NominalTimeSeg2 = 0x08;      /* 对应位时间特性图的 Phase_Seg2 */


  42.         /*
  43.                 配置数据阶段波特率
  44.                 CAN时钟20MHz时,数据阶段的波特率就是
  45.                 CAN FD Freq / (Sync_Seg + Pro_Seg + Phase_Seg1 + Phase_Seg2) = 20MHz / (1+5+ 4) = 2Mbps
  46.                
  47.                 其中Sync_Seg是固定值 = 1 , Pro_Seg + Phase_Seg1 = DataTimeSeg1, Phase_Seg2 = DataTimeSeg2
  48.         */
  49.         hfdcan1.Init.DataPrescaler = 0x01;            /* CAN时钟分配设置,一般设置为1即可,全部由PLL配置好,tq = NominalPrescaler x (1/ fdcan_ker_ck),范围1-32 */
  50.         hfdcan1.Init.DataSyncJumpWidth = 0x04;  /* 用于动态调节  Phase_Seg1和 Phase_Seg1,所以不可以比Phase_Seg1和 Phase_Seg1大,范围1-16 */
  51.         hfdcan1.Init.DataTimeSeg1 = 0x05;       /* 特别注意这里的Seg1,这里是两个参数之和,对应位时间特性图的 Pro_Seg + Phase_Seg1,范围 */
  52.         hfdcan1.Init.DataTimeSeg2 = 0x04;       /* 对应位时间特性图的 Phase_Seg2 */   
  53.         
  54.         
  55.         hfdcan1.Init.MessageRAMOffset = 0;      /* CAN1和CAN2共享2560个字, 这里CAN1分配前1280字 */
  56.         
  57.         
  58.         hfdcan1.Init.StdFiltersNbr = 1;                        /* 设置标准ID过滤器个数,范围0-128 */      
  59.         hfdcan1.Init.ExtFiltersNbr = 0;                          /* 设置扩展ID过滤器个数,范围0-64 */   
  60.         hfdcan1.Init.RxFifo0ElmtsNbr = 2;                   /* 设置Rx FIFO0的元素个数,范围0-64 */  
  61.         hfdcan1.Init.RxFifo0ElmtSize = FDCAN_DATA_BYTES_8;         /* 设置Rx FIFO0中每个元素大小,支持8,12,16,20,24,32,48或者64字节 */   
  62.         hfdcan1.Init.RxFifo1ElmtsNbr = 0;                   /* 设置Rx FIFO1的元素个数,范围0-64 */
  63.         hfdcan1.Init.RxFifo1ElmtSize = FDCAN_DATA_BYTES_8;  /* 设置Rx FIFO1中每个元素大小,支持8,12,16,20,24,32,48或者64字节 */        
  64.         hfdcan1.Init.RxBuffersNbr = 0;                      /* 设置Rx Buffer个数,范围0-64 */
  65.         hfdcan1.Init.RxBufferSize = 0;                      /* 设置Rx Buffer中每个元素大小,支持8,12,16,20,24,32,48或者64字节 */        


  66.         hfdcan1.Init.TxEventsNbr = 0;                                /* 设置Tx Event FIFO中元素个数,范围0-32 */        
  67.         hfdcan1.Init.TxBuffersNbr = 0;                               /* 设置Tx Buffer中元素个数,范围0-32 */
  68.         hfdcan1.Init.TxFifoQueueElmtsNbr = 2;                   /* 设置用于Tx FIFO/Queue的Tx Buffers个数。范围0到32 */
  69.         hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION; /* 设置FIFO模式或者QUEUE队列模式 */
  70.         hfdcan1.Init.TxElmtSize = FDCAN_DATA_BYTES_8;   /* 设置Tx Element中的数据域大小,支持8,12,16,20,24,32,48或者64字节 */
  71.         HAL_FDCAN_Init(&hfdcan1);


  72.         /*
  73.                 配置过滤器, 过滤器主要用于接收,这里采样屏蔽位模式。
  74.                 FilterID1 = filter
  75.                 FilterID2 = mask
  76.                
  77.                 FilterID2的mask每个bit含义
  78.                 0: 不关心,该位不用于比较;
  79.                 1: 必须匹配,接收到的ID必须与滤波器对应的ID位相一致。
  80.                
  81.                 举例说明:
  82.                 FilterID1 = 0x111
  83.                 FilterID2 = 0x7FF
  84.                 表示仅接收ID为0x111的FDCAN帧。
  85.                
  86.         */
  87.         sFilterConfig1.IdType = FDCAN_STANDARD_ID;              /* 设置标准ID或者扩展ID */
  88.         sFilterConfig1.FilterIndex = 0;                                      /* 用于过滤索引,如果是标准ID,范围0到127。如果是扩展ID,范围0到64 */
  89.         sFilterConfig1.FilterType = FDCAN_FILTER_MASK;          /* 过滤器采样屏蔽位模式 */
  90.         sFilterConfig1.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;  /* 如果过滤匹配,将数据保存到Rx FIFO 0 */
  91.         sFilterConfig1.FilterID1 = 0x111;                                  /* 屏蔽位模式下,FilterID1是消息ID */
  92.         sFilterConfig1.FilterID2 = 0x7FF;                                   /* 屏蔽位模式下,FilterID2是消息屏蔽位 */
  93.         HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig1);     /* 配置过滤器 */
  94.         
  95.         /* 设置Rx FIFO0的wartermark为1 */
  96.         HAL_FDCAN_ConfigFifoWatermark(&hfdcan1, FDCAN_CFG_RX_FIFO0, 1);

  97.         /* 激活RX FIFO0的watermark通知中断,位开启Tx Buffer中断*/
  98.         HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_WATERMARK, 0);

  99.         /* 启动FDCAN */
  100.         HAL_FDCAN_Start(&hfdcan1);        
  101. }
复制代码




回复

使用道具 举报

25

主题

287

回帖

367

积分

高级会员

积分
367
发表于 2021-10-30 19:08:24 | 显示全部楼层
感谢分享
回复

使用道具 举报

3

主题

1228

回帖

1237

积分

至尊会员

积分
1237
发表于 2021-10-30 20:52:26 | 显示全部楼层
感谢分享,点赞硬汉大哥
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-15 16:18 , Processed in 0.184577 second(s), 25 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表