⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dnet development dnd欢迎你的到来2.htm

📁 canopen 通信协议
💻 HTM
📖 第 1 页 / 共 2 页
字号:
                <P 
                style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; WORD-SPACING: 0px">&nbsp;</P>
                <P 
                style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; WORD-SPACING: 0px" 
                150% ;line-height:><FONT 
                face=Tahoma>以前曾经有一段时间认真的想过CAN数据报文中的ACK应答机制问题,原以为自己想通了,但前两天又再想想,觉得还是没有想清楚故将其放到论坛上,虽然到如今还没有人来回复,但通过与一些朋友的确认,发现自己犯了一个不小错误,对协议本身的理解产生了错误,以至后来竟无法找到答案,改换过前提后,问题得以解决。下面将此次思考的情况一一列出,以希各位同道中的朋友不要再犯与我相似之低级错误:) 
                <BR><BR><BR>CAN协议里对ACK(应答场)有如下的描述: <BR><BR>应答场长度为2 个位,包含应答间隙(ACK 
                SLOT)和应答界定符(ACK 
                DELIMITER)。在应答场里,发送站发送两个“隐性”位。当接收器正确地接收到有效的报文,接收器就会在应答间隙(ACK 
                SLOT)期间(发送ACK 信号)向发送器发送一“显性”的位以示应答。 <BR><BR>应答间隙:所有接收到匹配CRC 
                序列(CRC SEQUENCE)的站会在应答间隙(ACK SLOT)期间用一“显性”的位写入发送器的“隐性”位来作出回答。 
                <BR>ACK 界定符:ACK 界定符是ACK 场的第二个位,并且是一个必须为“隐性”的位。因此,应答间隙(ACK 
                SLOT)被两个“隐性”的位所包围,也就是CRC 界定符(CRC DELIMITER)和ACK 界定符(ACK 
                DELIMITER)。 <BR><BR><IMG height=182 
                src="DNet Development DND欢迎你的到来2.files/ack.jpg" width=473 
                border=0> <BR><BR>在CAN协议的错误检测部分有这样的描述: 
                <BR><BR>位错误:站单元在发送位的同时也对总线进行监视。如果所发送的位值与所监视的位值不相符合,则在此位时间里检测到一个位错误(BIT 
                ERROR)。但是在仲裁场(ARBITRATION FIELD)的填充位流期间或ACK间隙(ACK 
                SLOT)发送一“隐性”位的情况是例外的—— 此时,当监视到一“显性”位时,不会发出位错误(BIT ERROR)。 
                <BR><BR>应答错误:只要在ACK 间隙(ACK SLOT)期间所监视的位不为“显性”,则发送器会检测到一个应答错误 
                <BR>(ACKNOWLEDGMENT ERROR)。 
                <BR><BR>从协议所描述的内容来看,我们不难得出一个结论:CAN是一种基于广播的通讯方式,为了保证总线上的每一个节点(处于normal 
                mode)都能正确的接收到报文,报文的发送者要求每一个接收节点在报文发送结束前,也就是ACK 
                slot的时间内,作出应答,即要求接收的节点都在这个时间发送一个“显性”位。发送者在发送的同时,会监视总线上的数据,如果与发送的娄据不一致,则表示发送失败或自己失去仲裁,立即停止发送或转入接收模式。如果有一个节点在ACK 
                SLOT的时间内发送“显性”位,则发送者认为此次发送报文成功;如果发送者检测到ACK SLOT为隐性位,则表示没有节点填充ACK 
                SLOT,则发送者会检测到这个隐性位而知道发送失败,此条报文需要重发。所以,当总线上只有一个节点的时候,或是只有一个节点可以收发数据的时候,这个节点是发不出去数据的,因为它所发出的数据帧中的ACK 
                SLOT没有另外一个节点来填充,将永远是隐性位,这个节点会一直重发数据直到BUS OFF状态。 <BR><BR>ACK 
                SLOT只有一个BIT,而接下去的ACK delimiter始终为隐性(我们可认为是1),当数据到达ACK 
                SLOT的时候,所有的节点都会发送显性位(我们可以认为是0),而发送者在ACK这个时间里保持隐性位(即发送者在发送的时候ACK 
                SLOT 
                为1),这时发送者会检测总线上的ACK时间内的信号,如果是0,则表示正确,如果是1,表示有错误。如果当中有某一个节点在ACK 
                SLOT填入隐性位,则总线上同样还是显性位电平,故只要总线上有一个节点正确接收到数据,则ACK 
                SLOT就会被填入显性电平;那么,接收错误的节点如何来告知发送者此次发送不成功呢?这时候就要用到CAN的错误帧,当一个接收者收到错误的数据的时候,它立即开始发送一个错误帧,则接下去总线上的信号就是这个错误帧,其它的节点和发送者也都会收到这个错误帧,那所有的节点都知道出错了,接收者会丢掉此次消息,而发送者会试图重发此次消息。这才是ACK 
                SLOT真正的含义。 <BR><BR>  <BR><BR>下面我们通过一个实例来看看CAN节点是如何进行ACK 
                SLOT的动作的。我们抓取一个总线上面的信号波形,此波形已经是通过82C251解码过后的。 <BR><BR><IMG 
                height=381 src="DNet Development DND欢迎你的到来2.files/ack_b.jpg" 
                width=523 border=0> 
                <BR><BR>抓取的波形,图中的四个通道分别表示两个节点的CANTX和CANRX,其中通道A,B表示NODE 1 
                的CANTX和CANRX,通道C,D表示NODE 2 
                的CANTX和CANRX。将其正对坐标中轴的部分展开,得到如下的图形,由上图我们清楚的看到,NODE 
                1的CANTX在接收到数据后立即响应,即向外发送数据,当数据发送完毕,到了ACK的时间内,见下图中黄色图标处,NODE 
                1的CANTX发送两个隐性位,而对于NODE 2,当发送者NODE 
                1的CANTX到了报文的ACK时间,NODE2也接收完数据,如果CRC校验通过,则NODE2的CANTX会相应的发送显性位,即通道C的红色图标处。如果总线上存在NODE 
                3和NODE 4或是更多NODE,则波形相同。图中的B和D都是CANRX,所以都有ACK的显性位出现。 <BR><BR><IMG 
                height=382 src="DNet Development DND欢迎你的到来2.files/ack_de.jpg" 
                width=520 border=0> 
                <BR><BR>我们认为,发送者在发数据的时候,CANTX在发送数据,而CANRX同时也在接收数据,当发送者发送ACK为隐性时,接收到的ACK 
                SLOT一定要是显性才会正确。那么,当有节点正确接收到了数据,在ACK 
                SLOT填上显性位后,接收错误的节点这时候会如何呢?接收错误的节点就会马上发送错误帧,一般是发送连续的6个0或1,根据CAN的位填充原理,当有五个连续的0或1出现时,为了传送中的同步,必须插入一个反相位的BIT作为填充位,如果连续出现6个或以上的相同信号,则此次传送错误,数据将被丢弃。故当发送者收到这个错误帧后,便会知道发送出错,并试图重发数据。 
                <BR></FONT></P>
                <P 
                style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; WORD-SPACING: 0px"> 
                </P>
                <P 
                style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; WORD-SPACING: 0px"> 
                </P></P></TR></TBODY></TABLE>
            <TABLE height=107 cellSpacing=0 cellPadding=0 width=475 border=0>
              <TBODY>
              <TR>
                <TD vAlign=top width="100%" 
                background="DNet Development DND欢迎你的到来2.files/bg_head.jpg" 
                height=21><FONT size=+0> </FONT></TD></TR>
              <TR>
                <TD width="100%" 
                background="DNet Development DND欢迎你的到来2.files/bg_mid.jpg">
                  <TABLE cellSpacing=10 cellPadding=0 width="100%" border=0>
                    <TBODY>
                    <TR>
                      <TD width="100%">
                        <TABLE borderColor=#ffffff cellSpacing=0 cellPadding=0 
                        width="100%" bgColor=#404040 border=0>
                          <TBODY>
                          <TR>
                            <TD width="20%">
                              <P align=left><IMG 
                              src="DNet Development DND欢迎你的到来2.files/gbook.gif"><FONT 
                              face=Tahoma>&nbsp;zilch </FONT></P></TD>
                            <TD width="40%"><FONT 
                              face=Tahoma>&nbsp;[00013] <FONT 
                              size=+0></FONT></FONT></TD>
                            <TD width="40%">
                              <P align=right><FONT face=Tahoma>发表于2005-06-17 
                              15:54 </FONT></P></TD></TR></TBODY></TABLE>
                        <P 
                        style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; WORD-SPACING: 0px; LINE-HEIGHT: 100%"><FONT 
                        face=Tahoma> <FONT size=+0></P>
                        <P 
                        style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; WORD-SPACING: 0px; LINE-HEIGHT: 150%"><FONT 
                        face=Tahoma>好厉害啊,看得头疼. 
                        <BR>能给讲解下在一个节点发送完了以后其余节点判断总线空闲是怎么回事吗?</FONT></P>
                        <P 
                        style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; WORD-SPACING: 0px; LINE-HEIGHT: 100%"><FONT 
                        face=Tahoma> <FONT size=+0></P>
                        <TABLE borderColor=#ffffff cellSpacing=0 cellPadding=0 
                        width="100%" bgColor=#404040 border=0>
                          <TBODY>
                          <TR>
                            <TD width="20%">
                              <P align=left><IMG 
                              src="DNet Development DND欢迎你的到来2.files/gbook.gif"><FONT 
                              face=Tahoma>&nbsp;XSmart64 </FONT></P></TD>
                            <TD width="40%"><FONT 
                              face=Tahoma>&nbsp;[00015] <FONT 
                              size=+0></FONT></FONT></TD>
                            <TD width="40%">
                              <P align=right><FONT face=Tahoma>发表于2005-07-09 
                              11:39 </FONT></P></TD></TR></TBODY></TABLE>
                        <P 
                        style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; WORD-SPACING: 0px; LINE-HEIGHT: 100%"><FONT 
                        face=Tahoma> <FONT size=+0></P>
                        <P 
                        style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; WORD-SPACING: 0px; LINE-HEIGHT: 150%"><FONT 
                        face=Tahoma>我的理解和远方兄弟的在大体上一致,但是在细节上有一些偏差。一:总线上只有一个节点而且它向外发送了数据。它确实不会收到任何ACK,它会变成“error 
                        passive”但是它不会变成BUS off。why?请参考CAN specificaton 
                        2.0-partB-Fault_Confinement--rule3--exception1 
                        <BR>二:其它检测到CRC错误的节点不会马上发送错误帧,而是在ACK 
                        delimiter之后才发送。请参考CAN specificaton 
                        2.0-partB-Error_Signalling</FONT></P>
                        <P 
                        style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; WORD-SPACING: 0px; LINE-HEIGHT: 100%"><FONT 
                        face=Tahoma> <FONT size=+0></P>
                        <TABLE borderColor=#ffffff cellSpacing=0 cellPadding=0 
                        width="100%" bgColor=#404040 border=0>
                          <TBODY>
                          <TR>
                            <TD width="20%">
                              <P align=left><IMG 
                              src="DNet Development DND欢迎你的到来2.files/gbook.gif"><FONT 
                              face=Tahoma>&nbsp;远方 </FONT></P></TD>
                            <TD width="40%"><FONT 
                              face=Tahoma>&nbsp;[00016] <FONT 
                              size=+0></FONT></FONT></TD>
                            <TD width="40%">
                              <P align=right><FONT face=Tahoma>发表于2005-08-09 
                              07:48 </FONT></P></TD></TR></TBODY></TABLE>
                        <P 
                        style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; WORD-SPACING: 0px; LINE-HEIGHT: 100%"><FONT 
                        face=Tahoma> <FONT size=+0></P>
                        <P 
                        style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; WORD-SPACING: 0px; LINE-HEIGHT: 150%"><FONT 
                        face=Tahoma>謝謝XSmart64兄弟的更正,這是我的錯誤: <BR><BR>上文中的這段話: 
                        <BR><BR>所以,当总线上只有一个节点的时候,或是只有一个节点可以收发数据的时候,这个节点是发不出去数据的,因为它所发出的数据帧中的ACK 
                        SLOT没有另外一个节点来填充,将永远是隐性位,这个节点会一直重发数据直到BUS OFF状态。 
                        <BR><BR>應該更改為: 
                        <BR><BR>所以,当总线上只有一个节点的时候,或是只有一个节点可以收发数据的时候,这个节点是发不出去数据的,因为它所发出的数据帧中的ACK 
                        SLOT没有另外一个节点来填充,将永远是隐性位,这个节点会一直重发数据直到发送成功或发送被取消。 
                        <BR></FONT></P>
                        <P 
                        style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; WORD-SPACING: 0px; LINE-HEIGHT: 100%"><FONT 
                        face=Tahoma> <FONT 
                        size=+0></P></FONT></FONT></FONT></FONT></FONT></FONT></FONT></FONT></FONT></FONT></FONT></FONT></TD></TR></TBODY></TABLE></TD></TR>
              <TR>
                <TD vAlign=top width="100%" 
                background="DNet Development DND欢迎你的到来2.files/bg_tail.jpg" 
                height=10><FONT face=Tahoma><FONT 
              size=+0> </FONT></FONT></TD></TR></TBODY></TABLE>
            <TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
              <TBODY></TBODY></TABLE>
            <TABLE height=190 cellSpacing=0 cellPadding=0 width=480 
            background="DNet Development DND欢迎你的到来2.files/bg_res.jpg" 
              border=0><TBODY>
              <TR>
                <TD vAlign=top width=469 height=172>
                  <TABLE height=176 cellSpacing=0 cellPadding=10 width="100%" 
                  border=0>
                    <TBODY>
                    <TR>
                      <TD width="100%" height=18></TD></TR>
                    <TR>
                      <TD width="100%" height=134>
                        <FORM action=addpaper.pl method=post>
                        <P 
                        style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; WORD-SPACING: 0px; LINE-HEIGHT: 100%"><FONT 
                        face=Tahoma>姓 名: <INPUT 
                        style="COLOR: #ffffff; BORDER-TOP-STYLE: groove; BORDER-RIGHT-STYLE: groove; BORDER-LEFT-STYLE: groove; BACKGROUND-COLOR: #000000; BORDER-BOTTOM-STYLE: groove" 
                        maxLength=16 size=10 name=user> &nbsp;&nbsp;密 码: <INPUT 
                        style="COLOR: #ffffff; BORDER-TOP-STYLE: groove; BORDER-RIGHT-STYLE: groove; BORDER-LEFT-STYLE: groove; BACKGROUND-COLOR: #000000; BORDER-BOTTOM-STYLE: groove" 
                        type=password size=10 name=passwd> <A 
                        href="http://www.dndev.com/cgi-bin/register.pl?action=new" 
                        target=_blank>注册</A> <A 
                        href="http://www.dndev.com/cgi-bin/register.pl?action=mod" 
                        target=_blank>修改</A> </FONT>
                        <P 
                        style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; WORD-SPACING: 0px; LINE-HEIGHT: 100%"><TEXTAREA style="FONT-SIZE: 9pt; COLOR: #cccccc; FONT-FAMILY: Tahoma; BACKGROUND-COLOR: #000000" name=detail rows=5 cols=60 groove? border-style: ;></TEXTAREA></P>
                        <P 
                        style="MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px; WORD-SPACING: 0px; LINE-HEIGHT: 100%" 
                        align=center><FONT face=Tahoma><INPUT type=hidden 
                        value=11 name=ID> <INPUT type=hidden value=res name=OP> 
                        <INPUT type=hidden value=2 name=Class> <INPUT style="COLOR: #cccccc; BORDER-TOP-STYLE: groove; BORDER-RIGHT-STYLE: groove; BORDER-LEFT-STYLE: groove; BACKGROUND-COLOR: #000000; BORDER-BOTTOM-STYLE: groove" type=submit value=提交 name=B1>&nbsp; 
<INPUT style="COLOR: #ffffff; BORDER-TOP-STYLE: groove; BORDER-RIGHT-STYLE: groove; BORDER-LEFT-STYLE: groove; BACKGROUND-COLOR: #000000; BORDER-BOTTOM-STYLE: groove" type=reset value=全部重写 name=B2></FONT></P></FORM></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>
            <CENTER></CENTER></TD></TR></TBODY></TABLE></CENTER></TD></TR></TBODY></TABLE>
<TABLE cellPadding=10 width="100%" border=0>
  <TBODY>
  <TR>
    <TD width="100%">
      <HR>

      <P 
      style="MARGIN-TOP: 1px; MARGIN-BOTTOM: 1px; WORD-SPACING: 1px; LINE-HEIGHT: 100%" 
      align=center><FONT face=Tahoma>Copyright &copy; 2003 <A 
      href="http://www.dndev.com/">DnDev.com</A>&nbsp; All Rights 
      Reserved.<BR>DND-DeviceNet 开发网&nbsp; 版权所有</FONT></P>
      <P 
      style="MARGIN-TOP: 1px; MARGIN-BOTTOM: 1px; WORD-SPACING: 1px; LINE-HEIGHT: 100%" 
      align=center><FONT face=Tahoma>制作维护:远方 &nbsp; Email:<A 
      href="mailto:yuanfang@dndev.com">yuanfang@dndev.com</A></FONT></P></TD></TR></TBODY></TABLE>
<P><FONT size=2> </FONT></P></TD></TR></TABLE></CENTER></BODY></HTML>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -