请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
部件号:TM4C1230E6PM 您好,
我用10毫秒的CAN询问时间做了3次功能测试,系统工作了一个星期,然后我有了CAN总线框架,但没有传输。
我使用TM4C1230E6PM。
这是CANBUS配置
/** * @fn static void vd_srv_COM_Init(void) * @brief Activate interrupt CAN FIFO0 RX * @param none * @return none */ void vd_srv_COM_Init(void) { u32_UiCanBus = CAN0_BASE; /* Enable Rx interrupt */ CANDisable(u32_UiCanBus); CANIntDisable(u32_UiCanBus, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS); switch (u32_UiCanBus) { case CAN0_BASE: IntDisable(INT_CAN0); break; default: break; } IntDisable(INT_CAN0); CANInit(u32_UiCanBus); CANBitRateSet(u32_UiCanBus, SysCtlClockGet(), 250000); CANIntEnable(u32_UiCanBus, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS); switch (u32_UiCanBus) { case CAN0_BASE: IntEnable(INT_CAN0); IntPrioritySet(INT_CAN0, 10); break; default: break; } CANEnable(u32_UiCanBus); g_sCANMsgObjectRx1.ui32Flags = (MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER ); g_sCANMsgObjectRx1.pui8MsgData = u8_CanRxData; g_sCANMsgObjectRx1.ui32MsgID = 0x20; g_sCANMsgObjectRx1.ui32MsgIDMask = 0; g_sCANMsgObjectRx1.ui32Flags = (MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER ); g_sCANMsgObjectRx1.ui32MsgLen = 8; CANMessageSet(u32_UiCanBus, 1, &g_sCANMsgObjectRx1, MSG_OBJ_TYPE_RX); g_sCANMsgObjectRx1.ui32MsgLen = 7; CANMessageSet(u32_UiCanBus, 2, &g_sCANMsgObjectRx1, MSG_OBJ_TYPE_RX); g_sCANMsgObjectRx1.ui32MsgLen = 8; g_sCANMsgObjectRx1.ui32Flags = (MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER | MSG_OBJ_REMOTE_FRAME ); CANMessageSet(u32_UiCanBus, 3, &g_sCANMsgObjectRx1, MSG_OBJ_TYPE_RX_REMOTE); }
这是带有传输的代码
static void vd_srv_com_WriteCanData8Octet(uint32_t u32_UiCanBus) { uint16_t u16_CalculData = U16_NULL; int16_t i16_CalculCurrent = 0; /* Construit la trame � envoyer */ g_sCANMsgObjectTx1.ui32MsgID = g_sCANMsgObjectRx1.ui32MsgID; g_sCANMsgObjectTx1.ui32MsgIDMask = 0; g_sCANMsgObjectTx1.ui32Flags = MSG_OBJ_TX_INT_ENABLE; g_sCANMsgObjectTx1.ui32MsgLen = NB_DATA_LECTURE_8OCTET; /* S'il n'y � pas de d�faut dans le lecture de la tension alors */ /* la tension prends la valeur de la jauge */ if ( (u16_srv_SNS_GetVoltage() > 0) && ( u16_srv_SNS_GetVoltage() < 0xFFFF)) { u16_CalculData = u16_srv_SNS_GetVoltage() / COEFF_MES; } else { u16_CalculData = u16_srv_MEASANA_GetVBattInMv() / COEFF_MES; } u8_CanTxData[0] = (u16_CalculData & FILTRE_POIDS_FORT) >> DECALAGE_8BIT; u8_CanTxData[1] = u16_CalculData & FILTRE_POIDS_FAIBLE; u8_CanTxData[2] = (uint8_t)(i8_srv_MEASANA_GetTempBattInDeg() + OFFSET_TEMP); u16_CalculData = u16_srv_MEASANA_GetIchargeInMa() / COEFF_MES; u8_CanTxData[3] = u16_CalculData & FILTRE_POIDS_FAIBLE; if (u16_srv_MEASANA_GetIoutInMa() < U16_SEUIL_SELECT_CURRENT) { i16_CalculCurrent = i16_srv_SNS_GetCurrent() - (int16_t)(u16_srv_MEASANA_GetIchargeInMa()); if (i16_CalculCurrent > 0) { u16_CalculData = U16_NULL; } else { u16_CalculData = (uint16_t)(-1 * i16_CalculCurrent); u16_CalculData = u16_CalculData / COEFF_MES; } } else { u16_CalculData = u16_srv_MEASANA_GetIoutInMa() / COEFF_MES; } u8_CanTxData[4] = u16_CalculData & FILTRE_POIDS_FAIBLE;; u8_CanTxData[5] = (uint8_t)(u16_srv_REGISTER_GetValue(ADD_REG_PARCBATTERIESOUSPARC)) & 0x0F; u8_CanTxData[5] |= ((uint8_t)(u16_srv_REGISTER_GetValue(ADD_REG_PARCBATTERIEPARC)) & 0x0F) << 4; u8_CanTxData[6] = (uint8_t)(u16_srv_REGISTER_GetValue(ADD_REG_STATUS)); u8_CanTxData[7] = u8_srv_SNS_GetRsoc(); /* Envoie de la trame CAN */ g_sCANMsgObjectTx1.pui8MsgData = u8_CanTxData; CANMessageSet(u32_UiCanBus, 4, &g_sCANMsgObjectTx1, MSG_OBJ_TYPE_TX); while(!g_bMsgObj4Sent) { } g_bMsgObj4Sent = 0; }
中断可以
/** * @fn void vd_app_scheduler_Update(void) * @brief Update scheduler counter and variable * @param none * @return none */ void CAN0_Handler(void) { uint32_t ui32Status; // // Read the CAN interrupt status to find the cause of the interrupt // ui32Status = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE); // // If the cause is a controller status interrupt, then get the status // if(ui32Status == CAN_INT_INTID_STATUS) { // // Read the controller status. This will return a field of status // error bits that can indicate various errors. Error processing // is not done in this example for simplicity. Refer to the // API documentation for details about the error status bits. // The act of reading this status will clear the interrupt. If the // CAN peripheral is not connected to a CAN bus with other CAN devices // present, then errors will occur and will be indicated in the // controller status. // ui32Status = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL); // // Set a flag to indicate some errors may have occurred. // g_bErrFlag = 1; g_bMsgObj3Sent = 1; g_bMsgObj4Sent = 1; u8_FlagErrorCan = 1; u8_FlagRx = 1; CANIntClear(CAN0_BASE, 0); CANIntClear(CAN0_BASE, 1); CANIntClear(CAN0_BASE, 2); CANIntClear(CAN0_BASE, 3); CANIntClear(CAN0_BASE, 4); if (ui32Status & 0xE7) { vd_srv_COM_Init(); } } // // Check if the cause is message object 1, which is used for sending // message 1. // else if(ui32Status == 1) { u8_FlagRx = 1; // // Getting to this point means that the TX interrupt occurred on // message object 1, and the message TX is complete. Clear the // message object interrupt. // CANIntClear(CAN0_BASE, 1); // // Increment a counter to keep track of how many messages have been // sent. In a real application this could be used to set flags to // indicate when a message is sent. // g_ui32Msg1Count++; // // Since the message was sent, clear any error flags. // g_bErrFlag = 0; // vd_srv_COM_ReceptInt(CAN0_BASE); } // // Check if the cause is message object 2, which is used for sending // message 2. // else if(ui32Status == 2) { u8_FlagRx = 1; // // Getting to this point means that the TX interrupt occurred on // message object 1, and the message TX is complete. Clear the // message object interrupt. // CANIntClear(CAN0_BASE, 2); // // Increment a counter to keep track of how many messages have been // sent. In a real application this could be used to set flags to // indicate when a message is sent. // g_ui32Msg1Count++; // // Since the message was sent, clear any error flags. // g_bErrFlag = 0; // vd_srv_COM_ReceptInt(CAN0_BASE); } // // Check if the cause is message object 3, which is used for sending // messages 3 and 4. // else if(ui32Status == 3) { u8_FlagRx = 1; // // Getting to this point means that the TX interrupt occurred on // message object 1, and the message TX is complete. Clear the // message object interrupt. // CANIntClear(CAN0_BASE, 3); // // Increment a counter to keep track of how many messages have been // sent. In a real application this could be used to set flags to // indicate when a message is sent. // g_ui32Msg1Count++; // // Since the message was sent, clear any error flags. // g_bErrFlag = 0; //vd_srv_COM_ReceptInt(CAN0_BASE); } // // Otherwise, something unexpected caused the interrupt. This should // never happen. // else if(ui32Status == 4) { CANIntClear(CAN0_BASE, 4); // // Increment a counter to keep track of how many messages have been // sent. In a real application this could be used to set flags to // indicate when a message is sent. // g_ui32Msg1Count++; g_bMsgObj3Sent = 1; g_bMsgObj4Sent = 1; // // Since the message was sent, clear any error flags. // g_bErrFlag = 0; } else { g_bMsgObj3Sent = 1; g_bMsgObj4Sent = 1; u8_FlagErrorCan = 1; CANIntClear(CAN0_BASE, 0); } }
此致,
Ludovic Micou