Программирование МК STM32. УРОК 15. HAL. USART. DMA
HTML-код
- Опубликовано: 2 авг 2024
- Программирование на СИ в среде Keil μVision.
Пишем код под микроконтроллер STM32F407VG на плате STM32F4DISCOVERY.
Продолжаем работать с библиотекой HAL. Продолжаем пытаться реализовать интерфейс USART (Универсальный синхронно-асинхронный приемопередатчик)
В данном занятии пишем код для передачи и приема данных через интерфейс USART с использованием DMA.
Для визуализации принятых данных микроконтроллером используем дисплей LCD 20x4
Купить отладочную плату STM32F4-DISCOVERY можно здесь ali.pub/178fif
Переходник USB-TTL лучше купить такой (сейчас у меня именно такой и он мне больше нравится) ali.pub/yv3is
Дисплей LCD 20x4 можно приобрести тут ali.pub/vk7tl
Навигация по видео:
00:00 Введение
00:35 Коротко о DMA
02:35 Создаем проект для передачи по USART с использованием технологии DMA
08:00 Пишем код для передачи
10:05 Смотрим результаты работы
10:55 Создаем проект для приема данных по USART с использованием DMA
12:50 Пишем код для приема
17:05 Используем отладку кода для исследования нужного значения статуса для перехвата в дальнейшем
24:03 Радуемся результатам нашего труда
Рекомендуется также перед просмотром данного урока просмотреть данное видео:
УРОК 1. Установка Keil μVision • Программирование МК ST...
УРОК 4. Библиотека HAL. STM32 CUBE MX. Светодиоды и кнопка • Программирование МК ST...
УРОК 6. Библиотека HAL. LCD 20x4. 4-битный режим • Программирование МК ST...
УРОК 7. HAL. LCD 20x4. 4-битный режим. Выводим информацию • Программирование МК ST...
УРОК 13. HAL. USART. Передача данных • Программирование МК ST...
УРОК 14. HAL. USART. Прием данных • Программирование МК ST...
Текстовая версия и исходный код здесь narodstream.ru/stm-urok-15-hal...
Группа в контакте club116656325
Группа в Одноклассниках ok.ru/group/52987126153436
Группа в Facebook / 236905359999556
Мой сайт "Программирование МК" narodstream.ru
Форум narodstream.ru/forum
Вы можете помочь проекту:
ЮMoney
yoomoney.ru/to/41001176473465
Webmoney
Z341906933112
Карта Сбербанка (МИР)
2202201799288929
Можно в USDT
1) Сеть:TRC20
Адрес: TBBPFk5Widf1CYvF7Xk5ssKXeiPJHwtMgS
2) Сеть: BSC BNB Smart Chain (BEP20) (комиссия намного меньше)
Адрес: 0x2e38754DF1e54649Bf0D5CD6fD6D8c96a9f22f17
3) Сеть: Huobi ECO Chain (HECO) (комиссия еще меньше)
Адрес: 0x2e38754DF1e54649Bf0D5CD6fD6D8c96a9f22f17 Наука
Спасибо за Ваш труд. Желаю Вам здаровя и много денег за то, что Ви совсем безплатно сдалали Ваш канал за люди как нам. Вый являетесь кредитор на библейском принципе"сделай добро и брось его в море", а мы являемся дольжники, ваш резонанс на хорошо и вселена дает вам удачи от другое место.
Благодарю вас за ваш труд! Кажый день слежу за вашим каналом
Самый крутой канал. Много чему можно научиться
Привет из Азербайджана)
Спасибо за уроки
Terminal v1.9b не любит некоторые символы, к примеру, знак доллара, решотку и т.п., почему - то, передает какую - то белиберду или вообще, игнорирует их
А, вообще, спасибо за видеву, осваиваю сейчас самый дрянной STM32F030F4 о двадцати ногах. Поскоку платы для него нет, раскорячили его на NUCLEO F030R8, тот выпаяли, этот впендюрили, вроде, работает. Но, тема контроллеров новая для меня, посему хэлловорлд без бубна не напишу для него. Будем учиться
Спасибо)
Спасибо
спасибо!
Вовчик диджей))))) йоу.!!! лайк
Thanks
классное видео!👍
+MR TORNADO
Спасибо! Я рад, что Вам понравилось!
Сделал я как на видео, с передачей данных на комп получилось с приёмом я поймал вилы. Пол дня просидел так ни фига не получилось, потом я стал уже придираться к каждой мелочи и заметил что у автора сначала идёт инициализация DMA а потом UART у меня наоборот. На просторах инета я нашёл статью где как раз были описаны подобные грабли и как это исправить, DMA периферии с которой будете работать должна быть настроена первее самой периферии. Как оказалось порядок инициализации можно настроить в Кубе во вкладке Project Manager\Advanced Settings поставил как у автора и о чудо данные стали приниматься. В даташитах про этот прикол также ни фига не сказано.
Дай Вам Бог Здоровья!
вообще работает как-то странно. Есть такой участот кода.
if(hdma_usart1_rx.State == HAL_DMA_STATE_READY){
HAL_Delay(100);
HAL_UART_Receive_DMA(&huart1, (uint8_t*) str, 20);
//HAL_Delay(100);
hdma_usart1_rx.State = HAL_DMA_STATE_BUSY;
}
при передачи по ASART в переменной str сохраняются значения "поочереди". При чем без прохождения курсора в код IF(...) То есть передаю 12 еще раз 12 итд. В переменной все сохраняется 121212... Но при этом STATE остается Busy, а значит код в IF(...) не должен выполнятся. Когда переменная str наполняется, State становится Ready и начинает выполнятся код в IF(...). Не могу понять одного , как переменная str может заполнятся без прохождения курсорра в IF(...)?
thanks for the explanation. How is it possible to write data from BufferDMA to UARTBuffer both when the CpltCallback interrupt (BufferDMA full) is triggered and when the IDLE interrupt is triggered. What strategy do you use to manage writing pointers? thank you
Здравствуйте! Подскажите пожалуйста, что может быть ? Делаю все как в вашем видео, по приему данных UART через DMA, но почему-то первый и второй байт массива одинаковый, хотя если смотреть через преобразователь UART USB , первый и второй байт не дублируется
STM32 в каких то вещах поражает продуманностью, но в каких то просто убивает, так что хочется выкинуть все камни и стлинки в окно на прохожих. Вот неужели нельзя делать прием не по заказанной длине , а по
например.
Это DMA, оно к ядру процессора доступ не имеет - чем байты сравнивать будете?
Да и к тому же какой максимальный буфер тогда брать
А почему не использовался стандартный колбэк дма функции UART_DMAReceiveCplt()? Крутить проверку в режиме блокировки безусловно понятнее, но так вся библиотека хол выстраивается уже в понятную архитектуру.
Даже не знаю. Я скорей всего 13 мая про них еще не знал. Сейчас их и использую. Но я думаю в данном уроке пусть будет такая. Зато с некоторыми флагами познакомились.
подскажите, где вы узнаете о том, какие статусы принимает DMA? (Ну тот статус, который вы отслеживали при приеме данных). В Refferense Manual и HAL Driver Manual об этом ничего не сказано просто.
В файлах подключенных библиотек есть все переопределения любых статусных флагов, и зная те или иные флаги статусных регистров не важно какой шины, можно найти замену непосредственно в библиотеке, а можно в принципе и напрямую использовать флаги регистров, что не очень красиво на фоне пестрящих команд из библиотеки HAL.
Короче, кроме мануала по HAL есть еще мануалы, в которых имеются все регистры. Смотрим их и изучаем там, а затем ищем их переопределения в хедерах и с-файлах подключенных библиотек.
То есть, кроме мануалов, причем не кроме, а даже более мануалов я читаю исходные коды библиотек и примеров.
Добрый день, я нечего не понимаю с STM32. Проста почему то прерывании отслеживаем в бесконечном цикле. Проста на AVR указывается конкретный код в обработчике прерывании и тем самым его не запускали с бесконечного цикла. Ведь прерывание на то и прерывание, чтоб вызывалось по наступлению события, для этого даже отдельная функция. А тут мы постоянно ещё что та отслеживаем, ведь это теряет всякий смысл. Или я что та не понимаю?
Здравствуйте!
Мы отслеживаем скорей всего не само прерывание, а его флаг в данный момент. А так да. Нужно обработать событие.
А можно просто конкретно урок про DMA отснять уж просто бьюсь не первый день когда работает когда нет
Здравствуйте , подскажите как правильно отправить строку в которой есть спец символы ?
Я по вашим урокам понял для этого есть sprinf но он не понимает символ "
Передать нужно строку AT+SAPBR=3,1,"CONTYPE","GPRS" в юарт .
разобрался сам
sprintf(usb_tx,"AT+SAPBR=3,1,\"CONTYPE\",\"GPRS\"
");
Denys Nikolaevich здравствуйте! Обычная работа со строками в си.
Ну это очевидно вам , я же си не знаю только учусь =)
Спасибо за урок. Возможно в библиотеке HAL произошли какие то изменения у меня после передачи всего слова state=0x01 HAL_DMA_STATE_READY
Tozhe samoe.
Wot takaya struktura v hal dlya statusov
typedef enum
{
HAL_DMA_STATE_RESET = 0x00U, /*!< DMA not yet initialized or disabled */
HAL_DMA_STATE_READY = 0x01U, /*!< DMA initialized and ready for use */
HAL_DMA_STATE_BUSY = 0x02U, /*!< DMA process is ongoing */
HAL_DMA_STATE_TIMEOUT = 0x03U /*!< DMA timeout state */
}HAL_DMA_StateTypeDef;
Widno chto half_MEM0 statusa net. w stm32f100 ili hal obnovili. Nuzhno smotret Dokumentyciyu.
В stm32f407 тоже самое.
Произошли, рабочий интерфейс сильно поменялся
Здравствуйте. Подскажите пожалуйста. Копаюсь с реализацией протокола modbus на rs 485 через usart стмки. С помощью обычных прерываний всё работает. Пытаюсь прикрутить dma, но вот в чем проблема. То количество байт, которое я приму, заранее не известно. Поэтому нужно дать команду на приём большого количества байт и в процессе того, как они будут идти, прервать приём и сбросить его в 0 байт, чтобы новый пакет опять начал писаться в массив сначала. Как это сделать? И в регистры тыкался, и функции всякие вызывал, ничего не помогло. Цифра в регистре, соответстветвующая количеству принятых байт никак не хочет меняться. Заранее спасибо за ответ
Full или half duplex был?
Как реализовали обработку таймаута на modbus при использовании dma?
Zdravstvuitje. A jest kokojeto vozmoznost vyvodit dannyje bjes polnogo zapolnjenije registra pri Recieve? Ili objezatjelno nado zaplonit ves register? Sposiba.
Ergo Kannikka может буфера, а не регистра? И какого именно буфера? Буфера FIFO DMA или буфера USART?
Ja pytajus vyvesti dannyje s DMA buffera. Sozdavaja massiv na 10 bayt DMA interrupt nje actevirujetsja poka ves buffer nje zapolnish. Vozmozno li zdjelat chtoto na podobije massiv na 30 bayt i snimat kak tolko hot chtoto tam okazetsja. Tipo variable data length. Vozmozno tokoje?
Так должно и быть. DMA не отчитывается о каждом байте, т.к. передача через DMA происходит как известно без использования АЛУ, а код работает именно в нем
жалко нельзя поставить сразу 500 лайков
Тем не менее спасибо Вам за один! Это также поддержка канала.
Какой-то странный пример с ДМА. Зачем ждать заполнения не пойму. Вся философия ДМА в том что бы он заполнялся независимо от процессора, а когда у программы будет время она сразу же извлекает данные из ДМА или передает ссылку дальше, что бы не переполнился буфер. Т.е. в идеале полного заполнения не должно быть, следующее что должен сделать процессор после заполнения это остановить поток данных, т.е. Убрать CTS. Единственное когда реализуется ожидание заполнения, это ДМА с двойной буферизацией, там в то время когда один буфер заполняется второй извлекается, обычно используется в системах захвата данных в реальном времени, типа АЦП и тд. Правда как для демонстрации работы дма может и сойдет и так.
Вы верно подметили! Именно демонстрация. Урок не метит на оптимизацию кода, он направлен именно на то, чтобы показать применение периферии!