工具与软件:
您好!
这是一个奇怪的行为,我们观察到,并希望得到一些帮助,以了解正在发生什么,为什么它正在发生。
我们正在为我们的一款产品设置 CAN 外设。 我们按如下方式设置 CAN 和 ISR:
void setup_can(void)
{
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_CANA);
// Initialize the CAN controller
CAN_initModule(CANA_BASE);
//
// setup Auto Bus On and delay time (in clock cycles - default is 0h)
//
CAN_setAutoBusOnTime(CANA_BASE, 0UL);
CAN_enableAutoBusOn(CANA_BASE);
// Set up the CAN bus bit rate depending on CAN_SPEED_UC digital input; 0 = 250kBits/s / 1 = 500kBits/s
if (0u == GpioDataRegs.GPADAT.bit.GPIO11)
{
CAN_setBitRate(CANA_BASE, DEVICE_SYSCLK_FREQ, 250000, 16);
}
else
{
CAN_setBitRate(CANA_BASE, DEVICE_SYSCLK_FREQ, 500000, 25);
}
// Enable interrupts on the CAN peripheral.
CAN_enableInterrupt(CANA_BASE, CAN_INT_IE0 | CAN_INT_ERROR);
CAN_enableRetry(CANA_BASE);
// Start CAN module operations
CAN_startModule(CANA_BASE);
}
__interrupt void can_isr(void)
{
#define CAN_ERROR_COUNT 25
uint32_t status_ui32, status2_ui32;
uint16_t can_msg_frame_type[1];
//Allow ADC1/SCIB_TX/Timer0/Timer1/SCIB_Rx to pre-empt ISR
IER |= (M_INT1|M_INT9|M_INT13);
IER &= (M_INT1|M_INT9|M_INT13);
// Enable PIE interrupt group 1 - Interrupt 1 (ADCA1)
// Enable PIE interrupt group 1 - Interrupt 3 (ADCC1)
// Enable PIE interrupt group 1 - Interrupt 7 (TIMER0)
// Enable PIE interrupt group 9 - Interrupt 4 (SCIB_TX)
// Enable PIE interrupt group 9 - Interrupt 3 (SCIB_RX)
// Enable PIE interrupt group 9 - Interrupt 4 (SCIB_TX)
PieCtrlRegs.PIEIER1.bit.INTx1 = 1;
PieCtrlRegs.PIEIER1.bit.INTx3 = 1;
PieCtrlRegs.PIEIER1.bit.INTx7 = 1;
PieCtrlRegs.PIEIER9.bit.INTx3 = 1;
PieCtrlRegs.PIEIER9.bit.INTx4 = 1;
// Clear ACK to allow group 1 INT
// Clear ACK to allow group 9 INT
PieCtrlRegs.PIEACK.bit.ACK1 = 1;
PieCtrlRegs.PIEACK.bit.ACK9 = 1;
// Wait one cycle as per errata
asm(" NOP");
EINT;
// Read the CAN interrupt status to find the cause of the interrupt
status_ui32 = CAN_getInterruptCause(can_base_ui16);
// If the cause is a controller status interrupt, then get the status
if (status_ui32 < RX_MSG_OBJ_ID_END)
{
can_msg_count_ui32++;
// TX interrupt occurred on message object and the message TX is complete
if(status_ui32 <= TX_MSG_OBJ_ID_END)
{
//Clear the message object interrupt
CAN_clearInterruptStatus(can_base_ui16, status_ui32);
}
// RX interrupt occurred on message object and the message RX is complete
else
{
// Get the received message
CAN_readMessageWithID(can_base_ui16, status_ui32, can_msg_frame_type, (uint32_t *)can_rx_msg_identifer29_ui32, can_rx_msg_data_buffer_ui16);
// CAN bus message receive data parser
can_rx_msg_parser(status_ui32);
//Clear the message object interrupt
CAN_clearInterruptStatus(can_base_ui16, status_ui32);
}
}
else
{
// Spurious interrupt handling can go here.
}
// Clear the global interrupt flag for the CAN interrupt line
CAN_clearGlobalInterruptStatus(can_base_ui16, CAN_GLOBAL_INT_CANINT0);
// Acknowledge the PIE interrupt
PieCtrlRegs.PIEACK.bit.ACK9 = 1;
DINT;
}
我们观察到的是在客户系统启动期间、CAN 总线上除节点之外的所有节点都存在初始噪声、导致所有 TX 消息都不存在 ACK。 期望是节点进入被动错误状态、直到系统节点否定确认消息、但我们注意到的是、微控制器会由于看门狗复位而复位、我们认为这是导致在我们尝试按照 TX 调度程序发送更多消息时尝试重新发送消息的原因。 这是预期结果吗?
此外、这种行为还会导致互补 PWM 信号发生跨导、从而导致单元故障。
我在这里捕获了一些图:

绿色信号=应用开始时设置 Testpin
红色和蓝色信号=互补的 PWM 信号
您可以清楚地看到 PWM 的跨导和测试引脚的未知切换就在看门狗复位之前。
我们的问题是、为什么 PWM 和测试引脚会因 CAN 挂起而受到影响?
我们能够使用 can_getStatus (can_base_ui16)在 ISR 中读取错误和状态寄存器来解决复位问题;这仅供您参考、但我们仍想知道为何观察到这种奇怪的行为、以及它是否会与其他类型的错误有关。
此致、
Harsha.

