AnsweredAssumed Answered

CAN cannot enter RX interrupt when ADC enabled

Question asked by lu.tongjun on Nov 27, 2013
Hi eveveryone,
I met a very strange problem in STM32F103VC. I used PB8 and PB9 for CAN, PA6 and PA7 for 2 channel ADC. The CAN communication use interrrupt mode, ADC use query mode. If I only use CAN, it works well, any message in CAN bus will generate RX interrupt; and if only ADC, it works well, I can get the voltage. But if I make them work togother, the ADC works well, the CAN cannot goto RX interrupt, but if I send message to the CAN bus, the CAN can goto RX interrupt once.

This is my code.


//////////////////////////////////////////////
void NVIC_Configuration(void)
{
     NVIC_InitTypeDef NVIC_InitStructure;     //???????
     
     #ifdef  VECT_TAB_RAM
     /* Set the Vector Table base location at 0x20000000 */
     NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0);
     #else  /* VECT_TAB_FLASH  */
     /* Set the Vector Table base location at 0x08000000 */
     NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0);
     #endif
     
     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//
     
     //enable USART interrupt
     NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
     NVIC_Init(&NVIC_InitStructure);     //
     
     /* Enable CAN1 RX0 interrupt IRQ channel */
     NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
     NVIC_Init(&NVIC_InitStructure);
     
     //enable TIM2 interrupt
     NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
     NVIC_Init(&NVIC_InitStructure);
     /*
     //enable TIM3 interrupt
     NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 4;
     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
     NVIC_Init(&NVIC_InitStructure);
     */
}

/********* CAN Configuration*************************/
void CAN_GPIO_Configuration(void)
{
     GPIO_InitTypeDef GPIO_InitStructure;
     
     /* CAN Periph clock enable */
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO ,ENABLE);
     RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE);
     
     GPIO_PinRemapConfig(GPIO_Remap1_CAN1,ENABLE); 
     /* Configure CAN pin: RX */
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//GPIO_Mode_IN_FLOATING;
     GPIO_Init(GPIOB, &GPIO_InitStructure);   
     /* Configure CAN pin: TX */
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
     GPIO_Init(GPIOB, &GPIO_InitStructure);          
}


void CAN_Configuration(void)
{
     CAN_InitTypeDef        CAN_InitStructure;
     CAN_FilterInitTypeDef  CAN_FilterInitStructure;


     CAN_GPIO_Configuration();
     /* CAN register init */
     CAN_DeInit(CAN1);
     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 = ENABLE;
     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_2tq;
     CAN_InitStructure.CAN_Prescaler = 6;          //1MHz


     if (CAN_Init(CAN1,&CAN_InitStructure) == CANINITFAILED)           
     {
     }     


     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=0;
     CAN_FilterInitStructure.CAN_FilterActivation=ENABLE;
     CAN_ITConfig(CAN1,CAN_IT_FMP0, ENABLE);
     CAN_FilterInit(&CAN_FilterInitStructure);
}

/************ ADC configuration ***************************/
void ADC_Configuration(void)
{
     ADC_InitTypeDef ADC_InitStructure;   
     GPIO_InitTypeDef GPIO_InitStructure;  
     RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); // If I disable this line, CAN will enter interrupt
     RCC_ADCCLKConfig(RCC_PCLK2_Div6);   
                               
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;  
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;       
     GPIO_Init(GPIOA, &GPIO_InitStructure);    
     
     ADC_DeInit(ADC1);  
     
     ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; 
     ADC_InitStructure.ADC_ScanConvMode = DISABLE; 
     ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; 
     ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; 
     ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; 
     ADC_InitStructure.ADC_NbrOfChannel = 1; 
     ADC_Init(ADC1, &ADC_InitStructure); 
     
     
     ADC_Cmd(ADC1, ENABLE); 
       
     ADC_ResetCalibration(ADC1);
        
     while(ADC_GetResetCalibrationStatus(ADC1)); 
       
     ADC_StartCalibration(ADC1);  
     
     while(ADC_GetCalibrationStatus(ADC1));


}


u16 ADC_GetVal(ADC_TypeDef *  ADCx, uint8_t  ADC_Channel)
{
     u16 adc_val = 0;


     ADC_RegularChannelConfig(ADCx, ADC_Channel, 1, ADC_SampleTime_239Cycles5 );                     


     ADC_SoftwareStartConvCmd(ADCx, ENABLE);     
        
     while(!ADC_GetFlagStatus(ADCx, ADC_FLAG_EOC ));


     adc_val = ADC_GetConversionValue(ADCx); 
     return adc_val;
}

Outcomes