judoka_acl
judoka_acl

Reputation: 385

Can't make the ADC of stm32f4-discovery work

I have a stm32f4-discovery with the stm32f407vg uC on it and I'm trying to program the ADC1 and measure some signals on the port PC5 with it. According to the documentation PC5 hangs on the ADC12_IN15 which I'm interpreting as ADC1 and ADC2 channel 15. I want to use the ADC_DMA example projects from the STD library STM32F4xx_DSP_StdPeriph_Lib_V1.6.1. The signal to the PC5 is provided by a signal generator and it's a square signal with frequency of 10 Hz, Vpp of 900 mV and offset of 2 V. Then I'm running the following code, which is successfully compiled and uploaded:

#define ADCx                     ADC1
#define ADC_CHANNEL              ADC_Channel_15
#define ADCx_CLK                 RCC_APB2Periph_ADC1
#define ADCx_CHANNEL_GPIO_CLK    RCC_AHB1Periph_GPIOC
#define GPIO_PIN                 GPIO_Pin_5
#define GPIO_PORT                GPIOC
#define DMA_CHANNELx             DMA_Channel_0
#define DMA_STREAMx              DMA2_Stream0
#define ADCx_DR_ADDRESS          ((uint32_t)0x4001224C)
static void ADC_Config(void);
/**
  * @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
       files (startup_stm32f40_41xxx.s/startup_stm32f427_437xx.s/startup_stm32f429_439xx.s)
       before to branch to application main. 
       To reconfigure the default setting of SystemInit() function, refer to
       system_stm32f4xx.c file
     */






  /* ADC configuration */
  ADC_Config();


  /* Start ADC Software Conversion */ 
  ADC_SoftwareStartConv(ADCx);


  while (1)
  {
    uwADCxConvertedVoltage = uhADCxConvertedValue *3300/0xFFF;
  }
}


/**
  * @brief  ADC3 channel07 with DMA configuration
  * @note   This function Configure the ADC peripheral  
            1) Enable peripheral clocks
            2) DMA2_Stream0 channel2 configuration
            3) Configure ADC Channel7 pin as analog input
            4) Configure ADC3 Channel7 
  * @param  None
  * @retval None
  */
static void ADC_Config(void)
{
  ADC_InitTypeDef       ADC_InitStructure;
  ADC_CommonInitTypeDef ADC_CommonInitStructure;
  DMA_InitTypeDef       DMA_InitStructure;
  GPIO_InitTypeDef      GPIO_InitStructure;


  /* Enable ADCx, DMA and GPIO clocks ****************************************/ 
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
  RCC_AHB1PeriphClockCmd(ADCx_CHANNEL_GPIO_CLK, ENABLE);  
  RCC_APB2PeriphClockCmd(ADCx_CLK, ENABLE);



  /* DMA2 Stream0 channel15 configuration **************************************/
  DMA_InitStructure.DMA_Channel = DMA_CHANNELx;  
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADCx_DR_ADDRESS;
  DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)&uhADCxConvertedValue;
  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(DMA_STREAMx, &DMA_InitStructure);
  DMA_Cmd(DMA_STREAMx, ENABLE);


  /* Configure ADC1 Channel15 pin as analog input ******************************/
  GPIO_InitStructure.GPIO_Pin = GPIO_PIN;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIO_PORT, &GPIO_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);


  /* ADC1 Init ****************************************************************/
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  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(ADCx, &ADC_InitStructure);


  /* ADC1 regular channel15 configuration **************************************/
  ADC_RegularChannelConfig(ADCx, ADC_CHANNEL, 1, ADC_SampleTime_3Cycles);


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


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


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

When I set a break point at the line

uwADCxConvertedVoltage = uhADCxConvertedValue *3300/0xFFF;

the variable is always zero. In addition I see no changes in the ADC1 registers or DMA2 registers during the operation and the SWSTART flag of the ADC_CR2 register is never set. The ADC_DR register is always 0 too. It seems like the function

ADC_SoftwareStartConv(ADCx);

fails to set the SWSTART flag and the conversion is never performed.

What could be wrong?

Upvotes: 0

Views: 1782

Answers (2)

mban
mban

Reputation: 442

It looks like you're configuring the wrong DMA stream/channel. You select ADC1 but configure DMA_Channel_1. You'll need to configure DMA_Channel_0 using DMA_Stream_0. The following tables shows the DMA stream/channel configuration.

enter image description here

enter image description here

Upvotes: 1

Stian Skjelstad
Stian Skjelstad

Reputation: 2335

You have selected to have an external trigger, ADC_ExternalTrigConv_T1_CC1, but I can not see Timer1 configured and running. Select no external trigger instead, and call ADC_SoftwareStartInjectedConvCmd I believe.

Upvotes: 0

Related Questions