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.

MSPM0G3519: MSPM0G3519,CAN仲裁协议错误如何恢复

Part Number: MSPM0G3519
Other Parts Discussed in Thread: SYSCONFIG

MCAN_IR的pea位被置1,产生的仲裁协议错误该如何修复

  • 确保CAN总线上的所有节点在仲裁和数据阶段都以完全相同的比特率运行。即使是微小的差异也会导致错误。

  • 在初始化过程中,如果上位机发送数据到MCU,会导致pea被置1,mcu后续也不能上发数据,此种情况产生的仲裁协议错误,有没有办法通过软件解决。正常情况下CAN收发正常

  • 我认为重置和重新初始化MCAN模块应该可以清除所有剩余的错误。

  • void MCAN_BUS_OFF_recovery(void)
    {
        // 将基地址转换为 MCAN_Regs 结构体指针
        volatile MCAN_Regs * const mcan_regs = (MCAN_Regs *)MCAN_BASE_ADDRESS;
        // 读取 MCAN_PSR 数据
        uint32_t psr_value = mcan_regs->MCANSS.MCAN.MCAN_PSR;
        // 提取 BO 位的值
        uint8_t bo_bit = (psr_value & MCAN_PSR_BO_MASK) >> MCAN_PSR_BO_OFS;
        // 读取 MCAN_CCCR 数据
        uint32_t cccr_value = mcan_regs->MCANSS.MCAN.MCAN_CCCR;
        // 提取 INIT 位的值
        uint8_t init_bit = (cccr_value & MCAN_CCCR_INIT_MASK) >> MCAN_CCCR_INIT_OFS;
    
    //    if (bo_bit == 1)
    //    {
    //        // 清除 INIT 位
    //        cccr_value &= ~MCAN_CCCR_INIT_MASK;
    //
    //        // 将修改后的值写回 MCAN_CCCR 寄存器
    //        mcan_regs->MCANSS.MCAN.MCAN_CCCR = cccr_value;
    //    }
    
        uint32_t ir_value = mcan_regs->MCANSS.MCAN.MCAN_IR;
        uint8_t pea_bit = (ir_value & MCAN_IR_PEA_MASK) >> MCAN_IR_PEA_OFS;
        if (pea_bit == 1 || bo_bit == 1){
            //cccr_value &= ~MCAN_CCCR_INIT_MASK;
            //mcan_regs->MCANSS.MCAN.MCAN_CCCR = cccr_value;
            //DL_GPIO_setPins(GPIO_CAN1_STB_GRP_PORT, GPIO_CAN1_STB_GRP_PIN_CAN1_STB_PIN);
            DL_MCAN_disablePower(MCAN0_INST);
            delay_ms(1000);
            DL_MCAN_enablePower(MCAN0_INST);
            SYSCFG_DL_MCAN0_init();
            hal_can_init();
            //delay_ms(1000);
            //cccr_value &= ~MCAN_CCCR_INIT_MASK;
            //mcan_regs->MCANSS.MCAN.MCAN_CCCR = cccr_value;
            //DL_GPIO_clearPins(GPIO_CAN1_STB_GRP_PORT, GPIO_CAN1_STB_GRP_PIN_CAN1_STB_PIN);
        }
    
    
        //uint32_t ir_value = mcan_regs->MCANSS.MCAN.MCAN_IR;
        //printf("0x%x \r\n",psr_value);
        //printf("0x%x \r\n",cccr_value);
        //printf("0x%x \r\n",ir_value);
    }
    void hal_can_init(void)
    {
        xCAN_recv_Queue = xQueueCreate(CAN_QUEUE_LEN, CAN_QUEUE_SIZE);
         if (NULL == xCAN_recv_Queue){
                printf("CAN Queue err !\r\n");
         }
        /* Initialize global variables */
        gServiceInt           = 0;  // Indicates whether the service interrupt is active
        gInterruptLine1Status = 0;      // Status of interrupt line 1
    
        /* Clear GPIO pins for CAN1 standby */
        // DL_GPIO_clearPins(GPIO_CAN1_STB_GRP_PORT, GPIO_CAN1_STB_GRP_PIN_CAN1_STB_PIN);
    
        /* Enable MCAN0 interrupt in the NVIC (Nested Vectored Interrupt Controller) */
        NVIC_EnableIRQ(MCAN0_INST_INT_IRQN);
    
        /* Wait until MCAN0 enters normal operation mode */
        while (DL_MCAN_OPERATION_MODE_NORMAL != DL_MCAN_getOpMode(MCAN0_INST));
    }

    这是我写的一个重新初始化MCAN模块的代码,在检测到pea或者bo被置位,会按照以下代码重置恢复,
    DL_MCAN_disablePower(MCAN0_INST);
    delay_ms(100);
    DL_MCAN_enablePower(MCAN0_INST);
    SYSCFG_DL_MCAN0_init();
    hal_can_init();
    但是,代码运行完之后CAN通讯并没有恢复,以下为寄存器的值,

    MCAN_CCCR = 0x00000001
    MCAN_PSR = 0x000007E7
    MCAN_IR = 0x0A000000

    总线依旧存在问题



    添加cccr_value &= ~MCAN_CCCR_INIT_MASK;
    mcan_regs->MCANSS.MCAN.MCAN_CCCR = cccr_value;去重置

    CAN通讯并没有恢复,也会一直进入中断重新初始化MCAN模块

    MCAN_CCCR = 0x00000000
    MCAN_PSR = 0x0000070F
    MCAN_IR = 0x00000000

    CCCR.INIT重置后,寄存器虽然恢复正常,但是通讯依旧有问题,恢复不了CAN通讯
    您觉得这代码哪里有问题,或者代码缺少了什么部分

  • 有新回复吗

  • 有结果会在帖子里面回复您。

  • bus仍然有问题。它应该与硬件问题有关。您仍然需要确保CAN总线上的所有节点在仲裁和数据阶段都以完全相同的比特率运行。即使是微小的差异也会导致错误。在项目sysconfig中,您可以设置MSPM0节点的比特率。您需要与其他节点保持相同的设置。

  • 我这边没有使能CANFD,仲裁比特率和数据比特率都是一样的值吧,500k, 然后上位机设置的值也是500k,正常通讯不会出现问题。只有上述的出现的仲裁协议错误会导致can恢复不了,这种仲裁协议错误会导致两个节点设置的比特率值出现问题?节点设置参数并没有修改,原参数能够维持出现问题前的正常通讯。

  • 问题出现后,可以通过重置MCU来解决这个问题吗?如果设置MCU可以解决这个问题,那么您可以尝试添加一个软件MCU重置来解决这个问题。