STM Урок 21. HAL. ADC. Regular Channel. Trigger



Урок 21

HAL. ADC. Regular Channel. Trigger

 

Проект создаём из ADC_REGULAR, называем его ADC_REGULAR_TRIGGER.

Запускаем Cube. Добавим 2 таймер, включив в нем внутреннее тактирование. Включим также PD12 на выход. Затем зайдём в Clock Configuration и посмотрим частоту на этот таймер (стр 67 Ref Manual). Она 21000, поэтому заходим в закладку Configuration и включаем там делитель 20999 и период 3000, а в последней строке Update Event, таким образом мы настроили таймер на период 3 секунды, также необходимо включить у таймера прерывания. Заходим в АЦП, выключим там прерывания. А в 1 закладке включим триггер

 

image00

 

Генерируем проект, открываем его, настроим программатор, подключим файл lcd.c и соберем код.

 

 

Убавим задержки, очистим дисплей, стартуем таймер и АЦП в главной функции.

 

        LCD_String(str);

        HAL_Delay(500);

        LCD_Clear();

        LCD_SetPos(4, 0);

        LCD_SendChar('s');

        LCD_SetPos(8, 1);

        LCD_SendChar('t');

        LCD_SetPos(12, 2);

        LCD_SendChar('m');

        LCD_SetPos(16, 3);

        LCD_SendChar('3');

        LCD_SendChar('2');

        HAL_Delay(500);

        LCD_Clear();

        HAL_TIM_Base_Start_IT(&htim2);

        HAL_ADC_Start(&hadc1);

 

 

Добавим функцию для обработки прерывания таймеру по флагу совпадения (стр 842 мануала библиотеки HAL) и будем там менять состояние светодиода

 

/* USER CODE BEGIN 4 */

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim2)

{

  HAL_GPIO_TogglePin(GPIOD, GPIO_PIN_12);

}

/* USER CODE END 4 */

 

Теперь возьмём данные из АЦП и покажем их на дисплее. Ничего для этого особенного делать не нужно. Нужно только закомментировать там ненужный код и убавить немного задержку.

 

  while (1)

  {

//                HAL_ADC_Start(&hadc1);//запустим аналогово-цифровое преобразование

//                HAL_ADC_PollForConversion(&hadc1,100);//дождёмся окончания преобразований

                        u=((float)HAL_ADC_GetValue(&hadc1))*3/4096;//занесём результат преобразований в переменную

//                HAL_ADC_Stop(&hadc1);//остановим преобразования

                sprintf(str,»%.2fv»,u);//преобразуем результат в строку

                LCD_SetPos(0,3);//покажем результат на ЖКИ-дисплее

                LCD_String(str);

                HAL_Delay(100);//задержка перед следующим циклом

  /* USER CODE END WHILE */

 

Компилируем. Прошиваем. Смотрим результаты.

 

 

Предыдущий урок Программирование МК STM32 Следующий урок

 

Исходный код

 

Отладочную плату и дисплей можно приобрести здесь:

STM32F4-DISCOVERY

Дисплей LCD 20×4

 

 

Смотреть ВИДЕОУРОК

 

STM32 HAL. ADC. Regular Channel. Trigger

 

9 комментариев на “STM Урок 21. HAL. ADC. Regular Channel. Trigger
  1. Сергей:

    Здравствуйте. А Вы не пробовали с помощью триггера запускать АЦП в режиме DMA? Интересует, где именно необходимо задавать массив для сохранения значений через ПДП. В стандартном исполнении мы задаем массив при старте ПДП HAL_ADC_Start_DMA(), но т.к. у нас он запускается по триггеру, непонятно где указывать этот массив. Спасибо.

    • Я думаю, это вопрос не только ко мне. Здесь посетителей уже немало, я подсчитывал. Я лично, к сожалению не пробовал. Думаю, кто-то пробовал. И он непременно напишет.

      • Сергей:

        К сожалению, так и не удалось найти ответ на свой вопрос. А Вы не подскажите, как работает режим ПДП Circular, т.е. работа ПДП идет непрерывная или только как поступил какой-то запрос?

        Мне интересно, что будет больше нагружать процессор, если я по таймеру каждые 100мс буду через прерывание запускать АЦП с ПДП или по триггеру без прерываний буду запускать АЦП, но при этом ПДП будет в режме Circular?

        • Жаль.
          Если бы я точно знал ответ на вопрос, то ответил бы. давно не ковырялся с АЦП.

        • Андрей:

          Приветствую. Я пробовал через DMA. В основной программе после запуска таймера запускаем АЦП через DMA следующей командой:

          HAL_ADC_Start_DMA(&hadc1, (uint32_t*)buffer, 5);

          А сам массив uint16_t buffer[5] объявляем в начале основной программы main. В результате DMA считает 5 выборок данных из регистра DR ADC1 в наш массив после каждого преобразования.

          В режиме ПДП Circular ПДП переносит данные из периферии в память непрерывно, но по запросу. Соответственно запросы к DMA от АЦП тоже должны идти непрерывно, поэтому hadc1.Init.DMAContinuousRequests = ENABLE;

  2. Василий:

    Зачем нужен особый обработчик прерывания таймера? Почему нельзя использовать штатный TIM2_IRQHandler(void) в файле it.c?

    • Данный обработчик, который в файле, отреагирует сразу на все типы прерываний таймера, а библиотечный — только на одно, то, которое нам нужно.

  3. Кирилл:

    Также нужно, чтобы HCLK совпадала с частотой АЦП

  4. АЛЕКСАНДР:

    Здраствуйте, а вы пробывали запускать АЦП в режиме injected по таймеру, просто сейчас пробую поставил все режимы, однако, не идет и все.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*