cancel
Showing results for 
Search instead for 
Did you mean: 

ADC whit DMA. stm32f0

Nmo.1
Associate III

Hi every one.

I want to read the value of a potentiometer connected to the pinA1, and if the read value is more than 2000, one of the LEDs, otherwise the second LED, will be on.

Can anybody please help me? what is wrong with my code? I don't have too much experience and  I can't find problem.

#include "stm32f0xx.h"
#include "stm32f0xx_conf.h"
 
void Delay(__IO uint32_t nCount) {
  while(nCount--) {
  }
}
 
 
int main(int argc, char* argv[])
{
 
      //(#) ADC pins (pA1) configuration  --------------------------------------------------------------
    GPIO_InitTypeDef GPIO_InitStructure;
      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
      GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
      GPIO_Init(GPIOA, &GPIO_InitStructure);
 
//leds (pB0... pB3) configuration--------------------------------------------------------------
 
      GPIO_InitTypeDef  GPIO_LEDs;
                  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
                  GPIO_LEDs.GPIO_Pin = GPIO_Pin_0 |GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
                  GPIO_LEDs.GPIO_Mode = GPIO_Mode_OUT;
                  GPIO_LEDs.GPIO_OType = GPIO_OType_PP;
                  GPIO_LEDs.GPIO_Speed = GPIO_Speed_50MHz;
                  GPIO_LEDs.GPIO_PuPd = GPIO_PuPd_NOPULL;
                  GPIO_Init(GPIOB, &GPIO_LEDs);
//ADC-------------------------------------------------------------------------------------------
      ADC_InitTypeDef  ADC_InitStructure;
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
      ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
      ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
      ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
      ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
      ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;
      ADC_Init(ADC1, &ADC_InitStructure);
 
 
 
 
      ADC_GetCalibrationFactor(ADC1);
      ADC_Cmd(ADC1, ENABLE);
      while(ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN) == RESET);
      ADC_StartOfConversion(ADC1);
      uint16_t valueADC = ADC_GetConversionValue(ADC1);
      ADC_ChannelConfig(ADC1, ADC_Channel_1, ADC_SampleTime_1_5Cycles);
 
 
 
 
      //dma--------------------------------------------------------------------------------------
      DMA_InitTypeDef DMA_InitStructure;
      RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);
      DMA_DeInit(DMA1_Channel1);
      DMA_InitStructure.DMA_PeripheralBaseAddr= (uint32_t)&ADC1->DR;
      DMA_InitStructure.DMA_MemoryBaseAddr=(uint32_t)&valueADC;
      DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
      DMA_InitStructure.DMA_BufferSize = 2;
      DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
      DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
      DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
      DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
      DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
      DMA_InitStructure.DMA_Priority = DMA_Priority_High;
      DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
      DMA_Init(DMA1_Channel1, &DMA_InitStructure);
           DMA_Cmd(DMA1_Channel1, ENABLE);
        ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);
        ADC_DMACmd(ADC1, ENABLE);
 
 
 
    while (1)
    {
        if(valueADC<2000){
        GPIO_SetBits(GPIOB, GPIO_Pin_0);
        GPIO_ResetBits(GPIOB, GPIO_Pin_1);
        }
        else if(valueADC>2000){
            GPIO_SetBits(GPIOB, GPIO_Pin_1);
            GPIO_ResetBits(GPIOB, GPIO_Pin_0);
 
 
                }
}
}
 
 

5 REPLIES 5
berendi
Principal

Declare valueADC as volatile, otherwise the main loop may keep it in a register, and never pick up any changes at the memory location allocated to it.

All variables touched by DMA or interrupt handlers should be declared as volatile.

It is also good practice to declare those variables with static storage duration, i.e. never as local variables.

      volatile uint16_t valueADC = ADC_GetConversionValue(ADC1);
 

Thanks a lot. I did that, but it still doesn't work.

all LEDs are off. When I change the potentiometer, nothing happens.

berendi
Principal

What MCU is that?

Please post the contents of the DMA and ADC registers.

stm32f091

Do you mean ADC and DMA register map?0693W000001cIA4QAM.jpg0693W000001cI9vQAE.jpg

berendi
Principal

I mean the contents of the registers. Then it would be possible to check them against the pages preceding the ones that you have posted.