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

 

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

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

*