AnsweredAssumed Answered

[2 serious bugs in Cube library] ADC interrupt on STM32F302x8 is continously fired

Question asked by dolezal.ivan on Nov 26, 2014
Latest reply on Jan 16, 2015 by dolezal.ivan
I have transferred code for ADC using an interrupt from STM32F405 to STM32F302 but it seems that the interrupt is probably fired again immediatelly after return. I see it by a permanent lit of a LED and on scope at LED signal, too.
If I add
HAL_ADC_Start_IT(&hadc1);
at the end of the interrupt handler, the interrupt is not fired next.

How to clear an interrupt flag or so?

// main.h
 
#include "stm32f3xx_hal.h"
#include "stm32f302x8.h"
#include <stdbool.h>
 
// Macro -------------------------------------------------------------
#define  SETPIN(port,pin)  (port->BSRRL = pin)
#define  CLRPIN(port,pin)  (port->BSRRH = pin)
#define  TSTPIN(port,pin)  (port->IDR & pin)
#define  TGLPIN(port,pin)  (port->ODR ^= pin)
 
// Pin definitions
#define  LED_PIN    GPIO_PIN_15
#define  LED_PORT   GPIOA
 
// Function prototypes
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);

#include "main.h"
 
ADC_HandleTypeDef hadc1;
extern volatile bool adc1done;
 
//------------------------------------------------------------------------------
int main(void)
{
HAL_Init();
SystemClock_Config();
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_ADC1_Init();
 
SETPIN(LED_PORT,LED_PIN);
HAL_Delay(1000);
CLRPIN(LED_PORT,LED_PIN);
HAL_Delay(1000);
 
HAL_ADC_Start_IT(&hadc1);
 
while (1)
    {
    if (adc1done)
        {
        // process data
        adc1done = false;
        }
    }
}
 
//------------------------------------------------------------------------------
// System Clock Configuration
void SystemClock_Config(void)
{
  RCC_ClkInitTypeDef RCC_ClkInitStruct;
  RCC_OscInitTypeDef RCC_OscInitStruct;
 
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = 16;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL16;
  HAL_RCC_OscConfig(&RCC_OscInitStruct);
 
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK|RCC_CLOCKTYPE_PCLK1;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2);
 
  __SYSCFG_CLK_ENABLE();
}
 
//------------------------------------------------------------------------------
void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct;
 
  /* GPIO Ports Clock Enable */
  __GPIOA_CLK_ENABLE();
 
  /*Configure GPIO pin : PA15 for LED */
  GPIO_InitStruct.Pin = GPIO_PIN_15;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
 
//------------------------------------------------------------------------------
/* ADC1 init function */
void MX_ADC1_Init(void)
{
  ADC_ChannelConfTypeDef sConfig;
 
  //Common config
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCKPRESCALER_PCLK_DIV4;
  hadc1.Init.Resolution = ADC_RESOLUTION12b;
  hadc1.Init.ScanConvMode = DISABLE;
  hadc1.Init.ContinuousConvMode = ENABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.NbrOfDiscConversion = 1;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DMAContinuousRequests = DISABLE;
  hadc1.Init.EOCSelection = EOC_SINGLE_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.Overrun = OVR_DATA_OVERWRITTEN;
  HAL_ADC_Init(&hadc1);
 
  //Configure Regular Channel
  sConfig.Channel = ADC_CHANNEL_10; // OpAmp2 output
  sConfig.Rank = 1;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.SamplingTime = ADC_SAMPLETIME_601CYCLES_5;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  HAL_ADC_ConfigChannel(&hadc1, &sConfig);
}

#include "main.h"
 
extern ADC_HandleTypeDef hadc1;
volatile uint32_t ticks;
volatile bool adc1done;
 
//------------------------------------------------------------------------------
void SysTick_Handler(void)
{
  ticks++;
  HAL_IncTick();
}
 
//------------------------------------------------------------------------------
void ADC1_IRQHandler(void)
{
uint16_t data;
 
SETPIN(LED_PORT,LED_PIN);
 
NVIC_ClearPendingIRQ(ADC1_IRQn);
if (__HAL_ADC_GET_FLAG(&hadc1, ADC_FLAG_EOC))
    {
    data = ADC1->DR;
    // preprocess and store data
    adc1done = true;
    __HAL_ADC_CLEAR_FLAG(&hadc1, ADC_FLAG_EOC);
    }
 
CLRPIN(LED_PORT,LED_PIN);
}

// stm32f3xx_hal_msp.c
 
#include "stm32f3xx_hal.h"
 
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
  if(hadc->Instance==ADC1)
  {
    /* Peripheral clock enable */
    __ADC1_CLK_ENABLE();
    __HAL_RCC_ADC1_CONFIG(RCC_ADC1PLLCLK_DIV4);
 
    /* Peripheral interrupt init*/
    /* Sets the priority grouping field */
    HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
    HAL_NVIC_SetPriority(ADC1_IRQn, 2, 0);
    HAL_NVIC_EnableIRQ(ADC1_IRQn);
  }
}

Outcomes