Problem with STM32F407VET6 ADC via CMSIS. The ADC returns zero values

45 Views Asked by At

I am configuring the ADC to sequentially digitize the inputs ADC9, ADC14, ADC15, ADC6, ADC7, ADC8 (pins PF3, PF4, PF5, PF6, PF7, PF8). The controller pins are also configured. I also allow interrupts and read the DR value in the interrupt handler and pass it to the function for calculating the value of a physical quantity. In my opinion, the values of the analog signal levels from these inputs should appear sequentially in ADC3->DR. But zeros are coming (this can be seen when intercepting the interrupt handler). Perhaps the problem is that when digitizing sequences, the DMA controller is included in the case, and the ADC3->DR register should have zero. But I did not find explicit instructions in the documentation, so I cannot determine the exact cause of the problem.

I used a voltmeter to estimate the voltages at the PF3-PF8 pins. They have about 2 Volts on them. I use the following code:

int main() {
    dummy_loop(100000);
    // Setting the delay for reading instructions from Flash
    FLASH->ACR |= ( 7 << FLASH_ACR_LATENCY_Pos );
    for ( Iteration = 0; Iteration < 1000; Iteration++ );
    // Setting the PLL to multiply HSI16 clock to 96 MHz
    RCC->PLLCFGR = ( 2 << 28 ) | ( 16 << RCC_PLLCFGR_PLLM_Pos ) | ( 192 << RCC_PLLCFGR_PLLN_Pos ) | ( 4 << RCC_PLLCFGR_PLLQ_Pos );
    for ( Iteration = 0; Iteration < 1000; Iteration++ );
    // Switch on PLL
    RCC->CR |= ( 1 << RCC_CR_PLLON_Pos );
    for ( Iteration = 0; Iteration < 1000; Iteration++ );
    // Waiting for the PLL to be ready
    while ((RCC->CR&(1<<RCC_CR_PLLRDY_Pos)) == 0) {}
    for ( Iteration = 0; Iteration < 1000; Iteration++ );
    // Switch clock source from HSI16 on PLL
    RCC->CFGR = ( 2 << RCC_CFGR_SW_Pos );
    for ( Iteration = 0; Iteration < 1000; Iteration++ );
    // Switch on GPIOA, GPIOC, GPIOE, GPIOF
    RCC->AHB1ENR |= ( 1 << RCC_AHB1ENR_GPIOAEN_Pos) | ( 1 << RCC_AHB1ENR_GPIOCEN_Pos) | ( 1 << RCC_AHB1ENR_GPIOEEN_Pos ) | ( 1 << RCC_AHB1ENR_GPIOFEN_Pos ) | ( 1 << RCC_AHB1ENR_CCMDATARAMEN_Pos );
    for ( Iteration = 0; Iteration < 1000; Iteration++ );
    // Switch on TIM2
    RCC->APB1ENR |= ( 1 << RCC_APB1ENR_TIM2EN_Pos );
    for ( Iteration = 0; Iteration < 1000; Iteration++ );
    // Switch on ADC3
    RCC->APB2ENR = ( 1 << RCC_APB2ENR_ADC3EN_Pos );
    for ( Iteration = 0; Iteration < 1000; Iteration++ );
    GPIOF->MODER = ( 3 << GPIO_MODER_MODE3_Pos ) | ( 3 << GPIO_MODER_MODE4_Pos ) | ( 3 << GPIO_MODER_MODE5_Pos ) | ( 3 << GPIO_MODER_MODE6_Pos ) |                              ( 3 << GPIO_MODER_MODE7_Pos ) | ( 3 << GPIO_MODER_MODE8_Pos );
    TIM2->ARR = 0xFFFFFFFF;
    TIM2->CR1 |= ( 1 << TIM_CR1_CEN_Pos );
    GetTimeStamp ( &(LastTimeStamp1.AsUint64) );
    for ( Iteration = 0; Iteration < 10000; Iteration++ );
    // ADC clock frequency = 16 MHz
    ADC->CCR = ( 3 << ADC_CCR_ADCPRE_Pos );
    // The sequence of digitization is 9, 14, 15, 6, 7, 8
    ADC3->SQR3 = ( 8 << 25 ) | ( 7 << 20 ) | ( 6 << 15 ) | ( 15 << 10 ) | ( 14 << 5 ) | ( 9 << 0 );
    // The length of sequence is 6
    ADC3->SQR1 = ( 5 << ADC_SQR1_L_Pos );
    // Enable end-of-conversion interrupt
    ADC3->CR1 = ( 1 << ADC_CR1_EOCIE_Pos );
    // ADC On, continuous mode, event after each conversion
    ADC3->CR2 = ( 1 << ADC_CR2_ADON_Pos ) | ( 1 << ADC_CR2_CONT_Pos ) | ( 1 << ADC_CR2_EOCS_Pos );
        // 112 cycles for each conversion
    ADC3->SMPR1 = ( 5 << 0 ) | ( 5 << 3 ) | ( 5 << 6 ) | ( 5 << 9 ) | ( 5 << 12 ) | ( 5 << 15 ) | ( 5 << 18 ) | ( 5 << 21 ) | ( 5 << 24 );
        // 112 cycles for each conversion
    ADC3->SMPR2 = ( 5 << 0 ) | ( 5 << 3 ) | ( 5 << 6 ) | ( 5 << 9 ) | ( 5 << 12 ) | ( 5 << 15 ) | ( 5 << 18 ) | ( 5 << 21 ) | ( 5 << 24 ) | ( 5 << 27 );
        // Start conversion
    ADC3->CR2 = ( 1 << ADC_CR2_ADON_Pos ) | ( 1 << ADC_CR2_CONT_Pos ) | ( 1 << ADC_CR2_EOCS_Pos ) | ( 1 << ADC_CR2_SWSTART_Pos );
        // Enable interrupt
    NVIC_EnableIRQ(ADC_IRQn);
    
    while (1) {
    }
}

uint32_t ADCInputIndex = 0;

void ADC_IRQHandler ( void ) {
  if ( ADC3->SR & (1<<1) ) {
        Result = ADC3->DR;
                // Zeros are transmitted here all the time
        RegisterMeasure ( ADCInputIndex, Result );
        ADCInputIndex++;
        if (ADCInputIndex > 5) { ADCInputIndex = 0; }
  }
}
0

There are 0 best solutions below