这里我们对 C A N CAN CAN总线协议进行了一个基本的讲解,接下来我们将对基于 C A N CAN CAN总线协议的高层协议 T T C A N , T i m e T r i g g e r e d C o m m u n i c a t i o n TTCAN,Time\quad Triggered\quad Communication TTCAN,TimeTriggeredCommunication做一个基本的讲解。 T T C A N TTCAN TTCAN是基于基本的 C A N CAN CAN总线协议的一种高层协议,其物理层和数据链路层和基本的 C A N CAN CAN总线协议是一样的,也就是在一个运行 T T C A N TTCAN TTCAN的高层网络中,电平状态和帧格式和基本的 C A N CAN CAN总线协议是一样的。在基本的 C A N CAN CAN总线协议网络中如果多个节点同时发送数据帧,那么根据总线仲裁规则具有最高优先级的数据帧才能被发送出去,这样最低优先级的节点的数据可能很长一段时间都无法发送出去,因此基本的 C A N CAN CAN总线协议网络很难保证消息的实时性,正是为了保证消息的实时性要求, T T C A N TTCAN TTCAN出现了。实时性要求就是当某个节点发生某个事件,该节点必须在一定的时间范围内通过消息帧将该状态发送出去。
下面的讲解我主要参考了 I S O − 11898 − 4 ISO-11898-4 ISO−11898−4文档以及其他网路上的参考资料,具体看这里。还有就是下面某些内容的讲解会以某个特定的 I P IP IP作为例子,这里这个特定的 I P IP IP是 B O S C H BOSCH BOSCH半导体公司的M_TTCAN,如图1和图2所示,目前 S T ST ST的 H 742 H742 H742系列使用了这个 I P IP IP。
T T C A N TTCAN TTCAN从总体上通俗的来说的话就是把什么时候发送消息和什么时候接收消息都规定好了,这样就没有了节点的相互竞争总线而造成无法达到实时性的问题。前面提到 T T C A N TTCAN TTCAN把消息的发送和接收的时刻都规定好了,那么有时刻 就必然有时间的基准, T T C A N TTCAN TTCAN的时间基准一共有两个 l e v e l level level, l e v e l 1 level1 level1和 l e v e l 2 level2 level2, B O S C H BOSCH BOSCH的那个IP增加了一个 l e v e l 0 level0 level0。这个 l e v e l 0 level0 level0不是 I S O − 11898 − 4 ISO-11898-4 ISO−11898−4文档规定的,而是 B O S C H BOSCH BOSCH半导体公司自己加的,这个 l e v e l 0 level0 level0是在事件触发的通信模式( I S O − 11898 − 1 ISO-11898-1 ISO−11898−1)的基础上仅仅保留了 l e v e l 2 level2 level2的可以通过参考消息的发送而在整个网络中建立校准了的时间基准的这一功能, l e v e l 2 level2 level2的其它功能 l e v e l 0 level0 level0不具有。 T T C A N TTCAN TTCAN的 l e v e l 1 level1 level1和 l e v e l 2 level2 level2是时间触发的通信模式( I S O − 11898 − 4 ISO-11898-4 ISO−11898−4)。在 T T C A N TTCAN TTCAN网络中消息的发送和接收都是基于系统矩阵 S y s t e m m a t r i x System\quad matrix Systemmatrix的,如图3所示。系统矩阵是在整个 T T C A N TTCAN TTCAN网络运行之前就规划好的,一个系统矩阵由多个基本周期组成,如图4所示,基本周期是系统矩阵的一行,一般一个系统矩阵包含2的n次方个基本周期,基本周期的最小值是1。一个基本周期又由多个 T i m e S l o t Time\quad Slot TimeSlot组成, T i m e S l o t Time\quad Slot TimeSlot是系统矩阵的列。 T i m e S l o t Time\quad Slot TimeSlot也可以叫做时间窗口,一条消息的发送和接收都必须在一个时间窗口内完成,当然某些特别的消息可以横跨多个时间窗口。时间窗口分为三种类型:
那如何确定一个基本周期的开始,如图4所示一种特别的消息帧,参考消息 R e f e r e n c e M e s s a g e Reference\quad Message ReferenceMessage,的发送与接收意味着一个基本周期的开始。参考消息是由 T i m e M a s t e r Time\quad Master TimeMaster发送的,参考消息与其他消息帧的不同之处在于其 I D ID ID不一样,一个 T T C A N TTCAN TTCAN网络中最多有8个 T i m e M a s t e r Time\quad Master TimeMaster,每一个 T i m e M a s t e r Time\quad Master TimeMaster发送的参考消息的 I D ID ID基本一样,只是 I D ID ID的最低三位不一样,这是为了区分不同 T i m e M a s t e r Time\quad Master TimeMaster的优先级,一个 T T C A N TTCAN TTCAN网络中只能有一个激活的 T i m e M a s t e r Time\quad Master TimeMaster,准备8个 T i m e M a s t e r Time\quad Master TimeMaster的原因是防止当前激活的 T i m e M a s t e r Time\quad Master TimeMaster失效之后其他 T i m e M a s t e r Time\quad Master TimeMaster可以马上替代这个失效的 T i m e M a s t e r Time\quad Master TimeMaster。
在 l e v e l 1 level1 level1时间基准下,参考消息的数据字节最少1个,在 l e v e l 2 level2 level2时间基准下,参考消息的数据字节最少4个,参考消息的数据字段的最小要求分别如图5和图6所示。无论是在 l e v e l 1 level1 level1时间基准下或是在 l e v e l 2 level2 level2时间基准下,参考消息中都应该包含这个参考消息所开启的基本周期的索引(可选),即这是第几个基本周期,以及 N e x t _ i s _ G a p Next\_is\_Gap Next_is_Gap状态位(后面会重点讲到)。在 l e v e l 2 level2 level2时间基准下,参考消息中还额外的包含 M a s t e r _ R e f _ M a r k Master\_Ref\_Mark Master_Ref_Mark(后面会重点讲到)和状态比特位 D i s c _ B i t Disc\_Bit Disc_Bit(后面会重点讲到)。 T i m e M a s t e r Time\quad Master TimeMaster一般会以一种稳定的时间间隔(就相当于是基本周期的长度)去发送参考消息。从图5和图6中的 l e v e l 1 level1 level1时间基准下或是在 l e v e l 2 level2 level2时间基准下的参考消息的数据字段的最小要求下,只为基本周期的索引提供了6个比特位,但是协议中并没有限制说一个系统矩阵中最多只有 2 6 = 64 2^6=64 26=64个基本周期,也就是说可以在剩余的数据字段的字节中扩展基本周期的索引的比特位。图6中的第二个字节的高3位是 l e v e l 2 level2 level2时间基准下 M a s t e r _ R e f _ M a r k Master\_Ref\_Mark Master_Ref_Mark的小数部分,协议要求至少是3个比特位,但是也可以扩充至7个比特位。 这里有一点需要注意的是 T T C A N TTCAN TTCAN协议是先于 F D C A N FDCAN FDCAN协议出现的,因此 T T C A N TTCAN TTCAN协议是否支持 F D C A N FD\quad CAN FDCAN协议的数据帧那就要看具体的芯片IP决定了。 B O S C H BOSCH BOSCH半导体公司的这个 I P IP IP是支持在 T T C A N TTCAN TTCAN操作中使用 F D C A N FD\quad CAN FDCAN数据帧的,如图8所示。
事件同步的基本周期的开始( E v e n t s y n c h r o n i s e d s t a r t o f b a s i c c y c l e Event\quad synchronised\quad start\quad of\quad basic\quad cycle Eventsynchronisedstartofbasiccycle):这是针对前面讲到的参考消息中的 N e x t _ i s _ G a p Next\_is\_Gap Next_is_Gap状态位。参考消息一般会以一种稳定的时间间隔进行发送,但是 T T C A N TTCAN TTCAN协议也允许基本周期的发送重新同步到 T i m e M a s t e r Time\quad Master TimeMaster的某一个事件的开始,这就是 N e x t _ i s _ G a p Next\_is\_Gap Next_is_Gap状态位的作用,如图7所示。当有这个需求的时候,当前的 T i m e M a s t e r Time\quad Master TimeMaster会将此时发送的参考消息的 N e x t _ i s _ G a p Next\_is\_Gap Next_is_Gap状态位置1,当从这个参考消息开始的基本周期结束的时候,一个 T i m e G a p Time\quad Gap TimeGap就会开始,这也就导致了前面的周期发送参考消息的状态结束了,在 T i m e G a p Time\quad Gap TimeGap期间所有的发送操作停止,整个总线处于静默状态那么这个 T i m e G a p Time\quad Gap TimeGap多长时间结束呢?只要当前的 T i m e M a s t e r Time\quad Master TimeMaster或者是潜在的另一个 T i m e M a s t e r Time\quad Master TimeMaster发送参考消息之后这个 T i m e G a p Time\quad Gap TimeGap就结束了, T T C A N TTCAN TTCAN网络的通信又开始了。
在 B O S C H BOSCH BOSCH公司的这个 I P IP IP中,如果要使用 N e x t _ i s _ G a p Next\_is\_Gap Next_is_Gap位相关的功能的话, T T O C F TTOCF TTOCF寄存器的 G E N GEN GEN位要置1(网络中的所有节点并包括 T i m e M a s t e r Time\quad Master TimeMaster),也就是不是严格的时间触发的操作模式。 G a p Gap Gap操作由 T i m e M a s t e r Time\quad Master TimeMaster发起, I P IP IP中由两种方式可以发起 G a p Gap Gap操作:
根据 B O S C H BOSCH BOSCH公司的这个 I P IP IP的描述,网络中的Potential time master有四种方式来结束 G a p Gap Gap周期(虽然 I P IP IP文档描述是Potential time master进行以下四种操作来结束 G a p Gap Gap周期,但是我总觉得Current time master也可以进行以下四种操作来结束 G a p Gap Gap周期,不知道对不对):
前面提到 T T C A N TTCAN TTCAN的时间基准一共有两个 l e v e l level level, l e v e l 1 level1 level1和 l e v e l 2 level2 level2。下面我们来看一下这两个 l e v e l level level具体是如何实现的。如图9所示,简单的说每一个 C A N CAN CAN节点芯片都有自己的晶振电路,时间基准就是靠这个晶振电路来实现的,晶振的时钟周期 t s y s t_{sys} tsys经过分频以后就得到了最基本的时间基准 N T U , n e t w o r k t i m e u n i t NTU,network\quad time\quad unit NTU,networktimeunit,分频的参数是 T U R , t i m e u n i t r a t i o TUR,time\quad unit\quad ratio TUR,timeunitratio, N T U = t s y s × T U R NTU=t_{sys}\times TUR NTU=tsys×TUR。可以看出 T U R TUR TUR是 N T U NTU NTU和晶振的时钟周期的比值。在 l e v e l 1 level1 level1, N T U NTU NTU是 C A N CAN CAN总线协议中的比特时间,各个节点的 T U R TUR TUR值不变。在 l e v e l 2 level2 level2, N T U NTU NTU大概是一秒钟时间的一个部分,也就是不到一秒钟,各个节点的 T U R TUR TUR值根据接收到的time master发送的参考消息里面的有关time master节点时间基准的信息不断做出调整,这样可以使得网络中其它节点的时间基准尽量和time master保持一致。因为在 l e v e l 2 level2 level2, T U R TUR TUR的值在不断调整,因此整个网络里面各个节点的时间基准视角比 l e v e l 1 level1 level1下要精确。
下面我们再来介绍几个时间概念 L o c a l T i m e Local\quad Time LocalTime, C y c l e T i m e Cycle\quad Time CycleTime, G l o b a l T i m e Global\quad Time GlobalTime:
前面我们提到过,在 l e v e l 2 level2 level2时间基准下, T U R , t i m e u n i t r a t i o TUR,time\quad unit\quad ratio TUR,timeunitratio的值在不断调整,因此整个网络里面各个节点的时间基准视角比 l e v e l 1 level1 level1下要精确。 T U R , t i m e u n i t r a t i o TUR,time\quad unit\quad ratio TUR,timeunitratio的值的不断调整就是为了同步整个网络中的各个节点的时间基准,下面我们来看一下同步的过程,如图12所示。不是 T i m e M a s t e r Time\quad Master TimeMaster的节点在连续接收到两次连续的参考消息之后,调整后的 T U R , t i m e u n i t r a t i o TUR,time\quad unit\quad ratio TUR,timeunitratio值为:
{ d f = R e f _ M a r k a c t u a l – R e f _ M a r k p r e v i o u s M a s t e r _ R e f _ M a r k a c t u a l – M a s t e r _ R e f _ M a r k p r e v i o u s , T U R = d f ⋅ T U R p r e v i o u s \left\{ \begin{array}{lr} df=\frac{Ref\_Mark_{actual} – Ref\_Mark{previous}} {Master\_Ref\_Mark_{actual} – Master\_Ref\_Mark_{previous}}, & \\ TUR = df · TUR_{previous} & \end{array} \right. {df=Master_Ref_Markactual–Master_Ref_MarkpreviousRef_Markactual–Ref_Markprevious,TUR=df⋅TURprevious
在 B O S C H BOSCH BOSCH公司的这个 I P IP IP中, T U R TUR TUR值有两个相关的寄存器, T U R C F TURCF TURCF寄存器和 T U R N A TURNA TURNA寄存器,分别如图13和图14所示。 T U R = T U R N A . N A V T U R C F . D C TUR=\frac{TURNA.NAV} {TURCF.DC} TUR=TURCF.DCTURNA.NAV, T U R N A . N A V TURNA.NAV TURNA.NAV的初始值是 T U R C F . N C TURCF.NC TURCF.NC,它的取值范围是 0 x 010000 − > 0 x 01 F F F F 0x010000->0x01FFFF 0x010000−>0x01FFFF。 T U R C F . D C TURCF.DC TURCF.DC的取值范围是 0 x 0001 − > 0 x 3 F F F 0x0001->0x3FFF 0x0001−>0x3FFF。在 L e v e l 1 Level1 Level1, T U R ≥ 4 TUR \geq4 TUR≥4。在 L e v e l 0 Level0 Level0和 L e v e l 2 Level2 Level2, T U R ≥ 8 TUR \geq8 TUR≥8,这是为了满足 L e v e l 0 Level0 Level0和 L e v e l 2 Level2 Level2下 N T U NTU NTU至少有3个小数位的要求。在 L e v e l 1 Level1 Level1下 T U R TUR TUR值是不会改变的,也就是说 T U R N A . N A V TURNA.NAV TURNA.NAV和 T U R C F . D C TURCF.DC TURCF.DC的值是不会改变的。在 L e v e l 0 Level0 Level0和 L e v e l 2 Level2 Level2下,Time slaves和backup time master的 T U R TUR TUR值会根据接收到的time master发送的 M a s t e r _ R e f _ M a r k Master\_Ref\_Mark Master_Ref_Mark做一定的调整,这里的调整实际是根据接收到的time master发送的 M a s t e r _ R e f _ M a r k Master\_Ref\_Mark Master_Ref_Mark来重新计算 T U R N A . N A V TURNA.NAV TURNA.NAV的值( T U R C F . D C TURCF.DC TURCF.DC的值再自动调整过程中不变),自然也就调整了 T U R TUR TUR值,在这里 I P IP IP中需要使能自动校准功能, T T O C F TTOCF TTOCF寄存器的 E C C ECC ECC位需要置1。
还有一种情况也可以调整 T U R TUR TUR的值。这种情况是,一个网络中的 N T U NTU NTU想被调整为某个特定的长度,按照 I S O − 11898 − 4 ISO-11898-4 ISO−11898−4文档中的描述,这就属于是频率调整了。这项操作只能当前网络中的time master来完成,此时 I P IP IP中需要使能外部时钟同步功能, T T O C F TTOCF TTOCF寄存器的 E E C S EECS EECS位需要置1。当前网络中的time master首先修改 T U R C F . N C TURCF.NC TURCF.NC的值(注意这里没有修改 T U R C F . D C TURCF.DC TURCF.DC的值),然后触发外部时钟同步流程, T T O C N TTOCN TTOCN寄存器的 E C S ECS ECS位需要置1。这个当前网络中的time master下一次发送参考消息的时候 T U R N A . N A V TURNA.NAV TURNA.NAV的值将被更新为刚刚配置的 T U R C F . N C TURCF.NC TURCF.NC的值,从这之后当前网络中的time master的 T U R TUR TUR的值就算得到的更新,也算是当前网络中的time master的 N T U NTU NTU的值得到了更新,同时当前网络中的time master的 l o a c a l t i m e loacal\quad time loacaltime和 g l o b a l l t i m e globall\quad time globalltime的值也得到了更新。此后当前网络中的time master发送的 M a s t e r _ R e f _ M a r k Master\_Ref\_Mark Master_Ref_Mark也得到了更新,这样一来当前网络中的time slaves和backup time master的 T U R TUR TUR的值也得到了更新,最后整个网络中的节点的 T U R TUR TUR的值都更新到预期的值。
T U R N A . N A V TURNA.NAV TURNA.NAV和 T U R C F . N C TURCF.NC TURCF.NC的差值 ∣ T U R N A . N A V − T U R C F . N C ∣ |TURNA.NAV-TURCF.NC| ∣TURNA.NAV−TURCF.NC∣叫做同步偏移,按照 I S O − 11898 − 4 ISO-11898-4 ISO−11898−4文档中的描述,对这个同步偏移应该是有一定的限制的,也就是不能超过一定的值,否则就算是不符合 I S O − 11898 − 4 ISO-11898-4 ISO−11898−4协议要求的。这个差值的极限值可以根据实际情况来进行配置,这个极限值在 I P IP IP中是 2 T T O C F . L D S D L + 5 2^{TTOCF.LDSDL + 5} 2TTOCF.LDSDL+5,其中 T T O C F . L D S D L TTOCF.LDSDL TTOCF.LDSDL是 I P IP IP的 T T O C F TTOCF TTOCF寄存器的 L D S D L LDSDL LDSDL域, L D S D L LDSDL LDSDL域的取值范围是 0 − > 7 0->7 0−>7,因此这个可以配置的极限值的范围是 [ 32 , 4096 ] [32,4096] [32,4096]
在 l e v e l 2 level2 level2时间基准下,参考消息中的 D i s c Disc Disc比特位的使用:在 T T C A N TTCAN TTCAN网络中,可能会有将 G l o b a l T i m e Global\quad Time GlobalTime同步到一个外部时间的需求,按照 I S O − 11898 − 4 ISO-11898-4 ISO−11898−4文档中的描述,这就属于是相位调整了。这种同步需求的操作如下,首先计算出当前的 T T C A N TTCAN TTCAN网络中 G l o b a l T i m e Global\quad Time GlobalTime和外部时间的差异 G l o b a l _ T i m e _ P r e s e t Global\_Time\_Preset Global_Time_Preset,然后将 G l o b a l _ T i m e _ P r e s e t Global\_Time\_Preset Global_Time_Preset加到当前 T i m e M a s t e r Time\quad Master TimeMaster节点的 L o c a l _ O f f s e t Local\_Offset Local_Offset参数中,这样下次 T i m e M a s t e r Time\quad Master TimeMaster发送的参考消息中的 M a s t e r _ R e f _ M a r k Master\_Ref\_Mark Master_Ref_Mark就将是更新了 L o c a l _ O f f s e t Local\_Offset Local_Offset的 G l o b a l T i m e Global\quad Time GlobalTime,同时这个参考消息中的 D i s c Disc Disc比特位也将会被置1,其它收到这个参考消息的节点会重新更新自己的 L o c a l _ O f f s e t Local\_Offset Local_Offset参数,这样进而也就同步到了外部时间了。这里需要注意的是 D i s c Disc Disc比特位值为1的参考消息不能连续发送两次且这种参考消息也不会用来调整节点的 T U R , t i m e u n i t r a t i o TUR,time\quad unit\quad ratio TUR,timeunitratio的值。
在 B O S C H BOSCH BOSCH公司的这个 I P IP IP中,对应于 D i s c Disc Disc比特位的操作流程如下。此时 I P IP IP中需要使能外部时钟同步功能, T T O C F TTOCF TTOCF寄存器的 E E C S EECS EECS位需要置1。当前网络中的 T i m e M a s t e r Time\quad Master TimeMaster将 T T O C N TTOCN TTOCN寄存器的 S G T SGT SGT位置1,之后硬件会自动激活对应于 D i s c Disc Disc比特位的流程,在前网络中的 T i m e M a s t e r Time\quad Master TimeMaster发送下一个参考消息的时候会对发送的参考消息的 M a s t e r _ R e f _ M a r k Master\_Ref\_Mark Master_Ref_Mark做相应的调整,这个调整的值就是 G l o b a l _ T i m e _ P r e s e t Global\_Time\_Preset Global_Time_Preset,这个值对应于 T T G T P TTGTP TTGTP寄存器的 T P TP TP位域,如图16所示。 I P IP IP具体如何调整,也如图16所示。同时这个参考消息中的 D i s c Disc Disc比特位也将会被置1。
T T C A N TTCAN TTCAN网络中消息的发送和接收:前面我们提到 T T C A N TTCAN TTCAN中把什么时候发送消息和什么时候接收消息都规定好了,消息的发送和接收都是基于系统矩阵 S y s t e m m a t r i x System\quad matrix Systemmatrix的。参考消息的接收意味着 C y c l e T i m e Cycle\quad Time CycleTime从零开始计时,这时每一个基本周期中的时间窗口对应的消息的发送好接收的时刻 ( T i m e m a r k ) (Time\quad mark) (Timemark)都是和 C y c l e T i m e Cycle\quad Time CycleTime做对比,如果当前的 C y c l e T i m e Cycle\quad Time CycleTime和相应的时间窗口内规定的接收和发送消息的时刻一致,就会进行相应的发送个接收操作。
下面来介绍几个和消息发送和接收相关的协议中的专业叫法: T x _ T r i g g e r , R x _ T r i g g e r , T x _ R e f _ T r i g g e r , T x _ E n a b l e w i n d o w Tx\_Trigger, Rx\_Trigger, Tx\_Ref\_Trigger, Tx\_Enable\quad window Tx_Trigger,Rx_Trigger,Tx_Ref_Trigger,Tx_Enablewindow和 W a t c h _ T r i g g e r Watch\_Trigger Watch_Trigger:
以上对 T T C A N TTCAN TTCAN协议的一些比较关键的概念作了一些介绍,当然 T T C A N TTCAN TTCAN协议还有错误处理等一些其它内容,这里我就不详细介绍了,等以后遇到实际的项目且项目中对 T T C A N TTCAN TTCAN协议有这些要求的时候可以自己再详细的看一看 11898 − 4 11898-4 11898−4协议,相信有了上面的了解,在上手 T T C A N TTCAN TTCAN相关项目的时候会比较容易。
/*
**************************************************************************************************************************************
**************************************************************************************************************************************
**************************************************************************************************************************************
**************************************************************************************************************************************
*/
下面我们将基于野火的 S T M 32 H 750 X B H 6 STM32H750XBH6 STM32H750XBH6开发板对上面提到的 T T C A N TTCAN TTCAN协议的几点重点内容做一个简单的 D E M O DEMO DEMO。 S T M 32 H 750 X B H 6 STM32H750XBH6 STM32H750XBH6这款芯片的 F D C A N FD\quad CAN FDCAN模块采用的是 B O S C H BOSCH BOSCH公司的 M _ T T C A N M\_TTCAN M_TTCAN这个 I P IP IP,因此 S T M 32 H 750 X B H 6 STM32H750XBH6 STM32H750XBH6这款芯片的 F D C A N FD\quad CAN FDCAN模块是支持 T T C A N TTCAN TTCAN协议的,但是在使用中需要注意的是,这款芯片的 F D C A N FD\quad CAN FDCAN模块一共有两个 I n s t a n c e Instance Instance: F D C A N 1 FD\quad CAN\quad 1 FDCAN1和 F D C A N 2 FD\quad CAN\quad 2 FDCAN2其中只有 F D C A N 1 FD\quad CAN\quad 1 FDCAN1是支持 T T C A N TTCAN TTCAN协议。对于野火的 S T M 32 H 750 X B H 6 STM32H750XBH6 STM32H750XBH6开发板,野火官方给出的普通 D E M O DEMO DEMO是基于 F D C A N 2 FD\quad CAN\quad 2 FDCAN2的,野火的 S T M 32 H 750 X B H 6 STM32H750XBH6 STM32H750XBH6这款开发板上面的 C A N CAN CAN收发器的引脚也被固定死了在 S T M 32 H 750 X B H 6 STM32H750XBH6 STM32H750XBH6这款芯片的 F D C A N 2 FD\quad CAN\quad 2 FDCAN2模块的 P B 6 PB6 PB6和 P B 5 PB5 PB5引脚上。因此下面针对 T T C A N TTCAN TTCAN协议的 D E M O DEMO DEMO就无法使用板子自带的 C A N CAN CAN收发器而必须使用自己的收发器,其使用的引脚是 T X : P A 12 TX:PA12 TX:PA12和 R X : P A 11 RX:PA11 RX:PA11。
从这篇文章我们可以了解到在 H A L HAL HAL库中的 S y s t e m I n i t ( v o i d ) SystemInit(void) SystemInit(void)函数里面没有像标准库里面的 S y s t e m I n i t ( v o i d ) SystemInit(void) SystemInit(void)函数一样去调用 S e t S y s C l o c k ( v o i d ) SetSysClock (void) SetSysClock(void)函数来对整个系统的时钟进行初始化,因为 H A L HAL HAL库里面也没有现成的 S e t S y s C l o c k ( v o i d ) SetSysClock (void) SetSysClock(void)函数。因此这里我们首先使用 S T M 32 C u b e M X STM32\quad CubeMX STM32CubeMX工具来生成整个系统时钟的基本配置函数,这里整个系统时钟的基本配置如图17所示,具体的操作也请参考这篇文章。这里野火的 S T M 32 H 750 X B H 6 STM32H750XBH6 STM32H750XBH6开发板上面的外部晶振的频率为 25 M H Z 25MHZ 25MHZ, P L L PLL PLL的时钟源采用 H S E HSE HSE时钟, F D C A N 2 FD\quad CAN\quad 2 FDCAN2模块的内核时钟采用 p l l 1 _ q _ c k pll1\_q\_ck pll1_q_ck,如图18所示(对应图17中红圈中的时钟, 40 M H Z 40MHZ 40MHZ)。 S T M 32 C u b e M X STM32\quad CubeMX STM32CubeMX工具生成的整个系统时钟的基本配置函数如下所示。
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/** Supply configuration update enable
*/
HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);
/** Configure the main internal regulator output voltage
*/
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {}
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 5;
RCC_OscInitStruct.PLL.PLLN = 160;
RCC_OscInitStruct.PLL.PLLP = 2;
RCC_OscInitStruct.PLL.PLLQ = 20;
RCC_OscInitStruct.PLL.PLLR = 2;
RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2;
RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
RCC_OscInitStruct.PLL.PLLFRACN = 0;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
|RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
具体的 D E M O DEMO DEMO如下详细介绍,这里的 D E M O DEMO DEMO基本上都使用了两块开发板,一块作为 t i m e m a s t e r time\quad master timemaster另一块作为 t i m e s l a v e time\quad slave timeslave(这个 I P IP IP的 T T C A N TT\quad CAN TTCAN$)。
D E M O 1 DEMO\quad 1 DEMO1,基本的 T T C A N L e v e l 1 TT\quad CAN\quad Level\quad1 TTCANLevel1通信:板1( t i m e m a s t e r time\quad master timemaster)和板2( t i m e s l a v e time\quad slave timeslave)都配置为正常模式,且为严格的 T T C A N TT\quad CAN TTCAN操作模式。这里 T h e n o m i n a l b i t r a t e The\quad nominal\quad bit\quad rate Thenominalbitrate配置为 500 K 500K 500K(因为协议要求在 T T C A N L e v e l 1 TT\quad CAN\quad Level\quad1 TTCANLevel1下一个 N T U NTU NTU时间为一个比特位,以 T h e n o m i n a l b i t r a t e The\quad nominal\quad bit\quad rate Thenominalbitrate为准,所占用的时间,因此这里TUR的值配置为80, 80 ∗ 25 n s = 2 u s = 500 k , t t _ p a r a m e t e r . T U R N u m e r a t o r = 0 x 13880 , t t _ p a r a m e t e r . T U R D e n o m i n a t o r = 0 x 03 E 8 80 * 25 ns=2 us=500k, tt\_parameter.TURNumerator=0x13880,tt\_parameter.TURDenominator=0x03E8 80∗25ns=2us=500k,tt_parameter.TURNumerator=0x13880,tt_parameter.TURDenominator=0x03E8), D a t a f i e l d b i t r a t e Data\quad field\quad bit\quad rate Datafieldbitrate配置为 2 M 2M 2M。这里板1只发送消息,因此没有配置过滤器。板1配置了 T x _ T r i g g e r _ S i n g l e Tx\_Trigger\_Single Tx_Trigger_Single, T X _ T r i g g e r _ C o n t i n o u s TX\_Trigger\_Continous TX_Trigger_Continous, T x _ T r i g g e r _ M e r g e d Tx\_Trigger\_Merged Tx_Trigger_Merged, T x _ T r i g g e r _ A r b i t r a t i o n Tx\_Trigger\_Arbitration Tx_Trigger_Arbitration, T x _ R e f _ T r i g g e r Tx\_Ref\_Trigger Tx_Ref_Trigger和 W a t c h _ T r i g g e r Watch\_Trigger Watch_Trigger等几种 T r i g g e r Trigger Trigger。板2配置了 R X _ T r i g g e r RX\_Trigger RX_Trigger和 W a t c h _ T r i g g e r Watch\_Trigger Watch_Trigger两种 T r i g g e r Trigger Trigger。板2配置了两个 R X _ T r i g g e r RX\_Trigger RX_Trigger,分别用来检查板1的 T x _ T r i g g e r _ S i n g l e Tx\_Trigger\_Single Tx_Trigger_Single和 T X _ T r i g g e r _ C o n t i n o u s TX\_Trigger\_Continous TX_Trigger_Continous发送的消息是否按时接收到了。这里需要注意的是 R X _ T r i g g e r RX\_Trigger RX_Trigger仅仅用来检查 e x c l u s i v e t i m e w i n d o w s exclusive\quad time\quad windows exclusivetimewindows(针对 T x _ T r i g g e r _ S i n g l e Tx\_Trigger\_Single Tx_Trigger_Single和 T X _ T r i g g e r _ C o n t i n o u s TX\_Trigger\_Continous TX_Trigger_Continous)发送的消息的接收而不用于检查 a r b i t r a t i n g t i m e w i n d o w s arbitrating\quad time\quad windows arbitratingtimewindows(针对 T x _ T r i g g e r _ M e r g e d Tx\_Trigger\_Merged Tx_Trigger_Merged和 T x _ T r i g g e r _ A r b i t r a t i o n Tx\_Trigger\_Arbitration Tx_Trigger_Arbitration)发送的消息的接收。这里板2配置了两个过滤器,一个用来过滤接收 T x _ T r i g g e r _ S i n g l e Tx\_Trigger\_Single Tx_Trigger_Single和 T X _ T r i g g e r _ C o n t i n o u s TX\_Trigger\_Continous TX_Trigger_Continous发送的消息,另一个用来过滤接收 T x _ T r i g g e r _ M e r g e d Tx\_Trigger\_Merged Tx_Trigger_Merged和 T x _ T r i g g e r _ A r b i t r a t i o n Tx\_Trigger\_Arbitration Tx_Trigger_Arbitration发送的消息。这里配置一个系统矩阵有8个基本周期。这里有一些点需要注意的是:
D E M O 3 DEMO\quad 3 DEMO3,基本的 T T C A N L e v e l 2 TT\quad CAN\quad Level\quad2 TTCANLevel2通信:和 D E M O 1 DEMO\quad 1 DEMO1基本一样,只是配置成 l e v e l 2 level\quad 2 level2且系统矩阵配置为32个基本周期
D E M O 4 DEMO\quad 4 DEMO4,基本的 T T C A N L e v e l 1 TT\quad CAN\quad Level\quad1 TTCANLevel1通信+ g a p gap gap+ E x t e r n a l e v e n t − s y n c h r o n i z e d External\quad event-synchronized Externalevent−synchronized:和 D E M O 2 DEMO\quad 2 DEMO2基本一样,只是配置成 l e v e l 2 level\quad 2 level2且系统矩阵配置为64个基本周期
D E M O 5 DEMO\quad 5 DEMO5,基本的 T T C A N L e v e l 2 TT\quad CAN\quad Level\quad2 TTCANLevel2通信+ F r e q u e n c y a d j u s t m e n t Frequency\quad adjustment Frequencyadjustment(这里需要使能自动时钟校准以及外部时钟同步功能, T T O C F TTOCF TTOCF寄存器的 E C C ECC ECC位和 E E C S EECS EECS位需要置1):板1( t i m e m a s t e r time\quad master timemaster)和板2( t i m e s l a v e time\quad slave timeslave)都配置为正常模式,且为严格的 T T C A N TT\quad CAN TTCAN操作模式。这里 T h e n o m i n a l b i t r a t e The\quad nominal\quad bit\quad rate Thenominalbitrate配置为 20 K 20K 20K(在 T T C A N L e v e l 2 TT\quad CAN\quad Level\quad2 TTCANLevel2下没有要求一个 N T U NTU NTU时间为一个比特位,但是这里为了方便,配置 N T U NTU NTU时间为一个比特位时间,以 T h e n o m i n a l b i t r a t e The\quad nominal\quad bit\quad rate Thenominalbitrate为准,因此这里TUR的值配置为2000, 2000 ∗ 25 n s = 50 u s = 20 k , t t _ p a r a m e t e r . T U R N u m e r a t o r = 0 x 13880 , t t _ p a r a m e t e r . T U R D e n o m i n a t o r = 0 x 0028 2000 * 25 ns=50 us=20k, tt\_parameter.TURNumerator=0x13880,tt\_parameter.TURDenominator=0x0028 2000∗25ns=50us=20k,tt_parameter.TURNumerator=0x13880,tt_parameter.TURDenominator=0x0028), D a t a f i e l d b i t r a t e Data\quad field\quad bit\quad rate Datafieldbitrate配置为 2 M 2M 2M。这里板1只发送消息,因此没有配置过滤器。板1配置了 T X _ T r i g g e r _ C o n t i n o u s TX\_Trigger\_Continous TX_Trigger_Continous, T x _ R e f _ T r i g g e r Tx\_Ref\_Trigger Tx_Ref_Trigger和 W a t c h _ T r i g g e r Watch\_Trigger Watch_Trigger等几种 T r i g g e r Trigger Trigger。板2配置了 R X _ T r i g g e r RX\_Trigger RX_Trigger和 W a t c h _ T r i g g e r Watch\_Trigger Watch_Trigger两种 T r i g g e r Trigger Trigger。板2配置了1个 R X _ T r i g g e r RX\_Trigger RX_Trigger用来检查板1的 T X _ T r i g g e r _ C o n t i n o u s TX\_Trigger\_Continous TX_Trigger_Continous发送的消息是否按时接收到了。这里板2配置了1个过滤器,用来过滤接收 T X _ T r i g g e r _ C o n t i n o u s TX\_Trigger\_Continous TX_Trigger_Continous发送的消息。这里有一些点需要注意的是:
D E M O 6 DEMO\quad 6 DEMO6,基本的 T T C A N L e v e l 2 TT\quad CAN\quad Level\quad2 TTCANLevel2通信+ P h a s e a d j u s t m e n t Phase\quad adjustment Phaseadjustment(这里需要使能自动时钟校准以及外部时钟同步功能, T T O C F TTOCF TTOCF寄存器的 E C C ECC ECC位和 E E C S EECS EECS位需要置1):板1( t i m e m a s t e r time\quad master timemaster)和板2( t i m e s l a v e time\quad slave timeslave)都配置为正常模式,且为严格的 T T C A N TT\quad CAN TTCAN操作模式。这里 T h e n o m i n a l b i t r a t e The\quad nominal\quad bit\quad rate Thenominalbitrate配置为 20 K 20K 20K(在 T T C A N L e v e l 2 TT\quad CAN\quad Level\quad2 TTCANLevel2下没有要求一个 N T U NTU NTU时间为一个比特位,但是这里为了方便,配置 N T U NTU NTU时间为一个比特位时间,以 T h e n o m i n a l b i t r a t e The\quad nominal\quad bit\quad rate Thenominalbitrate为准,因此这里TUR的值配置为2000, 2000 ∗ 25 n s = 50 u s = 20 k , t t _ p a r a m e t e r . T U R N u m e r a t o r = 0 x 13880 , t t _ p a r a m e t e r . T U R D e n o m i n a t o r = 0 x 0028 2000 * 25 ns=50 us=20k, tt\_parameter.TURNumerator=0x13880,tt\_parameter.TURDenominator=0x0028 2000∗25ns=50us=20k,tt_parameter.TURNumerator=0x13880,tt_parameter.TURDenominator=0x0028), D a t a f i e l d b i t r a t e Data\quad field\quad bit\quad rate Datafieldbitrate配置为 2 M 2M 2M。这里板1只发送消息,因此没有配置过滤器。板1配置了 T X _ T r i g g e r _ C o n t i n o u s TX\_Trigger\_Continous TX_Trigger_Continous, T x _ R e f _ T r i g g e r Tx\_Ref\_Trigger Tx_Ref_Trigger和 W a t c h _ T r i g g e r Watch\_Trigger Watch_Trigger等几种 T r i g g e r Trigger Trigger。板2配置了 R X _ T r i g g e r RX\_Trigger RX_Trigger和 W a t c h _ T r i g g e r Watch\_Trigger Watch_Trigger两种 T r i g g e r Trigger Trigger。板2配置了1个 R X _ T r i g g e r RX\_Trigger RX_Trigger用来检查板1的 T X _ T r i g g e r _ C o n t i n o u s TX\_Trigger\_Continous TX_Trigger_Continous发送的消息是否按时接收到了。这里板2配置了1个过滤器,用来过滤接收 T X _ T r i g g e r _ C o n t i n o u s TX\_Trigger\_Continous TX_Trigger_Continous发送的消息。等到整个 T T C A N TT\quad CAN TTCAN网络的通信稳定之后,板1修改 T T G T P TTGTP TTGTP寄存器的 T P [ 15 : 0 ] TP[15:0] TP[15:0]域,然后将 T T O C N TTOCN TTOCN寄存器的 S G T SGT SGT位置1,此时板1的 T T O S T TTOST TTOST寄存器的 W G T D WGTD WGTD位会被置1, W G T D WGTD WGTD位被置1的状态会一直持续到下一个参考消息的发送,这个参考消息中的 D I S C DISC DISC位会被置1( D I S C DISC DISC位被置1的参考消息不会用于 T U R TUR TUR值更新的计算),此时板1的 g l o b a l t i m e global\quad time globaltime会被更新,从 T T L G T TTLGT TTLGT寄存器的 G T [ 15 : 0 ] GT[15:0] GT[15:0]域的值可以看出, G T [ 15 : 0 ] GT[15:0] GT[15:0]域的值相比之前出现了一次跳跃(出现在 W G T D WGTD WGTD位被置0之后),(更新基于设置的TTGTP寄存器的TP[15:0]域),也就相当于板1的 l o c a l o f f s e t local\quad offset localoffset被更新了。板2收到板1发送的 D I S C DISC DISC位被置1的参考消息之后, T T I R TTIR TTIR寄存器的 G T D GTD GTD位会被置1,同时 g l o b a l t i m e global\quad time globaltime也会被更新,从 T T L G T TTLGT TTLGT寄存器的 G T [ 15 : 0 ] GT[15:0] GT[15:0]域的值可以看出, G T [ 15 : 0 ] GT[15:0] GT[15:0]域的值相比之前出现了一次跳跃,也就相当于板2的 l o c a l o f f s e t local\quad offset localoffset被更新了。如图22和图23所示,图22对应板1,图23对应板2。
D E M O 7 DEMO\quad 7 DEMO7,基本的 T T C A N L e v e l 0 TT\quad CAN\quad Level\quad 0 TTCANLevel0通信+ F r e q u e n c y a d j u s t m e n t Frequency\quad adjustment Frequencyadjustment(这里需要使能自动时钟校准以及外部时钟同步功能, T T O C F TTOCF TTOCF寄存器的 E C C ECC ECC位和 E E C S EECS EECS位需要置1):板1( t i m e m a s t e r time\quad master timemaster)和板2( t i m e s l a v e time\quad slave timeslave)都配置为正常模式,且为严格的 T T C A N TT\quad CAN TTCAN操作模式(这里应该可以不关心,因为 T T C A N L e v e l 0 TT\quad CAN\quad Level\quad 0 TTCANLevel0不支持外部事件同步的 T T C A N TT\quad CAN TTCAN操作模式)。这里 T h e n o m i n a l b i t r a t e The\quad nominal\quad bit\quad rate Thenominalbitrate配置为 20 K 20K 20K(在 T T C A N L e v e l 0 TT\quad CAN\quad Level\quad0 TTCANLevel0下没有要求一个 N T U NTU NTU时间为一个比特位,但是这里为了方便,配置 N T U NTU NTU时间为一个比特位时间,以 T h e n o m i n a l b i t r a t e The\quad nominal\quad bit\quad rate Thenominalbitrate为准,因此这里TUR的值配置为2000, 2000 ∗ 25 n s = 50 u s = 20 k , t t _ p a r a m e t e r . T U R N u m e r a t o r = 0 x 13880 , t t _ p a r a m e t e r . T U R D e n o m i n a t o r = 0 x 0028 2000 * 25 ns=50 us=20k, tt\_parameter.TURNumerator=0x13880,tt\_parameter.TURDenominator=0x0028 2000∗25ns=50us=20k,tt_parameter.TURNumerator=0x13880,tt_parameter.TURDenominator=0x0028), D a t a f i e l d b i t r a t e Data\quad field\quad bit\quad rate Datafieldbitrate配置为 2 M 2M 2M。这里板1只发送消息,因此没有配置过滤器,这里板1的普通的消息的发送使用 T X F I F O TX\quad FIFO TXFIFO来进行发送。这里板2配置了1个过滤器,用来过滤接收板1用 T X F I F O TX\quad FIFO TXFIFO发送的消息。这里板1和板2都没有配置 T r i g g e r M e m o r y Trigger\quad Memory TriggerMemory。在最开始的时候板2的 t t _ p a r a m e t e r . T U R N u m e r a t o r , t t _ p a r a m e t e r . T U R D e n o m i n a t o r tt\_parameter.TURNumerator,tt\_parameter.TURDenominator tt_parameter.TURNumerator,tt_parameter.TURDenominator配置和板1的 t t _ p a r a m e t e r . T U R N u m e r a t o r , t t _ p a r a m e t e r . T U R D e n o m i n a t o r tt\_parameter.TURNumerator,tt\_parameter.TURDenominator tt_parameter.TURNumerator,tt_parameter.TURDenominator配置不一样,板2的 t t _ p a r a m e t e r . T U R N u m e r a t o r , t t _ p a r a m e t e r . T U R D e n o m i n a t o r tt\_parameter.TURNumerator,tt\_parameter.TURDenominator tt_parameter.TURNumerator,tt_parameter.TURDenominator配置为 t t _ p a r a m e t e r . T U R N u m e r a t o r = 0 x 13800 , t t _ p a r a m e t e r . T U R D e n o m i n a t o r = 0 x 0028 tt\_parameter.TURNumerator=0x13800,tt\_parameter.TURDenominator=0x0028 tt_parameter.TURNumerator=0x13800,tt_parameter.TURDenominator=0x0028。板1每间隔一段时间发送一个参考消息和一个普通的消息(这里软件通过读取 T T C T C TTCTC TTCTC寄存器的 C T [ 15 : 0 ] CT[15:0] CT[15:0]域,也就是 c y c l e t i m e cycle\quad time cycletime,当 C T [ 15 : 0 ] CT[15:0] CT[15:0]域的值为 0 x 4000 0x4000 0x4000的时候发送普通消息,当 C T [ 15 : 0 ] CT[15:0] CT[15:0]域的值为 0 x 6000 0x6000 0x6000的时候发送参考消息,)一段时间之后我们可以看到板2的 T U R N A TURNA TURNA寄存器的值逐渐调整的和板1的接近。之后过一段时间之后板1再次修改 T U R C F TURCF TURCF寄存器的 N C L [ 15 : 0 ] NCL[15:0] NCL[15:0]域(修改之后需要将 T T O C N TTOCN TTOCN寄存器的 E C S ECS ECS位置1)使得 T U R N A TURNA TURNA寄存器的值变为 0 x 138 F F 0x138FF 0x138FF。我们应该可以发现过一段时间之后板2的 T U R N A TURNA TURNA寄存器的值再次逐渐调整的和板1的接近。这里有一些点需要注意的是:
D E M O 8 DEMO\quad 8 DEMO8,基本的 T T C A N L e v e l 0 TT\quad CAN\quad Level\quad 0 TTCANLevel0通信+ P h a s e a d j u s t m e n t Phase\quad adjustment Phaseadjustment(这里需要使能自动时钟校准以及外部时钟同步功能, T T O C F TTOCF TTOCF寄存器的 E C C ECC ECC位和 E E C S EECS EECS位需要置1):板1( t i m e m a s t e r time\quad master timemaster)和板2( t i m e s l a v e time\quad slave timeslave)都配置为正常模式,且为严格的 T T C A N TT\quad CAN TTCAN操作模式(这里应该可以不关心,因为 T T C A N L e v e l 0 TT\quad CAN\quad Level\quad 0 TTCANLevel0不支持外部事件同步的 T T C A N TT\quad CAN TTCAN操作模式)。这里 T h e n o m i n a l b i t r a t e The\quad nominal\quad bit\quad rate Thenominalbitrate配置为 20 K 20K 20K(在 T T C A N L e v e l 0 TT\quad CAN\quad Level\quad0 TTCANLevel0下没有要求一个 N T U NTU NTU时间为一个比特位,但是这里为了方便,配置 N T U NTU NTU时间为一个比特位时间,以 T h e n o m i n a l b i t r a t e The\quad nominal\quad bit\quad rate Thenominalbitrate为准,因此这里TUR的值配置为2000, 2000 ∗ 25 n s = 50 u s = 20 k , t t _ p a r a m e t e r . T U R N u m e r a t o r = 0 x 13880 , t t _ p a r a m e t e r . T U R D e n o m i n a t o r = 0 x 0028 2000 * 25 ns=50 us=20k, tt\_parameter.TURNumerator=0x13880,tt\_parameter.TURDenominator=0x0028 2000∗25ns=50us=20k,tt_parameter.TURNumerator=0x13880,tt_parameter.TURDenominator=0x0028), D a t a f i e l d b i t r a t e Data\quad field\quad bit\quad rate Datafieldbitrate配置为 2 M 2M 2M。这里板1只发送消息,因此没有配置过滤器。这里板1和板2都没有配置 T r i g g e r M e m o r y Trigger\quad Memory TriggerMemory。板1每间隔一段时间发送一个参考消息,等到整个 T T C A N L e v e l 0 TT\quad CAN\quad Level\quad 0 TTCANLevel0网络的通信稳定之后板1修改 T T G T P TTGTP TTGTP寄存器的 T P [ 15 : 0 ] TP[15:0] TP[15:0]域,然后将 T T O C N TTOCN TTOCN寄存器的 S G T SGT SGT位置1,此时板1的 T T O S T TTOST TTOST寄存器的 W G T D WGTD WGTD位会被置1, W G T D WGTD WGTD位被置1的状态会一直持续到下一个参考消息的发送,这个参考消息中的 D I S C DISC DISC位会被置1( D I S C DISC DISC位被置1的参考消息不会用于 T U R TUR TUR值更新的计算),此时板1的 g l o b a l t i m e global\quad time