AnsweredAssumed Answered

Do Peripherals on ADC Pins Need Remap for ADC to work?

Question asked by slimsly on Jun 20, 2013
Latest reply on Jun 20, 2013 by Amel N
Hello,

I configure STM32F103RB ADC (GPIO_PA0 --PA7) as analog input with Interrupt enable.During the ADC is trigger but I get the wrong values. Do peripherals on ADC pin need Remapping for the ADC to function properly or there is something wrong with my code which I can not see.I will be glad if I can get help from anyone.

// ADC Definition
#define ADC_MODE_REGSIMULT                 ((uint32_t)0x00060000)
#define SWSTART                            ((uint32_t)0x000E0000)  /*Software Ext Trig conversion for Reg Channels*/
#define ADC_1_CONV_LENGTH                  ((uint16_t)0x0000)
//ADC Sampling Time
#define VIRTUAL_VOLTAGE_SAMPLE_75          ((uint32_t)0x00000040)
#define PHASE_VOLTAGE_A_SAMPLE_75          ((uint32_t)0x00000200)
#define PHASE_VOLTAGE_B_SAMPLE_75          ((uint32_t)0x00001000)
#define PHASE_VOLTAGE_C_SAMPLE_75          ((uint32_t)0x00008000)
#define MOTOR_CURRENT_SAMPLE_75            ((uint32_t)0x00040000)
#define BATTERY_VOLTAGE_SAMPLE_75          ((uint32_t)0x00200000)
//ADC GPIO Definition
#define GPIO_PA0_PA7_ANALOG                ((uint32_t)0x00000000)
//ADC Mux Input
#define VIRTUAL_VOLTAGE                    ((uint32_t)0x00000002)//PA2=>ADC1 CHANNELL 2
#define PHASE_VOLTAGE_A                    ((uint32_t)0x00000003)//PA3=>ADC2 CHANNELL 3  
#define PHASE_VOLTAGE_B                    ((uint32_t)0x00000004)//PA4=>ADC2 CHANNELL 4
#define PHASE_VOLTAGE_C                    ((uint32_t)0x00000005)//PA5=>ADC2 CHANNELL 5
#define MOTOR_CURRENT                      ((uint32_t)0x00000006)//PA6=>ADC1 CHANNELL 6
#define BATTERY_VOLTAGE                    ((uint32_t)0x00000007)//PA7=>ADC2 CHANNELL 7

====================================
void GPIO_Init(void)
{
    GPIOA->CRL = GPIO_PA0_PA7_ANALOG;         //PA0 - PA7 are Analog Input

    GPIOA->CRH = ENABLE_PWMCH1 |               //PWM CH1->PA8
                 ENABLE_PWMCH2 |               //PWM CH1->PA9
                 ENABLE_PWMCH3 |               //PWM CH1->PA10
                 ENABLE_PWMCH4;                //PWM CH1->PA11
    
    GPIOB->CRH = ENABLE_PWMCH1N |              //PWM CH1N->PB13
                 ENABLE_PWMCH2N |              //PWM CH1N->PB14
                 ENABLE_PWMCH3N;               //PWM CH1N->PB15
    
    /*LED OutPut GPI0B*/
    GPIOB->CRH |= GPIO_CRH_MODE8_1 |           //PB8-> 2MHz Output Mode, Push-Pull
                  GPIO_CRH_MODE9_1;            //PB9-> 2MHz Output Mode, Push-Pull*/

    GPIOC->CRL = 0x33333333;                   //PC0 - PC7 Configure as 50MHz Output Push Pull
    GPIOC->CRH = 0x44444444;                   //Input Floating*/
                  
}

void RCC_Init(void)
{
  RCC->APB2ENR |= RCC_APB2ENR_AFIOEN | RCC_APB2ENR_IOPAEN |         /*Enable Alternate Function & GPIOA*/
                    RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN |         /*Enable GPIOB & GPIOC*/
                    RCC_APB2ENR_IOPDEN | RCC_APB2ENR_TIM1EN |         /*Enable GPIOD & TIMER1*/
                  RCC_APB2ENR_ADC1EN | RCC_APB2ENR_ADC2EN;          /*Enable ADC1 & ADC2*/

  RCC->APB1ENR |= RCC_APB1ENR_TIM2EN | RCC_APB1ENR_TIM3EN |         /*Enable TIMER2 & TIMER3*/  
                    RCC_APB1ENR_TIM4EN | RCC_APB1ENR_I2C1EN |         /*Enable TIMER4, TIMER3 & I2C1 */
                    RCC_APB1ENR_USART2EN;                             /*Enable USART2*/

  RCC->AHBENR |= RCC_AHBENR_DMA1EN ;                                 /*Enable DMA1 clock*/
    
  RCC-> CFGR |= RCC_CFGR_ADCPRE_DIV6;  //ADC divided by 4 (12MHz)Tconv->(1.5+12.5)/12 = 1.17us
    
}
=============================
void ADC_Init(void)
{
    
     ADC1->CR1 |= ADC_MODE_REGSIMULT |         //Regular simultaneous mode only
                  ADC_CR1_EOCIE;               //EOC (End of ADC1_2 Conversion interrupt enabled
    
   ADC2->CR1 |= ADC_MODE_REGSIMULT |         //Regular simultaneous mode only
                  ADC_CR1_EOCIE;               //EOC (End of ADC1_2 Conversion interrupt enabled
                                
   ADC1->CR2 |= ADC_CR2_DMA |                //Enable DMA
                  ADC_CR2_EXTTRIG |            //Conversion on external event enabled
                ADC_CR2_EXTSEL;                     //External event select for regular group(SWSTART)    
                                
   ADC2->CR2 |= ADC_CR2_EXTTRIG |            //Conversion on external event enabled
                                ADC_CR2_EXTSEL;              //External event select for regular group(SWSTART)                         

   ADC1->SMPR2 |= VIRTUAL_VOLTAGE_SAMPLE_75;
   ADC1->SMPR2 |= MOTOR_CURRENT_SAMPLE_75;
    
   ADC2->SMPR2 |= PHASE_VOLTAGE_A_SAMPLE_75;
   ADC2->SMPR2 |= PHASE_VOLTAGE_B_SAMPLE_75;    
   ADC2->SMPR2 |= PHASE_VOLTAGE_C_SAMPLE_75;
     ADC2->SMPR2 |= BATTERY_VOLTAGE_SAMPLE_75;
    
   ADC1->SQR1 = ADC_1_CONV_LENGTH ;           //ADC1 Regular channel sequence length (1 conversions)
   ADC2->SQR1 = ADC_1_CONV_LENGTH ;           //ADC2 Regular channel sequence length (1 conversions)
    
     ADC1->HTR = 2048;                         //Analog WatchDog for OverCurrent Detection (20Amps)    
    
     ADC1->CR2 |= ADC_CR2_ADON;                //Enable ADC1
    
   ADC1->CR2 |= ADC_CR2_RSTCAL;              //Init ADC1 Reset Calibration register
            while (ADC1->CR2 & ADC_CR2_RSTCAL)     //ADC1 Reset Calibration Initialization Completed ??
                        {
                            //Do nothing
                        }
                        
     ADC1->CR2 |= ADC_CR2_CAL;                 //Start ADC2 calibration    
        while (ADC1->CR2 & ADC_CR2_CAL);         //ADC1 Calibration Completed??
                    {
                        //Do nothing
                    }    
     ADC2->CR2 |= ADC_CR2_ADON;                //Enable ADC2
                    
   ADC2->CR2 |= ADC_CR2_RSTCAL;              //Init Reset ADC2 Calibration register                
            while (ADC2->CR2 & ADC_CR2_RSTCAL);    //ADC2 Reset Calibration Initialization Completed??
                        {
                            //Do nothing
                        }
        
   ADC2->CR2 |= ADC_CR2_CAL;                 //Start ADC2 calibration
      while(ADC2->CR2 & ADC_CR2_CAL);        //ADC2 Calibration Completed
                        {
                            //Do nothing
                        }
     NVIC_SetPriority(ADC1_2_IRQn,24);         //Set Priority to 24                    
   NVIC_EnableIRQ(ADC1_2_IRQn);

}
===============================
void ADC1_2_IRQHandler(void)
 {
      static uint32_t temp_Voltage;
      static uint16_t Virtual_Voltage;
      static uint16_t CommuationTime;
    
        if (ADC1->SR & ADC_SR_EOC)                        //Master ADC1 Regular channel end of conversion Completed
            {
                ADC1->SR &= ~ADC_SR_EOC;                      //Clear Master ADC1 Regular channel Flag
                ADC2->SR &= ~ADC_SR_EOC;                      //Clear Slave ADC2 Regular channel Flag    
                
                Neutral_Voltage = ADC1->DR;                   //Neutral_Voltage is in the 16bits LSB of the ADC_DR 32bits Register
                temp_Voltage = (ADC1->DR & 0xFFFF0000) >> 16;    //Extract 16bit Phase_Voltage from the MSB of the ADC_DR Register
                Phase_Voltage = temp_Voltage;                 //Open Phase_Voltage

            }
    }

Outcomes