АЦП в режиме опроса (polling)

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

Напишем программу, которая будет анализировать сигнал на контакте PA0, и в зависимости от полученной величины зажигать или гасить штатный светодиод на контакте PC13.

Настройка АЦП

Нажимаем правую кнопку мыши на PA0 и выбираем пункт ADC1_IN0. Выбор этого пункта означает, что мы подключаем данный контакт к каналу №0 аппаратного АЦП №1. Теперь к PA0 можно подключить нужный нам прибор с аналоговым выходом, с которого мы в дальнейшем будем снимать данные.

STM32 АЦП и DMA. Настройка АЦП

Индикатор

Настроим штатный индикатор, который на отладочных платах обычно привязан к контакту PC13.

Жмём на контакт PC13 и выбираем режим GPIO_Output. Теперь этот контакт будет работать на выход, и мы сможем выставлять на нем логический уровень. Затем в левом меню открываем раздел GPIO, прописываем этому контакту псевдоним LED в поле User Label.

STM32 настройка светодиода PC13

Программа

После генерации шаблона, приступаем к написанию своего программного кода, строго в выделенных для этого разделах.

Будем зажигать светодиод при достижении значения 2100 на потенциометре, и выключать его при снижении до 2000. Разница в 100 единиц сделана для создания гистерезиса — чтобы исключить мерцание светодиода в пограничном состоянии потенциометра.

В начале программы запускаем процедуру самокалибровки АЦП.

/* USER CODE BEGIN 2 */
HAL_ADCEx_Calibration_Start(&hadc1); // калибровка АЦП

&hadc1 — это указатель на АЦП №1 (для второго будет &adc2).

В тело суперцикла добавим код, который будет:

  • включать АЦП;
  • запускать процедуру опроса каналов, в нашем случае канал один;
  • получать от АЦП результат анализа;
  • менять состояние светодиода в зависимости от значения на АЦП;
  • выключать АЦП.
  /* USER CODE BEGIN WHILE */

while (1)
{
HAL_ADC_Start(&hadc1); // запуск АЦП
HAL_ADC_PollForConversion( &hadc1, 100 ); // преобразование величин

uint16_t pot_adc = HAL_ADC_GetValue( &hadc1 ); // получить значение
if( pot_adc > 2100 ){
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET);
} else
if( pot_adc < 2000 ){
HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
}

HAL_ADC_Stop( &hadc1 ); // остановка АЦП

HAL_Delay( 10 ); // пауза 10мс

/* USER CODE END WHILE */

Второй аргумент в функции HAL_ADC_PollForConversion задаёт максимальное время для опроса каналов, в миллисекундах.

Поскольку АЦП у нас 12 разрядное, то для для хранения результата достаточно будет типа данных uin16_t.

Загружаем программу на отладочную плату и пробуем крутить потенциометр. Примерно на середине хода ручки светодиод будет включаться/выключаться.


Изменено: