STM Урок 213. LL. STM32F4. USART. DMA



Продолжаем нашу работу с шиной USART контроллера STM32F4.

В данном уроке мы поработаем с возможностью использования периферии DMA при передаче данных по интерфейсу USART.

С передачей данных по USART контроллера STM32F4 с применением DMA в мы уже знакомы из урока 15, правда использовалась там библиотека HAL. А при работе с контроллером STM32F1 мы уже очень глубоко изучили данный процесс и не только с применением LL, но и CMSIS, а, так как мы уже убедились в идентичности USART и DMA наших контроллеров, то нам будет несложно написать проект и данного урока, и, следовательно, и достигнуть его цели.

Работать мы будем в нашем уроке с той же отладочной платой — STM32F429I-Discovery.

Проект мы в качестве основы возьмём из прошлого урока с именем LL_USART и назовём его LL_USART_DMA.

Откроем наш проект в Cube MX и задействуем DMA-потоки для приёма и передачи данных в USART

 

 

 

В настройках SPI5 немного поднимем приоритет DMA

 

 

Сгенерируем код и откроем наш проект в Cube IDE, где перейдём в файл main.c и у глобального буфера приёма изменим тип, а также объявим заодно и буфер передачи

 

uint8_t rx_str[30], tx_str[30];

 

 

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

 

uint8_t fl_rx=0, fl_tx=0;

 

В функции main() мы можем уменьшить размер символьного массива

 

char str1[10];

 

Настроим каналы DMA, показав им также адреса наших буферов, аналогично как мы делали и для контроллера STM32F1 в подобном уроке и так же, как мы делали и для SPI

 

 

Из бесконечного цикла пока удалим весь пользовательский код, чтобы нам не показывало ошибку.

У пользовательского обработчика DMA от SPI немного изменим имя, так как у нас DMA2, а не DMA1, а то как-то нечестно

 

void DMA2_Stream4_TransferComplete(void)

 

Пользовательский обработчик событий от USART с именем USART1_RX_Callback удалим вместе с телом, мы теперь будем обрабатывать события от DMA, а не от интерфейса USART. Вместо него мы добавим обработчики для каналов DMA

 

 

В файле stm32f4xx_it.c изменим также имя прототипа обработчика от DMA, а прототип обработчика событий от USART удалим

 

void DMA2_Stream4_TransferComplete(void);

void USART1_RX_Callback(void);

 

Соответственно, добавим также прототипы на обработчики событий от каналов DMA, задействованных для USART

 

 

В штатном обработчике событий от USART USART1_IRQHandler мы удалим вызов нашего пользовательского обработчика, которого, соответственно, сейчас уже нет

 

USART1_RX_Callback();

 

 

А вместо этой строки мы просто считаем регистр данных

 

 

В обработчике DMA SPI с именем DMA2_Stream4_IRQHandler мы также изменим имя нашего пользовательского обработчика

 

DMA2_Stream4_TransferComplete();

 

В теле обработчика DMA2_Stream2_IRQHandler обработаем события, отследив флаги, вызвав при этом наш пользовательский обработчик либо сбросив флаг ошибки

 

 

Аналогично поступим и с функцией-обработчиком DMA2_Stream7_IRQHandler

 

 

Вернёмся в файл main.c и немного изменим код тела функции USART_TX, в котором для начала просто удалим весь код и затем занесём значение размера передаваемых данных в соответствующий регистр потока DMA

 

 

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

 

 

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

 

 

Теперь займёмся бесконечным циклом функции main(), в котором сначала попытаемся принять строку символов с заранее известным количеством байтов

 

 

Я часто в комментариях к моим урокам вижу вопросы, а как принять строку с неизвестным количеством байтов с использованием DMA по SPI, I2C и UART. Ответ очевиден. Нужно для начала источнику таких посылок посылать какой-то маркер, в котором будет информация о количестве информации, который мы должны будем принять стандартным способом без использования DMA, а затем уже с использованием DMA принять весь основной поток байтов.

Из пришедшей строки заберём подстроку с цифрой

 

 

Вычтем из числа 1024 число, преобразованное из нашей подстроки, и, преобразовав его обратно в строку, а также приклеив спереди другую строку, отправим всё это обратно в ПК

 

 

Запустим терминальную программу Terminal v1.9b, настроим на порт платы, также настроим скорость, собрав перед этим код в Cube IDE и прошив контроллер, затем соединимся с портом, запустим соответствующий скрипт, который будет передавать нужные строки в порт. Напомню код скрипта, хотя мы данный скрипт уже использовали в других уроках, но вдруг кто не видел данных уроков (хотя я не думаю, что уроки смотрятся не сначала, а избирательно, тогда просто смысл теряется)

 

 

Если мы всё сделали правильно, то мы должны в окне терминальной программы увидеть строки ответных пакетов от платы

 

 

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

Итак, на данном уроке нам удалось настроить DMA для приёма и передачи байтов через шину USART контроллера STM32F4.

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

 

 

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

 

Исходный код

 

 

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

 

 

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

STM LL. STM32F4. USART. DMA

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

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

*