我采用MXCHIP的MCBSTM32板子2块,用DB9直通线连接2块板子上的CAN接口,用万用表测量2,7脚连通。我写了一个发送测试程序和一个接收测试程序如下,程序在CAN_Mode_LoopBack能自发自收,但是改成CAN_Mode_Normal收发不正常。各位大侠看看问题在哪里? 发送程序: /* Includes ------------------------------------------------------------------*/ #include "stm32f10x_lib.h"
/* Local includes ------------------------------------------------------------*/ /* Private typedef -----------------------------------------------------------*/ typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;
/* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ vu32 ret; /* for return of the interrupt handling */ volatile TestStatus TestRx; ErrorStatus HSEStartUpStatus;
/* Private functions ---------------------------------------------------------*/ void RCC_Configuration(void); void GPIO_Configuration(void); void NVIC_Configuration(void); TestStatus CAN_Polling(void); TestStatus CAN_Interrupt(void);
/******************************************************************************* * Function Name : main * Description : Main program * Input : None * Output : None * Return : None *******************************************************************************/ int main(void) { #ifdef DEBUG debug(); #endif
RCC_Configuration(); // System Clocks Configuration NVIC_Configuration(); // NVIC Configuration GPIO_Configuration(); // GPIO ports pins Configuration
TestRx = CAN_Polling(); // CAN transmit at 100Kb/s and receive by polling in loopback mode
if (TestRx == FAILED) { GPIO_SetBits(GPIOB, GPIO_Pin_10); // Turn on led connected to PC.08 pin (LD3) } else { GPIO_SetBits(GPIOB, GPIO_Pin_11); // Turn on led connected to PC.06 pin (LD1) }
while (1) { } }
/******************************************************************************* * Function Name : RCC_Configuration * Description : Configures the different system clocks. * Input : None * Output : None * Return : None *******************************************************************************/ void RCC_Configuration(void) { RCC_DeInit(); /* RCC system reset(for debug purpose) */ RCC_HSEConfig(RCC_HSE_ON); /* Enable HSE */ HSEStartUpStatus = RCC_WaitForHSEStartUp(); /* Wait till HSE is ready */ if(HSEStartUpStatus == SUCCESS) { FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); /* Enable Prefetch Buffer */ RCC_HCLKConfig(RCC_SYSCLK_Div1); /* HCLK = SYSCLK */ RCC_PCLK2Config(RCC_HCLK_Div1); /* PCLK2 = HCLK */ RCC_PCLK1Config(RCC_HCLK_Div2); /* PCLK1 = HCLK/2 */ RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE); /* Select HSE as system clock source */ while(RCC_GetSYSCLKSource() != 0x04) { // Wait till HSE is used as system clock source } } RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); /* GPIOA and GPIOC clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE); /* CAN Periph clock enable */ }
/******************************************************************************* * Function Name : GPIO_Configuration * Description : Configures the different GPIO ports. * Input : None * Output : None * Return : None *******************************************************************************/ void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); /* Configure PC.06, PC.07, PC.08 and PC.09 as Output push-pull */
/* Configure CAN pin: RX */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOB, &GPIO_InitStructure); /* Configure CAN pin: TX */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOB, &GPIO_InitStructure);
/* Enable the USART2 Pins Software Remapping */ GPIO_PinRemapConfig(GPIO_Remap1_CAN, ENABLE); }
/******************************************************************************* * Function Name : NVIC_Configuration * Description : Configures the NVIC and Vector Table base address. * Input : None * Output : None * Return : None *******************************************************************************/ void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure;
#ifdef VECT_TAB_RAM NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); /* Set the Vector Table base location at 0x20000000 */ #else /* VECT_TAB_FLASH */ NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); /* Set the Vector Table base location at 0x08000000 */ #endif
/* enabling interrupt */ NVIC_InitStructure.NVIC_IRQChannel=USB_LP_CAN_RX0_IRQChannel; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }
/******************************************************************************* * Function Name : CAN_Polling * Description : Configures the CAN and transmit and receive by polling * Input : None * Output : None * Return : PASSED if the reception is well done, FAILED in other case *******************************************************************************/ TestStatus CAN_Polling(void) { u8 Error;
CAN_InitTypeDef CAN_InitStructure; CAN_FilterInitTypeDef CAN_FilterInitStructure; CanTxMsg TxMessage; u32 i = 0; u8 TransmitMailbox;
/* CAN register init */ CAN_DeInit(); 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_Mode_Normal; // CAN_Mode_LoopBack CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; CAN_InitStructure.CAN_BS1 = CAN_BS1_8tq; CAN_InitStructure.CAN_BS2 = CAN_BS2_7tq; CAN_InitStructure.CAN_Prescaler = 5; Error = CAN_Init(&CAN_InitStructure); if (Error == 0) return FAILED;
/* CAN filter init */ CAN_FilterInitStructure.CAN_FilterNumber = 0; 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 = CAN_FIFO0; //0; CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; CAN_FilterInit(&CAN_FilterInitStructure);
/* transmit */ TxMessage.StdId = 0x18; TxMessage.RTR = CAN_RTR_DATA; TxMessage.IDE = CAN_ID_STD; TxMessage.DLC = 8; TxMessage.Data[0] = 0x40; TxMessage.Data[1] = 0x40; TxMessage.Data[2] = 0x45; TxMessage.Data[3] = 0x51; TxMessage.Data[4] = 0x52; TxMessage.Data[5] = 0x65; TxMessage.Data[6] = 0x61; TxMessage.Data[7] = 0x64; // @@EQRead
TransmitMailbox = CAN_Transmit(&TxMessage);
i = 0; while((CAN_TransmitStatus(TransmitMailbox) != CANTXOK) && (i != 0xFF)) { i++; }
if (i < 80) return PASSED; // Test Passed else return FAILED; }
接收程序: /* Includes ------------------------------------------------------------------*/ #include "stm32f10x_lib.h"
/* Local includes ------------------------------------------------------------*/ /* Private typedef -----------------------------------------------------------*/ typedef enum {FAILED = 0, PASSED = !FAILED} TestStatus;
/* Private define ------------------------------------------------------------*/ /* Private macro -------------------------------------------------------------*/ /* Private variables ---------------------------------------------------------*/ vu32 ret; /* for return of the interrupt handling */ volatile TestStatus TestRx; ErrorStatus HSEStartUpStatus;
/* Private functions ---------------------------------------------------------*/ void RCC_Configuration(void); void GPIO_Configuration(void); void NVIC_Configuration(void); TestStatus CAN_Polling(void); TestStatus CAN_Interrupt(void);
/******************************************************************************* * Function Name : main * Description : Main program * Input : None * Output : None * Return : None *******************************************************************************/
/******************************************************************************* * Function Name : RCC_Configuration * Description : Configures the different system clocks. * Input : None * Output : None * Return : None *******************************************************************************/ void RCC_Configuration(void) { RCC_DeInit(); /* RCC system reset(for debug purpose) */ RCC_HSEConfig(RCC_HSE_ON); /* Enable HSE */ HSEStartUpStatus = RCC_WaitForHSEStartUp(); /* Wait till HSE is ready */ if(HSEStartUpStatus == SUCCESS) { FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); /* Enable Prefetch Buffer */ RCC_HCLKConfig(RCC_SYSCLK_Div1); /* HCLK = SYSCLK */ RCC_PCLK2Config(RCC_HCLK_Div1); /* PCLK2 = HCLK */ RCC_PCLK1Config(RCC_HCLK_Div2); /* PCLK1 = HCLK/2 */ RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE); /* Select HSE as system clock source */ while(RCC_GetSYSCLKSource() != 0x04) { // Wait till HSE is used as system clock source } } RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); /* GPIOA and GPIOC clock enable */ RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN, ENABLE); /* CAN Periph clock enable */ }
/******************************************************************************* * Function Name : GPIO_Configuration * Description : Configures the different GPIO ports. * Input : None * Output : None * Return : None *******************************************************************************/ void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); /* Configure PC.06, PC.07, PC.08 and PC.09 as Output push-pull */
/* Enable the USART2 Pins Software Remapping */ GPIO_PinRemapConfig(GPIO_Remap1_CAN, ENABLE);
/* Configure CAN pin: RX */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOB, &GPIO_InitStructure); /* Configure CAN pin: TX */ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOB, &GPIO_InitStructure); }
/******************************************************************************* * Function Name : NVIC_Configuration * Description : Configures the NVIC and Vector Table base address. * Input : None * Output : None * Return : None *******************************************************************************/ void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure;
#ifdef VECT_TAB_RAM NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); /* Set the Vector Table base location at 0x20000000 */ #else /* VECT_TAB_FLASH */ NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); /* Set the Vector Table base location at 0x08000000 */ #endif
/* enabling interrupt */ NVIC_InitStructure.NVIC_IRQChannel=USB_LP_CAN_RX0_IRQChannel; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); }
/******************************************************************************* * Function Name : CAN_Configuration * Description : Configures the CAN * Input : None * Output : None * Return : PASSED if the configration is well done, FAILED in other case *******************************************************************************/ TestStatus CAN_Configuration(void) { u8 Error; CAN_InitTypeDef CAN_InitStructure; CAN_FilterInitTypeDef CAN_FilterInitStructure;
/* CanTxMsg TxMessage; u32 i = 0; u8 TransmitMailbox; */
CAN_DeInit(); // CAN register init CAN_StructInit(&CAN_InitStructure);
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_Mode_LoopBack; CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; CAN_InitStructure.CAN_BS1 = CAN_BS1_8tq; CAN_InitStructure.CAN_BS2 = CAN_BS2_7tq; CAN_InitStructure.CAN_Prescaler = 5; Error = CAN_Init(&CAN_InitStructure); // CAN cell init
if (Error == 0) return FAILED;
CAN_FilterInitStructure.CAN_FilterNumber = 0; CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0300; // StdId << 20 | ExID << 2 | IDE << 1 | RTR CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000; // StdId << 20 | ExID << 2 | IDE << 1 | RTR CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000; CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000; CAN_FilterInitStructure.CAN_FilterFIFOAssignment = 0; CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; CAN_FilterInit(&CAN_FilterInitStructure); // CAN filter init
/* transmit TxMessage.StdId = 0x18; TxMessage.RTR = CAN_RTR_DATA; TxMessage.IDE = CAN_ID_STD; TxMessage.DLC = 8; TxMessage.Data[0] = 0x40; TxMessage.Data[1] = 0x40; TxMessage.Data[2] = 0x45; TxMessage.Data[3] = 0x51; TxMessage.Data[4] = 0x52; TxMessage.Data[5] = 0x65; TxMessage.Data[6] = 0x61; TxMessage.Data[7] = 0x64; // @@EQRead
TransmitMailbox = CAN_Transmit(&TxMessage); */
return PASSED; }
/******************************************************************************* * Function Name : main * Description : Main program * Input : None * Output : None * Return : None *******************************************************************************/ int main(void) { CanRxMsg RxMessage; u32 i = 0;
#ifdef DEBUG debug(); #endif
RCC_Configuration(); // System Clocks Configuration NVIC_Configuration(); // NVIC Configuration GPIO_Configuration(); // GPIO ports pins Configuration
do { TestRx = CAN_Configuration(); // CAN transmit at 100Kb/s and receive by polling in loopback mode } while (TestRx == 0);
/* receive */ RxMessage.StdId = 0x00; RxMessage.IDE = CAN_ID_STD; RxMessage.DLC = 0; for (i = 0; i < 8; i++) { RxMessage.Data = 0x00; }
while (1) { if (CAN_MessagePending(CAN_FIFO0)) { CAN_Receive(CAN_FIFO0, &RxMessage); TestRx = PASSED; if (RxMessage.StdId!=0x18) TestRx = FAILED;
/* if (RxMessage.IDE!=CAN_ID_STD) TestRx = FAILED;
if (RxMessage.DLC!=2) TestRx = FAILED;
if ((RxMessage.Data[0] << 8 | RxMessage.Data[1]) != 0xCAFE) TestRx = FAILED; */
if (TestRx == FAILED) { GPIO_SetBits(GPIOB, GPIO_Pin_12); // Turn on led connected to PC.08 pin (LD3) } else { GPIO_SetBits(GPIOB, GPIO_Pin_13); // Turn on led connected to PC.06 pin (LD1) } } } }
|