0
votes

Using CubeIDE and a STM32F4 board I'm trying to start an ADC conversion and make one of the two LEDs blink depending on the ADC value - if the value is smaller than a certain limit then one LED should blink and the other stay off, but if the ADC value is larger than the limit I set then the other LED should blink. That should happen when I push a button and blinking should continue until the button is pushed down.

So I have 4 pins - two (G2 and D8) GPIO outputs for blinking LEDs, one (A0) pin is analog input, and one pin (F2) GPIO input for the pushbutton. It is set as pull-up and it is connected to GND through a pushbutton.

The relevant code is

/* USER CODE BEGIN 0 */
uint32_t adcVal;
/* USER CODE END 0 */
  /* USER CODE BEGIN 2 */
//HAL_ADC_Start(&hadc1);
HAL_ADC_Start_IT (&hadc1);
  /* USER CODE END 2 */
/* USER CODE BEGIN 4 */
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
    adcVal = HAL_ADC_GetValue(&hadc1);
    if (!HAL_GPIO_ReadPin(GPIOF, GPIO_PIN_2)) {
        HAL_ADC_Start_IT (&hadc1);
        adcVal = HAL_ADC_GetValue(&hadc1);
        if (adcVal > 2000) {HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_8); HAL_GPIO_WritePin(GPIOG, GPIO_PIN_2, GPIO_PIN_RESET);}
        else {HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_2); HAL_GPIO_WritePin(GPIOD, GPIO_PIN_8, GPIO_PIN_RESET);}
        HAL_Delay(500);
        //HAL_ADC_Start_IT (&hadc1);
    }
    else {HAL_GPIO_WritePin(GPIOG, GPIO_PIN_2, GPIO_PIN_RESET); HAL_GPIO_WritePin(GPIOD, GPIO_PIN_8, GPIO_PIN_RESET);}
}
/* USER CODE END 4 */

I didn't put anything to the while(1) loop.

When compiling, I get no errors or warnings, when I run the code then the F2 pin is set HIGH (to 3V when I measure it with a tester, and goes to zero when the button is pushed) but the LEDs don't react at all, although voltage is applied to A0. I suspect I'm using the ADC in a wrong way. I want the ADC to stay idle and read and convert a value when the pin connected to the button goes low.

When I put the GPIO related rows to the while(1) loop it didn't work either. It might be a simple mistake somewhere but could anyone tell me where it is?

I found such lines from the auto generated code

/*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_8, GPIO_PIN_RESET);

  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOG, GPIO_PIN_2, GPIO_PIN_RESET);

but when I commented them out it didn't help. I also add the ADC settings, maybe the problem lies there:

  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.ScanConvMode = DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  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 = 1;
  hadc1.Init.DMAContinuousRequests = DISABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
1

1 Answers

0
votes

The problems are that

  • you are calling HAL_Delay() in the execution context of HAL_ADC_ConvCpltCallback(), which is run by the interrupt handler. That means you are blocking execution of the main loop and interrupts (at a priority not greater than that ADC interrupt) for half a second!

  • the ADC is in one-shot mode as far as I see (not scan or continuous mode). If the GPIO F2 is found to be set in the conversion-complete callback, the call to HAL_ADC_Start_IT() doesn't happen, and the ADC stands still.