我在TI官方例程CAN0回环调试通过,然后将管脚和初始化配置设置成CAN1后,软件调试不通。CAN无输出
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.
我在TI官方例程CAN0回环调试通过,然后将管脚和初始化配置设置成CAN1后,软件调试不通。CAN无输出
CAN0官方例程运行通过如下:
void
CANIntHandler(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
{
}
}
void
CANInit(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);
}
void
CANMessageSet(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;
}
int
main(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口的寄存器?我觉得按正常逻辑不应该,可能是我对这个库函数还不理解,调用不对?
你可以在can.c的文件中找找这三个函数的原型看看。任然还是坚信,肯定是你有个地方没有修改过来。你修改后的代码也发上来看看。