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.
各位专家、您好!
我需要您的帮助^对于我的程序、我想配置我目前开发第一个节点的电路板和第二个节点的具有峰值 CAN 探针的 PC 的 CAN 通信。
此时我想发送一个对象并接收第二个对象 、但接下来我需要配置更多对象。 传输很好、我看到我的帧从板到 PC、但 Opposit 在 CAN_IF2DATA / CAN_IF2DATB 中不起作用 、我从未看到数据。
我正在尝试在传入 ID 上设置一个筛选器、我只想接受我从 PC 发送的 ID、在这种情况下、ID = 0x010为标准格式。
我在您的文档和论坛上做了大量研究、但没有成功。 我尝试通过不加掩码而不成功地在 ID 上进行配置、因此我不确定问题是否来自 ID 的筛选(以查看我是否没有犯错)
因此我配置:
CANARegs.CAN_IF2MSK.bit.MSK = 0x1FFFFFFF;
CanaRegs.CAN_IF2ARB.bit.ID =(msgid << 18);
CANaRegs.CAN_IF2CMD.bit.DIR = 0;
CANaRegs.CAN_IF2ARB.bit.Dir = 0;
这行是正确的? 对我来说是的,但是……
您可以看到屏幕截图和我的代码:
void can_init(void) { EALLOW; /// Configure CANA_RX GpioCtrlRegs.GPAPUD.bit.GPIO3 = 1; /// Disable the pullup on GPIO3 GpioCtrlRegs.GPAGMUX1.bit.GPIO3 = 3; /// To define mux position, mux position equal GPAGMUX(2bits) - GPAMUX(2bits) 0 to 15 number, here mux position equal 14 so GPAGMUX1 = 11b and GPAMUX1 = 10b. GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 2; /// GPIO3 = CANA_RX, see pin attributes documentation for mux position. GpioCtrlRegs.GPADIR.bit.GPIO3 = 0; /// GPIO3 = input GpioCtrlRegs.GPAINV.bit.GPIO3 = 0; /// Not inverted GPIO input /// Configure CANA_TX GpioCtrlRegs.GPAPUD.bit.GPIO2 = 1; /// Disable the pullup on GPIO2 GpioCtrlRegs.GPADIR.bit.GPIO2 = 1; /// GPIO2 = output GpioCtrlRegs.GPAODR.bit.GPIO2 = 0; /// Normal output not open drain GpioCtrlRegs.GPAQSEL1.bit.GPIO2 = 0; /// Synchronous GpioCtrlRegs.GPAGMUX1.bit.GPIO2 = 3; /// To define mux position, mux position equal GPBGMUX(2bits) - GPBMUX(2bits) 0 to 15 number, here mux position equal 14 so GPAGMUX1 = 11b and GPAMUX1 = 10b. GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 2; /// GPIO2 = CANA_TX, see pin attributes documentation for mux position. /// 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. /// CAN module ignore bus activity during configuration. CanaRegs.CAN_CTL.bit.Init = 1; /// CAN software reset. CanaRegs.CAN_CTL.bit.SWR = 1; /// The CPU has write access to the configuration register. CanaRegs.CAN_CTL.bit.CCE = 1; /// Clock and timing bit configuration ClkCfgRegs.CLKSRCCTL2.bit.CANABCLKSEL = 0; /// Set up the bit rate for the CAN bus, with 250kbit/s. /// Bit time (Tq) = 8 /// Bit clock prescaler = 49dec = 0x31 /// Propagation segment (Tq) = 1 /// Phase segment 1 (Tq) = 3dec = 0x3 /// Phase segment 2 (Tq) = 2dec = 0x2 /// Synchronization jump width (Tq) = 2dec = 0x2 /// Sampling point = 62.5% /// Oscillator tolerance = 1.48% /// Set Baud rate prescaler. CanaRegs.CAN_BTR.bit.BRP = 0x31; /// Synchronization jump width. CanaRegs.CAN_BTR.bit.SJW = 0x2; /// Time segment before the sample point. CanaRegs.CAN_BTR.bit.TSEG1 = 0x3; /// Time segment after the sample point. CanaRegs.CAN_BTR.bit.TSEG2 = 0x2; /// CAN module processes messages normally CanaRegs.CAN_CTL.bit.Init = 0; //setupMessageObject(1, 0x100, MSG_OBJ_TYPE_TRANSMIT); setupMessageObject(2, 0x010, MSG_OBJ_TYPE_RECEIVE); EDIS; } ... /// Receive message else { /// Wait for busy bit to clear. while(CanaRegs.CAN_IF2CMD.bit.Busy) { } /// Clear and Write out the registers to program the message object. CanaRegs.CAN_IF2CMD.all = 0; CanaRegs.CAN_IF2MSK.all = 0; CanaRegs.CAN_IF2ARB.all = 0; CanaRegs.CAN_IF2MCTL.all = 0; /// Use mask (Msk, MXtd and Mdir) for acceptance filtering. CanaRegs.CAN_IF2MCTL.bit.UMask = 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. /// Data frame has 8 data bytes CanaRegs.CAN_IF2MCTL.bit.DLC = 9; /// The message object is a single message object or the last message object in a FIFO buffer. CanaRegs.CAN_IF2MCTL.bit.EoB = 1; /// Extended identifier bit has no effect on the acceptance filtering (standard mode is used). CanaRegs.CAN_IF2MSK.bit.MXtd = 0; /// The message direction bit has no effect on the acceptance filtering. CanaRegs.CAN_IF2MSK.bit.MDir = 0; /// The corresponding bit in the identifier of the message object is used for acceptance filtering. CanaRegs.CAN_IF2MSK.bit.Msk = 0x1FFFFFFF; /// IF command registers configure and initiate the transfer between the IF register sets and the message RAM. /// Set the Control, Mask, and Arb bit so that they get transferred to the message object. /// The message control bits will be transferred from the IF2 register set to the message object. CanaRegs.CAN_IF2CMD.bit.Control = 1; /// The arbitration bits will be transferred from the IF2 register set to the message object. CanaRegs.CAN_IF2CMD.bit.Arb = 1; /// The mask bits (Identifier mask + Mdir + MXtd) will be transferred from the IF2 register to the message object. CanaRegs.CAN_IF2CMD.bit.Mask = 1; /// Read message object (mail box). CanaRegs.CAN_IF2CMD.bit.DIR = 0; /// Transfer data to message object RAM CanaRegs.CAN_IF2CMD.bit.MSG_NUM = objID; /// Arbitration /// Transmit direction = receive, a remote frame with the identifier of this message object is transmitted. CanaRegs.CAN_IF2ARB.bit.Dir = 0; /// Set Message ID. CanaRegs.CAN_IF2ARB.bit.ID = (msgID << 18); /// Standard identifier is used for this message object. CanaRegs.CAN_IF2ARB.bit.Xtd = 0; /// Mail box is enabled after mask configuration. CanaRegs.CAN_IF2ARB.bit.MsgVal = 1; } } Read data function bool receive_CAN_message() { bool status; /// Detect for mail box number 2 (receive) //if(CanaRegs.CAN_NDAT_21 == 2) //{ // Set the Message Data A, Data B to be read on request for data from the message object. CanaRegs.CAN_IF2CMD.bit.DATA_A = 1; CanaRegs.CAN_IF2CMD.bit.DATA_B = 1; // Wait for busy bit to clear. while(CanaRegs.CAN_IF2CMD.bit.Busy) { } // Read out the data from the CAN registers. uint16_t index; for(index = 0; index < 8; index++) { switch(index) { case 0: rx_data[index] = CanaRegs.CAN_IF2DATA.bit.Data_0; break; case 1: rx_data[index] = CanaRegs.CAN_IF2DATA.bit.Data_1; break; case 2: rx_data[index] = CanaRegs.CAN_IF2DATA.bit.Data_2; break; case 3: rx_data[index] = CanaRegs.CAN_IF2DATA.bit.Data_3; break; case 4: rx_data[index] = CanaRegs.CAN_IF2DATB.bit.Data_4; break; case 5: rx_data[index] = CanaRegs.CAN_IF2DATB.bit.Data_5; break; case 6: rx_data[index] = CanaRegs.CAN_IF2DATB.bit.Data_6; break; case 7: rx_data[index] = CanaRegs.CAN_IF2DATB.bit.Data_7; break; } } status = true; /*} else { status = false; }*/ // Clear New Data Flag CanaRegs.CAN_IF2CMD.bit.TxRqst = 1; return(status); }
谢谢
Damien
尊敬的 Damien:
您能澄清几个问题吗? 我假设您 没有使用中断来触发帧接收。 上述代码(第55行)中的注释 显示///接收消息、但后续代码似乎正在配置消息对象。 有一个函数 READ_CAN_MESSAGE(),但对 NewDat 的检查注释掉。 您如何检查邮箱2的新数据是否出现?
此致、
Joseph
您好、Joseph、
您是我希望使用轮询模式触发火焰接收而不是中断的原因。 我在第55行的注释不适合它是用于接收邮件的邮箱配置。 邮箱1我配置用于传输消息、但这里不显示、因为它可以正常工作、邮箱2用于接收。
我使用 CAN_ndat_21第113行测试邮件 box2的新数据是否出现,但该寄存器始终为0,因此我认为接收时没有帧会通过掩码过滤器 no 触发?
如果我不想使用这一个读功能,只需验证一个邮箱配置的 Candata 寄存器,它将不起作用? 当我配置更多接收邮箱时、将进行此检测。
我的邮箱2配置良好,可以接收消息吗?
我不明白为什么 CAN_ndat_21等于0? 我认为触发器不起作用。
谢谢
Damien
尊敬的 Damien:
您能否移动以下语句:
CANARegs.CAN_IF2CMD.bit.DATA_A = 1;
CANARegs.CAN_IF2CMD.bit.DATA_B = 1;
这当前位于先前已定义消息对象2以查看其是否起作用的例程中的 Receive_CAN_message 中? 我在您发送的快照中看不到这些位在 IF2CMD 寄存器中设置。
此致、
Joseph
您好、Joseph、
我正在调试中取得进展、但我遇到了一个问题。 我仍然配置了 ID 为0x100 (µC -> PC)的发送帧和 ID 为0x010 (PC ->µC)的另一帧。 我想在 CAN_IF1DATx 寄存器中查看 ID 为0x100的帧上发送的数据、并在第二个 CAN_IF2DAT 缓冲区中查看 ID 为0x010的 PC 发送的数据。 但在调试器模式下、我在 CAN_IF1DAT 和 CAN_IF2DAT 中看到 Tx 中 ID 0x100上传输的相同数据。 我不访问 CAN_Rx 中帧0x010的数据。
为什么在 CAN_IF2DAT 中看不到 CAN_Rx 中的数据? 我肯定在配置上犯了错误?
I defined CAN_IF1CMD.bit.DIR = 1 (发送方向)
CAN_IF1ARB.bit.Dir = 1 (发送方向)
CAN_IF1ARB.bit.ID = 0x100 << 18
CAN_IF1CMD.bit.MSG_NUM = 1
CAN_IF1CMD DIR = 0 (接收方向)
CAN_IF1ARB.bit.Dir = 0 (接收方向)
CAN_IF1ARB.bit.ID = 0x010 << 18
CAN_IF1CMD.bit.MSG_NUM = 2
我看不到问题、可以帮我吗?
#include "f28002x_device.h" #include "HPTS100_can.h" uint16_t rx_data[8]; void can_init(void) { EALLOW; /// Configure CANA_RX GpioCtrlRegs.GPAPUD.bit.GPIO3 = 1; /// Disable the pullup on GPIO3 GpioCtrlRegs.GPAGMUX1.bit.GPIO3 = 3; /// To define mux position, mux position equal GPAGMUX(2bits) - GPAMUX(2bits) 0 to 15 number, here mux position equal 14 so GPAGMUX1 = 11b and GPAMUX1 = 10b. GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 2; /// GPIO3 = CANA_RX, see pin attributes documentation for mux position. GpioCtrlRegs.GPADIR.bit.GPIO3 = 0; /// GPIO3 = input GpioCtrlRegs.GPAINV.bit.GPIO3 = 0; /// Not inverted GPIO input /// Configure CANA_TX GpioCtrlRegs.GPAPUD.bit.GPIO2 = 1; /// Disable the pullup on GPIO2 GpioCtrlRegs.GPADIR.bit.GPIO2 = 1; /// GPIO2 = output GpioCtrlRegs.GPAODR.bit.GPIO2 = 0; /// Normal output not open drain GpioCtrlRegs.GPAQSEL1.bit.GPIO2 = 0; /// Synchronous GpioCtrlRegs.GPAGMUX1.bit.GPIO2 = 3; /// To define mux position, mux position equal GPBGMUX(2bits) - GPBMUX(2bits) 0 to 15 number, here mux position equal 14 so GPAGMUX1 = 11b and GPAMUX1 = 10b. GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 2; /// GPIO2 = CANA_TX, see pin attributes documentation for mux position. /// 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. /// CAN module ignore bus activity during configuration. CanaRegs.CAN_CTL.bit.Init = 1; /// The CPU has write access to the configuration register. CanaRegs.CAN_CTL.bit.CCE = 1; /// Clock and timing bit configuration ClkCfgRegs.CLKSRCCTL2.bit.CANABCLKSEL = 0; /// Set up the bit rate for the CAN bus, with 250kbit/s. /// Bit time (Tq) = 8 /// Bit clock prescaler = 49dec = 0x31 /// Propagation segment (Tq) = 1 /// Phase segment 1 (Tq) = 3dec = 0x3 /// Phase segment 2 (Tq) = 2dec = 0x2 /// Synchronization jump width (Tq) = 2dec = 0x2 /// Sampling point = 62.5% /// Oscillator tolerance = 1.48% /// Set Baud rate prescaler. CanaRegs.CAN_BTR.bit.BRP = 0x31; /// Synchronization jump width. CanaRegs.CAN_BTR.bit.SJW = 0x2; /// Time segment before the sample point. CanaRegs.CAN_BTR.bit.TSEG1 = 0x3; /// Time segment after the sample point. CanaRegs.CAN_BTR.bit.TSEG2 = 0x2; /// CAN module processes messages normally CanaRegs.CAN_CTL.bit.Init = 0; setupMessageObject(1, 0x100, MSG_OBJ_TYPE_TRANSMIT); setupMessageObject(2, 0x010, MSG_OBJ_TYPE_RECEIVE); EDIS; } void setupMessageObject(uint32_t objID, uint32_t msgID, msgObjType msgType) { if(msgType == MSG_OBJ_TYPE_TRANSMIT) { /// 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. /// The message control bits will be transferred from the IF1 register set to the message object. CAN_IF1CMD_SHADOW.bit.Control = 1; /// The arbitration bits will be transferred from the IF1 register set to the message object. CAN_IF1CMD_SHADOW.bit.Arb = 1; /// The mask bits (Identifier mask + Mdir + MXtd) will be transferred from the IF1 register to the message object. CAN_IF1CMD_SHADOW.bit.Mask = 1; /// Transfer direction is transferred to the message object : write CAN_IF1CMD_SHADOW.bit.DIR = 1; /// Transmit direction CanaRegs.CAN_IF1ARB.bit.Dir = 1; /// Set Message ID. CanaRegs.CAN_IF1ARB.bit.ID = (msgID << 18); /// Mail box is enabled. 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. /// Data frame has 8 data bytes CanaRegs.CAN_IF1MCTL.bit.DLC = 9; /// The message object is a single message object or the last message object in a FIFO buffer. CanaRegs.CAN_IF1MCTL.bit.EoB = 1; /// Transfer data to message object RAM CAN_IF1CMD_SHADOW.bit.MSG_NUM = objID; CanaRegs.CAN_IF1CMD.all = CAN_IF1CMD_SHADOW.all; } else { /// Use Shadow variable for IF1CMD. IF1CMD should be written to in single 32-bit write. union CAN_IF2CMD_REG CAN_IF2CMD_SHADOW; /// Wait for busy bit to clear. while(CanaRegs.CAN_IF2CMD.bit.Busy) { } /// Clear and Write out the registers to program the message object. CAN_IF2CMD_SHADOW.all = 0; CanaRegs.CAN_IF2MSK.all = 0; CanaRegs.CAN_IF2ARB.all = 0; CanaRegs.CAN_IF2MCTL.all = 0; /// Set the Control, Mask, and Arb bit so that they get transferred to the message object. /// The message control bits will be transferred from the IF1 register set to the message object. CAN_IF2CMD_SHADOW.bit.Control = 1; /// The arbitration bits will be transferred from the IF1 register set to the message object. CAN_IF2CMD_SHADOW.bit.Arb = 1; /// The mask bits (Identifier mask + Mdir + MXtd) will be transferred from the IF1 register to the message object. CAN_IF2CMD_SHADOW.bit.Mask = 1; /// Transfer direction is transferred to the message object : read CAN_IF2CMD_SHADOW.bit.DIR = 0; /// Receive direction CanaRegs.CAN_IF2ARB.bit.Dir = 0; /// Set Message ID. CanaRegs.CAN_IF2ARB.bit.ID = (msgID << 18); /// Mail box is enabled. CanaRegs.CAN_IF2ARB.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. /// Data frame has 8 data bytes CanaRegs.CAN_IF2MCTL.bit.DLC = 9; /// The message object is a single message object or the last message object in a FIFO buffer. CanaRegs.CAN_IF2MCTL.bit.EoB = 1; /// Transfer data to message object RAM CAN_IF2CMD_SHADOW.bit.MSG_NUM = objID; CanaRegs.CAN_IF2CMD.all = CAN_IF2CMD_SHADOW.all; } } void send_CAN_message() { // 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) { } CanaRegs.CAN_IF1DATA.bit.Data_0 = 0x1; CanaRegs.CAN_IF1DATA.bit.Data_1 = 0x2; CanaRegs.CAN_IF1DATA.bit.Data_2 = 0x3; CanaRegs.CAN_IF1DATA.bit.Data_3 = 0x4; CanaRegs.CAN_IF1DATB.bit.Data_4 = 0x5; CanaRegs.CAN_IF1DATB.bit.Data_5 = 0x6; CanaRegs.CAN_IF1DATB.bit.Data_6 = 0x7; CanaRegs.CAN_IF1DATB.bit.Data_7 = 0x8; // 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.DIR = 1; CAN_IF1CMD_SHADOW.bit.DATA_A = 1; CAN_IF1CMD_SHADOW.bit.DATA_B = 1; // Set Tx Request Bit CAN_IF1CMD_SHADOW.bit.TXRQST = 1; // Transfer the message object to the message object specified by objID. CAN_IF1CMD_SHADOW.bit.MSG_NUM = 1;//obj id; CanaRegs.CAN_IF1CMD.all = CAN_IF1CMD_SHADOW.all; } void receive_CAN_message() { //CanaRegs.CAN_IF2CMD.bit.Arb = 1; CanaRegs.CAN_IF2CMD.all = 0; CanaRegs.CAN_IF2CMD.bit.Control = 1; CanaRegs.CAN_IF2CMD.bit.DATA_A = 1; CanaRegs.CAN_IF2CMD.bit.DATA_B = 1; /// Obj ID CanaRegs.CAN_IF2CMD.bit.MSG_NUM = 2; // Wait for busy bit to clear. while(CanaRegs.CAN_IF2CMD.bit.Busy) { } if(CanaRegs.CAN_IF2MCTL.bit.NewDat == 1) { rx_data[0] = CanaRegs.CAN_IF2DATA.bit.Data_0; rx_data[1] = CanaRegs.CAN_IF2DATA.bit.Data_1; rx_data[2] = CanaRegs.CAN_IF2DATA.bit.Data_2; rx_data[3] = CanaRegs.CAN_IF2DATA.bit.Data_3; rx_data[4] = CanaRegs.CAN_IF2DATB.bit.Data_4; rx_data[5] = CanaRegs.CAN_IF2DATB.bit.Data_5; rx_data[6] = CanaRegs.CAN_IF2DATB.bit.Data_6; rx_data[7] = CanaRegs.CAN_IF2DATB.bit.Data_7; } CanaRegs.CAN_IF2CMD.bit.TxRqst = 1; // Transfer the message object to the message object IF register. //CanaRegs.CAN_IF2CMD.bit.MSG_NUM = 2; }
谢谢
Damien
尊敬的 Damien:
很高兴听到您在代码方面取得了良好的进展。 我看到您开始接收 CAN 帧。 在随附的代码上、您可以参考影子寄存器。 我们的 F28002x 示例目前使用 driverlib 代码编写、您似乎使用 了一些旧代码来引用不同类型 CAN (eCAN)的影子寄存器。 F28002x DCAN 中没有影子寄存器。 我只想确保您正在对正确的 CAN 寄存器进行编程。 您能否澄清一下您在 F28002x 上使用过哪些影子寄存器?
谢谢、
Joseph