2013-11-14 05:57 AM
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 #adc2013-11-14 06:35 AM
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.2013-11-14 06:56 AM
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.2013-11-14 09:14 AM
Changing by how much?
I'd be using a sample time significantly longer than 3-cycles, tends to be pretty noisy2013-11-14 10:07 AM
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.