当 CAN 总线上有帧时,CAN 上 fifo 的接收回调挂起不会触发

the receive Callaback pending of fifo on CAN does not fire when there is frames on CAN bus

我正在使用 C 语言在 STM32F1xx 上开发,直到现在我正在尝试使用 "CANopenNode-master" 实现 CANopen 堆栈,并且我正在使用 2 个中断。 第一个是用于处理 SYNC TPDO 和 RPDO 的定时器中断,第二个 CAN_Rx_fifo0_msgpendingCallback 并且在这个中断中我管理接收到的消息但是在完成所有配置之后需要这个中断(fifo0)不起作用 定时器周期为 1ms。 我使用 NVIC 来赋予优先级和次级优先级,并启用每个中断的 IRQ。 我把 CAN 接收 fifo0 设置为高优先级(第一)。 我按照应该的方式设置了我的 CAN(我认为) 但它不像正常工作的定时器中断那样工作。

验证回调不会在每次总线上有来自其他节点而不是我的节点的帧时起作用;: 1. 我刚刚在我的回调函数中使用了 printf,但它不起作用。 2. 我一直检查 Instance->RF0R 的值,它总是等于 0。

//HeaderCaninit是指向hcan的指针.

 CANmodule->CANbaseAddress = *(HeaderCaninit);
            CANmodule->CANbaseAddress.Instance = HeaderCaninit->Instance;



 switch (CANbitRate)
        {
        case 1000: CANmodule->CANbaseAddress.Init.Prescaler = 2;
        break;
        case 500: CANmodule->CANbaseAddress.Init.Prescaler = 4;// in our example we choose a prescaler 4 with other setting to get the 1Mb/s
        break;
        default:
        case 250: CANmodule->CANbaseAddress.Init.Prescaler = 8;
        break;
        case 125: CANmodule->CANbaseAddress.Init.Prescaler = 16;
        break;
        case 100: CANmodule->CANbaseAddress.Init.Prescaler = 20;
        break;
        case 50: CANmodule->CANbaseAddress.Init.Prescaler = 40;
        break;
        case 20: CANmodule->CANbaseAddress.Init.Prescaler = 100;
        break;
        case 10: CANmodule->CANbaseAddress.Init.Prescaler = 200;
        break;
        }


CANmodule->CANbaseAddress.Init.SyncJumpWidth =CAN_SJW_1TQ;     // changed by VJ, old value = CAN_SJW_1tq;//chngeD by aziz grib and we follow our CAN setting to get 1Mb/s
    CANmodule->CANbaseAddress.Init.TimeSeg1 = CAN_BS1_4TQ;    // changed by VJ, old value = CAN_BS1_3tq;// changed by GA to follow CAN transmit example = CAN_BS1_4TQ
    CANmodule->CANbaseAddress.Init.TimeSeg2 = CAN_BS2_1TQ;   ``
    CANmodule->CANbaseAddress.Init.AutoRetransmission= DISABLE;   // No Automatic retransmision//AG:if the first transmission fail the seconde is done automatically
    CANmodule->CANbaseAddress.Init.Mode = CAN_MODE_NORMAL;
    CANmodule->CANbaseAddress.Init.TimeTriggeredMode = DISABLE;
    CANmodule->CANbaseAddress.Init.ReceiveFifoLocked = DISABLE;
    CANmodule->CANbaseAddress.Init.TransmitFifoPriority = DISABLE;


memset(&CAN_FilterInitStruct, 0, sizeof (CAN_FilterInitStruct));
//CAN_FilterInitStruct.FilterNumber = 0; // for STM32F4
CAN_FilterInitStruct.FilterMaskIdHigh = 0x0000;
CAN_FilterInitStruct.FilterIdLow = 0x0000;
CAN_FilterInitStruct.FilterIdHigh = 0x0000;
CAN_FilterInitStruct.FilterMaskIdLow = 0x0000;
CAN_FilterInitStruct.FilterFIFOAssignment = CAN_RX_FIFO0; 
CAN_FilterInitStruct.FilterMode = CAN_FILTERMODE_IDMASK;
CAN_FilterInitStruct.FilterScale = CAN_FILTERSCALE_32BIT;
CAN_FilterInitStruct.FilterActivation = DISABLE;
CAN_FilterInitStruct.FilterBank = 0;
CAN_FilterInitStruct.SlaveStartFilterBank = 14;


if (HAL_CAN_Init(&CANmodule->CANbaseAddress) != HAL_OK)
    {
           // TRACE_DEBUG_WP("res=%d\n\r", result);
           return CO_ERROR_PARAMETERS;  /* CO- Return Init failed */
        }



 HAL_CAN_ConfigFilter(&CANmodule->CANbaseAddress, &CAN_FilterInitStruct);
 CAN_OperatingModeRequest(CANmodule->CANbaseAddress, CAN_Mode_Normal);
if (HAL_CAN_Start(&CANmodule->CANbaseAddress) != HAL_OK)
    {
        /* Start Error */
        Error_Handler();
        printf("--------------------------CANstart_error------------- 
    --------");
    }

// 这是 NVIC 设置

     static void MX_NVIC_Init(void)
      {
  /* TIM4_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(TIM4_IRQn, 0, 1);
  HAL_NVIC_EnableIRQ(TIM4_IRQn);
  /* CAN1_RX1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(CAN1_RX1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(CAN1_RX1_IRQn);
  /* CAN1_SCE_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(CAN1_SCE_IRQn, 1, 2);
  HAL_NVIC_EnableIRQ(CAN1_SCE_IRQn);
  /* EXTI9_5_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(EXTI9_5_IRQn, 15, 15);
  HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
}

//主要是我做了

 HAL_CAN_ActivateNotification(&CO->CANmodule[0]->CANbaseAddress,CAN_IT_TX_MAILBOX_EMPTY|CAN_IT_RX_FIFO0_MSG_PENDING);

//在回调函数中

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
    printf("TIMI");// it does not work


    /* Get RX message */
    CO_CANinterrupt_Rx(CO->CANmodule[0]);
}

预期结果: 我放了一个 printf 它必须被执行。 并且回调中的函数也应该被执行。

我通过在 CubeMx 上选择 USB0_CAN_Callback_interrupt 而不是 Rx0 中断解决了这个问题,然后一切都正常了。