cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 - Discovery ADC Example Problem

anil_kirkil
Associate II
Posted on November 14, 2013 at 14:57

Hello everyone,

I've been trying to discover the STM32F4-Discovery features and peripheral examples of its firmware package lately. I'm having trouble with the ADC-DMA example. Actually, I wanted to observe only continuous mode of ADC is working. So, I removed codes related to DMA. But, when I run the program, it stucks in the HardFault_Handler function. I don't know why this happens. Can anyone tell me what is wrong with this code? Here is my code below.

&sharpinclude ''stm32f4_discovery.h''

&sharpinclude <stdio.h>

//&sharpdefine ADC3_DR_ADDRESS     ((uint32_t)0x4001224C)

__IO uint16_t ADC3ConvertedValue = 0;

__IO uint32_t ADC3ConvertedVoltage = 0;

void ADC3_Config(void);

int main(void)

{

  ADC3_Config();

  /* Start ADC3 Software Conversion */ 

  ADC_SoftwareStartConv(ADC3);

while(ADC_GetFlagStatus(ADC3, ADC_FLAG_EOC) == RESET);

  while (1)

  {

ADC3ConvertedValue = ADC_GetConversionValue(ADC3);

ADC3ConvertedVoltage = ADC3ConvertedValue *3.3/0xFFF;

if(ADC3ConvertedVoltage >=0 && ADC3ConvertedVoltage < 1)

{

GPIO_ResetBits(GPIOD, GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);

GPIO_SetBits(GPIOD, GPIO_Pin_12);

}

else if(ADC3ConvertedVoltage >=1 && ADC3ConvertedVoltage < 1.8)

{

GPIO_ResetBits(GPIOD, GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);

GPIO_SetBits(GPIOD, GPIO_Pin_13);

}

else if(ADC3ConvertedVoltage >=1.8 && ADC3ConvertedVoltage < 2.5)

{

GPIO_ResetBits(GPIOD, GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);

GPIO_SetBits(GPIOD, GPIO_Pin_14);

}

if(ADC3ConvertedVoltage >=2.5 && ADC3ConvertedVoltage < 3.3)

{

GPIO_ResetBits(GPIOD, GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);

GPIO_SetBits(GPIOD, GPIO_Pin_15);

}

else

{

GPIO_ResetBits(GPIOD, GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);

GPIO_SetBits(GPIOD, GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);

}

  }

}

void ADC3_Config(void)

{

  ADC_InitTypeDef       ADC_InitStructure;

  ADC_CommonInitTypeDef ADC_CommonInitStructure;

  GPIO_InitTypeDef      GPIO_InitStructure;

  /* Enable ADC3 and GPIO clocks ****************************************/

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2 | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD, ENABLE);

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);

  /* Configure ADC3 Channel12 pin as analog input ******************************/

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;

  GPIO_Init(GPIOC, &GPIO_InitStructure);

/* Configure PD12, PD13, PD14 and PD15 in output pushpull mode ************* */

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

  GPIO_Init(GPIOD, &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);

  /* ADC3 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_DataAlign = ADC_DataAlign_Right;

  ADC_InitStructure.ADC_NbrOfConversion = 1;

  ADC_Init(ADC3, &ADC_InitStructure);

  /* ADC3 regular channel12 configuration *************************************/

  ADC_RegularChannelConfig(ADC3, ADC_Channel_12, 1, ADC_SampleTime_3Cycles);

  /* Enable ADC3 */

  ADC_Cmd(ADC3, ENABLE);

}

#adc-example #adc
4 REPLIES 4
Posted on November 14, 2013 at 15:35

Not sure of your tool chain, but I'm going to guess you have a problem with floating point math, and settings related to the FPU and use of FPU instructions.

Be aware that an int32 will not hold a decimal value.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
anil_kirkil
Associate II
Posted on November 14, 2013 at 15:56

Adding this line of code [*((int*)0xE000ED88))|=0x0F00000;] in SystemInit() to activate FPU unit solved the HardFault_Handler problem. Also, I changed the ADC3ConvertedVoltage variable type as float. But, another problem is popped up. I'm using Keil uvision4 by the way. In the debug screen, i added to ADC3ConvertedValue and ADC3ConvertedVoltage to watch tab. When I run the program, the ADC3ConvertedValue is changing irrelatively to applied voltage. So, how can i overcome this problem?

Thank you.

Posted on November 14, 2013 at 18:14

Changing by how much?

I'd be using a sample time significantly longer than 3-cycles, tends to be pretty noisy
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
anil_kirkil
Associate II
Posted on November 14, 2013 at 19:07

I agree with you about sample time should be longer but, this changes are senseless. Although, i don't apply any voltage, the register value can be 0xFFF which its maximum. Generally, this value is taking any values between 0-0xFFF regardless input voltage. Something is really wrong and I don't get it.