CAN帧分为数据帧与远程帧 数据帧又分为 标准帧与扩展帧 FD-CAN多出3个位,如下: EDL 扩展数据长度 BRS (数据)波特率切换 ESL 错误状态指示器
下图看看STM32H743的CAN结构,不知道这是CAN协议标准就让这么设计的,还是ST公司自己开发的,
从这个图可以看出,FD-CAN分为3部分,CCU、 FDCAN、 RAM,其中FDCAN其实是由2部分组成,FDCAN1 FDCAN2,这2个是相互独立的单元,它们2个共享一个RAM区, CCU是时钟校准单元,我看了好半天,也没看明白是干什么的,不过在正常的使用中,是用不到CCU的,因为fdcan_ker_clk可以直接穿过CCU进入CAN内核,(在我下面的使用中,确实也没有用到CCU) 每个FDCAN都有2条中断线,intr0, intr1,但这也是假象,因为在FDCAN中是可以配置中断事件向哪条中断线申请中断的,不清楚这么做有什么好处?显得高级? 从上面的框图中还可以看到时钟域的不同,FDCAN的内核与CCU是一个时钟域, FDCAN的其它逻辑部分与RAM使用一个时钟域,因此需要同步,作为懂得FPGA的工程师,同步时钟域,我还是可以理解的。 关键来了,“共享RAM”,这也是最复杂的部分;由于FDCAN1FDCAN2是使用一块RAM进行缓冲数据的,所有必须要有RAM仲裁器,正是由搞的如此复杂,才会给后面出问题埋下伏笔。 很关键的一点,CCU、 FDCAN、 RAM在STM32的地址空间中是独立的,从上面可以看到这3部分都有独立的32APB总线,这与之前的CAN是有很大的区别的,也就是说CCU、共享RAM在芯片内部是独立的模块,并不是从属于FDCAN,虽然在使用上,CCU与共享RAM仅仅只为FDCAN服务。 共享内存结构(其实是人为划分的)
看这段内存的功能,似曾相识,有一咱把RAM当作寄存器的味道,想起来了,我第一次遇到这样的操作是在LPC4357的USB控制器是这样做的。 由上图可知,这段10KB的内存可以分为过滤区、接收区、发送区,有些区域并不是必备的,但是如果配置有,那必须按上图的顺序分配。
还有一个比较难懂的波特率设置,我这项目只是用了经典CAN,并没有用FD-CAN,所以没有涉及可变波特率,还算简单点。在H743的官方文档中就这么描述的,“DTSEG1 为 Prop_Seg 与 Phase_Seg1 之和。 DTSEG2 为 Phase_Seg2。因此,位时间的 长度为(编程值) [DTSEG1 + DTSEG2 + 3] tq ” (tq:time quantum时间量子),而在HAL库中,我特意详细跟踪了下,NominalTimeSeg1,NominalTimeSeg2的值已经是加过1的,因此计算位时间=【NominalTimeSeg1+NominalTimeSeg2+1】就可以了。
同步段(SYNCHRONIZATION SEGMENT,SYNC_SEG): 多个连接在总线上的单元通过此段实现时序调整,同步进行接收和发送的工作。由隐性电平到显性电平的边沿或由显性电平到隐性电平边沿最好出现在此段中。 传播时间段(PROPAGATION TIME SEGMENT,PROP_SEG): 用于吸收网络上的物理延迟的段。所谓的网络的物理延迟指发送单元的输出延迟、总线上信号的传播延迟、接收单元的输入延迟。这个段的时间为以上各延迟时间的和的两倍。长度可编程为 1 ~ 8个时间量子Tq 相位缓冲段1(PHASE BUFFER SEGMENT1,PHASE_SEG1)和 相位缓冲段2(PHASE BUFFER SEGMENT2,PHASE_SEG2): 当信号边沿不能被包含于 SS 段中时,可在这两个段中进行补偿。由于各单元以各自独立的时钟工作,细微的时钟误差会累积起来,PBS 段可用于吸收此误差。通过对相位缓冲段加减 SJW 吸收误差。SJW 加大后允许误差加大,但通信速度下降。相位缓冲段1 可以通过同步暂时延长;相位缓冲段2 可以通过同步暂时缩短。
|