STM Урок 184. CMSIS. STM32F1. USART. DMA



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

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

С применением DMA в работе с модулем USART мы уже знакомы из урока 15 и урока 164. Правда, тогда мы использовали при этом библиотеки HAL и LL, но тем не менее со спецификой применения DMA мы познакомились полностью. Также, как работать с DMA и как его настраивать при использовании библиотеки CMSIS, мы также знаем уже не понаслышке. Мы работали с данной периферией в уроке 176 и уроке 178.

Схема наша также со времён трёх прошлых уроков никаких изменений не претерпела.

Поэтому мы можем смело приступать к проекту, который был сделан из проекта прошлого урока с именем CMSIS_USART_INT и имя ему новое было дано CMSIS_USART_DMA.

Откроем наш проект в Keil и в файле main.c удалим вот эти две глобальные переменные

 

uint8_t fl=0;

uint8_t dt1;

 

Вместо них добавим два флага, один — для отслеживания окончания передачи пакета, другой — приёма

 

 

Удалим также объявления символьных массивов

 

char rx_str[30], tx_str[30], tmp_str[10];

 

А добавим один инициализированный, другой — неинициализированный

 

 

Добавим также функцию инициализации DMA над функцией USART1_Init

 

 

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

 

 

Основная инициализация DMA будет уже в функции инициализации модуля USART1 — USART1_Init.

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

 

//USART1 interrupt Init

NVIC_EnableIRQ(USART1_IRQn);

 

Вместо этих строк добавим код инициализации нашего DMA

 

 

Данную инициализацию мы тажке видели в уроке 164, здесь она просто переписана с использованием макросов библиотеки CMSIS. Практически такая же инициализация DMA была у нас в уроке 178, когда мы работали с модулем SPI.

Универсальную функцию USART_RX_TX_Str удалим вместе с телом.

В функции main вызовем функцию инициализации DMA

 

 

Удалим разрешение локальных прерываний от USART

 

SET_BIT(USART1->CR1, USART_CR1_RXNEIE);

SET_BIT(USART1->CR3, USART_CR3_EIE);

 

Вместо этого сначала отключим каналы DMA

 

 

Очистим флаги прерываний каналов

 

 

Разрешим запросы DMA для USART1

 

 

 

Разрешим прерывания по событиям ошибки и окончания передачи для каналов DMA

 

 

Сконфигурируем в DMA адреса буферов источника и приёмника для передачи и приёма

 

 

Из бесконечного цикла пока всё удалим.

Обработчик прерываний USART1_IRQHandler удалим вместе с телом, а вместо него добавим два обработчика прерываний от каналов DMA

 

 

Здесь всё так же, как и в уроке 164.

Если мы попали в обработчик канала 4, значит это окончание передачи данных через DMA приёмного пакета. В данном случае, если это именно окончание, то мы сбрасываем флаг прерывания, а устанавливаем пользовательский по приёму, а если ошибка, то отключаем оба канала. В случае с каналом 5 всё то же самое, только флаг устанавливаем передачи.

В функции передачи пакета по шине USART в ПК удалим весь код из тела, а вместо него добавим вот такой

 

 

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

Ниже добавим функцию приёма пакета от ПК по шине USART

 

 

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

В бесконечный цикл функции main() добавим следующий код

 

 

Здесь мы сначала принимаем пакет данных с массивом чисел из ПК, передаём нашу текстовую строку в ПК, далее мы гасим все разряды индикатора и в цикле с перерывом в 10 милисекунд выводи туда числа из принятого массива данных.

Соберём проект, прошьём контроллер, запустим терминальную программу, соединимся с портом и запустим тот же скрипт, который запускали в уроке 164.

Индикатор начнёт показ принятых чисел

 

 

А в терминальной программе начнут в ответ появляться наши строки, принятые из МК

 

 

Посмотрим также, как идёт передача данных по USART, в программе логического анализа

 

 

 

 

Всё передаётся без пропусков и непрерывно.

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

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

 

 

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

 

Исходный код

 

 

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

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

Переходник USB to TTL можно приобрести здесь ftdi ft232rl

Индикатор светодиодный семиразрядный с драйвером MAX7219

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

 

 

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

 

STM CMSIS. STM32F1. USART. DMA

2 комментария на “STM Урок 184. CMSIS. STM32F1. USART. DMA
  1. onur:

    why didn't you use dma circular mode?

  2. Алекандр:

    Здравствуйте, непонятно зачем в функциях USART_RX , USART_TX ссылки на буфер,если они там не используются?

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

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

*