Keil Logo

Analog Digital Converter

Analog-to-digital converters bring the analog world to the processor. Some complex ADCs can be triggered through events, such as Timers or DMA-controllers. This section describes the very basic setup that they all have in common.

For this example the following steps are required:

  1. Create a new project.
  2. Select the STM32F107VC microcontroller from the Device Database.
  3. Include the files:
    • startup_stm32f10x_cl.s
    • system_stm32f10x_cl.c
    • core_cm3.c
    • Serial.c
    • Retarget.c
  4. Create and add a new file, adc.c, to the project.
  5. Use the code below as a reference.
    /*-----------------------------------------------------------------------------
     * Name:    ADC.c
     * Purpose: The signal of the potentiometer is printed.
     * Notes:
    *----------------------------------------------------------------------------*/
    #include <stdio.h>
    #include <stm32f10x_cl.h>
    
    unsigned short AD_last;                    // Last converted value
    unsigned char  clock_1s;                   // Flag activated each second
    
    extern void init_serial (void);            // Import function from Serial.c
    
    /*-----------------------------------------------------------------------------
      Function that initializes ADC
    *----------------------------------------------------------------------------*/
    void ADC_init (void)  {
    
      RCC->APB2ENR |= (1<<4);                  // enable peripheral clock for GPIOC
      GPIOC->CRL &= ~0x000F0000;               // Configure PC4 as ADC.14 input
    
      RCC->APB2ENR |= (1<<9);                  // enable peripheral clock for ADC1
    
      ADC1->SQR1    = 0x00000000;              // Regular channel 1 conversion
      ADC1->SQR2    = 0x00000000;              // Clear register
      ADC1->SQR3    = (14<< 0);                // SQ1 = channel 14
      ADC1->SMPR1   = ( 5<<12);                // sample time channel 14 55,5 cycles
      ADC1->CR1     = (1 <<  8) |              // Scan mode on
                      (1 <<  5) ;              // EOC interrupt enable
      ADC1->CR2     = (1 << 20) |              // Enable external trigger
                      (7 << 17) |              // EXTSEL = SWSTART
                      (1 <<  0) ;              // ADC enable
      ADC1->CR2    |= (1 <<  3);               // Reset calibration
      while (ADC1->CR2 & (1 << 3));            // wait until reset finished
    
      ADC1->CR2    |= (1 <<  2);               // start calibration
      while (ADC1->CR2 & (1 << 2));            // wait until calibration finished
    
      NVIC_EnableIRQ (ADC_IRQn);               // enable ADC Interrupt
    }
    
    /*-----------------------------------------------------------------------------
      SysTick IRQ: Executed periodically (10ms)
    *----------------------------------------------------------------------------*/
    void SysTick_Handler (void)  {
    static unsigned long ticks;
    
      if (ticks++ >= 99)  {                    // Set Clock1s to 1 every 1 second
        ticks    = 0;
        clock_1s = 1;
      }
    
      ADC1->CR2  |= (1 << 22);                 // start SW conversion
    }
    
    /*-----------------------------------------------------------------------------
      A/D IRQ: Executed when A/D Conversion is done
    *----------------------------------------------------------------------------*/
    void ADC1_2_IRQHandler (void)  {
      if (ADC1->SR & (1<<1))  {                // ADC1 EOC interrupt?
        AD_last = (ADC1->DR) & 0xFFF;          // Read Conversion Result
    
        ADC1->SR &= ~(1<<1);                   // clear EOC interrupt
      }
    
    }
    
    /*-----------------------------------------------------------------------------
      MAIN function
    *----------------------------------------------------------------------------*/
    int main (void)  {
    
      SystemInit ();
      SysTick_Config (SystemFrequency/100);    // Generate interrupt each 10 ms
    
      init_serial();                           // UART#2 Initialization
      ADC_init();                              // ADC Initialization
    
      while (1)  {                             // Loop forever
        if (clock_1s)  {
          clock_1s = 0;
          printf ("AD value = 0x%03x\n\r", AD_last);
        }
      }
    }
    
  6. Build the project.
  7. Connect a Flash programming utility to the PC and to the board.
  8. Configure µVision for Flash downloading.
  9. Download to Flash and debug the application.
  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.