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