1
votes

I'm trying to read ADC values from three different channels(right now, later it will be 6 channels, 3 on each ADC), and I would like to access my ADC buffer after some random time and send it forward using UART later on. Right now they are just connected to +3.3V with a trimpotentiometer inbetween, resulting in different voltages on all three pins, which means I should be able to read the ADCs wuite often? Anyway, to do this I'm using a STM32f303k8 board where I've set up ADC1 channel 2,4 & 11 to be used. I generated the code using STM32CubeMX, using HAL libraries, where I configured it to be using DMA in circular mode, scan conversion with continous conversion and different ranks. Upon startup(using breakpoints), I can see that the init-part of the code works fine. The ADC is initialized and the DMA is started, I even get values into my buffer from ADC1 with correct values, channel1 != channel2 != channel3. The problem is when proceeding, the process gets stuck in and infinite loop handler and does never reach my while(1) where I have some arbitrary statement. Code below.

I've been following different guides to see if maybe I've set it up wrong. One of them being https://tunizem.blogspot.com/2014/09/using-adc-with-dma-on-stm32.html?showComment=1562660027777#c1229743050555367742. I've tried changing the sampletime from 1.5 all the way up to 601.5 cycles, also tried changing EOCSelection from single to sequential.

ADC_HandleTypeDef hadc1;
DMA_HandleTypeDef hdma_adc1;

void MX_DMA_Init(void) 
{
  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();

  /* DMA interrupt init */
  /* DMA1_Channel1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
}


/* ADC1 init function */
void MX_ADC1_Init(void)
{
  ADC_MultiModeTypeDef multimode = {0};
  ADC_ChannelConfTypeDef sConfig = {0};

  /** Common config 
  */
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.ScanConvMode = ADC_SCAN_ENABLE;
  hadc1.Init.ContinuousConvMode = ENABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc1.Init.NbrOfConversion = 3;
  hadc1.Init.DMAContinuousRequests = ENABLE;//ENABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.Overrun = ADC_OVR_DATA_PRESERVED;//OVERWRITTEN;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure the ADC multi-mode 
  */
  multimode.Mode = ADC_MODE_INDEPENDENT;
  if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
  {
     Error_Handler();
  }
  /** Configure Regular Channel 
  */
  sConfig.Channel = ADC_CHANNEL_2;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SingleDiff = ADC_SINGLE_ENDED;
  sConfig.SamplingTime = ADC_SAMPLETIME_61CYCLES_5;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
     Error_Handler();
  }
  /** Configure Regular Channel 
  */
  sConfig.Channel = ADC_CHANNEL_4;
  sConfig.Rank = ADC_REGULAR_RANK_2;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
     Error_Handler();
  }
  /** Configure Regular Channel 
  */
  sConfig.Channel = ADC_CHANNEL_11;
  sConfig.Rank = ADC_REGULAR_RANK_3;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

}

 *
 *
 *


uint32_t adcValue1[60];

int main(void)
{
  /* MCU Configuration-----------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the 
Systick. */
  HAL_Init();

  /* Configure the system clock */
  SystemClock_Config();

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_ADC1_Init();
  //MX_ADC2_Init();
  MX_I2C1_Init();
  MX_USART1_UART_Init();
  MX_USART2_UART_Init();

  //Start ADC writing to DMA on scan complete
  if(HAL_ADC_Start_DMA(&hadc1, (uint32_t*)adcValue1, 120) != HAL_OK)
      return 0;


  uint32_t stopwatch = HAL_GetTick();

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while(1)
  {
      if(((uint32_t)HAL_GetTick() - stopwatch) > 49)
      {
          stopwatch = HAL_GetTick();
          HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_3);

          sprintf((char*)buffer, "(%d)\t ADC1, (%d)\t ADC2, (%d)\t ADC3", 
adcValue1[0],
                  adcValue1[1], adcValue1[2]);

      }
  }
  /* USER CODE END 3 */
}
}

I've got a breakpoint at "uint32_t stopwatch = HAL_GetTick();" where I can see that adcValue1 is reading values. Those are correct since there is 3.3V going into all three with the difference that the potentiometer is set to give out 2.2V at channel 2, i.e. it's lower than the other two. But this is the only time I can see a reading being done since it get stuck in the infinite loop after this.

enter code here

adcValue1   uint32_t [60]   0x20000220 <adcValue1>  
adcValue1[0]    uint32_t    2614    
adcValue1[1]    uint32_t    3638    
adcValue1[2]    uint32_t    3639    
adcValue1[3]    uint32_t    2612    
adcValue1[4]    uint32_t    3639    
adcValue1[5]    uint32_t    3637    
adcValue1[6]    uint32_t    2615    
adcValue1[7]    uint32_t    3642    
adcValue1[8]    uint32_t    3641    
adcValue1[9]    uint32_t    2616    
adcValue1[10]   uint32_t    3642    
adcValue1[11]   uint32_t    3638    
adcValue1[12]   uint32_t    2611    
adcValue1[13]   uint32_t    3637    
adcValue1[14]   uint32_t    3640    
adcValue1[15]   uint32_t    2614    
adcValue1[16]   uint32_t    3639    
adcValue1[17]   uint32_t    3639    
adcValue1[18]   uint32_t    2615    
adcValue1[19]   uint32_t    3643    


 * @brief  This is the code that gets called when the processor receives 
an
 *         unexpected interrupt.  This simply enters an infinite loop, 
preserving
 *         the system state for examination by a debugger.
 *
 * @param  None
 * @retval : None
 */

Default_Handler:
Infinite_Loop:  <--- STUCK HERE
    b   Infinite_Loop
    .size   Default_Handler, .-Default_Handler
1
Does this -keil.com/support/docs/3907.htm relate to your problem?Piotr Kamoda
Good input, removing HAL_GetTick() resulted in the process reaching the statement and toggle the GPIO, but then it goes back to the infinite loop. So I removed all the GetTick calls and changed the statement to if(adcValue[0] != 0), but still reaches Default_Handler after 1 loop..Mikebebe
When removing HAL_GetTick() and HAL_Delay(), I noticed that I can use "Step Into" to actually make it work. The process enters my statement, toggles the pin and then back to the statement again etc. But if I press "Resume" and just let the process proceed, it doesn't reach my statement ever again, it just gets stuck. Could there be a timing problem??Mikebebe

1 Answers

2
votes

Default_Handler is invoked when there is an interrupt for which no handler exists in the user code. All addresses in the interrupt vector table point to this code, when you don't supply a handler for that interrupt.

You can examine the VECTACTIVE bits in SCB->ICSR (see the STM32F4 programming manual) to find out which interrupt vector is missing, then provide a proper handler in your code.