-1

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;
reip
  • 11
  • 4

1 Answers1

0

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.

HelpingHand
  • 1,294
  • 11
  • 27
  • You are absolutely right, it put the triggering if-statement into the while loop: – reip Apr 27 '20 at 12:16
  • I wanted to add that I left only ´adcVal = HAL_ADC_GetValue(&hadc1);´ to the conversion complete callback, and this way it works. I just wonder that when ´HAL_ADC_Start_IT (&hadc1);´ comes right after ´if (!HAL_GPIO_ReadPin(GPIOF, GPIO_PIN_2))´ then an old conversion value is used first when the code after that if-statement is executed. If the button is pushed after the input voltage is changed so that the other LED should blink, then before it starts blinking, first the previous LED lights up for one blink... But shouldn't the ADC start after the first if() and also bring a new value? – reip Apr 27 '20 at 12:41