STM Урок 17. HAL. ADC. Regular Channel. Interrupt



Урок 17

HAL. ADC. Regular Channel. Interrupt

 

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

Запускаем Cube, проверим на всякий случай прерывания, что они включены.

Генерируем и запускаем наш проект. Добавим также в него lcd.c. Соберем его.

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

        LCD_String(str);

        HAL_ADC_Start_IT(&hadc1);

  /* USER CODE END 2 */

А в бесконечном цикле пока можно всё закомментировать.

 

 

В начале главного модуля добавим переменную для хранения результата преобразования

ADC_HandleTypeDef hadc1;

 

/* USER CODE BEGIN PV */

/* Private variables ———————————————————*/

        uint16_t ADC_Data = 0;

/* USER CODE END PV */

Ближе к концу главного модуля добавим функцию

/* USER CODE BEGIN 4 */

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc1)

{

  ADC_Data = HAL_ADC_GetValue(hadc1);

}

/* USER CODE END 4 */

Можно конечно это воткнуть и в обработчик прерывания, но лучше этого не делать. Разработчики библиотеки советуют нам именно такую функцию. Она выполняется не при любом прерывании, а именно тогда, когда закончились преобразования.

Также нужно повторно в этой же функции запустить преобразование, у нас же не автоматический режим.

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc1)

{

          ADC_Data = HAL_ADC_GetValue(hadc1);

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

}

 

 

Ну и давайте ещё отобразим опять же наши данные на дисплее

  while (1)

  {

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

                sprintf(str,»%04d»,ADC_Data);//преобразуем результат в строку

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

                LCD_String(str);

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

  /* USER CODE END WHILE */

Соберем проект, прошьем контроллер и посмотрим.

У нас преобразования происходят только 1 раз, при старте либо вообще не работает ничего.

Может показаться, что мы что-то не доделали, но дело не в этом. В обработчике прерывания от АЦП вызывается функция

  /* USER CODE END ADC_IRQn 0 */

  HAL_ADC_IRQHandler(&hadc1);

  /* USER CODE BEGIN ADC_IRQn 1 */

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

Давайте настроим делитель в кубе. Вместо 2 поставим 8.

Соберем проект, прошьем контроллер и видим, что всё заработало. Давайте теперь немного убавим делитель.

Сделаем 4.

Опять все соберем и прошьем

Вроде тоже работает. Таким образом, нужно просто поиграть с частотой и понять, какая будет работать.

Теперь давайте превратим показания на дисплее в удобочитаемый вид по подобию как на прошлом занятии

  while (1)

  {

        u=((float)ADC_Data)*3/4096;

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

Вот теперь дело другое.

 

Зайдём в Configuration и включим там Continuous Conversion Mode

Опять сгенерируем проект и соберем код

Теперь строчку в обработчике надо удалить

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc1)

{

          ADC_Data = HAL_ADC_GetValue(hadc1);

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

}

Соберем, Прошьем и посмотрим

Все работает.

 

 

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

 

Исходный код

 

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

STM32F4-DISCOVERY

Дисплей LCD 20×4

 

 

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

 

STM32 HAL. ADC. Regular Channel. Interrupt

 

3 комментария на “STM Урок 17. HAL. ADC. Regular Channel. Interrupt
  1. Андрей:

    Здравствуйте. Пишу сказать большое спасибо за эти уроки, очень полезные и доступные. Увы, на моей stm32f103 код не хочет работать, выводит число 0.38, а если включить Continuous Conversion Mode, то выводит 0.56, эти числа не меняются никак. Уже поигрался с делителем частоты для АЦП, ни в какую. Прошу у Вас совет, заранее спасибо

    • Андрей:

      Ответ вроде как сам вырисовался) Вообщем, если у кого будет такая проблема на stm32f103c8t6, то у меня при системном такте 72Мгц, таком же такте на самой шине APB2 и делителе АЦП 6 (получается на АЦП 12Мгц) — все работает. Пока бьюсь со связкой АЦП и ДМА, но это уже другая история. Короче говоря, приколы с тактированием на 103й плате еще похуже, чем на 407й)

      • Александр:

        Конечно, это можно назвать приколом, но это задокументированный прикол. В даташите написано, что максимальная частота, на которой может работать АЦП — 14 МГц. Её можно достичь при делителе АЦП 4 и тактовой частоте 56 МГц.

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

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

*