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