用can上位机模拟下发给dsp一帧固定的8个字节数据,dsp接收的,偶尔会有接收错误。调用的这个函数(getCANAMessage),查询接受CAN接收的数据,这个数组(ucRXMsgData),接收的数据,偶尔会有高字节的,数据不对。当前,每间隔4ms,调用一次getCANAMessage函数,CAN上位机间隔20ms发送一帧数据。
在线等!
//########################################################################### // // FILE: F2837xD_can.c // // TITLE: F2837xD CAN Support Functions. // //########################################################################### // // Included Files // #include "F28x_Project.h" #include "F2837xD_device.h" #include "F2837xD_Examples.h" #include "Custom_ECan.h" #include "Variable.h" #include "Modbus.h" #include "Commu_Para.h" /*****************************************************************/ union CanWord_Type CANB_ID,CANA_ID; Uint8 ucTXMsgData[8], ucRXMsgData[8],ucRX2MsgData[8],ucTX2MsgData[8]; Uint8 ucRX3MsgData[8],ucTX3MsgData[8],ucRX4MsgData[8],ucTX4MsgData[8]; Uint8 ucRX5MsgData[8],ucTX5MsgData[8],ucRX6MsgData[8],ucTX6MsgData[8]; Uint8 ucRX9MsgData[8],ucTX9MsgData[8]; uint32_t ucRXMsg_MSGID_EMS,ucRXMsg_MSGID_STS,ucRXMsg_MSGID_PCSOne,ucRXMsg_MSGID_PCSTwo,ucRXMsg_MSGID_PCS; Uint32 Test1U32=0,Test2U32=0; Uint32 Test3U32=0,Test4U32=0; /*****************************************************************/ static const uint16_t canBitValues[] = { 0x1100, // TSEG2 2, TSEG1 2, SJW 1, Divide 5 0x1200, // TSEG2 2, TSEG1 3, SJW 1, Divide 6 0x2240, // TSEG2 3, TSEG1 3, SJW 2, Divide 7 0x2340, // TSEG2 3, TSEG1 4, SJW 2, Divide 8 0x3340, // TSEG2 4, TSEG1 4, SJW 2, Divide 9 0x3440, // TSEG2 4, TSEG1 5, SJW 2, Divide 10 0x3540, // TSEG2 4, TSEG1 6, SJW 2, Divide 11 0x3640, // TSEG2 4, TSEG1 7, SJW 2, Divide 12 0x3740 // TSEG2 4, TSEG1 8, SJW 2, Divide 13 }; /* typedef enum { //! Transmit message object. MSG_OBJ_TYPE_TRANSMIT, //! Receive message object. MSG_OBJ_TYPE_RECEIVE } msgObjType; */ // // InitCAN - Initializes the CAN-A controller after reset. // void InitCANA(void) { int16_t iMsg; // // 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; CanaRegs.CAN_CTL.bit.SWR = 1; CanaRegs.CAN_CTL.bit.ABO = 1; // // Wait for busy bit to clear // while(CanaRegs.CAN_IF1CMD.bit.Busy) { } // // Clear the message value bit in the arbitration register. This indicates // the message is not valid and is a "safe" condition to leave the message // object. The same arb reg is used to program all the message objects. // CanaRegs.CAN_IF1CMD.bit.DIR = 1; CanaRegs.CAN_IF1CMD.bit.Arb = 1; CanaRegs.CAN_IF1CMD.bit.Control = 1; CanaRegs.CAN_IF1ARB.all = 0; CanaRegs.CAN_IF1MCTL.all = 0; CanaRegs.CAN_IF2CMD.bit.DIR = 1; CanaRegs.CAN_IF2CMD.bit.Arb = 1; CanaRegs.CAN_IF2CMD.bit.Control = 1; CanaRegs.CAN_IF2ARB.all = 0; CanaRegs.CAN_IF2MCTL.all = 0; // // Loop through to program all 32 message objects // for(iMsg = 1; iMsg <= 32; iMsg+=2) { // // Wait for busy bit to clear // while(CanaRegs.CAN_IF1CMD.bit.Busy) { } // // Initiate programming the message object // CanaRegs.CAN_IF1CMD.bit.MSG_NUM = iMsg; // // Wait for busy bit to clear // while(CanaRegs.CAN_IF2CMD.bit.Busy) { } // // Initiate programming the message object // CanaRegs.CAN_IF2CMD.bit.MSG_NUM = iMsg + 1; } // // Acknowledge any pending status interrupts. // //volatile uint32_t discardRead = CanaRegs.CAN_ES.all; } void InitCANB(void) { int16_t iMsg; // // 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. // CanbRegs.CAN_CTL.bit.Init = 1; CanbRegs.CAN_CTL.bit.SWR = 1; CanbRegs.CAN_CTL.bit.ABO = 1; // // Wait for busy bit to clear // while(CanbRegs.CAN_IF1CMD.bit.Busy) { } // // Clear the message value bit in the arbitration register. This indicates // the message is not valid and is a "safe" condition to leave the message // object. The same arb reg is used to program all the message objects. // CanbRegs.CAN_IF1CMD.bit.DIR = 1; CanbRegs.CAN_IF1CMD.bit.Arb = 1; CanbRegs.CAN_IF1CMD.bit.Control = 1; CanbRegs.CAN_IF1ARB.all = 0; CanbRegs.CAN_IF1MCTL.all = 0; CanbRegs.CAN_IF2CMD.bit.DIR = 1; CanbRegs.CAN_IF2CMD.bit.Arb = 1; CanbRegs.CAN_IF2CMD.bit.Control = 1; CanbRegs.CAN_IF2ARB.all = 0; CanbRegs.CAN_IF2MCTL.all = 0; // // Loop through to program all 32 message objects // for(iMsg = 1; iMsg <= 32; iMsg+=2) { // // Wait for busy bit to clear // while(CanbRegs.CAN_IF1CMD.bit.Busy) { } // // Initiate programming the message object // CanbRegs.CAN_IF1CMD.bit.MSG_NUM = iMsg; // // Wait for busy bit to clear // while(CanbRegs.CAN_IF2CMD.bit.Busy) { } // // Initiate programming the message object // CanbRegs.CAN_IF2CMD.bit.MSG_NUM = iMsg + 1; } // // Acknowledge any pending status interrupts. // //volatile uint32_t discardRead = CanbRegs.CAN_ES.all; } // // setCANBitRate - Set the CAN bit rate based on device clock (Hz) // and desired bit rate (Hz) // uint32_t setCANABitRate(uint32_t sourceClock, uint32_t bitRate) { uint32_t desiredRatio; uint32_t canBits; uint32_t preDivide; uint32_t regValue; uint16_t canControlValue; // // Calculate the desired clock rate. // desiredRatio = sourceClock / bitRate; // // Make sure that the Desired Ratio is not too large. This enforces the // requirement that the bit rate is larger than requested. // if((sourceClock / desiredRatio) > bitRate) { desiredRatio += 1; } // // Check all possible values to find a matching value. // while(desiredRatio <= CAN_MAX_PRE_DIVISOR * CAN_MAX_BIT_DIVISOR) { // // Loop through all possible CAN bit divisors. // for(canBits = CAN_MAX_BIT_DIVISOR; canBits >= CAN_MIN_BIT_DIVISOR; canBits--) { // // For a given CAN bit divisor save the pre divisor. // preDivide = desiredRatio / canBits; // // If the calculated divisors match the desired clock ratio then // return these bit rate and set the CAN bit timing. // if((preDivide * canBits) == desiredRatio) { // // Start building the bit timing value by adding the bit timing // in time quanta. // regValue = canBitValues[canBits - CAN_MIN_BIT_DIVISOR]; // // To set the bit timing register, the controller must be // placed // in init mode (if not already), and also configuration change // bit enabled. The state of the register should be saved // so it can be restored. // canControlValue = CanaRegs.CAN_CTL.all; CanaRegs.CAN_CTL.bit.Init = 1; CanaRegs.CAN_CTL.bit.CCE = 1; // // Now add in the pre-scalar on the bit rate. // regValue |= ((preDivide - 1) & CAN_BTR_BRP_M) | (((preDivide - 1) << 10) & CAN_BTR_BRPE_M); // // Set the clock bits in the and the bits of the // pre-scalar. // CanaRegs.CAN_BTR.all = regValue; // // Restore the saved CAN Control register. // CanaRegs.CAN_CTL.all = canControlValue; // // Return the computed bit rate. // return(sourceClock / ( preDivide * canBits)); } } // // Move the divisor up one and look again. Only in rare cases are // more than 2 loops required to find the value. // desiredRatio++; } return 0; } // // setCANBitRate - Set the CAN bit rate based on device clock (Hz) // and desired bit rate (Hz) // uint32_t setCANBBitRate(uint32_t sourceClock, uint32_t bitRate) { uint32_t desiredRatio; uint32_t canBits; uint32_t preDivide; uint32_t regValue; uint16_t canControlValue; // // Calculate the desired clock rate. // desiredRatio = sourceClock / bitRate; // // Make sure that the Desired Ratio is not too large. This enforces the // requirement that the bit rate is larger than requested. // if((sourceClock / desiredRatio) > bitRate) { desiredRatio += 1; } // // Check all possible values to find a matching value. // while(desiredRatio <= CAN_MAX_PRE_DIVISOR * CAN_MAX_BIT_DIVISOR) { // // Loop through all possible CAN bit divisors. // for(canBits = CAN_MAX_BIT_DIVISOR; canBits >= CAN_MIN_BIT_DIVISOR; canBits--) { // // For a given CAN bit divisor save the pre divisor. // preDivide = desiredRatio / canBits; // // If the calculated divisors match the desired clock ratio then // return these bit rate and set the CAN bit timing. // if((preDivide * canBits) == desiredRatio) { // // Start building the bit timing value by adding the bit timing // in time quanta. // regValue = canBitValues[canBits - CAN_MIN_BIT_DIVISOR]; // // To set the bit timing register, the controller must be // placed // in init mode (if not already), and also configuration change // bit enabled. The state of the register should be saved // so it can be restored. // canControlValue = CanbRegs.CAN_CTL.all; CanbRegs.CAN_CTL.bit.Init = 1; CanbRegs.CAN_CTL.bit.CCE = 1; // // Now add in the pre-scalar on the bit rate. // regValue |= ((preDivide - 1) & CAN_BTR_BRP_M) | (((preDivide - 1) << 10) & CAN_BTR_BRPE_M); // // Set the clock bits in the and the bits of the // pre-scalar. // CanbRegs.CAN_BTR.all = regValue; // // Restore the saved CAN Control register. // CanbRegs.CAN_CTL.all = canControlValue; // // Return the computed bit rate. // return(sourceClock / ( preDivide * canBits)); } } // // Move the divisor up one and look again. Only in rare cases are // more than 2 loops required to find the value. // desiredRatio++; } return 0; } // // setupMessageObject - Setup message object as Transmit or Receive // void setupCanAMessageObject(uint32_t objID,uint32_t msgIDMsk,uint16_t messageSize,uint32_t msgID, msgObjType msgType) { // // 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.DIR = 1; // // Set direction to transmit // if(msgType == MSG_OBJ_TYPE_TRANSMIT) { CanaRegs.CAN_IF1ARB.bit.Dir = 1; } /*if(msgType == MSG_OBJ_TYPE_RECEIVE) { CanaRegs.CAN_IF1ARB.bit.Dir = 0; }*/ // // Set Message ID (this example assumes 11 bit ID mask) // CanaRegs.CAN_IF1MSK.bit.MXtd = 1; CanaRegs.CAN_IF1MSK.bit.MDir = 1; CanaRegs.CAN_IF1MSK.bit.Msk = msgIDMsk; CanaRegs.CAN_IF1MCTL.bit.UMask = 1; // // Set Message ID (this example assumes 29 bit ID mask) // CanaRegs.CAN_IF1ARB.bit.Xtd = 1; CanaRegs.CAN_IF1ARB.bit.ID = msgID; 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; // // Transfer data to message object RAM // CAN_IF1CMD_SHADOW.bit.MSG_NUM = objID; CanaRegs.CAN_IF1CMD.all = CAN_IF1CMD_SHADOW.all; } // // setupMessageObject - Setup message object as Transmit or Receive // void setupCanBMessageObject(uint32_t objID,uint32_t msgIDMsk,uint16_t messageSize,uint32_t msgID, msgObjType msgType) { // // 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(CanbRegs.CAN_IF1CMD.bit.Busy) { } // // Clear and Write out the registers to program the message object. // CAN_IF1CMD_SHADOW.all = 0; CanbRegs.CAN_IF1MSK.all = 0; CanbRegs.CAN_IF1ARB.all = 0; CanbRegs.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.DIR = 1; // // Set direction to transmit // if(msgType == MSG_OBJ_TYPE_TRANSMIT) { CanbRegs.CAN_IF1ARB.bit.Dir = 1; } /*if(msgType == MSG_OBJ_TYPE_RECEIVE) { CanaRegs.CAN_IF1ARB.bit.Dir = 0; }*/ // // Set Message ID (this example assumes 11 bit ID mask) // CanbRegs.CAN_IF1MSK.bit.MXtd = 1; CanbRegs.CAN_IF1MSK.bit.MDir = 1; CanbRegs.CAN_IF1MSK.bit.Msk = msgIDMsk; CanbRegs.CAN_IF1MCTL.bit.UMask = 1; // // Set Message ID (this example assumes 11 bit ID mask) // CanbRegs.CAN_IF1ARB.bit.Xtd = 1; CanbRegs.CAN_IF1ARB.bit.ID = msgID; CanbRegs.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. // CanbRegs.CAN_IF1MCTL.bit.DLC = messageSize; CanbRegs.CAN_IF1MCTL.bit.EoB = 1; // // Transfer data to message object RAM // CAN_IF1CMD_SHADOW.bit.MSG_NUM = objID; CanbRegs.CAN_IF1CMD.all = CAN_IF1CMD_SHADOW.all; } // // setupMessageObject - Transmit data from the specified message object // Uint32 CanA_baudrate = 500000; Uint32 CanB_baudrate = 500000; void ECan_MObjectInit(void) { uint32_t messageSize; union CanWord_Type MessageID; CanA_baudrate = (Uint32)Can_BaudRate * 1000; setCANABitRate(200000000,CanA_baudrate); // // Enable the CAN for operation. // CanaRegs.CAN_CTL.bit.Init = 0; // // Initialize the message object that will be used for sending CAN // messages. // //PCS To EMS Set MessageID.DataInt = CAN_MSG_ID_EMS_Tx; //ID_Addr = 0x01; //MessageID.bit.SRCADDR = ID_Addr; //MessageID.bit.DSTADDRL = EMS_Addr & 0x0f; //MessageID.bit.DSTADDRH = (EMS_Addr >>4) & 0x0f; messageSize = sizeof(ucTXMsgData); // Message Size (DLC) setupCanAMessageObject(CANA_TX_MSG_OBJ_EMS,CAN_MSG_IDMSK,messageSize,MessageID.DataInt, MSG_OBJ_TYPE_TRANSMIT); MessageID.DataInt = CAN_MSG_ID_EMS_Rx; //MessageID.bit.SRCADDR = EMS_Addr; //MessageID.bit.DSTADDRL = ID_Addr & 0x0f; //MessageID.bit.DSTADDRH = (ID_Addr >>4) & 0x0f; messageSize = sizeof(ucRXMsgData); // Message Size (DLC) setupCanAMessageObject(CANA_RX_MSG_OBJ_EMS,CAN_MSG_IDMSK,messageSize,MessageID.DataInt, MSG_OBJ_TYPE_RECEIVE); //PCS To STS Set MessageID.DataInt = CAN_MSG_ID_STS_Tx; messageSize = sizeof(ucTX2MsgData); // Message Size (DLC) setupCanAMessageObject(CANA_TX_MSG_OBJ_STS,CAN_MSG_IDMSK,messageSize,MessageID.DataInt, MSG_OBJ_TYPE_TRANSMIT); MessageID.DataInt = CAN_MSG_ID_STS_Rx; messageSize = sizeof(ucRX2MsgData); // Message Size (DLC) setupCanAMessageObject(CANA_RX_MSG_OBJ_STS,CAN_MSG_IDMSK,messageSize,MessageID.DataInt, MSG_OBJ_TYPE_RECEIVE); //PCS To PCS(During the grid connection process, the slave sends battery current, //and the host receives and calculates the total battery current.) MessageID.DataInt = CAN_MSG_ID_PCSDC_Tx; MessageID.bit.CNT = Can_BT; //Battery cluster number MessageID.bit.SRCADDR = ID_Addr; //Slave address messageSize = sizeof(ucTX3MsgData); // Message Size (DLC) setupCanAMessageObject(CANA_TX_MSG_OBJ_PCSOne,CAN_MSG_IDMSK,messageSize,MessageID.DataInt, MSG_OBJ_TYPE_TRANSMIT); MessageID.DataInt = CAN_MSG_ID_PCSDC_Rx; MessageID.bit.CNT = Can_BT; //Battery cluster number messageSize = sizeof(ucRX3MsgData); // Message Size (DLC) setupCanAMessageObject(CANA_RX_MSG_OBJ_PCSOne,CAN_MSG_IDMSK,messageSize,MessageID.DataInt, MSG_OBJ_TYPE_RECEIVE); /* //PCS To PCS锛圥arallel and offgrid hosts send running status锛夆�斺�擟ANA MessageID.DataInt = CAN_MSG_ID_PCSSet_Tx; messageSize = sizeof(ucTX4MsgData); // Message Size (DLC) setupCanAMessageObject(CANA_TX_MSG_OBJ_PCSTwo,CAN_MSG_IDMSK,messageSize,MessageID.DataInt, MSG_OBJ_TYPE_TRANSMIT); MessageID.DataInt = CAN_MSG_ID_PCSSet_Rx; messageSize = sizeof(ucRX4MsgData); // Message Size (DLC) setupCanAMessageObject(CANA_RX_MSG_OBJ_PCSTwo,CAN_MSG_IDMSK,messageSize,MessageID.DataInt, MSG_OBJ_TYPE_RECEIVE); */ } void ECan_RegInit_Internal() { uint32_t messageSize; union CanWord_Type MessageID; CanB_baudrate = (Uint32)CanB_BaudRate1 * 1000; setCANBBitRate(200000000,CanB_baudrate); CanbRegs.CAN_CTL.bit.Init = 0; //PCS To PCS (Parallel fast communication interface)-CANB MessageID.DataInt = CAN_MSG_ID_PCS_Tx; messageSize = sizeof(ucTX5MsgData); // Message Size (DLC) setupCanBMessageObject(CANB_TX_MSG_OBJ_PCS,CAN_MSG_IDMSK,messageSize,MessageID.DataInt, MSG_OBJ_TYPE_TRANSMIT); MessageID.DataInt = CAN_MSG_ID_PCS_Rx; messageSize = sizeof(ucRX5MsgData); // Message Size (DLC) setupCanBMessageObject(CANB_RX_MSG_OBJ_PCS,CAN_MSG_IDMSK,messageSize,MessageID.DataInt, MSG_OBJ_TYPE_RECEIVE); //PCS To PCS (Parallel fast communication interface)-CANB MessageID.DataInt = CAN_MSG_ID_PCS_Tx2; MessageID.bit.CNT = Can_BT; messageSize = sizeof(ucTX9MsgData); // Message Size (DLC) setupCanBMessageObject(CANB_TX_MSG_OBJ_PCS2,CAN_MSG_IDMSK,messageSize,MessageID.DataInt, MSG_OBJ_TYPE_TRANSMIT); MessageID.DataInt = CAN_MSG_ID_PCS_Rx2; MessageID.bit.CNT = Can_BT; messageSize = sizeof(ucRX9MsgData); // Message Size (DLC) setupCanBMessageObject(CANB_RX_MSG_OBJ_PCS2,CAN_MSG_IDMSK,messageSize,MessageID.DataInt, MSG_OBJ_TYPE_RECEIVE); } // // sendCANMessage - Transmit data from the specified message object // void sendCANAMessage(uint32_t objID,Uint8 *TXMsgData) { // // Use Shadow variable for IF1CMD. IF1CMD should be written to in // single 32-bit write. // union CAN_IF1CMD_REG CAN_IF1CMD_SHADOW; union CAN_IF1ARB_REG CAN_IF1ARB_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 // CanaRegs.CAN_IF1DATA.bit.Data_0 = *TXMsgData; CanaRegs.CAN_IF1DATA.bit.Data_1 = *(TXMsgData + 1); CanaRegs.CAN_IF1DATA.bit.Data_2 = *(TXMsgData + 2); CanaRegs.CAN_IF1DATA.bit.Data_3 = *(TXMsgData + 3); CanaRegs.CAN_IF1DATB.bit.Data_4 = *(TXMsgData + 4); CanaRegs.CAN_IF1DATB.bit.Data_5 = *(TXMsgData + 5); CanaRegs.CAN_IF1DATB.bit.Data_6 = *(TXMsgData + 6); CanaRegs.CAN_IF1DATB.bit.Data_7 = *(TXMsgData + 7); // // 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; /*CAN_IF1ARB_SHADOW.bit.Dir = 1; CAN_IF1ARB_SHADOW.bit.Xtd = 1; CAN_IF1ARB_SHADOW.bit.ID = msgID; CAN_IF1ARB_SHADOW.bit.MsgVal = 1; CanaRegs.CAN_IF1ARB.all = CAN_IF1ARB_SHADOW.all;*/ // // 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 = objID; CanaRegs.CAN_IF1CMD.all = CAN_IF1CMD_SHADOW.all; } // // sendCANMessage - Transmit data from the specified message object // void sendCANBMessage(uint32_t objID,Uint8 *TXMsgData) { // // 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(CanbRegs.CAN_IF1CMD.bit.Busy) { } // // Write data to transfer into DATA-A and DATA-B interface registers // CanbRegs.CAN_IF1DATA.bit.Data_0 = *TXMsgData; CanbRegs.CAN_IF1DATA.bit.Data_1 = *(TXMsgData + 1); CanbRegs.CAN_IF1DATA.bit.Data_2 = *(TXMsgData + 2); CanbRegs.CAN_IF1DATA.bit.Data_3 = *(TXMsgData + 3); CanbRegs.CAN_IF1DATB.bit.Data_4 = *(TXMsgData + 4); CanbRegs.CAN_IF1DATB.bit.Data_5 = *(TXMsgData + 5); CanbRegs.CAN_IF1DATB.bit.Data_6 = *(TXMsgData + 6); CanbRegs.CAN_IF1DATB.bit.Data_7 = *(TXMsgData + 7); // // 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 = objID; CanbRegs.CAN_IF1CMD.all = CAN_IF1CMD_SHADOW.all; } // // getCANMessage - Check the message object for new data. // If new data, data written into array and return true. // If no new data, return false. // uint16_t getCANAMessage(uint32_t objID,uint32_t *ui32ArbReg,Uint8 *ucRXMsgData) { uint16_t status; // // Use Shadow variable for IF2CMD. IF2CMD should be written to in // single 32-bit write. // union CAN_IF2CMD_REG CAN_IF2CMD_SHADOW; // // Set the Message Data A, Data B, and control values to be read // on request for data from the message object. // CAN_IF2CMD_SHADOW.all = 0; CAN_IF2CMD_SHADOW.bit.Control = 1; CAN_IF2CMD_SHADOW.bit.DATA_A = 1; CAN_IF2CMD_SHADOW.bit.DATA_B = 1; CAN_IF2CMD_SHADOW.bit.Arb = 1; //Enable reading of arbitration bits // // Transfer the message object to the message object IF register. // CAN_IF2CMD_SHADOW.bit.MSG_NUM = objID; CanaRegs.CAN_IF2CMD.all = CAN_IF2CMD_SHADOW.all; // // Wait for busy bit to clear. // while(CanaRegs.CAN_IF2CMD.bit.Busy) { } *ui32ArbReg = CanaRegs.CAN_IF2ARB.all; // // See if there is new data available. // if(CanaRegs.CAN_IF2MCTL.bit.NewDat == 1) { // // Read out the data from the CAN registers. // Test1U32=CanaRegs.CAN_IF2DATA.all; Test2U32=CanaRegs.CAN_IF2DATB.all; *ucRXMsgData = Test1U32 & 0xFF; *(ucRXMsgData+1) = (Test1U32 & 0xFF00) >> 8; *(ucRXMsgData+2) = (Test1U32 & 0xFF0000) >> 16; *(ucRXMsgData+3) = (Test1U32 & 0xFF000000) >> 24; *(ucRXMsgData+4) = Test2U32 & 0xFF; *(ucRXMsgData+5) = (Test2U32 & 0xFF00) >> 8; *(ucRXMsgData+6) = (Test2U32 & 0xFF0000) >> 16; *(ucRXMsgData+7) = (Test2U32 & 0xFF000000) >> 24; /* *ucRXMsgData = CanaRegs.CAN_IF2DATA.bit.Data_0; *(ucRXMsgData+1) = CanaRegs.CAN_IF2DATA.bit.Data_1; *(ucRXMsgData+2) = CanaRegs.CAN_IF2DATA.bit.Data_2; *(ucRXMsgData+3) = CanaRegs.CAN_IF2DATA.bit.Data_3; *(ucRXMsgData+4) = CanaRegs.CAN_IF2DATB.bit.Data_4; *(ucRXMsgData+5) = CanaRegs.CAN_IF2DATB.bit.Data_5; *(ucRXMsgData+6) = CanaRegs.CAN_IF2DATB.bit.Data_6; *(ucRXMsgData+7) = CanaRegs.CAN_IF2DATB.bit.Data_7; */ // // Populate Shadow Variable // //CAN_IF2CMD_SHADOW.all = CanaRegs.CAN_IF2CMD.all; CAN_IF2CMD_SHADOW.all = 0; CAN_IF2CMD_SHADOW.bit.Control = 1; //CAN_IF2CMD_SHADOW.bit.DATA_A = 1; //CAN_IF2CMD_SHADOW.bit.DATA_B = 1; CAN_IF2CMD_SHADOW.bit.Arb = 1; //Enable reading of arbitration bits // // Clear New Data Flag // CAN_IF2CMD_SHADOW.bit.TxRqst = 1; // // Transfer the message object to the message object IF register. // CAN_IF2CMD_SHADOW.bit.MSG_NUM = objID; CanaRegs.CAN_IF2CMD.all = CAN_IF2CMD_SHADOW.all; status = true; CanaRegs.CAN_IF2MCTL.bit.NewDat = 0; } else { status = false; } return(status); } // // getCANMessage - Check the message object for new data. // If new data, data written into array and return true. // If no new data, return false. // uint16_t getCANBMessage(uint32_t objID,uint32_t *ui32ArbReg,Uint8 *ucRXMsgData) { uint16_t status; // // Use Shadow variable for IF2CMD. IF2CMD should be written to in // single 32-bit write. // union CAN_IF2CMD_REG CAN_IF2CMD_SHADOW; // // Set the Message Data A, Data B, and control values to be read // on request for data from the message object. // CAN_IF2CMD_SHADOW.all = 0; CAN_IF2CMD_SHADOW.bit.Control = 1; CAN_IF2CMD_SHADOW.bit.DATA_A = 1; CAN_IF2CMD_SHADOW.bit.DATA_B = 1; CAN_IF2CMD_SHADOW.bit.Arb = 1; // // Transfer the message object to the message object IF register. // CAN_IF2CMD_SHADOW.bit.MSG_NUM = objID; CanbRegs.CAN_IF2CMD.all = CAN_IF2CMD_SHADOW.all; // // Wait for busy bit to clear. // while(CanbRegs.CAN_IF2CMD.bit.Busy) { } *ui32ArbReg = CanbRegs.CAN_IF2ARB.all; // // See if there is new data available. // if(CanbRegs.CAN_IF2MCTL.bit.NewDat == 1) { // // Read out the data from the CAN registers. // Test3U32=CanbRegs.CAN_IF2DATA.all; Test4U32=CanbRegs.CAN_IF2DATB.all; *ucRXMsgData = Test3U32 & 0xFF; *(ucRXMsgData+1) = (Test3U32 & 0xFF00) >> 8; *(ucRXMsgData+2) = (Test3U32 & 0xFF0000) >> 16; *(ucRXMsgData+3) = (Test3U32 & 0xFF000000) >> 24; *(ucRXMsgData+4) = Test4U32 & 0xFF; *(ucRXMsgData+5) = (Test4U32 & 0xFF00) >> 8; *(ucRXMsgData+6) = (Test4U32 & 0xFF0000) >> 16; *(ucRXMsgData+7) = (Test4U32 & 0xFF000000) >> 24; /* *ucRXMsgData = CanbRegs.CAN_IF2DATA.bit.Data_0; *(ucRXMsgData+1) = CanbRegs.CAN_IF2DATA.bit.Data_1; *(ucRXMsgData+2) = CanbRegs.CAN_IF2DATA.bit.Data_2; *(ucRXMsgData+3) = CanbRegs.CAN_IF2DATA.bit.Data_3; *(ucRXMsgData+4) = CanbRegs.CAN_IF2DATB.bit.Data_4; *(ucRXMsgData+5) = CanbRegs.CAN_IF2DATB.bit.Data_5; *(ucRXMsgData+6) = CanbRegs.CAN_IF2DATB.bit.Data_6; *(ucRXMsgData+7) = CanbRegs.CAN_IF2DATB.bit.Data_7; */ // // Populate Shadow Variable // //CAN_IF2CMD_SHADOW.all = CanbRegs.CAN_IF2CMD.all; CAN_IF2CMD_SHADOW.all = 0; CAN_IF2CMD_SHADOW.bit.Control = 1; //CAN_IF2CMD_SHADOW.bit.DATA_A = 1; //CAN_IF2CMD_SHADOW.bit.DATA_B = 1; CAN_IF2CMD_SHADOW.bit.Arb = 1; // // Clear New Data Flag // CAN_IF2CMD_SHADOW.bit.TxRqst = 1; // // Transfer the message object to the message object IF register. // CAN_IF2CMD_SHADOW.bit.MSG_NUM = objID; CanbRegs.CAN_IF2CMD.all = CAN_IF2CMD_SHADOW.all; status = true; CanbRegs.CAN_IF2MCTL.bit.NewDat = 0; } else { status = false; } return(status); } // // End of file //
您好,
已经收到了您的案例,调查需要些时间,感谢您的耐心等待
#define CAN_MAX_BIT_DIVISOR (12) // The maximum CAN bit timing divisor
#define CAN_MIN_BIT_DIVISOR (5) // The minimum CAN bit timing divisor
#define CAN_MAX_PRE_DIVISOR (1024) // The maximum CAN pre-divisor
#define CAN_MIN_PRE_DIVISOR (1) // The minimum CAN pre-divisor
#define CAN_BTR_BRP_M (0x3F)
#define CAN_BTR_BRPE_M (0xF0000)
#define CAN_MSG_ID_SHIFT 18U
什么是位计时设置? 您使用自己的功能来配置CAN模块,所以我找不到配置CAN位正时的代码。
位计时由4个段组成:SYNC,PROP,SEG1和SEG2。 prop和seg1组合在CAN配置寄存器中。 采样点=1 - seg2 / bit计时 您需要调整seg1和seg2以获得85%的采样点。