我在TI官方例程CAN0回环调试通过,然后将管脚和初始化配置设置成CAN1后,软件调试不通。CAN无输出
Jacky Xu:
这个。。。就是配置有问题咯
你确定引脚的辅助功能都配置对了?
xyz549040622:
上你的初始化代码看看,肯定是有个地方没有改过来。
xiaolong wei1:
回复 xyz549040622:
CAN0官方例程运行通过如下:
voidCANIntHandler(void){ uint32_t ui32Status; ui32Status = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE); if(ui32Status == CAN_INT_INTID_STATUS) { ui32Status = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL); g_bErrFlag = 1; } else if(ui32Status == 1) { CANIntClear(CAN0_BASE, 1); g_ui32MsgCount++; g_bErrFlag = 0; } else {
}}
voidCANInit(uint32_t ui32Base){ uint32_t ui32Msg; ASSERT(_CANBaseValid(ui32Base)); HWREG(ui32Base + CAN_O_CTL) = CAN_CTL_INIT; while(HWREG(ui32Base + CAN_O_IF1CRQ) & CAN_IF1CRQ_BUSY) { } HWREG(ui32Base + CAN_O_IF1CMSK) = (CAN_IF1CMSK_WRNRD | CAN_IF1CMSK_ARB | CAN_IF1CMSK_CONTROL); HWREG(ui32Base + CAN_O_IF1ARB2) = 0; HWREG(ui32Base + CAN_O_IF1MCTL) = 0; for(ui32Msg = 1; ui32Msg <= 32; ui32Msg++) { while(HWREG(ui32Base + CAN_O_IF1CRQ) & CAN_IF1CRQ_BUSY) { } HWREG(ui32Base + CAN_O_IF1CRQ) = ui32Msg; } HWREG(ui32Base + CAN_O_IF1CMSK) = (CAN_IF1CMSK_NEWDAT | CAN_IF1CMSK_CLRINTPND);
for(ui32Msg = 1; ui32Msg <= 32; ui32Msg++) { while(HWREG(ui32Base + CAN_O_IF1CRQ) & CAN_IF1CRQ_BUSY) { } HWREG(ui32Base + CAN_O_IF1CRQ) = ui32Msg; }
HWREG(ui32Base + CAN_O_STS);}
voidCANMessageSet(uint32_t ui32Base, uint32_t ui32ObjID, tCANMsgObject *psMsgObject, tMsgObjType eMsgType){ uint16_t ui16CmdMaskReg; uint16_t ui16MaskReg0, ui16MaskReg1; uint16_t ui16ArbReg0, ui16ArbReg1; uint16_t ui16MsgCtrl; bool bTransferData; bool bUseExtendedID;
bTransferData = 0;
ASSERT(_CANBaseValid(ui32Base)); ASSERT((ui32ObjID <= 32) && (ui32ObjID != 0)); ASSERT((eMsgType == MSG_OBJ_TYPE_TX) || (eMsgType == MSG_OBJ_TYPE_TX_REMOTE) || (eMsgType == MSG_OBJ_TYPE_RX) || (eMsgType == MSG_OBJ_TYPE_RX_REMOTE) || (eMsgType == MSG_OBJ_TYPE_TX_REMOTE) || (eMsgType == MSG_OBJ_TYPE_RXTX_REMOTE));
while(HWREG(ui32Base + CAN_O_IF1CRQ) & CAN_IF1CRQ_BUSY) { }
// // See if we need to use an extended identifier or not. // if((psMsgObject->ui32MsgID > CAN_MAX_11BIT_MSG_ID) || (psMsgObject->ui32Flags & MSG_OBJ_EXTENDED_ID)) { bUseExtendedID = 1; } else { bUseExtendedID = 0; }
// // This is always a write to the Message object as this call is setting a // message object. This call always sets all size bits so it sets // both data bits. The call uses the CONTROL register to set control // bits so this bit needs to be set as well. // ui16CmdMaskReg = (CAN_IF1CMSK_WRNRD | CAN_IF1CMSK_DATAA | CAN_IF1CMSK_DATAB | CAN_IF1CMSK_CONTROL);
// // Initialize the values to a known state before filling them in based on // the type of message object that is being configured. // ui16ArbReg0 = 0; ui16ArbReg1 = 0; ui16MsgCtrl = 0; ui16MaskReg0 = 0; ui16MaskReg1 = 0;
switch(eMsgType) { // // Transmit message object. // case MSG_OBJ_TYPE_TX: { // // Set the TXRQST bit and the reset the rest of the register. // ui16MsgCtrl |= CAN_IF1MCTL_TXRQST; ui16ArbReg1 = CAN_IF1ARB2_DIR; bTransferData = 1; break; }
// // Transmit remote request message object // case MSG_OBJ_TYPE_TX_REMOTE: { // // Set the TXRQST bit and the reset the rest of the register. // ui16MsgCtrl |= CAN_IF1MCTL_TXRQST; ui16ArbReg1 = 0; break; }
// // Receive message object. // case MSG_OBJ_TYPE_RX: { // // This clears the DIR bit along with everything else. The TXRQST // bit was cleared by defaulting ui16MsgCtrl to 0. // ui16ArbReg1 = 0; break; }
// // Receive remote request message object. // case MSG_OBJ_TYPE_RX_REMOTE: { // // The DIR bit is set to one for remote receivers. The TXRQST bit // was cleared by defaulting ui16MsgCtrl to 0. // ui16ArbReg1 = CAN_IF1ARB2_DIR;
// // Set this object so that it only indicates that a remote frame // was received and allow for software to handle it by sending back // a data frame. // ui16MsgCtrl = CAN_IF1MCTL_UMASK;
// // Use the full Identifier by default. // ui16MaskReg0 = 0xffff; ui16MaskReg1 = 0x1fff;
// // Make sure to send the mask to the message object. // ui16CmdMaskReg |= CAN_IF1CMSK_MASK; break; }
// // Remote frame receive remote, with auto-transmit message object. // case MSG_OBJ_TYPE_RXTX_REMOTE: { // // Oddly the DIR bit is set to one for remote receivers. // ui16ArbReg1 = CAN_IF1ARB2_DIR;
// // Set this object to auto answer if a matching identifier is seen. // ui16MsgCtrl = CAN_IF1MCTL_RMTEN | CAN_IF1MCTL_UMASK;
// // The data to be returned needs to be filled in. // bTransferData = 1; break; }
// // This case never happens due to the ASSERT statement at the // beginning of this function. // default: { return; } }
// // Configure the Mask Registers. // if(psMsgObject->ui32Flags & MSG_OBJ_USE_ID_FILTER) { if(bUseExtendedID) { // // Set the 29 bits of Identifier mask that were requested. // ui16MaskReg0 = psMsgObject->ui32MsgIDMask & CAN_IF1MSK1_IDMSK_M; ui16MaskReg1 = ((psMsgObject->ui32MsgIDMask >> 16) & CAN_IF1MSK2_IDMSK_M); } else { // // Lower 16 bit are unused so set them to zero. // ui16MaskReg0 = 0;
// // Put the 11 bit Mask Identifier into the upper bits of the field // in the register. // ui16MaskReg1 = ((psMsgObject->ui32MsgIDMask << 2) & CAN_IF1MSK2_IDMSK_M); } }
// // If the caller wants to filter on the extended ID bit then set it. // if((psMsgObject->ui32Flags & MSG_OBJ_USE_EXT_FILTER) == MSG_OBJ_USE_EXT_FILTER) { ui16MaskReg1 |= CAN_IF1MSK2_MXTD; }
// // The caller wants to filter on the message direction field. // if((psMsgObject->ui32Flags & MSG_OBJ_USE_DIR_FILTER) == MSG_OBJ_USE_DIR_FILTER) { ui16MaskReg1 |= CAN_IF1MSK2_MDIR; }
if(psMsgObject->ui32Flags & (MSG_OBJ_USE_ID_FILTER | MSG_OBJ_USE_DIR_FILTER | MSG_OBJ_USE_EXT_FILTER)) { // // Set the UMASK bit to enable using the mask register. // ui16MsgCtrl |= CAN_IF1MCTL_UMASK;
// // Set the MASK bit so that this gets transferred to the Message // Object. // ui16CmdMaskReg |= CAN_IF1CMSK_MASK; }
// // Set the Arb bit so that this gets transferred to the Message object. // ui16CmdMaskReg |= CAN_IF1CMSK_ARB;
// // Configure the Arbitration registers. // if(bUseExtendedID) { // // Set the 29 bit version of the Identifier for this message object. // ui16ArbReg0 |= psMsgObject->ui32MsgID & CAN_IF1ARB1_ID_M; ui16ArbReg1 |= (psMsgObject->ui32MsgID >> 16) & CAN_IF1ARB2_ID_M;
// // Mark the message as valid and set the extended ID bit. // ui16ArbReg1 |= CAN_IF1ARB2_MSGVAL | CAN_IF1ARB2_XTD; } else { // // Set the 11 bit version of the Identifier for this message object. // The lower 18 bits are set to zero. // ui16ArbReg1 |= (psMsgObject->ui32MsgID << 2) & CAN_IF1ARB2_ID_M;
// // Mark the message as valid. // ui16ArbReg1 |= CAN_IF1ARB2_MSGVAL; }
// // 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. // ui16MsgCtrl |= (psMsgObject->ui32MsgLen & CAN_IF1MCTL_DLC_M);
// // Mark this as the last entry if this is not the last entry in a FIFO. // if((psMsgObject->ui32Flags & MSG_OBJ_FIFO) == 0) { ui16MsgCtrl |= CAN_IF1MCTL_EOB; }
// // Enable transmit interrupts if they should be enabled. // if(psMsgObject->ui32Flags & MSG_OBJ_TX_INT_ENABLE) { ui16MsgCtrl |= CAN_IF1MCTL_TXIE; }
// // Enable receive interrupts if they should be enabled. // if(psMsgObject->ui32Flags & MSG_OBJ_RX_INT_ENABLE) { ui16MsgCtrl |= CAN_IF1MCTL_RXIE; }
// // Write the data out to the CAN Data registers if needed. // if(bTransferData) { _CANDataRegWrite(psMsgObject->pui8MsgData, (uint32_t *)(ui32Base + CAN_O_IF1DA1), psMsgObject->ui32MsgLen); }
// // Write out the registers to program the message object. // HWREG(ui32Base + CAN_O_IF1CMSK) = ui16CmdMaskReg; HWREG(ui32Base + CAN_O_IF1MSK1) = ui16MaskReg0; HWREG(ui32Base + CAN_O_IF1MSK2) = ui16MaskReg1; HWREG(ui32Base + CAN_O_IF1ARB1) = ui16ArbReg0; HWREG(ui32Base + CAN_O_IF1ARB2) = ui16ArbReg1; HWREG(ui32Base + CAN_O_IF1MCTL) = ui16MsgCtrl;
// // Transfer the message object to the message object specified by // ui32ObjID. // HWREG(ui32Base + CAN_O_IF1CRQ) = ui32ObjID & CAN_IF1CRQ_MNUM_M;}intmain(void){ tCANMsgObject sCANMessage; uint32_t ui32MsgData; uint8_t *pui8MsgData; pui8MsgData = (uint8_t *)&ui32MsgData;
SysCtlClockSet(SYSCTL_SYSDIV_1 | SYSCTL_USE_OSC | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB); GPIOPinConfigure(GPIO_PB4_CAN0RX); GPIOPinConfigure(GPIO_PB5_CAN0TX); GPIOPinTypeCAN(GPIO_PORTB_BASE, GPIO_PIN_4 | GPIO_PIN_5); SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0); CANInit(CAN0_BASE); CANBitRateSet(CAN0_BASE, SysCtlClockGet(), 500000); CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS); IntEnable(INT_CAN0); CANEnable(CAN0_BASE);
ui32MsgData = 0; sCANMessage.ui32MsgID = 1; sCANMessage.ui32MsgIDMask = 0; sCANMessage.ui32Flags = MSG_OBJ_TX_INT_ENABLE; sCANMessage.ui32MsgLen = sizeof(pui8MsgData); sCANMessage.pui8MsgData = pui8MsgData;
while(1) {
CANMessageSet(CAN0_BASE, 1, &sCANMessage, MSG_OBJ_TYPE_TX);
// // Increment the value in the message data. // ui32MsgData++; }
}
然后我对上述例程中的CAN0_BASE改为CAN1_BASE,将CANIntClear();CANInit();CANMessageSet();这三个函数里面的CAN_IF1,CAN_O_IF1等等CAN口1的寄存器改为CAN_IF2,CAN_O_IF2,。
经过测试发现只要CANMessageSet(CAN1_BASE);这条语句在就不行,而且单独跑CAN0可以,CAN0和CAN1一起就都不行了,单独CAN1也不行。所以感觉是初始化配置中某个寄存器藏的比较深没发现,可能没改过来。
另外既然封装库函数是为了工程师不接触底层寄存器,那现在这种改法还不如直接看寄存器重新编写,所以觉得这库函数封装的有问题,库函数里面只定义了CAN0的寄存器,没有定义其他CAN口的寄存器?我觉得按正常逻辑不应该,可能是我对这个库函数还不理解,调用不对?
xyz549040622:
回复 xiaolong wei1:
你可以在can.c的文件中找找这三个函数的原型看看。任然还是坚信,肯定是你有个地方没有修改过来。你修改后的代码也发上来看看。
ming cui:
回复 xiaolong wei1:
你可以看下是不是在startup文件中,你的中断号没有配置好,可以看下,配置一下can1的终端号