最近几天都在调试自己做的小型开发板,但是在CAN的这一块就是调试不过去,在初始化的时候就过不去了,程序如下: void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; /* Configure CAN1 pin: RX */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CAN_RX; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIO_CAN, &GPIO_InitStructure); /* Configure CAN1 pin: TX */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CAN_TX; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIO_CAN, &GPIO_InitStructure); GPIO_PinRemapConfig(GPIO_Remap_CAN , ENABLE); /* Configure CAN2 pin: RX */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CAN_RX_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIO_CAN_2, &GPIO_InitStructure); /* Configure CAN2 pin: TX */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_CAN_TX_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIO_CAN_2, &GPIO_InitStructure); GPIO_PinRemapConfig(GPIO_Remap_CAN_2 , ENABLE); } void CAN_Config(CAN_TypeDef* CANx, uint8_t CAN_FilterNumber) { /* CAN register init */ CAN_DeInit(CANx); CAN_StructInit(&CAN_InitStructure); /* CAN cell init */ CAN_InitStructure.CAN_TTCM = DISABLE; CAN_InitStructure.CAN_ABOM = DISABLE; CAN_InitStructure.CAN_AWUM = DISABLE; CAN_InitStructure.CAN_NART = DISABLE; CAN_InitStructure.CAN_RFLM = DISABLE; CAN_InitStructure.CAN_TXFP = DISABLE; CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; CAN_InitStructure.CAN_BS1 = CAN_BS1_3tq; CAN_InitStructure.CAN_BS2 = CAN_BS2_5tq; CAN_InitStructure.CAN_Prescaler = 4;//2 CAN_Init(CANx, &CAN_InitStructure); /* CAN filter init */ CAN_FilterInitStructure.CAN_FilterNumber=CAN_FilterNumber; CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask; CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit; CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000; CAN_FilterInitStructure.CAN_FilterIdLow=0x0000; CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000; CAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000; CAN_FilterInitStructure.CAN_FilterFIFOAssignment=(CANx == CAN1? 0:1); CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; CAN_FilterInit(CANx, &CAN_FilterInitStructure); /* transmit */ TxMessage.StdId = 0x321; TxMessage.ExtId = 0x01; TxMessage.RTR = CAN_RTR_DATA; TxMessage.IDE = CAN_ID_STD; TxMessage.DLC = 1; } CANx->MCR &= ~MCR_SLEEP; /* Request initialisation */ CANx->MCR |= MCR_INRQ ; /* Wait the acknowledge */ while (((CANx->MSR & MSR_INAK) != MSR_INAK) && (wait_ack != INAK_TimeOut)) { wait_ack++; } /* ...and check acknowledged */ if ((CANx->MSR & MSR_INAK) != MSR_INAK) { InitStatus = CANINITFAILED; } else { /* Set the time triggered communication mode */ if (CAN_InitStruct->CAN_TTCM == ENABLE) { CANx->MCR |= MCR_TTCM; } else { CANx->MCR &= ~MCR_TTCM; } /* Set the automatic bus-off management */ if (CAN_InitStruct->CAN_ABOM == ENABLE) { CANx->MCR |= MCR_ABOM; } else { CANx->MCR &= ~MCR_ABOM; } /* Set the automatic wake-up mode */ if (CAN_InitStruct->CAN_AWUM == ENABLE) { CANx->MCR |= MCR_AWUM; } else { CANx->MCR &= ~MCR_AWUM; } /* Set the no automatic retransmission */ if (CAN_InitStruct->CAN_NART == ENABLE) { CANx->MCR |= MCR_NART; } else { CANx->MCR &= ~MCR_NART; } /* Set the receive FIFO locked mode */ if (CAN_InitStruct->CAN_RFLM == ENABLE) { CANx->MCR |= MCR_RFLM; } else { CANx->MCR &= ~MCR_RFLM; } /* Set the transmit FIFO priority */ if (CAN_InitStruct->CAN_TXFP == ENABLE) { CANx->MCR |= MCR_TXFP; } else { CANx->MCR &= ~MCR_TXFP; } /* Set the bit timing register */ CANx->BTR = (uint32_t)((uint32_t)CAN_InitStruct->CAN_Mode << 30) | ((uint32_t)CAN_InitStruct->CAN_SJW << 24) | ((uint32_t)CAN_InitStruct->CAN_BS1 << 16) | ((uint32_t)CAN_InitStruct->CAN_BS2 << 20) | ((uint32_t)CAN_InitStruct->CAN_Prescaler - 1); /* Request leave initialisation */ CANx->MCR &= ~MCR_INRQ; /* Wait the acknowledge */ wait_ack = 0x00; while (((CANx->MSR & MSR_INAK) == MSR_INAK) && (wait_ack != INAK_TimeOut)) { wait_ack++; } /* ...and check acknowledged */ if ((CANx->MSR & MSR_INAK) == MSR_INAK) { InitStatus = CANINITFAILED; } else { InitStatus = CANINITOK ; } } /* At this step, return the status of initialization */ return InitStatus; 就是死在了 while (((CANx->MSR & MSR_INAK) == MSR_INAK) && (wait_ack != INAK_TimeOut)) { wait_ack++; }手册说是到这个地方是硬件自动对CAN_MSR_INAK位自动清零,但是就是一直没出现,希望各位大神赐教啊!!!!! |
总算是解决了,在CAN这一块卡了半个月,从头地仔细看了一遍STM32的CAN,检测硬件电路的设计,缺少帮忙真的很无助,总算黄天不负有心人,弄出来了,在此总结一下,感谢帮助过的各位。
CAN1在STM上有两个可以重映射的IO口PD0,PD1和PB8,PB9,因此在对他们进行重映射时有十分注意,必须要在一下每个地方修改:
CAN1的重映射:
#define RCC_APB2Periph_GPIO_CAN RCC_APB2Periph_GPIOB //端口修改
#define GPIO_Remap_CAN GPIO_Remap1_CAN1 //若是映射到PD口则是GPIO_Remap2_CAN1
#define GPIO_CAN GPIOB //端口修改
#define GPIO_Pin_CAN_RX GPIO_Pin_8 //Rx修改
#define GPIO_Pin_CAN_TX GPIO_Pin_9 //Tx修改
我就是在第二个地方失误了,重映射的时候没改,蛋疼了半个月,希望后来者能够避免此错误。