We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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 MDK 4.6 32K Version (for the moment, then I will buy the complete license). Is there anybody willing to give me some advice? Here below you will find the code I use.
Thank you Antonio (Milano - Italy)
/* 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 ; } }
I take that back; I just noticed you're trying to read 2 values and put them at 2 memory locations :-) So I don't know what your problem is; I can't get the code to work. If you did, please let me know.
Cat
Thank you Cat. I just would like to convert countinously vbat and temp sensor using the DMA and to put the rough values in an array where I can pick and process them. Do not consider the measurement algorhytm, just the acquisition of the ADC converter value. A last question: To measure the temperature sensor signal, do I need to convert also the vrefint? Ciao Antonio
I don't know. I'm also just trying to read the temperature as my first time ADC read on the STM32F4 without any luck... I always get 1104.