Получение показаний от АЦП STM32 при нажатии кнопки

Используя CubeIDE и плату STM32F4, я пытаюсь запустить преобразование АЦП и заставить один из двух светодиодов мигать в зависимости от значения АЦП - если значение меньше определенного предела, тогда один светодиод должен мигать, а другой оставаться выключенным, но если значение АЦП превышает установленный мной предел, другой светодиод должен мигать. Это должно произойти, когда я нажимаю кнопку, и мигание должно продолжаться, пока кнопка не будет нажата.

Итак, у меня есть 4 контакта - два (G2 и D8) выхода GPIO для мигающих светодиодов, один контакт (A0) - аналоговый вход, а один контакт (F2) - вход GPIO для кнопки. Он настроен как подтягивающий и подключается к GND с помощью кнопки.

Соответствующий код

/* 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 */

Я ничего не добавлял в цикл while(1).

При компиляции я не получаю ошибок или предупреждений, когда я запускаю код, тогда вывод F2 устанавливается на ВЫСОКОЕ (до 3 В, когда я измеряю его с помощью тестера, и обнуляется при нажатии кнопки), но светодиоды не реагируют вообще, хотя на A0 подается напряжение. Я подозреваю, что неправильно использую АЦП. Я хочу, чтобы АЦП оставался в режиме ожидания и читал и преобразовывал значение, когда вывод, подключенный к кнопке, становится низким.

Когда я помещал строки, связанные с GPIO, в цикл while(1), он тоже не работал. Где-то это может быть простая ошибка, но может ли кто-нибудь сказать мне, где она?

Я нашел такие строки из автоматически сгенерированного кода

/*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);

но когда я их закомментировал, это не помогло. Еще добавляю настройки АЦП, может проблема в этом:

  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 ответ

Проблемы в том, что

  • Вы звоните HAL_Delay() в контексте исполнения HAL_ADC_ConvCpltCallback(), который запускается обработчиком прерывания. Это означает, что вы блокируете выполнение основного цикла и прерываний (с приоритетом не выше, чем это прерывание АЦП) на полсекунды!

  • Насколько я понимаю, АЦП находится в однократном режиме (не в режиме сканирования или непрерывного режима). Если обнаружено, что GPIO F2 установлен в обратном вызове завершения преобразования, вызовHAL_ADC_Start_IT() не происходит, и АЦП стоит на месте.

Другие вопросы по тегам