Life.augmented

STM32

Modify settings and columns
STM32 - ARM Cortex-M 32-Bit MCU
Share Discussion
  
View: 
Post
Started: 6/24/2011 3:06 PM
fauskanger.tord
  Posts : 3
STM32F205 temperature sensor problems
Hi everybody,
I'm having some trouble with the STM32F205 temperature sensor. 

I'm using the algorithm from section 10.10 in the reference manual. {(V25 – VSENSE) / Avg_Slope} + 25

I'm using the following algorithm to convert the ADC value to a voltage value from the temperature sensor ADC channel (ch 16):
ADCConvertedValue*3.3/4096;

When I'm heating up the chip the ADCConvertedValue increases resulting in a greater voltage value, that results in lower temperature as a higher VSENSE value will subtract more from V25. 

Does anyone have the same problem ? 

Best Regards
Tord

Tags: STM32F205 temperature
Share Post
Edited: 6/25/2011 1:21 PM
ColdWeather
  Posts : 99
Hello, Tord!

I have STM32F103RC (not 205) running here and tested the temperature sensor. I think, the unit in 205 is not quite different from 103

The equation is correct. The board shows now +27^C and rises a bit if I hold a finger on the CPU. Well, indeed the room temperature now is about +21^C, but ST says, the embedded sensor is just for estimation purposes only and quite unprecise.
Share Post
Posted: 6/25/2011 5:20 PM
baird.hal.001
  Posts : 506
If you are using the 4.3 Avg_Slope from the datasheet, it is in millivolts, so your conversion to voltage should be ADCConvertedValue*3300/4096. And you will have to allow for integer overflow in this equation by using u32 type.

If that is not your problem, post the code so we can see what is going on.

Cheers, Hal

Share Post
Edited: 6/26/2011 3:31 PM
fauskanger.tord
  Posts : 3
Here's the code:
/* Includes ------------------------------------------------------------------*/
#include "stm32f2xx.h"

/** @addtogroup STM32F2xx_StdPeriph_Examples
  * @{
  */

/** @addtogroup ADC_ADC1_DMA
  * @{
  */ 

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define ADC1_DR_ADDRESS    ((uint32_t)0x4001204C)

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
__IO uint16_t ADCConvertedValue = 0;
__IO uint16_t TempSTM32 = 0;

ADC_InitTypeDef       ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
DMA_InitTypeDef       DMA_InitStructure;
GPIO_InitTypeDef      GPIO_InitStructure;

/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/**
  * @brief  Main program
  * @param  None
  * @retval None
  */
int main(void)
{
  /*!< At this stage the microcontroller clock setting is already configured, 
       this is done through SystemInit() function which is called from startup
       file (startup_stm32f2xx.s) before to branch to application main.
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f2xx.c file
     */     
       
  /* Enable peripheral clocks *************************************************/
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOC, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

  /* DMA2_Stream0 channel0 configuration **************************************/
  DMA_DeInit(DMA2_Stream0);
  DMA_InitStructure.DMA_Channel = DMA_Channel_0;  
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_ADDRESS;
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADCConvertedValue;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  DMA_InitStructure.DMA_BufferSize = 1;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;         
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  DMA_Init(DMA2_Stream0, &DMA_InitStructure);
  /* DMA2_Stream0 enable */
  DMA_Cmd(DMA2_Stream0, ENABLE);

  /* ADC1 configuration ------------------------------------------------------*/
  /* Configure ADC Channel12 pin as analog input */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  /* ADCs DeInit (for debug purpose) */  
  ADC_DeInit();
  /* ADC Common Init */
  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);
  
  /* ADC1 Init */
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;   
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfConversion = 1;
  ADC_Init(ADC1, &ADC_InitStructure);

  /* ADC1 regular channel12 configuration */ 
  ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_480Cycles);

  /* Enable DMA request after last transfer (Single-ADC mode) */
 // ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);

  /* Enable ADC1 DMA */
  //ADC_DMACmd(ADC1, ENABLE); 
    ADC_TempSensorVrefintCmd(ENABLE);
    ADC_EOCOnEachRegularChannelCmd(ADC1, ENABLE);
  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);
    
  /* Start ADC1 Software Conversion */ 
  ADC_SoftwareStartConv(ADC1);
  float adcVolt = 0;
  float diffVolt = 0;
  float temp1 = 0;
  float temp2 = 0;
  while (1)
  {
    ADC_SoftwareStartConv(ADC1);
    while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)== RESET);
   ADCConvertedValue = ADC_GetConversionValue(ADC1);
   adcVolt  = ADCConvertedValue*3.3/4096;
   diffVolt =   adcVolt - 0.76 ;
   temp1  = diffVolt / (2.5/1000);//0.00025;

   temp2 = temp1 +25;   
  }
}

#ifdef  USE_FULL_ASSERT

/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */

  /* Infinite loop */
  while (1)
  {
  }
}
#endif

/**
  * @}
  */ 

/**
  * @}
  */ 

/******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/


From: baird.hal.001
Posted: Saturday, June 25, 2011 5:20 PM
Subject: STM32F205 temperature sensor problems

If you are using the 4.3 Avg_Slope from the datasheet, it is in millivolts, so your conversion to voltage should be ADCConvertedValue*3300/4096. And you will have to allow for integer overflow in this equation by using u32 type.

If that is not your problem, post the code so we can see what is going on.

Cheers, Hal



From: fauskanger.tord
Posted: Friday, June 24, 2011 3:06 PM
Subject: STM32F205 temperature sensor problems

Hi everybody,
I'm having some trouble with the STM32F205 temperature sensor. 

I'm using the algorithm from section 10.10 in the reference manual. {(V25 – VSENSE) / Avg_Slope} + 25

I'm using the following algorithm to convert the ADC value to a voltage value from the temperature sensor ADC channel (ch 16):
ADCConvertedValue*3.3/4096;

When I'm heating up the chip the ADCConvertedValue increases resulting in a greater voltage value, that results in lower temperature as a higher VSENSE value will subtract more from V25. 

Does anyone have the same problem ? 

Best Regards
Tord
Share Post
Posted: 6/26/2011 4:49 PM
baird.hal.001
  Posts : 506
You made one simple error (probably a typo). The ADC1 address boundary starts at 0x40012400. The DR address offset is 0x4C, so the ADC1_DR_Address should be 0x4001244C.

If that doesn't fix the problem, I will give your code a more intensive review.

Cheers, Hal
Share Post
Posted: 6/27/2011 9:28 AM
fauskanger.tord
  Posts : 3
Thanks for the code review, nice catch, however the ADC address boundary starts at a address on the 2xx series, than the 1xx series. The code doesn't activate DMA on the ADC device so it is manually driven. I probably should have removed the unutilized  DMA code snippets to avoid confusion. 
Heres the code a bit more tidy: 

Cheers 
Tord

#include "stm32f2xx.h"

__IO uint16_t ADCConvertedValue = 0;
__IO uint16_t TempSTM32 = 0;

ADC_InitTypeDef       ADC_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
GPIO_InitTypeDef      GPIO_InitStructure;

int main(void)
{
       
  /* Enable peripheral clocks *************************************************/
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOC, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);


  /* ADC1 configuration ------------------------------------------------------*/
  /* Configure ADC Channel12 pin as analog input */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

  ADC_DeInit();
  /* ADC Common Init */
  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);
  
  /* ADC1 Init */
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;//ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;   
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfConversion = 1;
  ADC_Init(ADC1, &ADC_InitStructure);

  /* ADC1 regular channel16 configuration */ 
  ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_480Cycles);


    ADC_TempSensorVrefintCmd(ENABLE);
    ADC_EOCOnEachRegularChannelCmd(ADC1, ENABLE);
  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);
    
  /* Start ADC1 Software Conversion */ 
  ADC_SoftwareStartConv(ADC1);
  float adcVolt = 0;
  float diffVolt = 0;
  float temp1 = 0;
  float temp2 = 0;
  while (1)
  {
    ADC_SoftwareStartConv(ADC1);
    while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)== RESET);
   ADCConvertedValue = ADC_GetConversionValue(ADC1);
   adcVolt  = ADCConvertedValue*3.3/4096;
   diffVolt =   adcVolt - 0.76 ;
   temp1  = diffVolt / (2.5/1000);//0.00025;

   temp2 = temp1 +25;   
  }
}


Share Post
Posted: 6/28/2011 8:35 PM
baird.hal.001
  Posts : 506
Try calibrating the ADC one time before the conversion loop. You also have two start conversions the first time through. Eliminate the first one.

The data sheet says the slope is positive, but the formula indicates otherwise. Try assuming the formula should be Vsense - V25.

There is a more efficient way to perform the calculation than using floating variables, based on ADC values of 943 for V25 and 3.1 for slope.

    Temperature = 25 + BiasCorrection + (((s16) ADCConvValue-943)*10)/31;

Your CPU will be smoke and ash before you exceed 16 bit integer range.

Cheers, Hal
Share Post
Posted: 6/27/2012 3:02 PM
pop.cristi
  Posts : 4

Hi Tord,
I have the same problem, with the same uC. Did you solved the problem?
Thanks
Share Post
Posted: 6/27/2012 6:07 PM
clive1
  Posts : 11702
It's been a year since Tord posted, suggest you submit YOUR code and no doubt some of the members can critic it. Hal is still active here, and has a good handle on the ADC stuff.
Share Post
Posted: 6/27/2012 11:53 PM
Jack Peacock
  Posts : 252
Be sure the sample time for the temperature sensor is > 10usec, otherwise you get unreliable readings.  For an STM32F407, 168MHz, ADCCLK scaled to 21MHz, I have to use the 480 cycle setting for sample time of about 23usec.
  Jack Peacock


Tags: Vsense Temperature Sensor
Share Post
Posted: 6/29/2012 3:37 PM
pop.cristi
  Posts : 4
Hi this is mai code:


#define STM32_TEMPSENS_ADC_DEVICE                ADC1
#define STM32_TEMPSENS_ADC_IRQHANDLER            ADC_IRQHandler
#define STM32_TEMPSENS_ADC_IRQCHANNEL            ADC_IRQn
#define STM32_TEMPSENS_ADC_PERIPH_CLK            RCC_APB2Periph_ADC1
#define STM32_TEMPSENS_ADC_PERIPH_CLK_FREQ_HZ    (PROJECT_SYSCLK_HZ / 2)
#define STM32_TEMPSENS_ADC_PRESCALER            8

#define STM32_TEMPSENS_ADC_RESOL_BITS            12
#define STM32_TEMPSENS_ADC_SAMPLETIME_CYCLES    56
#define STM32_TEMPSENS_ADC_V_REF_4DD            33000 /* typical */
#define STM32_TEMPSENS_AVG_SLOPE_MV_DEGC_1DD    25    /* typical */
#define STM32_TEMPSENS_V_25DEGC_4DD                7600  /* typical */
#define STM32_TEMPSENS_T_S_US                    10    /* typical */
#define STM32_TEMPSENS_ADC_RESOL_STEPS    (1 << STM32_TEMPSENS_ADC_RESOL_BITS)

static volatile uint16_t tempsens_rawval;
static volatile uint8_t conv_running;

static int
_init(const struct w2h_dev_t *self, const void *cfg)
{
    ADC_InitTypeDef ADC_InitStructure;
    ADC_CommonInitTypeDef ADC_CommonInitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    /* Enable STM32_TEMPSENS_ADC_DEVICE clock. */
    (void)self;
    (void)cfg;
    RCC_APB2PeriphClockCmd(STM32_TEMPSENS_ADC_PERIPH_CLK, ENABLE);

    /* Configure NVIC for STM32_TEMPSENS_ADC_DEVICE. */
    NVIC_InitStructure.NVIC_IRQChannel = STM32_TEMPSENS_ADC_IRQCHANNEL;
    NVIC_Init(&NVIC_InitStructure);

    tempsens_rawval = 0;
    ADC_DeInit();

    /* ADC Common Init */
    ADC_CommonStructInit(&ADC_CommonInitStructure);
    ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;
    ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div8;
    ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;
    ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;
    ADC_CommonInit(&ADC_CommonInitStructure);

    /* STM32_TEMPSENS_ADC_DEVICE configuration. */
    ADC_StructInit(&ADC_InitStructure);

    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 = xxx; */
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfConversion = 1;
    ADC_Init(STM32_TEMPSENS_ADC_DEVICE, &ADC_InitStructure);
    /* STM32_TEMPSENS_ADC_DEVICE temperature sensor configuration. */
    /* The temperature sensor requires a sample time of at least 17.1 us. */
    /*
     * With ADC clock @12 MHz (PCLK2 / 6) and a sample time of 239.5 cycles,
     * the temperature sensor's required sample time can be matched.
     */

    ADC_RegularChannelConfig(STM32_TEMPSENS_ADC_DEVICE, ADC_Channel_TempSensor,
                             1, ADC_SampleTime_480Cycles);
    /* Enable temperature sensor and Vref. */
    ADC_TempSensorVrefintCmd(ENABLE);
    /* Enable STM32_TEMPSENS_ADC_DEVICE EOC interupt. */
    ADC_ITConfig(STM32_TEMPSENS_ADC_DEVICE, ADC_IT_EOC, ENABLE);
    /* Enable STM32_TEMPSENS_ADC_DEVICE. */
    ADC_Cmd(STM32_TEMPSENS_ADC_DEVICE, ENABLE);
    printfx("call adc_init\n");
    return W2H_ERR_OK;
}

static int
_deinit(const struct w2h_dev_t *self)
{
    (void)self;
    return W2H_ERR_OK;
}

static int
_read(const struct w2h_dev_t *self,  uint16_t *ptr)
{
    int32_t val;
    (void)self;
    /* Argument checks. */
    if (ptr == NULL) {
        return 1;
        /* NOTREACHED */
    }
    conv_running = 1;
    /* Start next STM32_TEMPSENS_ADC_DEVICE Software Conversion. */
    ADC_SoftwareStartConv(STM32_TEMPSENS_ADC_DEVICE);
    /* Loop until ISR has finished. */
    while (conv_running != 0) {
        /* Wait (do nothing). */
    }
    /* Convert ADC result to value in degC. */
    val = ((int32_t)tempsens_rawval * STM32_TEMPSENS_ADC_V_REF_4DD)
          / (STM32_TEMPSENS_ADC_RESOL_STEPS - 1);
    val = STM32_TEMPSENS_V_25DEGC_4DD - val;
    val /= STM32_TEMPSENS_AVG_SLOPE_MV_DEGC_1DD;
    val += 25;
    *ptr = val;
    return W2H_ERR_OK;
}




void w2h_stm32_adc_ev_irqh(const struct w2h_dev_t *self)
{
    (void)self;
    if (ADC_GetITStatus(STM32_TEMPSENS_ADC_DEVICE, ADC_IT_EOC) != RESET) {
        /*
         * The "End of conversion" bit (EOC) -- as the interrupt source --
         * is cleared by reading ADC_DR.
         */
        tempsens_rawval = ADC_GetConversionValue(STM32_TEMPSENS_ADC_DEVICE);

        conv_running = 0;
    }
}

And the problem is that, I am reading the same
conts = 0x3C4;  5 counts tolerance
Normaly, I think that even touching the uC, with my finger the conts should take other value.
I tried desabling the temp Vref, and I read:
conts =  0x05;  3 conts tolerance
I have tried spray the processor with an alcohool spray (-52 C deg), and I read more conts. Probably becouse of the variation, of internal reference.
Thank You for answer.




Share Post
Posted: 6/29/2012 8:45 PM
dimitrov.valentin
  Posts : 8
Temperature (in °C) = {(VSENSE– V25) / Avg_Slope} + 25
The formula was wrong in the earliest versions of the ref. manual.
Share Post
Posted: 6/29/2012 10:55 PM
baird.hal.001
  Posts : 506
And, remove the comment marks in

 /* ADC_InitStructure.ADC_ExternalTrigConv = xxx; */

and set xxx = 0.

Let us know what happens after these fixes.

Cheers, Hal


Share Post
Posted: 7/2/2012 8:39 AM
pop.cristi
  Posts : 4
Hello all,
It seems that i had only a conversion problem, in converting conts to temp.
Thank you Valentin for formula correction.
However I'm still not quite not happy, with what I obteined. Measuring the temp sensor once per second, I have jumps eaven of 2 C deg.
Although the ADC clock is divided by 8 and ADC_SampleTime_480Cycles, it seems a little bit strage for me.

Thank you for feedback,
Cristian
Share Post
Posted: 7/2/2012 9:50 AM
ColdWeather
  Posts : 99
> Temperature (in °C) = {(VSENSE– V25) / Avg_Slope} + 25

The equation above must be WRONG. The latest RM says:

{(V25 - VSENSE) / Avg_Slope} + 25

and it works on my boards (a part of the code):

    float
    _Vsense =  1.0 * ADC_ValueToVoltage(ADC_Values[0]);
    return (_V25 - _Vsense)*1000/_Slope + 25;    // ...and add 25^C



Share Post
Posted: 7/2/2012 10:36 AM
pop.cristi
  Posts : 4
RM0033 is the last?
http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/REFERENCE_MANUAL/CD00225773.pdf

Share Post
Posted: 4/1/2015 4:48 PM
cihan.ahmet
  Posts : 12
I have the same problem. I can read only one fixed value from temperature sensor after power-on. I've tried a lot of code, including the above examples. Using DMA, without DMA, interrupt, polling.. no way. I can read just only one value despite of heating/cooling the processor. It seems like the "continuous converting mode" is in trouble. As a said, I've tried all configurations. My last trial code;

(for stm32f205!)

void ADC_init(void){
    ADC_InitTypeDef       ADC_InitStructure;
    ADC_CommonInitTypeDef ADC_CommonInitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;
    DMA_InitTypeDef DMA_InitStructure;

    DMA_StructInit(&DMA_InitStructure);



    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
    DMA_InitStructure.DMA_Channel = DMA_Channel_0;
    DMA_InitStructure.DMA_BufferSize = 2;                    
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;    
    DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;    
    DMA_InitStructure.DMA_FIFOThreshold = 0;
    DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
    DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;          
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;       
 
    DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)ADCBuffer; 
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; 
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
    /* config of peripheral */
    DMA_InitStructure.DMA_PeripheralBaseAddr = &ADC1->DR; 
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
    DMA_Init(DMA2_Stream0, &DMA_InitStructure); 
    DMA_Cmd(DMA2_Stream0, ENABLE);


    ADC_StructInit(&ADC_InitStructure);
    ADC_CommonStructInit(&ADC_CommonInitStructure);

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);

    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 = ENABLE;
    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
    ADC_InitStructure.ADC_ExternalTrigConvEdge = 0;
    ADC_InitStructure.ADC_ExternalTrigConv = 0;
    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
    ADC_InitStructure.ADC_NbrOfConversion = 2;
    ADC_Init(ADC1, &ADC_InitStructure);

    ADC_TempSensorVrefintCmd(ENABLE);

    ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_480Cycles);
    /* VREF_int (2nd) */
    ADC_RegularChannelConfig(ADC1, ADC_Channel_17, 2, ADC_SampleTime_480Cycles);


    /* Enable ADC interrupts */
    ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);


    /* Enable DMA request after last transfer (Single-ADC mode) */
    ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);


    /* Enable ADC3 DMA */
    ADC_DMACmd(ADC1, ENABLE);
    /* Configure NVIC */
    NVIC_InitStructure.NVIC_IRQChannel = ADC_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
    NVIC_Init(&NVIC_InitStructure);

    /* Enable ADC1 **************************************************************/
    ADC_Cmd(ADC1, ENABLE);
}
void adc_ev_irqh(void){
ADC_ClearITPendingBit(ADC1, ADC_IT_EOC);
}

I can see both Vref and Temp values via serial port. There's no change after power-on, but the values are changing at each restart..

Share Post
Posted: 4/1/2015 6:28 PM
clive1
  Posts : 991
This seemed to work first time without any issues, should be fine on the F2, also use the DMA TC for the EOC
// STM32 ADC Sample Vref and Temp STM32F4 Discovery - sourcer32@gmail.com
 
#include "stm32f4_discovery.h"
 
/**************************************************************************************/
 
void RCC_Configuration(void)
{
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
}
 
/**************************************************************************************/
 
void ADC_Configuration(void)
{
  ADC_CommonInitTypeDef ADC_CommonInitStructure;
  ADC_InitTypeDef ADC_InitStructure;
 
  /* ADC Common Init */
  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 = ENABLE; // 2 Channels
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // Continuous Conversions
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
  ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO; // Ignored
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfConversion = 2;
  ADC_Init(ADC1, &ADC_InitStructure);
 
  /* ADC1 regular channel configuration */
  ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_480Cycles); // TEMP 16 on 40x/41x, 18 on 42x/43x
  ADC_RegularChannelConfig(ADC1, ADC_Channel_17, 2, ADC_SampleTime_480Cycles); // VREFINT
 
  /* Enable DMA request after last transfer (Single-ADC mode) */
  ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);
 
  /* Enable ADC1 DMA */
  ADC_DMACmd(ADC1, ENABLE);
 
  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);
}
 
/**************************************************************************************/
 
#define BUFFERSIZE 2
 
__IO uint16_t ADCConvertedValues[BUFFERSIZE];
 
static void DMA_Configuration(void)
{
  DMA_InitTypeDef DMA_InitStructure;
 
  DMA_InitStructure.DMA_Channel = DMA_Channel_0;
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADCConvertedValues[0];
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  DMA_InitStructure.DMA_BufferSize = BUFFERSIZE; // Count of 16-bit words
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
  DMA_InitStructure.DMA_Priority = DMA_Priority_High;
  DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
  DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
  DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
  DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
  DMA_Init(DMA2_Stream0, &DMA_InitStructure);
 
  /* Enable DMA Stream Transfer Complete interrupt */
  DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);
 
  /* DMA2_Stream0 enable */
  DMA_Cmd(DMA2_Stream0, ENABLE);
}
 
/**************************************************************************************/
 
void NVIC_Configuration(void)
{
  NVIC_InitTypeDef NVIC_InitStructure;
 
  /* Enable the DMA Stream IRQ Channel */
  NVIC_InitStructure.NVIC_IRQChannel = DMA2_Stream0_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);
}
 
/**************************************************************************************/
 
void DMA2_Stream0_IRQHandler(void)
{
  /* Test on DMA Stream Transfer Complete interrupt */
  if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0))
  {
    /* Clear DMA Stream Transfer Complete interrupt pending bit */
    DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);
 
    /* Toggle LED3: End of Transfer */
    STM_EVAL_LEDToggle(LED3);
 
    // Add code here to process buffer
  }
}
 
/**************************************************************************************/
 
int main(void)
{
    RCC_Configuration();
 
  NVIC_Configuration();
 
  DMA_Configuration();
 
  ADC_Configuration();
 
  STM_EVAL_LEDInit(LED3); /* Configure LEDs to monitor program status */
 
  STM_EVAL_LEDOn(LED3); /* Turn LED3 on */
 
  /* Start ADC1 Software Conversion */
  ADC_SoftwareStartConv(ADC1);
 
  while(1); // Don't want to exit
}
 
/**************************************************************************************/
 
#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *   where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t* file, uint32_t line)
{
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
 
  /* Infinite loop */
  while (1)
  {
  }
}
#endif
 
/**************************************************************************************/


Tags: not that complicated
Share Post
Edited: 4/2/2015 10:58 AM
cihan.ahmet
  Posts : 12
Thank you for your answer Clive, but still I have the same problem. I read different values for each restart and these values remain unchanged.. Here's my code;

void ADC_init(void){ /* Define ADC init structures */
    ADC_InitTypeDef       ADC_InitStructure;
    ADC_CommonInitTypeDef ADC_CommonInitStructure;
    DMA_InitTypeDef DMA_InitStructure;


     DMA_InitStructure.DMA_Channel = DMA_Channel_0;
     DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&ADCConvertedValues[0];
     DMA_InitStructure.DMA_PeripheralBaseAddr = ((uint32_t)0x4001204C);//(uint32_t)&ADC1->DR;
     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
     DMA_InitStructure.DMA_BufferSize = BUFFERSIZE; // Count of 16-bit words
     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
     DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
     DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
     DMA_InitStructure.DMA_Priority = DMA_Priority_High;
     DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
     DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull;
     DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
     DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
     DMA_Init(DMA2_Stream0, &DMA_InitStructure);


     /* Enable DMA Stream Transfer Complete interrupt */
     DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE);


     /* DMA2_Stream0 enable */
     DMA_Cmd(DMA2_Stream0, ENABLE);


     /* ADC Common Init */
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 = ENABLE; // 2 Channels
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; // Continuous Conversions
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T2_TRGO; // Ignored
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
ADC_InitStructure.ADC_NbrOfConversion = 2;
ADC_Init(ADC1, &ADC_InitStructure);

/* ADC1 regular channel configuration */
ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 1, ADC_SampleTime_480Cycles); // TEMP 16 on 40x/41x, 18 on 42x/43x
ADC_RegularChannelConfig(ADC1, ADC_Channel_17, 2, ADC_SampleTime_480Cycles); // VREFINT
//ADC_TempSensorVrefintCmd(ENABLE);
/* Enable DMA request after last transfer (Single-ADC mode) */
ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE);

/* Enable ADC1 DMA */
ADC_DMACmd(ADC1, ENABLE);

/* Enable ADC1 */
ADC_Cmd(ADC1, ENABLE);

}
void DMA2_Stream0_IRQHandler(void)
{
  /* Test on DMA Stream Transfer Complete interrupt */
  if(DMA_GetITStatus(DMA2_Stream0, DMA_IT_TCIF0))
  {
    /* Clear DMA Stream Transfer Complete interrupt pending bit */
    DMA_ClearITPendingBit(DMA2_Stream0, DMA_IT_TCIF0);


    /* Toggle LED3: End of Transfer */
toggle_leds(LED_2);
AD_value = ADCConvertedValues[0];
    // Add code here to process buffer
  }
}

main;

int main(void){
u32 i;

SystemInit();

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA|RCC_AHB1Periph_GPIOB|RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_DMA2, ENABLE);
//RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1|RCC_APB1Periph_USART2|RCC_APB1Periph_TIM3, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_ADC1, ENABLE);
for(i = 0 ; i < 1000000; i++); // a delay, may be useful
NVIC_Config();
LEDS_init();
OUTPUTS_init();
INPUTS_init();
FPGA_pins_init();
//USART2_init(115200);
//i2c_init();
ADC_init();
for(i = 0 ; i < 1000000; i++);


DAC8411_init();
TIM3_init();
SysTick_Config(SystemCoreClock / 1000);
initilize_variables();
bessel_filter_coeffs();
butterworth_filter_coeffs();
calibrated_filter_type = NO_FILTER;
raw_data_filter_type = NO_FILTER;


ADC_SoftwareStartConv(ADC1);


while(1){
......... lots of things
}
}


Share Post
Posted: 4/2/2015 5:07 PM
peacock.jack.003
  Posts : 55
If your value isn't changing most likely you are getting an error in either the ADC or DMA.  Check your ADC status, especially the EOC to see if you started a conversion, and the overflow flag to check for dropped data.  You won't see data change if you aren't converting.

On the DMA side check the TE and FE flags for errors.  Your data won't change if DMA is stopping.
  Jack Peacock

Tags: ADC DMA
Share Post

Browse Private Forums

NOTE: these forums are exclusive for users of this Extranet!)