This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS320F28374D:传输中可能会丢失数据

Guru**** 2424730 points
Other Parts Discussed in Thread: C2000WARE

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1049289/tms320f28374d-can-losing-data-in-transmission

器件型号:TMS320F28374D
主题中讨论的其他器件:C2000WARE

大家好,

我正在 CANopen 应用程序中使用 CAN。

现在,我们发现传输中的一些数据 丢失了,根本不会进行通信  。 管道没有溢出,但  数据丢失(我们在 CAN 总线上看不到它们), 我们发现 , 如果我们增加 要发送的数据的频率(如果我们保持在1 ms 之间 或更高,一切都很好),它们就会越来越丢失。  

我们使用此例程 检查将数据推送到 CAN 控制器  、显然没有问题  

   //等待忙位清零

   while (HWREGH (ui32Base + CAN_O_IF1CMD)和 CAN_IF1CMD_BUSY)

   {

   }

 请注意什么问题?    FYI 接收到我们 正在处理的数据、任何 情况下都不会丢失消息  

谢谢你  

BR

卡洛

BR

卡洛

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Carlo、

    您能否提供波特率、有效负载、扩展 ID 或标准 ID 等其他参数?  还有其他节点在传输还是仅 F28379D 器件?  根据这些参数、让我们计算 CAN 总线负载并查看其是否可接受。

    谢谢、

    Joseph  

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    卡洛、

       应用程序是否确保在启动新传输之前完成所有待处理的传输? 这是软件问题。 我认为这与 CAN 模块没有任何关系。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Haresh  

    您可以看到,我们 在下面作为例程等待  , 但  忙位似乎不起作用,因此 字节 丢失  

    这是例程  

       //等待忙位清零

        while (HWREGH (ui32Base + CAN_O_IF1CMD)和 CAN_IF1CMD_BUSY)

    数据 肯定会丢失(我们在总线上的“使用串行器”)。 我们使用 C2000ware (可能不是最新版本)。

    请确认这是否是"忙碌"进行检查  、或者我们会检查另一个信号/位?  为什么不让人绞死呢?

    谢谢你  

    BR

    卡洛

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Carlo、

    参考以下内容:

    [引用 userid="6487" URL"~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1049289/tms320f28374d-can-losing-data-in-transmission/3882862 #3882862"]

       //等待忙位清零

        while (HWREGH (ui32Base + CAN_O_IF1CMD)和 CAN_IF1CMD_BUSY)

    [/报价]

    我经常使用 CAN 通信将数据从不同的 C2000 DCAN 模块发送到 PC (多达16个节点)、并且每个节点发送至少8KB 的数据以进行验证测试(例如:用于线性的 ADC 计数值或用于 FFT 分析的采样数据)。  高于忙位检查也在我的代码中、我能够捕获所有数据。  我认为忙位工作正常。  如果有用、这里是我使用过的 CAN 例程的代码片段(没有机会使用最新的 driverlib 函数更新例程)。

    void TransmitData(uint32_t ui32Base, uint16_t ui16Source, uint32_t ui32SourceClock, uint32_t ui32BitRate, uint32_t startAddr, uint16_t numVars, uint16_t xmitlotinfo)
    {
    	Uint16 i, *staddr, nloop, last_msg_len, sub;
    	Uint32 Scribe, xCoord, yCoord, WfrNum, ScribeLSB, ScribeMSB;
    	float rem;
    
    	staddr = (Uint16 *)startAddr;
    
    	// add die ID
    	xCoord = (lv_dieid[0]&0xfff);
    	yCoord = (lv_dieid[0]>>12)&0xfff;
    	WfrNum = (lv_dieid[0]>>24)&0x3f;
    	Scribe = (lv_dieid[1]&0xffffff);
    	ScribeLSB = Scribe&0xffff;
    	ScribeMSB = Scribe>>16;
    
    	CANInit(ui32Base);
    	CANClkSourceSelect(ui32Base, ui16Source);   // 500kHz CAN-Clock
    	CANBitRateSet(ui32Base, ui32SourceClock, ui32BitRate);
    
    	//
    	// Initialize the transmit message object used for sending CAN messages.
    	// Message Object Parameters:
    
    	sTXCANMessage.ui32MsgID = ScribeLSB + (Uint32)(WfrNum<<16) + (Uint32)(xCoord<<21);
    	sTXCANMessage.ui32MsgIDMask = 0;
    	sTXCANMessage.ui32Flags = 0;//MSG_OBJ_TX_INT_ENABLE;//0;
    	sTXCANMessage.ui32MsgLen = 8;
    	sTXCANMessage.pucMsgData = txMsgData;
    
    	CANEnable(ui32Base);
    
    	nloop = (Uint16)(ceil(((float)numVars/(float)4)));
    	if(xmitlotinfo==0) nloop--;
    	rem = ((float)((float)numVars/(float)4) - floor(((float)numVars/(float)4)))*8;
    	last_msg_len = (Uint16)rem;
    	if(!last_msg_len) last_msg_len = 8;
    
    	// setup timer for CAN transmission delay using 20Mhz OSCIN
    	setup_timer(20);
    
    	// transmit CAN message
    	for(i=0;i<=nloop;i++)
    	{
    
            //sTXCANMessage.ui32MsgID = i + (Uint32)(((WfrNum*3) + (xCoord*25) + (yCoord*23) + xCoord + yCoord)<<16);
            sTXCANMessage.ui32MsgID = i + (Uint32)((((WfrNum-1)*237) + xCoord + ((yCoord-1)*50))<<16);
    		if(i==nloop) sTXCANMessage.ui32MsgLen =  last_msg_len;
    
    		if((i==0)&&xmitlotinfo)  // Transmit DieID information as first frame
    		{
    			txMsgData[0] = xCoord;
    			txMsgData[1] = yCoord;
    			txMsgData[2] = WfrNum;
    			txMsgData[3] = ScribeMSB;
    			txMsgData[4] = ScribeLSB>>8;
    			txMsgData[5] = ScribeLSB&0xff;
    			if(can_rcv_mbx[1])
    			{
    				txMsgData[6] = tempsense_read>>8;
    				txMsgData[7] = tempsense_read&0xff;
    			}
    			else
    			{
    				txMsgData[6] = GPIO_readPortData(7)>>8;
    				txMsgData[7] = GPIO_readPortData(7)&0xff;
    			}
    
    			CANMessageSet(ui32Base, TX_MSG_OBJ_ID, &sTXCANMessage,
    							MSG_OBJ_TYPE_TX_REMOTE);
    			can_xmit_delay();
    		}
    		else
    		{
    			if(xmitlotinfo==1) sub = i-1; else sub = i;
    			txMsgData[0] = staddr[(sub*4)+0]>>8;
    			txMsgData[1] = staddr[(sub*4)+0]&0xff;
    			txMsgData[2] = staddr[(sub*4)+1]>>8;
    			txMsgData[3] = staddr[(sub*4)+1]&0xff;
    			txMsgData[4] = staddr[(sub*4)+2]>>8;
    			txMsgData[5] = staddr[(sub*4)+2]&0xff;
    			txMsgData[6] = staddr[(sub*4)+3]>>8;
    			txMsgData[7] = staddr[(sub*4)+3]&0xff;
    		}
    
    		CANMessageSet(ui32Base, TX_MSG_OBJ_ID, &sTXCANMessage,
    						MSG_OBJ_TYPE_TX);
    		can_xmit_delay();
    
    	}
    
        CANDisable(ui32Base);
    }
    
    void setup_timer(Uint32 oscin_mhz)
    {
    	Uint32 counter_seed;
    
    	EALLOW;
    
    	counter_seed = oscin_mhz*can_rcv_mbx[0];
    	CPUTimer_selectClockSource(CPUTIMER2_BASE,CPUTIMER_CLOCK_SOURCE_INTOSC2,0);
    	CPUTimer_clearOverflowFlag(CPUTIMER2_BASE);
    	CPUTimer_enableInterrupt(CPUTIMER2_BASE);
    	CPUTimer_stopTimer(CPUTIMER2_BASE);
    	CPUTimer_setPeriod(CPUTIMER2_BASE, counter_seed);
    	CPUTimer_setPreScaler(CPUTIMER2_BASE, 0);
    	CPUTimer_reloadTimerCounter(CPUTIMER2_BASE);
    }
    
    void can_xmit_delay(void)
    {
    #ifdef USECPUTIMER
        EALLOW;
    	CPUTimer_resumeTimer(CPUTIMER2_BASE);
    	while(!CPUTimer_getTimerOverflowStatus(CPUTIMER2_BASE));
    	CPUTimer_stopTimer(CPUTIMER2_BASE);
        CPUTimer_clearOverflowFlag(CPUTIMER2_BASE);
        CPUTimer_reloadTimerCounter(CPUTIMER2_BASE);
    #endif
    #ifndef USECPUTIMER
       Uint32   i;
       for(i=0;i<255;i++) asm("   RPT#255 || NOP");
    #endif
    }
    
    //*****************************************************************************
    //
    //! Configures a message object in the CAN controller.
    //!
    //! \param ui32Base is the base address of the CAN controller.
    //! \param ui32ObjID is the object number to configure (1-32).
    //! \param pMsgObject is a pointer to a structure containing message object
    //! settings.
    //! \param eMsgType indicates the type of message for this object.
    //!
    //! This function is used to configure any one of the 32 message objects in the
    //! CAN controller.  A message object can be configured as any type of CAN
    //! message object as well as several options for automatic transmission and
    //! reception.  This call also allows the message object to be configured to
    //! generate interrupts on completion of message receipt or transmission.  The
    //! message object can also be configured with a filter/mask so that actions
    //! are only taken when a message that meets certain parameters is seen on the
    //! CAN bus.
    //!
    //! The \e eMsgType parameter must be one of the following values:
    //!
    //! - \b MSG_OBJ_TYPE_TX - CAN transmit message object.
    //! - \b MSG_OBJ_TYPE_TX_REMOTE - CAN transmit remote request message object.
    //! - \b MSG_OBJ_TYPE_RX - CAN receive message object.
    //! - \b MSG_OBJ_TYPE_RX_REMOTE - CAN receive remote request message object.
    //! - \b MSG_OBJ_TYPE_RXTX_REMOTE - CAN remote frame receive remote, then
    //! transmit message object.
    //!
    //! The message object pointed to by \e pMsgObject must be populated by the
    //! caller, as follows:
    //!
    //! - \e ui32MsgID - contains the message ID, either 11 or 29 bits.
    //! - \e ui32MsgIDMask - mask of bits from \e ui32MsgID that must match if
    //! identifier filtering is enabled.
    //! - \e ui32Flags
    //!   - Set \b MSG_OBJ_TX_INT_ENABLE flag to enable interrupt on transmission.
    //!   - Set \b MSG_OBJ_RX_INT_ENABLE flag to enable interrupt on receipt.
    //!   - Set \b MSG_OBJ_USE_ID_FILTER flag to enable filtering based on the
    //!   identifier mask specified by \e ui32MsgIDMask.
    //! - \e ui32MsgLen - the number of bytes in the message data.  This should be
    //! non-zero even for a remote frame; it should match the expected bytes of the
    //! data responding data frame.
    //! - \e pucMsgData - points to a buffer containing up to 8 bytes of data for a
    //! data frame.
    //!
    //! \b Example: To send a data frame or remote frame(in response to a remote
    //! request), take the following steps:
    //!
    //! -# Set \e eMsgType to \b MSG_OBJ_TYPE_TX.
    //! -# Set \e pMsgObject->ui32MsgID to the message ID.
    //! -# Set \e pMsgObject->ui32Flags. Make sure to set \b MSG_OBJ_TX_INT_ENABLE to
    //! allow an interrupt to be generated when the message is sent.
    //! -# Set \e pMsgObject->ui32MsgLen to the number of bytes in the data frame.
    //! -# Set \e pMsgObject->pucMsgData to point to an array containing the bytes
    //! to send in the message.
    //! -# Call this function with \e ui32ObjID set to one of the 32 object buffers.
    //!
    //! \b Example: To receive a specific data frame, take the following steps:
    //!
    //! -# Set \e eMsgObjType to \b MSG_OBJ_TYPE_RX.
    //! -# Set \e pMsgObject->ui32MsgID to the full message ID, or a partial mask to
    //! use partial ID matching.
    //! -# Set \e pMsgObject->ui32MsgIDMask bits that should be used for masking
    //! during comparison.
    //! -# Set \e pMsgObject->ui32Flags as follows:
    //!   - Set \b MSG_OBJ_TX_INT_ENABLE flag to be interrupted when the data frame
    //!   is received.
    //!   - Set \b MSG_OBJ_USE_ID_FILTER flag to enable identifier based filtering.
    //! -# Set \e pMsgObject->ui32MsgLen to the number of bytes in the expected data
    //! frame.
    //! -# The buffer pointed to by \e pMsgObject->pucMsgData  and
    //! \e pMsgObject->ui32MsgLen are not used by this call as no data is present at
    //! the time of the call.
    //! -# Call this function with \e ui32ObjID set to one of the 32 object buffers.
    //!
    //! If you specify a message object buffer that already contains a message
    //! definition, it will be overwritten.
    //!
    //! \return None.
    //
    //*****************************************************************************
    void
    CANMessageSet(uint32_t ui32Base, uint32_t ui32ObjID, tCANMsgObject *pMsgObject,
                  tMsgObjType eMsgType)
    {
        uint32_t ui32CmdMaskReg;
        uint32_t ui32MaskReg;
        uint32_t ui32ArbReg;
        uint32_t ui32MsgCtrl;
        bool bTransferData;
        bool bUseExtendedID;
    
        bTransferData = 0;
    
        // Check the arguments.
        ASSERT(CANBaseValid(ui32Base));
        ASSERT((ui32ObjID <= 32) && (ui32ObjID != 0));
        ASSERT((eMsgType == MSG_OBJ_TYPE_TX) ||
               (eMsgType == MSG_OBJ_TYPE_TX_REMOTE) ||
               (eMsgType == MSG_OBJ_TYPE_RX) ||
               (eMsgType == MSG_OBJ_TYPE_RX_REMOTE) ||
               (eMsgType == MSG_OBJ_TYPE_TX_REMOTE) ||
               (eMsgType == MSG_OBJ_TYPE_RXTX_REMOTE));
    
        // Wait for busy bit to clear
        while(HWREGH(ui32Base + CAN_O_IF1CMD) & CAN_IF1CMD_BUSY)
        {
        }
    
        // See if we need to use an extended identifier or not.
        if((pMsgObject->ui32MsgID > CAN_MAX_11BIT_MSG_ID) ||
           (pMsgObject->ui32Flags & MSG_OBJ_EXTENDED_ID))
        {
            bUseExtendedID = 1;
        }
        else
        {
            bUseExtendedID = 0;
        }
    
        // This is always a write to the Message object as this call is setting a
        // message object.  This call will also always set all size bits so it sets
        // both data bits.  The call will use the CONTROL register to set control
        // bits so this bit needs to be set as well.
        ui32CmdMaskReg = (CAN_IF1CMD_DIR | CAN_IF1CMD_DATA_A | CAN_IF1CMD_DATA_B |
                          CAN_IF1CMD_CONTROL);
    
        // Initialize the values to a known state before filling them in based on
        // the type of message object that is being configured.
        ui32ArbReg = 0;
        ui32MsgCtrl = 0;
        ui32MaskReg = 0;
    
        switch(eMsgType)
        {
        // Transmit message object.
        case MSG_OBJ_TYPE_TX:
        {
            // Set the TXRQST bit and the reset the rest of the register.
            ui32MsgCtrl |= CAN_IF1MCTL_TXRQST;
            ui32ArbReg = CAN_IF1ARB_DIR;
            bTransferData = 1;
            break;
        }
    
        // Transmit remote request message object
        case MSG_OBJ_TYPE_TX_REMOTE:
        {
            // Set the TXRQST bit and the reset the rest of the register.
            ui32MsgCtrl |= CAN_IF1MCTL_TXRQST;
            ui32ArbReg = 0;
            break;
        }
    
        // Receive message object.
        case MSG_OBJ_TYPE_RX:
        {
            // This clears the DIR bit along with everything else.  The TXRQST
            // bit was cleared by defaulting ui32MsgCtrl to 0.
            ui32ArbReg = 0;
            break;
        }
    
        // Receive remote request message object.
        case MSG_OBJ_TYPE_RX_REMOTE:
        {
            // The DIR bit is set to one for remote receivers.  The TXRQST bit
            // was cleared by defaulting ui32MsgCtrl to 0.
            ui32ArbReg = CAN_IF1ARB_DIR;
    
            // Set this object so that it only indicates that a remote frame
            // was received and allow for software to handle it by sending back
            // a data frame.
            ui32MsgCtrl = CAN_IF1MCTL_UMASK;
    
            // Use the full Identifier by default.
            ui32MaskReg = CAN_IF1MSK_MSK_M;
    
            // Make sure to send the mask to the message object.
            ui32CmdMaskReg |= CAN_IF1CMD_MASK;
            break;
        }
    
        // Remote frame receive remote, with auto-transmit message object.
        case MSG_OBJ_TYPE_RXTX_REMOTE:
        {
            // Oddly the DIR bit is set to one for remote receivers.
            ui32ArbReg = CAN_IF1ARB_DIR;
    
            // Set this object to auto answer if a matching identifier is seen.
            ui32MsgCtrl = CAN_IF1MCTL_RMTEN | CAN_IF1MCTL_UMASK;
    
            // The data to be returned needs to be filled in.
            bTransferData = 1;
            break;
        }
    
        // This case should never happen due to the ASSERT statement at the
        // beginning of this function.
        default:
        {
            return;
        }
        }
    
        // Configure the Mask Registers.
        if(pMsgObject->ui32Flags & MSG_OBJ_USE_ID_FILTER)
        {
            if(bUseExtendedID)
            {
                // Set the 29 bits of Identifier mask that were requested.
                ui32MaskReg = pMsgObject->ui32MsgIDMask & CAN_IF1MSK_MSK_M;
            }
            else
            {
    
                // Put the 11 bit Mask Identifier into the upper bits of the field
                // in the register.
                ui32MaskReg = ((pMsgObject->ui32MsgIDMask << CAN_IF1ARB_STD_ID_S) &
                               CAN_IF1ARB_STD_ID_M);
            }
        }
    
        // If the caller wants to filter on the extended ID bit then set it.
        if((pMsgObject->ui32Flags & MSG_OBJ_USE_EXT_FILTER) ==
           MSG_OBJ_USE_EXT_FILTER)
        {
            ui32MaskReg |= CAN_IF1MSK_MXTD;
        }
    
        // The caller wants to filter on the message direction field.
        if((pMsgObject->ui32Flags & MSG_OBJ_USE_DIR_FILTER) ==
           MSG_OBJ_USE_DIR_FILTER)
        {
            ui32MaskReg |= CAN_IF1MSK_MDIR;
        }
    
        if(pMsgObject->ui32Flags & (MSG_OBJ_USE_ID_FILTER | MSG_OBJ_USE_DIR_FILTER |
                                  MSG_OBJ_USE_EXT_FILTER))
        {
            // Set the UMASK bit to enable using the mask register.
            ui32MsgCtrl |= CAN_IF1MCTL_UMASK;
    
            // Set the MASK bit so that this gets transferred to the Message
            // Object.
            ui32CmdMaskReg |= CAN_IF1CMD_MASK;
        }
    
        // Set the Arb bit so that this gets transferred to the Message object.
        ui32CmdMaskReg |= CAN_IF1CMD_ARB;
    
        // Configure the Arbitration registers.
        if(bUseExtendedID)
        {
            // Set the 29 bit version of the Identifier for this message object.
            // Mark the message as valid and set the extended ID bit.
            ui32ArbReg |= (pMsgObject->ui32MsgID & CAN_IF1ARB_ID_M) |
                          CAN_IF1ARB_MSGVAL | CAN_IF1ARB_XTD;
        }
        else
        {
            // Set the 11 bit version of the Identifier for this message object.
            // The lower 18 bits are set to zero.
            // Mark the message as valid.
            ui32ArbReg |= ((pMsgObject->ui32MsgID << CAN_IF1ARB_STD_ID_S) &
                           CAN_IF1ARB_STD_ID_M) | CAN_IF1ARB_MSGVAL;
        }
    
        // Set the data length since this is set for all transfers.  This is also a
        // single transfer and not a FIFO transfer so set EOB bit.
        ui32MsgCtrl |= (pMsgObject->ui32MsgLen & CAN_IF1MCTL_DLC_M);
    
        // Mark this as the last entry if this is not the last entry in a FIFO.
        if((pMsgObject->ui32Flags & MSG_OBJ_FIFO) == 0)
        {
            ui32MsgCtrl |= CAN_IF1MCTL_EOB;
        }
    
        // Enable transmit interrupts if they should be enabled.
        if(pMsgObject->ui32Flags & MSG_OBJ_TX_INT_ENABLE)
        {
            ui32MsgCtrl |= CAN_IF1MCTL_TXIE;
        }
    
        // Enable receive interrupts if they should be enabled.
        if(pMsgObject->ui32Flags & MSG_OBJ_RX_INT_ENABLE)
        {
            ui32MsgCtrl |= CAN_IF1MCTL_RXIE;
        }
    
        // Write the data out to the CAN Data registers if needed.
        if(bTransferData)
        {
            CANDataRegWrite(pMsgObject->pucMsgData,
                            (uint32_t *)(ui32Base + CAN_O_IF1DATA),
                            pMsgObject->ui32MsgLen);
        }
    
        // Write out the registers to program the message object.
        HWREGH(ui32Base + CAN_O_IF1CMD + 2) = ui32CmdMaskReg >> 16;
    
        HWREGH(ui32Base + CAN_O_IF1MSK) = ui32MaskReg & CAN_REG_WORD_MASK;
        HWREGH(ui32Base + CAN_O_IF1MSK + 2) = ui32MaskReg >> 16;
    
        HWREGH(ui32Base + CAN_O_IF1ARB) = ui32ArbReg & CAN_REG_WORD_MASK;
        HWREGH(ui32Base + CAN_O_IF1ARB + 2) = ui32ArbReg >> 16;
    
        HWREGH(ui32Base + CAN_O_IF1MCTL) = ui32MsgCtrl & CAN_REG_WORD_MASK;
    
        // Transfer the message object to the message object specific by ui32ObjID.
        HWREGH(ui32Base + CAN_O_IF1CMD) = ui32ObjID & CAN_IF1CMD_MSG_NUM_M;
    
        return;
    }
    

    此致、

    Joseph

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    IF1CMD_BUSY 位仅告知您 IFx 寄存器的状态。 如果要轮询传输完成、请使用 TxRqst 位。 来自 TRM:

    在成功发送之后、如果没有新的数据被写入报文对象(NewDat ='0')、自此之后
    发送开始时、TxRqst 位将被复位。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Haresh,

    波特率为500KB/s  , 当延迟小于1ms 时,消息似乎会丢失 ,这可能是因为我们在中可以打开 PDO,并且 会出现一些异步消息。

    我会就您的建议给您反馈  

    谢谢你  

    BR
    卡洛

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Haresh,

    使用  TxRqst 位没有好处  ,消息也会丢失 。   只有添加延迟 才 会有所帮助  

    请注意什么问题?  我们做什么库仑?   

    给你听

    BR
    卡洛

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Carlo、

    消息之间的延迟<1ms 可能太短。  只是根据500kbps 进行粗略的较差情况计算、假设扩展 ID、一帧的总数据约为150位(起始、ID、控制、8字节数据、15位 CRC、 填充每5个连续的类似位、分隔符、ACK、帧结束等)。  一个位时间将为2us。  这意味着完整的 CAN 帧将在最坏的情况下占用~300uS (2uS x 150位-或标准11位 ID 为~250uS)。   如果总线中有其他节点在接收和发送 ACK 的节点上发送数据、则总线可能会过载。  是否可以增加、消息之间的延迟?  您能否切换到更高的波特率来缩短 CAN 帧持续时间?  设置为1Mbps 将会使帧持续时间减半、但需要考虑总线长度以确保仍然满足 CAN 时序要求。

    此致、

    Joseph

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Joseph,  

    它们是标准的,而不是扩展 的500Kbps。  他们可以增加 消息之间的时间 (到少数 MS):请 延迟您建议不要丢失 数据?

    关于 要检查的位活动,这是您希望工作和要检查的位活动?

    非常感谢

    BR

    卡洛

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    卡洛、

     也许我缺少一些东西。 客户为什么不使用中断? 如果您确保在下一帧传输开始之前已传输前一帧、则没有丢失帧的空间。 您可以轮询或使用中断、但在前一帧传输之前无法启动新的传输。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Carlo、

    假设是标准 ID、假设帧长度更差、为125位。  这将具有250us 的最大帧长度,如果帧间隔为1ms,则总线负载为(250US/1ms)*100=25%。  建议的 CAN 总线负载是将其保持在30%以下。  将帧间隔为1ms 或更大是安全的、以确保所有帧的正确传输。

    此致、

    Joseph

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Joseph,  

    好的  

    请 添加此延迟  ,以确保 执行正确的操作,这是您建议 同时检入 SW 的位 ?   TxRqst 位 ?  

    谢谢你

    BR

    卡洛

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Carlo、

    是的、也请轮询 TxRqst 位。

    谢谢、此致、

    Joseph