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通信中,只有默认邮箱1在进行通信,其余邮箱无法正常工作。更令人奇怪的是,即使注释掉通信代码后,邮箱1也仍然通信(一个神奇的bug)
在调试CAN通信时,参考C2000example的例程,对1~5号邮箱进行了初始化
以下为初始化代码
void CAN_init()//初始化CAN通信引脚 { GPIO_setPinConfig(GPIO_18_CANRXA); GPIO_setPinConfig(GPIO_19_CANTXA); CAN_initModule(CANA_BASE); // Set up the CAN bus bit rate to 500kHz for each module // Refer to the Driver Library User Guide for information on how to set // tighter timing control. Additionally, consult the device data sheet // for more information about the CAN module clocking. // CAN_setBitRate(CANA_BASE, DEVICE_SYSCLK_FREQ, 5000000, 16);//500Khz // Initialize the transmit message object used for sending CAN messages. // Message Object Parameters: // CAN Module: A // Message Object ID Number: 1 // Message Identifier: 0x01 数字越小 优先级越高 // Message Frame: Standard // Message Type: Transmit // Message ID Mask: 0x0 // Message Object Flags: None // Message Data Length: 8 Bytes //发送邮箱 4个16位的数据 CAN_setupMessageObject(CANA_BASE, 1, 0x01, CAN_MSG_FRAME_STD, CAN_MSG_OBJ_TYPE_TX, 0, CAN_MSG_OBJ_NO_FLAGS, MSG_DATA_LENGTH); CAN_setupMessageObject(CANA_BASE, 2, 0x02, CAN_MSG_FRAME_STD, CAN_MSG_OBJ_TYPE_TX, 0, CAN_MSG_OBJ_NO_FLAGS, MSG_DATA_LENGTH); CAN_setupMessageObject(CANA_BASE, 3, 0x03, CAN_MSG_FRAME_STD, CAN_MSG_OBJ_TYPE_TX, 0, CAN_MSG_OBJ_NO_FLAGS, MSG_DATA_LENGTH); CAN_setupMessageObject(CANA_BASE, 4, 0x04, CAN_MSG_FRAME_STD, CAN_MSG_OBJ_TYPE_TX, 0, CAN_MSG_OBJ_NO_FLAGS, MSG_DATA_LENGTH); CAN_setupMessageObject(CANA_BASE, 5, 0x05, CAN_MSG_FRAME_STD, CAN_MSG_OBJ_TYPE_TX, 0, CAN_MSG_OBJ_NO_FLAGS, MSG_DATA_LENGTH); //接收邮箱 CAN_setupMessageObject(CANA_BASE, 7, 0x07, CAN_MSG_FRAME_STD, CAN_MSG_OBJ_TYPE_RX, 0, CAN_MSG_OBJ_NO_FLAGS, MSG_DATA_LENGTH); CAN_startModule(CANA_BASE); }
随后是通信代码
void communication(void) { // 8字节数组可以放4个16位信号,需要移位进行组合 CanFrame1[0] = ((uint16_t)(Udc * 10) >> 8) & 0xFF; CanFrame1[1] = (uint16_t)(Udc * 10) & 0xFF; CanFrame1[2] = ((uint16_t)((Ua + 300) * 10) >> 8) & 0xFF; CanFrame1[3] = (uint16_t)((Ua + 300) * 10) & 0xFF; CanFrame1[4] = ((uint16_t)((Ub + 300) * 10) >> 8) & 0xFF; CanFrame1[5] = (uint16_t)((Ub + 300) * 10) & 0xFF; CanFrame1[6] = ((uint16_t)((Uc + 300) * 10) >> 8) & 0xFF; CanFrame1[7] = (uint16_t)((Uc + 300) * 10) & 0xFF; CAN_sendMessage(CANA_BASE, 1, MSG_DATA_LENGTH, CanFrame1); // 2号邮箱发送 Ia, Ib, Ic, Ipa CanFrame2[0] = ((uint16_t)((Ia + 40) * 10) >> 8) & 0xFF; CanFrame2[1] = (uint16_t)((Ia + 40) * 10) & 0xFF; CanFrame2[2] = ((uint16_t)((Ib + 40) * 10) >> 8) & 0xFF; CanFrame2[3] = (uint16_t)((Ib + 40) * 10) & 0xFF; CanFrame2[4] = ((uint16_t)((Ic + 40) * 10) >> 8) & 0xFF; CanFrame2[5] = (uint16_t)((Ic + 40) * 10) & 0xFF; CanFrame2[6] = ((uint16_t)((Ipa + 40) * 10) >> 8) & 0xFF; CanFrame2[7] = (uint16_t)((Ipa + 40) * 10) & 0xFF; CAN_sendMessage(CANA_BASE, 2, MSG_DATA_LENGTH, CanFrame2); // while(!(HWREGH(CANA_BASE + CAN_O_ES) & CAN_ES_TXOK)); // 3号邮箱发送 Ina, Ipb, Inb, Ipc CanFrame3[0] = ((uint16_t)((Ina + 40) * 10) >> 8) & 0xFF; CanFrame3[1] = (uint16_t)((Ina + 40) * 10) & 0xFF; CanFrame3[2] = ((uint16_t)((Ipb + 40) * 10) >> 8) & 0xFF; CanFrame3[3] = (uint16_t)((Ipb + 40) * 10) & 0xFF; CanFrame3[4] = ((uint16_t)((Inb + 40) * 10) >> 8) & 0xFF; CanFrame3[5] = (uint16_t)((Inb + 40) * 10) & 0xFF; CanFrame3[6] = ((uint16_t)((Ipc + 40) * 10) >> 8) & 0xFF; CanFrame3[7] = (uint16_t)((Ipc + 40) * 10) & 0xFF; CAN_sendMessage(CANA_BASE, 3, MSG_DATA_LENGTH, CanFrame3); // 4号邮箱发送 Inc, average_Aarm, average_Barm, average_Carm CanFrame4[0] = ((uint16_t)((Inc + 40) * 10) >> 8) & 0xFF; CanFrame4[1] = (uint16_t)((Inc + 40) * 10) & 0xFF; CanFrame4[2] = ((uint16_t)((average_Aarm + 40) * 10) >> 8) & 0xFF; CanFrame4[3] = (uint16_t)((average_Aarm + 40) * 10) & 0xFF; CanFrame4[4] = ((uint16_t)((average_Barm + 40) * 10) >> 8) & 0xFF; CanFrame4[5] = (uint16_t)((average_Barm + 40) * 10) & 0xFF; CanFrame4[6] = ((uint16_t)((average_Carm + 40) * 10) >> 8) & 0xFF; CanFrame4[7] = (uint16_t)((average_Carm + 40) * 10) & 0xFF; CAN_sendMessage(CANA_BASE, 4, MSG_DATA_LENGTH, CanFrame4); // 5号邮箱发送 ABC 调制波信号 CanFrame5[0] = (A_modu_12000 >> 8) & 0xFF; CanFrame5[1] = A_modu_12000 & 0xFF; CanFrame5[2] = (B_modu_12000 >> 8) & 0xFF; CanFrame5[3] = B_modu_12000 & 0xFF; CanFrame5[4] = (C_modu_12000 >> 8) & 0xFF; CanFrame5[5] = C_modu_12000 & 0xFF; CanFrame5[6] = ((uint16_t)((Theta + 100) * 10) >> 8) & 0xFF; CanFrame5[7] = ((uint16_t)((Theta + 100) * 10)) & 0xFF; CAN_sendMessage(CANA_BASE, 5, MSG_DATA_LENGTH, CanFrame5); // 7号邮箱接收 if(HWREGH(CANA_BASE + CAN_O_ES) & CAN_ES_RXOK) { CAN_readMessage(CANA_BASE, 7, CanRecFrame); disable = ((uint16_t)CanRecFrame[0] << 8) | CanRecFrame[1]; status = ((uint16_t)CanRecFrame[2] << 8) | CanRecFrame[3]; Uac_ref = ((uint16_t)CanRecFrame[4] << 8) | CanRecFrame[5]; pre_flag = ((uint16_t)CanRecFrame[6] << 8) | CanRecFrame[7]; } }
以下是实验现象,其中Uabc与Idc(实际为Idc中)能够正常接收(邮箱1),其余部分无法同步,观察can帧信号后也发现邮箱ID始终为1;
即使注释掉communication函数,邮箱1仍然发送。这个是什么原因导致的呢?
问题最终定位在
CAN_setBitRate(CANA_BASE, DEVICE_SYSCLK_FREQ, 5000000, 16);
TI所提供例程中的16bittime 在一个邮箱情况下是可以运行的;
但不足以支撑多个邮箱的快速发送,详情可见如下函数:
void CAN_setBitRate(uint32_t base, uint32_t clockFreq, uint32_t bitRate, uint16_t bitTime) { uint16_t brp; uint16_t tPhase; uint16_t phaseSeg2; uint16_t tSync = 1U; uint16_t tProp = 2U; uint16_t tSeg1; uint16_t tSeg2; uint16_t sjw; uint16_t prescaler; uint16_t prescalerExtension; // // Check the arguments. // ASSERT(CAN_isBaseValid(base)); ASSERT((bitTime > 7U) && (bitTime < 26U)); ASSERT(bitRate <= 1000000U); // // Calculate bit timing values // brp = (uint16_t)(clockFreq / (bitRate * bitTime)); tPhase = bitTime - (tSync + tProp); if((tPhase / 2U) <= 8U) { phaseSeg2 = tPhase / 2U; } else { phaseSeg2 = 8U; } tSeg1 = ((tPhase - phaseSeg2) + tProp) - 1U; tSeg2 = phaseSeg2 - 1U; if(phaseSeg2 > 4U) { sjw = 3U; } else { sjw = tSeg2; } prescalerExtension = ((brp - 1U) / 64U); prescaler = ((brp - 1U) % 64U); // // Set the calculated timing parameters // CAN_setBitTiming(base, prescaler, prescalerExtension, tSeg1, tSeg2, sjw); }
bittime决定了brq(波特率预分频值),若配置5个邮箱所计算得到的CAN通信情况下brq将会偏大,从而使得CAN邮箱发送时序被挤占,进一步导致其无法发送。
后续经过测试 将bittime改为20及以上能够满足多个邮箱发送的需求。
至此这个问题解决了,希望给后人一点帮助。
另外值得说明的是,CAN通信需要留够足够的时钟周期,放在中断中如果时钟周期不够 则同样不能工作。