AnsweredAssumed Answered

ADC & DMA programming issues on a STM32F4 Discovery Board

Question asked by pessina.antonio on Feb 1, 2013
Latest reply on Feb 1, 2013 by Clive One

Hello I’m new to the STM32 world and I’m making some experiments with the STM32F4 Discovery Board.
I would like to measure the VBAT and Temperature sensor signals using the ADC1 and the DMA, continously scanning both the channels.
The results I obtain are quite in the expected values …but I can see no significant changes for example varying the temperature applied to the microcontroller case.
I suspect that the ADC stops the conversions or the DMA stops the transferring.
I’m getting slightly insane with the ADC and DMA initialization.
I use the STM32F4xx DSP and Standard Peripherals Library and the Atollic TrueStudio 3.2 Lite Version.
Is there anybody willing to give me some advice?
Here below you will find the code I use.
Thank you
Antonio

/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define ADC1_DR_ADDRESS    ((uint32_t)0x4001204C)
#define V25                0.760
#define AVG_SLOPE          25.0
#define BUFFERLENGHT       2

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
__IO uint16_t ADC1ConvertedValue[BUFFERLENGHT];
__IO uint32_t ADC1ConvertedVoltage0 = 0;
__IO uint32_t ADC1ConvertedVoltage1 = 0;
__IO float Vsense = 0.0;
__IO float TCelsius = 0.0;
__IO float VBATVoltage = 0.0;

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

void ADC1_DMA_Config(void)
{
  ADC_InitTypeDef       ADC_InitStructure;
  ADC_CommonInitTypeDef ADC_CommonInitStructure;
  DMA_InitTypeDef       DMA_InitStructure;

  /* Enable ADC1, DMA2 clocks *************************************************/
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, 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)&ADC1ConvertedValue;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory;
  DMA_InitStructure.DMA_BufferSize = BUFFERLENGHT;
  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);
  DMA_Cmd(DMA2_Stream0, ENABLE);

  /* ADC Common Init **********************************************************/
  ADC_DeInit();
  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_20Cycles;
  ADC_CommonInit(&ADC_CommonInitStructure);

  /* ADC1 Init ****************************************************************/
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  ADC_InitStructure.ADC_ScanConvMode = ENABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
  ADC_InitStructure.ADC_ExternalTrigConv = 0;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfConversion = BUFFERLENGHT;
  ADC_Init(ADC1, &ADC_InitStructure);

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

  /* ADC1 regular channel18 (VBAT) & channel16 (TempSensor) configuration *****/
  ADC_RegularChannelConfig(ADC1, ADC_Channel_Vbat, 1, ADC_SampleTime_480Cycles);
  ADC_RegularChannelConfig(ADC1, ADC_Channel_TempSensor, 2, ADC_SampleTime_480Cycles);

  /* Enable VBAT channel: channel18 */
  ADC_VBATCmd(ENABLE);

  /* Enable TempSensor and Vrefint channels: channel16 and channel17 */
  ADC_TempSensorVrefintCmd(ENABLE);

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

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

int main(void)
{

  SystemCoreClockUpdate();                      /* Get Core Clock Frequency   */

  if (SysTick_Config(SystemCoreClock / 1000)) { /* SysTick 1 msec interrupts  */
    while (1);                                  /* Capture error              */
  }

  /* ADC1 Channel Temperature Sensor & VBAT measurement configuration */
  ADC1_DMA_Config();

 /* Start ADC1 Software Conversion */
  ADC_SoftwareStartConv(ADC1);

  while (1)
  {
     /* The VBAT pin is internally connected to a bridge divider by 2 */
     ADC1ConvertedVoltage1 = (uint32_t)(ADC1ConvertedValue[0] * 2) * 3300 / 0xfff;
     VBATVoltage = (float)(ADC1ConvertedVoltage1 / 1000.0);

     ADC1ConvertedVoltage0 = (uint32_t)(ADC1ConvertedValue[1] * 3300 / 0xfff);
     Vsense = (float)(ADC1ConvertedVoltage0 / 1000.0);
     TCelsius = ((Vsense - V25) / AVG_SLOPE) + 25.0 ;
  }
}

Attachments

Outcomes