AnsweredAssumed Answered

STM32f4xx ADC values to voltage float values

Question asked by weddon.josh on Oct 19, 2013
Latest reply on Oct 19, 2013 by Clive One
I'm pretty close, I got the value of the ADC conversion coming out on my CooCox Semihosting window. The one thing that I can't seem to wrap my head around is getting the ADCResult value (1-4095) to convert to voltage (reference 3v), within 2 decimal points.


/* Includes */
#include "stm32f4xx.h"
#include "stm32f4_discovery.h"
#include "stm32f4xx_adc.h"
#include "stm32f4xx_rcc.h"
#include "stm32f4xx_gpio.h"
#include "stm32f4xx_it.h"
#include "semihosting.h"
#include "stdio.h"
#include "math.h"


/* Private macro */
/* Private variables */
uint32_t countGreen = 0;
uint32_t countOrange = 0;
uint32_t countRed = 0;
uint32_t countBlue = 0;


GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;

/* Private function prototypes */
/* Private functions */
#include "delays.h"

void InitLEDs(GPIO_InitTypeDef * GPIO_InitStructure);
void InitUserButton(GPIO_InitTypeDef * GPIO_InitStructure_Button);
void RotateLEDCW(uint32_t * led);
void RotateLEDCCW(uint32_t * led);
void binToASCII(uint16_t binNumber);

/* Enumeration for LED colours. */
enum { GREEN, ORANGE, RED, BLUE };
enum { LEDGREEN = 0X1000, LEDORANGE = 0X2000, LEDRED = 0X4000, LEDBLUE = 0X8000 };


/**
**============
**
**   main
**
**============
*/
int main(void)
{
  uint16_t ADCResult;
  const float maxAdcBits = 4095.0f; // Using Float for clarity
  const float maxVolts = 3.0f;      // Using Float for clarity
  const float voltsPerBit = (maxVolts / maxAdcBits);


  /* =================================== Application Code ========================  */



  /* **********************************************************************
    *                        LED(s)
    * ***********************************************************************
    */

  /* Init LEDs */
  GPIO_InitTypeDef GPIO_InitStructure;    /* Create variable */
  InitLEDs(&GPIO_InitStructure);



  /* ***********************************************************************
    *                        Pushbutton
    * ***********************************************************************
    */

  /* Initialize User button */
  GPIO_InitTypeDef GPIO_InitStructure_Button;    /* Create variable */
  InitUserButton(&GPIO_InitStructure_Button);



  /* ***********************************************************************
   *                        ADC
   * ***********************************************************************
   */

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);



  // Configure GPIO PC1 as analog input ADC3 Channel11
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; //GPIO PC1
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  ADC_DeInit(); //Put ADCs back to power-on defaults
                          //runs a RCC_APB2PeriphResetCmd


              ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
              ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;
              ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
              ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
              ADC_CommonInit(&ADC_CommonInitStructure);

              ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
          ADC_InitStructure.ADC_ScanConvMode = DISABLE;
          ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
          ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
          ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
          ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
          ADC_InitStructure.ADC_NbrOfConversion = 1;
          ADC_Init(ADC3, &ADC_InitStructure);   //set config of ADC3

          ADC_RegularChannelConfig(ADC3, ADC_Channel_11, 1, ADC_SampleTime_3Cycles);

          ADC_Cmd (ADC3,ENABLE);  //enable ADC3










  int time_base = 1000; /* 1 ms time base */
  SystemInit();
  if(SysTick_Config(SystemCoreClock / time_base))
  {
      /* Capture error */
      while(1);
  }

  /* Start with Orange LED */
  uint32_t theLED = LEDORANGE;

  /* Infinite loop */
  while (1)
  {


      /* Turn LED on and then off. */
    GPIOD->BSRRL = theLED;         /* Turn LED on */
      Delay(250);


      ADC_SoftwareStartConv(ADC3);
      // Wait until conversion completion - ADC_FLAG_EOC bit set
      while(ADC_GetFlagStatus(ADC3, ADC_FLAG_EOC) == RESET);
      ADCResult = ADC_GetConversionValue(ADC3);
      /**
      * @brief Returns the last ADCx conversion result data for regular channel.
      * @param ADCx: where x can be 1, 2 or 3 to select the ADC peripheral.
      * @retval The Data conversion value.
      */
      uint16_t ADC_GetConversionValue(ADC_TypeDef* ADCx)
      {
      /* Check the parameters */
      assert_param(IS_ADC_ALL_PERIPH(ADCx));
      /* Return the selected ADC conversion value */
      return (uint16_t) ADCx->DR;
      }

      unsigned int temp = ADCResult;
      float yourVoltage = temp * voltsPerBit;

      printf("\n\nPC1 Value is: %d\t", ADCResult);
      printf("PC1 Volts is: %d \n\n", yourVoltage);







    /* Turn LED off */
      GPIOD->BSRRH = theLED;
      Delay(500);

  }
}


/*
 * @brief Initializes LEDs
 */
void InitLEDs(GPIO_InitTypeDef * GPIO_InitStructure)
{
      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE); /* Turn on AHB1 Bus Clock */
      (*GPIO_InitStructure).GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
      (*GPIO_InitStructure).GPIO_Mode = GPIO_Mode_OUT;
      (*GPIO_InitStructure).GPIO_OType = GPIO_OType_PP;
      (*GPIO_InitStructure).GPIO_Speed = GPIO_Speed_50MHz;
      (*GPIO_InitStructure).GPIO_PuPd = GPIO_PuPd_UP;
      GPIO_Init(GPIOD, GPIO_InitStructure);    /* Sets port registers with the values in our struct variables. */


}

void InitUserButton(GPIO_InitTypeDef * GPIO_InitStructure_Button)
{
     /* Initialize User button */
      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); /* Turn on AHB1 Bus Clock */

      (*GPIO_InitStructure_Button).GPIO_Pin = GPIO_Pin_0;
      (*GPIO_InitStructure_Button).GPIO_OType = GPIO_OType_PP;
      (*GPIO_InitStructure_Button).GPIO_Speed = GPIO_Speed_100MHz;
      (*GPIO_InitStructure_Button).GPIO_PuPd = GPIO_PuPd_NOPULL;
      GPIO_Init(GPIOD, GPIO_InitStructure_Button);    /* Sets port registers with the values in our struct variables. */

}

Outcomes