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.

[参考译文] TMS320F28377D:C2000微控制器论坛

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

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1516907/tms320f28377d-c2000-microcontrollers-forum

器件型号:TMS320F28377D

工具/软件:

您好、  专家!
我目前正在使用 bitfield 方法开发 CAN 通信。 我在发送和接收时遇到了一些问题。 感谢您的帮助。 具体问题如下:
我参考了示例: can_loopback_bitfields_cpu01 。 并使用 CANA 与外部工具进行通信。
can_init 代码:
void InitCAN_A(void)
{
	int16_t iMsg;
	uint32_t status;
	//
    // Place CAN controller in init state, regardless of previous state.  This
    // will put controller in idle, and allow the message object RAM to be
    // programmed.
	//
	CanaRegs.CAN_CTL.bit.Init = 1;
    // Wait for busy bit to clear
    while(CanaRegs.CAN_IF1CMD.bit.Busy);
	CanaRegs.CAN_CTL.bit.SWR = 1;
    while(CanaRegs.CAN_CTL.bit.SWR);
    //setCANBitRate
    do{
        status = setCANBitRate(CAN_SYSCLK,CAN_BITRATE);
        DELAY_US(500);
    }while(status == 0);
    //
    // Initialize the message object that will be used for sending CAN
    // messages.
    //
    //setupMessageObject(CAN_TX_MSG_OBJ, CAN_MSG_ID, MSG_OBJ_TYPE_TRANSMIT);
    setupSend_MessageObject(CAN_TX_MSG_OBJ, CAN_MSG_ID);
    //
    // Initialize the message object that will be used for receiving CAN
    // messages.
    //
    setupRecive_MessageObject(CAN_RX_MSG_OBJ, CAN_MSG_ID);
    //enable can using operating mode
    CanaRegs.CAN_CTL.bit.Init = 0;
}
设置发送对象  
void setupSend_MessageObject(Uint32 objID, Uint32 msgID)
{
    //
    // Use Shadow variable for IF1CMD. IF1CMD should be written to in
    // single 32-bit write.
    //
    union CAN_IF1CMD_REG CAN_IF1CMD_SHADOW;

    //
    // Wait for busy bit to clear.
    //
    while(CanaRegs.CAN_IF1CMD.bit.Busy)
    {
    }

    //
    // Clear and Write out the registers to program the message object.
    //
    CAN_IF1CMD_SHADOW.all = 0;
    CanaRegs.CAN_IF1MSK.all = 0;
    CanaRegs.CAN_IF1ARB.all = 0;
    CanaRegs.CAN_IF1MCTL.all = 0;

    //
    // Set the Control, Mask, and Arb bit so that they get transferred to the
    // Message object.
    //

    CAN_IF1CMD_SHADOW.bit.Control = 1;
    CAN_IF1CMD_SHADOW.bit.Arb = 1;
//    CAN_IF1CMD_SHADOW.bit.Mask = 1;
    CAN_IF1CMD_SHADOW.bit.Mask = 0;
    CAN_IF1CMD_SHADOW.bit.DIR = 1;

    CAN_IF1CMD_SHADOW.bit.DATA_A = 1;          // 使能数据寄存器 A 访问
    CAN_IF1CMD_SHADOW.bit.DATA_B = 1;          // 使能数据寄存器 B 访问

    CanaRegs.CAN_IF1ARB.bit.Dir = 1;


    //
    // Set Message ID (this example assumes 11 bit ID mask)
    //
//    CanaRegs.CAN_IF1ARB.bit.Xtd = 0;
    CanaRegs.CAN_IF1ARB.bit.Xtd = 1;

//    CanaRegs.CAN_IF1ARB.bit.ID = ((Uint32)(0x123) << CAN_MSG_ID_SHIFT);
    CanaRegs.CAN_IF1ARB.bit.ID = 0x123456;

    CanaRegs.CAN_IF1ARB.bit.MsgVal = 1;

    //
    // 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.
    //
    CanaRegs.CAN_IF1MCTL.bit.DLC = messageSize;
    CanaRegs.CAN_IF1MCTL.bit.EoB = 1;
    //CanaRegs.CAN_IF1MCTL.bit.RmtEn = 0;    //非远程帧
    //
    // Transfer data to message object RAM
    //
    CAN_IF1CMD_SHADOW.bit.MSG_NUM = objID;
    CanaRegs.CAN_IF1CMD.all = CAN_IF1CMD_SHADOW.all;
    CAN_IF1CMD_SHADOW.all = 0;
}
我使用以下代码来更改帧的 id 和长度。  
// 设置 CAN 发送 ID(支持标准帧和扩展帧)
void CAN_SetTxId(Uint32 id, Uint32 isExtId,Uint32 objID)
{
    // 等待发送缓冲区空闲
    while (CanaRegs.CAN_IF1CMD.bit.Busy);

    while(CanaRegs.CAN_IF1MCTL.bit.TxRqst);


    // 进入配置模式
    CanaRegs.CAN_IF1CMD.all = 0;
    CanaRegs.CAN_IF1CMD.bit.MSG_NUM = objID;
    CanaRegs.CAN_IF1CMD.bit.Arb = 1;

    if (isExtId)
    {
        // 扩展帧 ID (29 位)
        CanaRegs.CAN_IF1ARB.bit.Xtd = 1;         // 设置为扩展帧
        CanaRegs.CAN_IF1ARB.bit.ID = id;       // 设置扩展 ID
    }
    else
    {
        // 标准帧 ID (11 位)
        CanaRegs.CAN_IF1ARB.bit.Xtd = 0;         // 设置为标准帧
        CanaRegs.CAN_IF1ARB.bit.ID = (id << 18);     // 设置标准 ID
    }
    CanaRegs.CAN_IF1MCTL.bit.RmtEn = 0;      // 设置数据长度
    CanaRegs.CAN_IF1MCTL.bit.UMask = 0;      // 设置数据长度
}

void sendCANMessage_withID(Uint32 objID,Uint32 uID,Uint32 length)
{
    //
    // Use Shadow variable for IF1CMD. IF1CMD should be written to in
    // single 32-bit write.
    //
    union CAN_IF1CMD_REG CAN_IF1CMD_SHADOW;
    //
    // Wait for busy bit to clear.
    //
    while(CanaRegs.CAN_IF1CMD.bit.Busy);
    //
    // Write data to transfer into DATA-A and DATA-B interface registers
    //
    uint16_t index;
    for(index = 0; index < length; index++)
    {
        switch(index)
        {
            case 0:
                CanaRegs.CAN_IF1DATA.bit.Data_0 = ucTXMsgData[index];
                break;
            case 1:
                CanaRegs.CAN_IF1DATA.bit.Data_1 = ucTXMsgData[index];
                break;
            case 2:
                CanaRegs.CAN_IF1DATA.bit.Data_2 = ucTXMsgData[index];
                break;
            case 3:
                CanaRegs.CAN_IF1DATA.bit.Data_3 = ucTXMsgData[index];
                break;

            case 4:
                CanaRegs.CAN_IF1DATB.bit.Data_4 = ucTXMsgData[index];
                break;
            case 5:
                CanaRegs.CAN_IF1DATB.bit.Data_5 = ucTXMsgData[index];
                break;
            case 6:
                CanaRegs.CAN_IF1DATB.bit.Data_6 = ucTXMsgData[index];
                break;
            case 7:
                CanaRegs.CAN_IF1DATB.bit.Data_7 = ucTXMsgData[index];
                break;
        }
    }


    //
     // Set Direction to write and set DATA-A/DATA-B to be transfered to
     // message object
     //
     CAN_IF1CMD_SHADOW.all = 0;


     CAN_IF1CMD_SHADOW.bit.MSG_NUM = objID;

     CAN_IF1CMD_SHADOW.bit.Control = 1;



     CAN_IF1CMD_SHADOW.bit.Mask = 1;
     CAN_IF1CMD_SHADOW.bit.DIR = 1;

     CAN_IF1CMD_SHADOW.bit.DATA_A = 1;
     CAN_IF1CMD_SHADOW.bit.DATA_B = 1;


     CanaRegs.CAN_IF1MCTL.bit.DLC = (Uint8)length&0x0f;                  // 设置数据长度


     CanaRegs.CAN_IF1ARB.bit.MsgVal = 1;
     //
     // Set Tx Request Bit
     //


     CAN_IF1CMD_SHADOW.bit.TXRQST = 1;
     //
     // Transfer the message object to the message object specified by
     // objID.
     //

     CanaRegs.CAN_IF1CMD.all = CAN_IF1CMD_SHADOW.all;
     CAN_IF1CMD_SHADOW.all = 0;

}
  
但我发现 帧的 id 没有改变。  发送配置时是否有任何错误?
当我使用以下命令设置读取配置时。  我发现以下配置根本没有用。
void setupRecive_MessageObject(Uint32 objID, Uint32 msgID)
{
    //
    // Wait for the message object to be not busy.
    //
    while(CanaRegs.CAN_IF2CMD.bit.Busy);

    // 6. Configure the receive message object (object 1) - receive any extended frame
    CanaRegs.CAN_IF2CMD.bit.Control = 1;

    CanaRegs.CAN_IF2CMD.all = 0;
    CanaRegs.CAN_IF2CMD.bit.MSG_NUM = objID;
    CanaRegs.CAN_IF2CMD.bit.Arb = 1;

    CanaRegs.CAN_IF2CMD.bit.DATA_A = 1;
    CanaRegs.CAN_IF2CMD.bit.DATA_B = 1;
    CanaRegs.CAN_IF2CMD.bit.DIR = 0;             // Receive direction

    CanaRegs.CAN_IF2ARB.bit.Xtd = 1;             // Receive extended frame
//    CanaRegs.CAN_IF2ARB.bit.Xtd = 0;             // Receive standard frame
    CanaRegs.CAN_IF2ARB.bit.ID = 0;              // Set ID to 0 (used with mask)
 //   CanaRegs.CAN_IF2ARB.bit.Dir = 0;             // Set ID to 0 (used with mask)

    CanaRegs.CAN_IF2MCTL.bit.DLC = 8;            // Data length 8 bytes
    CanaRegs.CAN_IF2MCTL.bit.RmtEn = 0;          // Not a remote frame

    // 7. Set the receive mask (receive any extended frame)

    CanaRegs.CAN_IF2MSK.bit.MXtd = 1;            // Only receive extended frames
    //CanaRegs.CAN_IF2MSK.bit.MDir = 0;           // Only receive extended frames
    CanaRegs.CAN_IF2MSK.bit.Msk = 0;             // Extended frame ID mask all 0s (receive any ID)

    //CanaRegs.CAN_IF2ARB.bit.MsgVal = 1;
    while(CanaRegs.CAN_IF2CMD.bit.Busy);

//    CanaRegs.CAN_IER.bit.INT1 = 1;              // Enable interrupt for message object 1
//    PieCtrlRegs.PIEIER9.bit.INTx5 = 1;          // Enable PIE interrupt group 9 for CANA interrupt
//    IER |= M_INT9;

}
发送配置时是否有任何错误?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    这里还有一个  有关 接收。配置和接收接口的问题如下:

    //
    // setupMessageObject - Setup message object as Transmit or Receive
    //
    void setupRecive_MessageObject(Uint32 objID, Uint32 msgID)
    {
        //
        // Wait for busy bit to clear.
        //
        // 等待消息对象不忙
        while(CanaRegs.CAN_IF2CMD.bit.Busy);
    
        // 6. 配置接收消息对象(对象 1)- 接收任意扩展帧
        CanaRegs.CAN_IF2CMD.bit.Control = 1;
    
        CanaRegs.CAN_IF2CMD.all = 0;
        CanaRegs.CAN_IF2CMD.bit.MSG_NUM = objID;
        CanaRegs.CAN_IF2CMD.bit.Arb = 1;
    
    
        CanaRegs.CAN_IF2CMD.bit.DATA_A = 1;
        CanaRegs.CAN_IF2CMD.bit.DATA_B = 1;
        CanaRegs.CAN_IF2CMD.bit.DIR = 0;             // 接收方向
    
        CanaRegs.CAN_IF2ARB.bit.Xtd = 1;             // 接收扩展帧
    //    CanaRegs.CAN_IF2ARB.bit.Xtd = 0;             // 接收扩展帧
        CanaRegs.CAN_IF2ARB.bit.ID = 0;            // ID 设为 0(配合掩码使用
     //   CanaRegs.CAN_IF2ARB.bit.Dir = 0;            // ID 设为 0(配合掩码使用)
    
        CanaRegs.CAN_IF2MCTL.bit.DLC = 8;            // 数据长度 8 字节
        CanaRegs.CAN_IF2MCTL.bit.RmtEn = 0;            // 非远程帧
    
        // 7. 设置接收掩码(接收任意扩展帧)
    
        CanaRegs.CAN_IF2MSK.bit.MXtd = 1;             // 只接收扩展帧
        //CanaRegs.CAN_IF2MSK.bit.MDir = 0;             // 只接收扩展帧
        CanaRegs.CAN_IF2MSK.bit.Msk = 0;            // 扩展帧 ID 掩码全 0(接收任意 ID)
    
        //CanaRegs.CAN_IF2ARB.bit.MsgVal = 1;
        while(CanaRegs.CAN_IF2CMD.bit.Busy);
    
    //    CanaRegs.CAN_IER.bit.INT1 = 1;               // 使能消息对象 1 中断
    //    PieCtrlRegs.PIEIER9.bit.INTx5 = 1;           // 使能 PIE 中断组 9 中的 CANA 中断
    //    IER |= M_INT9;
    
    }
    
    /
    // getCANMessage - Check the message object for new data.
    //                 If new data, data written into array and return true.
    //                 If no new data, return false.
    //
    bool getCANMessage(Uint32 objID)
    {
        bool status;
    
        //
        // Use Shadow variable for IF2CMD. IF2CMD should be written to in
        // single 32-bit write.
        //
        while(CanaRegs.CAN_IF2CMD.bit.Busy);
    
        CanaRegs.CAN_IF2CMD.bit.Control = 1;
        CanaRegs.CAN_IF2CMD.bit.Arb    = 1;
        CanaRegs.CAN_IF2CMD.bit.DATA_A = 1;
        CanaRegs.CAN_IF2CMD.bit.DATA_B = 1;
    
        // 接收方向
        CanaRegs.CAN_IF2CMD.bit.MSG_NUM = objID;             // 接收方向
        //
        // See if there is new data available.
        //
        if(CanaRegs.CAN_IF2MCTL.bit.NewDat == 1)
        {
            //
            // Read out the data from the CAN registers.
            //
            uint16_t index;
            for(index = 0; index < messageSize; index++)
            {
                switch(index)
                {
                    case 0:
                        ucRXMsgData[index] = CanaRegs.CAN_IF2DATA.bit.Data_0;
                    break;
    
                    case 1:
                        ucRXMsgData[index] = CanaRegs.CAN_IF2DATA.bit.Data_1;
                    break;
    
                    case 2:
                        ucRXMsgData[index] = CanaRegs.CAN_IF2DATA.bit.Data_2;
                    break;
    
                    case 3:
                        ucRXMsgData[index] = CanaRegs.CAN_IF2DATA.bit.Data_3;
                    break;
    
                    case 4:
                        ucRXMsgData[index] = CanaRegs.CAN_IF2DATB.bit.Data_4;
                    break;
    
                    case 5:
                        ucRXMsgData[index] = CanaRegs.CAN_IF2DATB.bit.Data_5;
                    break;
    
                    case 6:
                        ucRXMsgData[index] = CanaRegs.CAN_IF2DATB.bit.Data_6;
                    break;
    
                    case 7:
                        ucRXMsgData[index] = CanaRegs.CAN_IF2DATB.bit.Data_7;
                    break;
                }
            }
    
            status = true;
        }
        else
        {
            status = false;
        }
    
        return(status);
    }
    

    使用上述界面、无法接收任何消息。    Rec configure 是否有一些错误?   谢谢

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

    您好 Joe、

    我建议使用 driverlib (具有 HWREG 宏的寄存器级)而不是 bitfield、因为位域方法存在很少的 MISRA-C 问题。  

    在您的示例中、是否使用 bitfield 方法对寄存器进行了正确编程?