Other Parts Discussed in Thread: SYSCONFIG
MCAN_IR的pea位被置1,产生的仲裁协议错误该如何修复
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.
确保CAN总线上的所有节点在仲裁和数据阶段都以完全相同的比特率运行。即使是微小的差异也会导致错误。
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节点的比特率。您需要与其他节点保持相同的设置。