STM Урок 19. HAL. ADC Injected Channel



Урок 19

HAL. ADC Injected Channel

 

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

Запускаем Cube. Заходим в Configuration. Отключим там везде DMA.

Также отключим прерывания от АЦП, если таковые включены. Они нам пока не нужны. Это тема следующего урока.

Настраиваем там вот так

 

 

image00

image01

 

Генерируем и запускаем проект.

 

 

Как всегда настроим программатор и подключим файл lcd.h

Удалим все счётчики cnt отовсюду, включая SysTick

 

volatile uint32_t cnt1, cnt2;

/* USER CODE END PV */

/* USER CODE BEGIN 2 */

        cnt1=0;cnt2=0;

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

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

        LCD_String(str);

        sprintf(str,»%10u»,cnt2);

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

        LCD_String(str);

        cnt1++;

//        ADC_Data[0] = HAL_ADC_GetValue(hadc1);

/* USER CODE BEGIN 0 */

extern volatile uint32_t cnt2;

/* USER CODE END 0 */

void SysTick_Handler(void)

{

  /* USER CODE BEGIN SysTick_IRQn 0 */

        cnt2++;

  /* USER CODE END SysTick_IRQn 0 */

 

 

Уберем также старт АЦП с DMA

 

        LCD_Clear();

        HAL_ADC_Start_DMA(&hadc1,(uint32_t*) &ADC_Data,4);

  /* USER CODE END 2 */

 

Уберем также цикл for из бесконечного цикла, содержимое цикла оставим

Все инжектоные функции теперь не на 108 странице, а на 126

Напишем в бесконечный цикл

 

  while (1)

  {

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

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

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

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

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

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

 

Добавим в main() еще переменную для строки. А существующую немного увеличим. Счётчик-переменную i можно убрать

 

  /* USER CODE BEGIN 1 */

        float u[4];

        char str[21];

        char str1[9];

  /* USER CODE END 1 */

 

Допишем в бесконечный цикл следующий код

 

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

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

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

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

                strcat(str,str1);

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

                strcat(str,str1);

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

                strcat(str,str1);

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

                LCD_String(str);

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

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

  /* USER CODE END WHILE */

 

Но чтобы нам использовать функцию strcat, подключим библиотеку

 

/* USER CODE BEGIN Includes */

#include «main.h»

#include <string.h><string.h»></string.h»>

/* USER CODE END Includes */

 

 

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

 

Исходный код

 

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

STM32F4-DISCOVERY

Дисплей LCD 20×4

 

 

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

 

STM32 HAL. ADC Injected Channel

 

12 комментариев на “STM Урок 19. HAL. ADC Injected Channel
  1. nomadenvoy:

    Владимир, извините!

    Во вложении не тот пример у ВАС, проверьте пожалуйста исходный код!

  2. nomadenvoy:

    Да! И ещё во многих случаях SWD выключен, народ будет мучаться как я…

    • admin:

      А я его принудительно и не включаю. Вроде всё прошивается и отлаживаетя. Вы имеете в виду в Cube в разделе SYS выбирать Serial Wire?

  3. nomadenvoy:

    Да, именно это. Как то нарвался на то что камень не откликался после прошивки, вот и решил поделиться.

    • admin:

      Спасибо!

      У меня вообще обычно всегда откликается, но учту. Для Workbench обычно всегда включаю, а для Keil как-то нет.

    • boichonoc:

      Я сталкивался с таким на F103c8t6, если не включить его, то МК будет шиться сначало по SWD, но потом будет ждать и шиться только по JTAG. В таком случае его нужно вводить в BOOT mode и затерать. Хорошо, что это можно сделать через SWD.

  4. Евгений:

    Добрый вечер.
    У меня отладочная плата Open746I-C.
    Все Ваши уроки по работе с ADC работают, кроме двух:
    STM Урок 20. HAL. ADC. Injected Channel.
    STM Урок 20. HAL. ADC. Injected Channel. Interrupt.
    ADC выдаёт не верные данные. Не могу понять в чём дело.

    • Периферия на разных версиях контроллеров может различаться, поэтому изучите внимательно ref manual на свой контроллер, а затем уже HAL and LL User Manual.

      • boichonoc:

        Хочу заметить, что вы используете HAL_ADC_PollForConversion(), что не есть корректно. Наверно правильней будет HAL_ADCEx_InjectedPollForConversion(). Хотя оба вроде работают.
        Столкнулся вот с другим. Использую 2 канала, PA2, PA3. Соответственно 2 банка. Делаю как у Вас в уроке, и оно как бы работает, но как бы и нет. РА2 канал выводит данные, но не корректно, а РА3 вообще нули.
        Работаю на дискаверки STM32L100rct6.

      • boichonoc:

        В той же документации к STM32L1_HAL_Driver, пишут мол функция по завершению преобразования не очищает флаг, и рекомендуют очищать его. 101я страница мануала. Если есть какие-то мысли по этому поводу, готов выслушать =)

  5. boichonoc:

    Когда генерируете проект в кубе, проверяйте функцию MX_ADC_Init(), что там куб сгенерировал.
    У меня к примеру не было вот такой строчки. Хотя в самом кубе количество диалогов АЦП выставлено 2. sConfigInjected.InjectedNbrOfConversion = 2;

    Еще момент. Когда параллельно еще работаете с таймерами то, повторно вызывайте MX_ADC_Init(). Пока еще не нашел какой именно флаг он не включает, но в дебаге заметил, что данные в последнем бите этой функции, отличается.

    Тестировал все на STM32L100RCT6, плата Discovery.

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

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

*