STM Урок 189. LL. STM32F1. ADC. Regular Once. DMA



Продолжаем работать с АЦП (ADC) контроллера STM32F1 с использованием библиотеки LL. Также работать мы пока будем с регулярным каналом.

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

Также теперь мы будем использовать режим SCAN, который сканирует сразу несколько каналов в заданной последовательности. Где именно задаётся последовательность эта, мы уже говорили. Тем не менее мы в процедуре инициализации всё это увидим.

Схема наша немного теперь изменится, потому что использовать мы будем сразу 4 канала, поэтому мы повесим 4 резистора, регулируемые ножки которых мы соединим с входами наших каналов, получив тем самым 4 примитивных независимых регулируемых источника напряжения.

Я образно набросал фрагмент нашей схемы, выбрав не совсем такой, но подобный контроллер

 

 

А живьём наша схема имеет следующий вид:

 

 

Проект нашего урока мы сделаем из проекта урока 185 с именем LL_ADC_REG_ONCE и назовём его LL_ADC_REG_DMA.

Откроем наш проект в Cube MX и в свойствах ADC1 включим ещё 3 канала

 

 

Соответственно, у нас включатся также и 3 ножки порта

 

 

Включаем также последовательное преобразование. Только его просто так не включишь, для этого нужно выставить число преобразований — 4 и Scan Conversion Mode включится сам

 

 

Добавим времени на преобразование и выберем соответствующие каналы в последовательность

 

 

Включим также в соответствующей закладке настроек ADC1 канал DMA, в настройках которого оставляем всё по умолчанию

 

 

 

Также не забываем в настройках проекта задействовать на периферию DMA библиотеку LL

 

 

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

В файле main.c в функции MX_ADC1_Init посмотрим, какие изменения теперь у нас произошли теперь в инициализации ADC. Причём практически все настройки DMA у нас находятся здесь. В функции инициализации DMA у нас будут только включение тактирования периферии DMA, включение глобальных прерываний и настройка приоритета. Мало того, в функции инициализации ADC всё начинается с настройки именно DMA после настройки ножке, а уж затем настраивается непосредственно ADC.

Настройки DMA тут, в принципе, стандартные, мы не будем их подробно рассматривать

 

 

Причём настройки здесь не все, часть инициализации DMA (изменение приоритета, включение другого режима, настройку адресов) нам придётся проделать затем отдельно.

Далее нам интересна вот эта настройка, с помощью которой включится бит SCAN в регистре CR1

 

 

Изменения нас ждут также здесь

 

 

Здесь включатся биты L1 и L0 в регистре SQR1, которые будут означать, что сканироваться будут именно 4 канала ADC.

При помощи следующей строки кода инициализации у нас включится бит DMA в регистре CR2

 

 

А далее стандартная настройка четырёх каналов ADC

 

 

В результате данной настройки в битовых полях SMP3:SMP0 регистра SMPR2 выставятся биты 1.

Вот и все изменения.

Добавим глобальный 4-элементный массив для хранения данных, считанных из ADC, а также заведём флаг

 

 

 

В функции main() удалим, соответственно теперь вот эту локальную переменную

 

__IO uint16_t ADC_Data;

 

Другую переменную того же типа превратим теперь в массив, а в символьный массив добавим ещё элементов

 

__IO uint16_t ADC_mVolt[4];

char str01[20];

 

Удалим инициализацию переменной

 

ADC_Data = 0;

 

Внесём изменения в настройки DMA, а также настроим там адреса приёмника и источника

 

 

Здесь возникает резонный вопрос, а почему бы данные настройки сразу не включить в Cube? Оказывается, не получится. Ничего не будет работать и всё повиснет, видимо, здесь важен какой-то порядок и слишком высокий приоритет не даст настроить ADC.

Настроим также длину пакета DMA, включим локальные прерывания по событию окончания приёма-передачи и по событию ошибки и включим канал

 

 

Здесь немного допишем

 

LCD_String("Regular Once DMA");

 

Выведем ещё одну строку на дисплей

 

 

Добавим также функцию для обработки прерывания от DMA, в которой взведём наш пользовательский флаг

 

 

В файле stm32f1xx_it.c добавим прототип на данную функцию

 

 

Затем в обработчике прерываний от DMA DMA1_Channel1_IRQHandler в случае установленного флага окончания передачи вызовем нашу функцию, а в случае ошибки только сбросим флаг

 

 

Вернёмся в функцию main() файла main.c и в бесконечном цикле удалим ожидание и сброс флага окончания преобразования, а также считывание показаний

 

while (!LL_ADC_IsActiveFlag_EOS(ADC1)) {}

LL_ADC_ClearFlag_EOS(ADC1);

ADC_Data = LL_ADC_REG_ReadConversionData12(ADC1);

 

Дождёмся здесь установки своего флага и сбросим его

 

 

Удалим следующую строку

 

ADC_mVolt = __LL_ADC_CALC_DATA_TO_VOLTAGE((uint32_t)3275, ADC_Data, LL_ADC_RESOLUTION_12B);

 

Вместо этого считаем и преобразуем в вольты весь наш массив

 

 

Удалим следующую строку

 

sprintf(str01,«%.2fv»,(float)ADC_mVolt/1000.);

 

А вместо этого выведем на дисплей показатели всех наших каналов ADC

 

 

Проверим работу нашего кода на практической схеме, собрав код и прошив контроллер, а также изменяя положения движков наших подстроечных резисторов

 

 

 

Всё работает отлично!

Таким образом, на данном уроке мы научились пользоваться режимом последовательного преобразования каналов с применением периферии DMA, что позволило нам получить четыре независимых измерителя напряжения сигнала на одном ADC. Практически, можно и больше, но для урока, думаю, и этого достаточно.

Всем спасибо за внимание!

 

 

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

 

Исходный код

 

 

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

Программатор недорогой можно купить здесь ST-Link V2

Дисплей LCD 16×2

Переходник I2C to LCD можно приобрести здесьI2C to LCD1602 2004

Логический анализатор 16 каналов можно приобрести здесь

 

 

Смотреть ВИДЕОУРОК в RuTube (нажмите на картинку)

STM LL. STM32F1. ADC. Regular Once. DMA

 

Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)

STM LL. STM32F1. ADC. Regular Once. DMA

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

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

*