请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
部件号: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
