В своем уроке вы сказали, что для библиотеки HAL скорость вывода не имеет какого-либо практического применения, потому что значения LOW и HIGH не оказывают никакого влияния на частоту переключения вывода. Сейчас я перевожу книгу Carmine Noviello - Mastering STM32, в которой разбирается библиотека HAL. В главе 6 про GPIO в пункте "6.2.3 Understanding GPIO Speed" автор указывает на то, что очень многие неверно понимают понятие скорости GPIO, поскольку STM32 выбрала неподходящее название для этого понятия. Так вот он говорит, что параметр скорость GPIO в HAL определяет не частоту переключения вывода, а скорость, с которой вывод GPIO переходит с нулевого уровня напряжения на уровень VDD, и наоборот, т.е. скорость нарастания или спада фронта. Далее этом пункте он приводит осциллограммы со сравнением скоростей, полученные на плате NUCLEO-F446RE, которые как раз и совпадают с описанием в документации. Поясняя это понятие, автор говорит, что высокая скорость нарастания GPIO влияет на общее излучение платы, поэтому советует ставить значение LOW, если не требуется резкое нарастание фронта. Такое вот неудачное понятие, которое все-таки несет практическое применение.
Отвечу вечерком, я читал его книгу и там вы немного не точно описываете. Вкратце, HALом достичь максимальную скорость на F103 не получается, и выше LOW ставить смысла нет. А регистрами эта скорость достигается. И скорость и частота переключения для GPIO это по сути одно и тоже. А скорость перехода с нулевого состояния до напряжения питания каким параметром и единицей измерения охарактеризовать?
@@NRelectronics Я понимаю, что HALом не достичь максимальной скорости переключения GPIO, как и не достичь на CMSIS той же скорости, что и на ассемблере, как вы показали в следующем своем видео. Чем выше уровень абстракции, тем меньше производительность. И я понимаю, что и скорость, и частота переключения для GPIO одно и то же. Просто в этом видео речь идет о скорости переключения GPIO (которую характеризует время между 2 передними фронтами соседних импульсов), и при настройке в кубе вы показываете, устанавливая значения скорости GPIO_SPEED_FREQ_HIGH и GPIO_SPEED_FREQ_LOW, что скорости переключения не меняются, из чего вы делаете вывод, что установка этой скорости в HAL не имеет никакого практического применения. Но этот параметр координально не влияет на ту скорость переключения GPIO, которую вы замеряли. Потому что скорости GPIO_SPEED_FREQ_LOW и GPIO_SPEED_FREQ_HIGH отвечают за скорость нарастания (или спада) фронта конкретного импульса, т.е. скорость перехода с нулевого состояния до напряжения питания. Так говорит автор приведенной книги. И эту скорость в своих осциллограммах он характеризует частотой. Эта частота равна 1/дельтаT, где дельтаТ - время перехода с нулевого состояния до напряжения питания. Мы говорим с вами о разных скоростях, а в видео вы принимаете их как одно понятие где-то на 28й минуте, либо я что-то не так понял.
@@ДмитрийКарасёв-и2ч нельзя время, между двумя фронтами характеризовать скоростью, блин ну это неправильно. Это время и время, малое большое, а перключение HIGH|LOW характеризуется скоростью, Гц-ми например, или раз/сек. Там автор в книге сам не совсем корректно это назвал. Щупы выдают затухание на реактивном сопротивлении, это влияет на фронты, завалы, но не на скорость как таковую же, нормальные щупы с запасом по полосе не вносят значимых искажений.
@@NRelectronics Что ж, может быть. Мне самому не нравятся все эти непонятки, и я недостаточно компетентен, чтобы спорить, но мне "понравилось" его объяснение на счет кривости названия понятия и проведенные эксперименты. В любом случае, в дальнейшем буду разбираться в официальной документации по HAL и выясню подробности этого вопроса.
6:53 правильно будет сказать "за одну инструкцию" и "за три инструкции". Одна инструкция может выполняться от 1 до 3 машинных тактов на процессоре Cortex-M3, в зависимости от инстркуций, идущих перед ней 22:51 На линии 106 вы перезаписываете все значения регистра ODR, цикла чтение-модификация-запись, о котором вы говорите там нет. Увеличение скорости при записи в регистр BSRR в сравнении с ODR, никак не зависит от самих регистров, потому что процессору всё равно куда вы записываете - это для него совершенно одинаковые ячейки памяти (с разными адресами, естественно). Ускорение связано с тем, что компилятор выгенерировал немного другую последовательность инструкций для этих двух примеров, потому что вы записываете другие значения (нужно смотреть листинг, чтобы узнать в чём конкретно отличие).
Спасибо за корректный и осмысленный ответ. С вами согласен. Хотелось сравнить библиотеки и команды выполнения. Это показательно конечно. Компилятор вносит свои не малые три копейки. Так и получается компилятором выполнение ODR более долгое чем BSRR. Все подтверждается.
Верно сказано. 3 операции при использовании регистра ORD - это 1-чтение значения, 2-наложение битовой маски для изменения только нужного бита, 3-запись нового значения в регистр. В случае с BSRR это всего одна операция - снятие или установка бита. За счёт этого и достигается ускорение. К этому же относится и атомарность. Если в первом случае у нас произойдёт прерывание и в нём поменяем значение порта, то накладывать маску и записывать обратно мы уже будет совершенно не то значение, которое сейчас находится в порте. В случае если мы делаем это всё с помощью регистра BSRR, мы делаем это за одну инструкцию, которую не сможет никто прервать, и гарантированно получим в регистре то, что хотели. Это и есть атомарность. В примере с F4 Вы как раз при работе с регистром ODR делаете верно, читаете, накладываете маску (инвертируете) и записываете ( хоть и одной строкой кода), по этому все рассчёты сходятся. А в примере с f1 просто пишете в регистр значения, но не читаете из него. Ну а значения "скорости" порта отвечают не за прямую скорость, а за скорость нарастания и спада импульса.
Провел тот же самый эксперимент с синий таблеткой, результат на cmsis скорость порта 2,8MHZ, HAL 788KHZ, а 8MHZ генерирует четко, очень разный результат получился почему то .
Еще на 46:30 немного удивился почему Вы просто не включили режим AC на осциллографе? На самом деле все видео нужно было с режимом AC работать. Просто постоянная составляющая по сути только мешала
2:52 Output Data Register. ODR - это один из регистров GPIO, который содержит все выходные состояния контактов порта GPIO. Сетресет на опеределённом выводе это что. Есть так же GPIO IDR- Input Data Register Согласитесь что так намного понятней.
Я вас неирвирую своими постами? В принципе мне не принципиально, могу и не писать. Думал может чем то поделюсь что замечаю и сам запоминаю лучше если пишу.
@@namename2031 просто вы не внимательно совсем смотрите, и одно из замечаний не корректное, не в формате вас как зрителя. Пишите если так легче учиться, я подправлю где нужно, или удалю))
Ух ты вот это урок , но есть нюанс с которым я как то столкнулся , если используем библиотеку HAL то можно и CubeMX использовать , а вот если использовать CMSIS то CubeMX лучьше не использовать , так как некоторые отладочные платы на примере NUCLEO тактируються от Stlin-Ka , и CubeMX выставляет там сои битики , так что если используем CMSIS и CubeMX то лучьше проверить что установленно , я уже просто сталкивался с подобной проблемой
Спасибо за совет. С нуклео не работал, учту для себя. Тактирование там МК осуществляется через вывод МСО отладчика встроенного читал. Технически нормуль. Видимо накладывается это на более "правильную" инициализацию RCC тактирование.
Спасибо за интересное и полезное видео. Только обратите внимание, что при разных скоростях GPIO выходной каскад работает в разных токовых режимах.Это прекрасно видно по выбросу на фронтах 30:20. И сравните с 21:13. Соответственно должно быть разное потребление контроллером.
Если есть сомнения в скорости , можно на вкладке ассемблера посмотреть за сколько команд происходит действие. Да и оптимизация может играть злую шутку. Видео хорошее , но осцилограф по частоте лучше с запасом в 10 раз
Согласен полностью на счет осциллографа, но другого нет и в 500МГц для дома не подъемно будет стоить. Есть урок 10 и там на ассемблере все получилось ;-)
Я по кусочкам смотрю видео , и вот назрел вопрос по скорости ногодрыга так называемого, 36 мГц я так и не смог добиться , а вот таймерами смог спокойно , в том числе с 50 % заполнением шим ,другие функции таймеров еще пока что изучаю , так что тут нужно искать где собака зарыта , скорее всего в HAL ?тут нужно отрывать и смотреть где какая проверка проходит
С халом все понятно. В видео хорошо показано на сравнении на кусочках как он работает. На Си я смог получить 36МГц для так называемого "ногодрыга". Таймером конечно удобнее работать.
1:14 4 Гигабайта адресного пространства это да. Но я совершенно уже запутался сколько Байт находится под каждым из этих адресов. Если вы найдёте в интернете тему: bit banding th-cam.com/video/IAMabY16PHw/w-d-xo.html то увидите что каждому адресу bit band региона соответствует 32 адреса региона псевдонимов. То есть на 1 Адрес который был, есть 32 адреса, а значит 32 бита. И много где ещё говорится что информация во Flash памяти хранится в 32 битных словах. Но когда пишешь в IDE и смотришь описание регистров, кажется что на каждый адрес один Байт. Не пойму.
@@NRelectronics th-cam.com/video/IAMabY16PHw/w-d-xo.html 4010 0000 - 4000 0000==1 048 576 это 1 Мегабайт адресов Каждый из этих адресов должен содержать 32 бита. Каждый из адресов. Так как ровно в 32 раза больше то пространство псевдонимов, на которое ссылается эта 1 мегабайтная область. Пространство псевдонимов от 4200 0000 до 4400 0000 4400 0000-4200 0000==200 0000== 32 Мб
Странно что они равные, bsrr работает атомарно быстрее. Собственно это лишь тест, использовать голый миландр редко когда нужно в мк, нужно данные вкладывать, а это ещё скорость снижает...
1:14 0хFFFF FFFF == 4 294 967 296== 4 Гибибайт. Один адрес это как в компьютере один Байт? Под порт А выделяется 1024 адреса. Это 1024 Байта? Это килобайт. Действительно так много надо для регистров? Один регистр 32 бит(16 во многих резервировано)==32 бит==4 Байта. 1024/4==256 Получается можно 256 регистров поместить в эту память. Но регистров я думаю ведь меньше?
@@NRelectronics На хабре я нашёл такое: Каждый из регистров имеет свой порядковый номер - адрес. Адрес регистра обозначается 32-битным числом представленным в шестнадцатеричной системе счисления. --------------------- Если адрессация побайтовая, то как каждый регист может иметь свой адрес? Это адрес начального байта регистра или что?
Вам нужно посмотреть Memory Map например на GPIO или любую другую периферию. Есть начальный адрес и о него для каждой частицы хардвера свой адрес, это начальный адрес + смещение. И всё.
@@NRelectronics большое спасибо. Пока досмотрел до нужного момента в видео, благодаря подсказке автора в комментарии, уже сам нашел куда ткнуть нужно). На всякий случай, чтобы таких вопросов не было потом у людей. В видео про пустой и рабочий проект в IDE на CMSIS показано, как прошивать.
Хорошие ролики, спасибо. Под STM32 еще не чего не писал, но писал под AVR8. Сейчас знакомлюсь, в том числе и по вашим роликам. Мне не понятно, зачем 2 регистра порта для записи, ODR и BSSR, если оба делают одно и тоже? Но за разное время. И как надо было извратится с HAL, что простая запись в регистр отнимает столько времени. И почему с HAL изменение скорости порта не к чему не приводит?
C HALом вот такие накладные расходы, он так сделан, что изменение скорости порта такое низкое... Его только самому переписывать или просто использовать значение регистров
С HALом все понятно, слишком унифицирован, я б сказал ардуиноподобный. Решил на начальном этапе с CMSIS поработать, а дальше видно будет, еще раз спасибо, за то что учите нас.
Спасибо! Можно ли сделать или будет ли более детальное описание вкладки Clock Configuration и показать как соотносить с даташитом? Пока выглядит как магия.
Почти все посмотрел. Мне, как новичку, не очень понятно в каких задачах может быть нужны эти эксперименты с тактированием. С точки зрения, больше частота - лучше. Когда нужно замедлять или использовать определенную частоту? Показано, что реальная частота на выходе все равно другая. Возможно, просто нужно смотреть дальше. :-)
Это нужно в задачах, когда нужно по серьёзному экономить потребление. Хороший ход занизить тактировпние. Вы невнимательно видео посмотрели, я с 72МГц уменьшил до 36 МГц, а потом вернул также легко обратно. И показал это на длительности свечения светодиода по осциллографу.
Интересует вопрос почему реальное смещение не совпадает с тем, что задает компилятор (при загрузке из ОЗУ)? 0x080004EA 480C LDR r0,[pc,#48] ; @0x0800051C 0x080004EA 480C LDR r0,[pc,#0x30] ; @0x0800051C offset = 0x0800051C - 0x080004EA = 0x32; address = 0x080004EA + 30 = 0x0800051A; diff = 0x0800051C - 0x0800051A = 0х02; На сколько я понимаю смещение должно быть кратное 4, но тогда почему компилятор не подставляет сразу значение кратное 4?
Подскажите пожалуйста, есть ли способ переключать состояния выходов, при этом не останавливая выполнение кода? Делаю буфер с шифратором, на несколько мегагерц. Пока идёт вывод, нужно также читать состояния других ножек и писать их в буфер. По коду 72 МГц едва хватит, но если он будет ждать каждого переключения выхода, то скорость будет как у атмеги. Даже плисы рассмотрел, но дорого и большой буфер не сделать.
@@NRelectronics Я имею в виду, что рассмотренные в видео операции по установке 1 или 0 на выводе занимают очень много процессного времени. На той же атмеге мы пишем в порт за один такт и сразу же выполняем дальнейший код. А на стм32, как я понимаю, при записи в порт программа ждет переключения ножки, в итоге контроллер будет всё процессорное время ждать переключения. То есть i++ в вечном цикле будет работать на 72 мгц (без учета перехода), но цикл с инкрементом и переключением ножки уже будет делать инкремент в десятки раз реже. Как этого избежать?
@@MrPusyakaryagin bsrr или brr регистр это производит, изменения состояния, сейчас не вспомню точное название, запись одного значения в регистр один, разве это долго??
Она считается менее насыщенной скажем так. С меньшим количеством проверок а значит стабильнее. Но на LL не все можно сделать как на HAL, посмотрим Description на эти библиотеку, хал по функционалу шире.
Встречал комбинацию HAL и LL, в LL советуют описывать GPIO , как раз из-за больших задержек в HAL, а можете добавить сравнение скорости работы выводов через LL, к уже имеющимся у Вас HAL и ассемблер ?
Большие задержки при старте МК и инициализации перефирии? Интересно это ж сколько в мс или мкс? При старте это происходит быстро, не думаю что это на что-то вообще может повлиять. Вы когда подаете питание на МК до десяти секунд можете с ним ничего не делать... А тут только инициализации. LLC мне библиотека мало интересна, пока не вижу смысла тратить на нее время.
@@NRelectronics всё именно так, прочитал в комментариях про оптимизацию с о3 добавилось ещё немного, но всё же меньше чем у вас по частотам. Плюс фронты не такие как у вас.
@@NRelectronics Разобрался BSRR - BR - 0 на выводе (32бита) BSRR - BS - 1 на выводе (32бита) --------------------------------------- BRR - (только BR) 1 на выводе (16бит) --------------------------------------- ODR - 0.7 мГц ногодрыг (пока прочитает - запишет) понятно А.... BSRR - BS - 1 на выводе 1,38 мГц ногодрыг BRR - BR - 1 на выводе 1,7 мГц ногодрыг почему разница 1,38 и 1,7 - не может быть что бы в 16 битный запись 16 бит происходила чуть быстрее или компилятор как то влияет ??? ведь stm прожевывает 32 бита за тик.
Доброго времени суток у меня почемуто вот при этих значениях GPIOA->ODR = 0x200; GPIOA->ODR = 0; частота показывает 12 мГц это нормально или не нормально А вот при таких значениях GPIOA->BSRR = GPIO_BSRR_BS9; GPIOA->BSRR = GPIO_BSRR_BR9; показывает 8 мГц что я могу делать не так или чего то я не понимаю
У меня почему-то команды HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_SET); //High HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET); //LOW и HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_9); Выдают максимум всего 500 Гц((( у меня STM32F407 Тактирование ставил 168 МГц и 84 МГц... Почему такое может быть?
@@NRelectronics всё верно, я хотел уточнить, выше у товарища 500 Гц. Наверное он имел в виду 500 кГц. 500 кГц и 0.5 МГц я написал, чтобы не повторяться)
Есть мнение, что фронты ограничены скоростью нарастания ослика. 50мгц меандр не тоже самое что 50мгц синуса. И по "постоянной" составляющей видно что 10+ мгц меандр он не может.
@@NRelectronics ну тут не все так просто) , скорость нарастание напряжение в/мкс связана с полосой пропускания. Понятно что так же связана и с амплитудой (но в тракте она +- постоянная). Так что измерить фронты импульса в 10мгц осликом на 50мгц не выйдет. 16нс для ослика со 125-250msa похоже на правду. Я думаю меандр там лучше чем на экране
@@NRelectronics На осциллографе с полосой пропускания 200MHz и частотой дискретизации 1GS/sec вы нормально (но не идеально) увидите меандр с частотой 20 MHz, с некоторыми оговорками (например измерять его параметры с известной погрешностью) имеющим частоту максимум 4MHz-6,6MHz. Если же Вы занимаетесь разработкой электронных устройств и Вам требуется изучать и измерять переходные процессы на фронтах меандра, вам по минимуму хватит для работы с меандром имеющим частоту в районе 50KHz.
Спасибо за видео ) интересно больше про cmsis смотреть , так как это основы , необдуманно юзать хал - как мне кажется , не правильно . P.S с вами как то можно связаться ?(почта , телеграм )
HEX 200==10 0000 0000 бинарный вид Единица стоит на десятом месте. Нумерация портов начинается ведь с нуля? Первый порт это 0? Второй порт 1? Третий порт 10? Если предположить что каждый бит это пин, то тоже не получается. Здесь 10 0000 0000 единица стоит на десятом месте. Получается что первый пин начинается с 10? Почему так? А, ок понял. Нулевой пин это 0 Первый пин это 10 Второй пин это 100 Третий пин 1000 и.т.д. 10 0000 0000 Это девятый пин, но учитывая что есть нулевой пин.
Не вижу настройки каждого пина для Mode,Pull,Speed,Alternate. #define GPIO_MODE_INPUT 0x00000000U Как это приспособить для определённого пина? То есть настройка пинов порта происходит всех сразу, а не поотдельности. Как выбирают из 16 ти пинов нужный, чтоб дать модус нужный? Здесь GPIO_InitStruct.Pin информация сразу о 16 ти пинах передаётся. Как узнать для какого именно пина я хочу сделать это #define GPIO_MODE_INPUT 0x00000000U Здесь #define GPIO_MODE_INPUT 0x00000000U ведь нет информации о порядковом номере пина.
Добра и счастья Вам автор видео!!!
Спасибо Вам большое! Подписывайтесь на телеграм канал
В своем уроке вы сказали, что для библиотеки HAL скорость вывода не имеет какого-либо практического применения, потому что значения LOW и HIGH не оказывают никакого влияния на частоту переключения вывода. Сейчас я перевожу книгу Carmine Noviello - Mastering STM32, в которой разбирается библиотека HAL. В главе 6 про GPIO в пункте "6.2.3 Understanding GPIO Speed" автор указывает на то, что очень многие неверно понимают понятие скорости GPIO, поскольку STM32 выбрала неподходящее название для этого понятия. Так вот он говорит, что параметр скорость GPIO в HAL определяет не частоту переключения вывода, а скорость, с которой вывод GPIO переходит с нулевого уровня напряжения на уровень VDD, и наоборот, т.е. скорость нарастания или спада фронта. Далее этом пункте он приводит осциллограммы со сравнением скоростей, полученные на плате NUCLEO-F446RE, которые как раз и совпадают с описанием в документации. Поясняя это понятие, автор говорит, что высокая скорость нарастания GPIO влияет на общее излучение платы, поэтому советует ставить значение LOW, если не требуется резкое нарастание фронта. Такое вот неудачное понятие, которое все-таки несет практическое применение.
Отвечу вечерком, я читал его книгу и там вы немного не точно описываете. Вкратце, HALом достичь максимальную скорость на F103 не получается, и выше LOW ставить смысла нет. А регистрами эта скорость достигается. И скорость и частота переключения для GPIO это по сути одно и тоже. А скорость перехода с нулевого состояния до напряжения питания каким параметром и единицей измерения охарактеризовать?
@@NRelectronics Я понимаю, что HALом не достичь максимальной скорости переключения GPIO, как и не достичь на CMSIS той же скорости, что и на ассемблере, как вы показали в следующем своем видео. Чем выше уровень абстракции, тем меньше производительность. И я понимаю, что и скорость, и частота переключения для GPIO одно и то же. Просто в этом видео речь идет о скорости переключения GPIO (которую характеризует время между 2 передними фронтами соседних импульсов), и при настройке в кубе вы показываете, устанавливая значения скорости GPIO_SPEED_FREQ_HIGH и GPIO_SPEED_FREQ_LOW, что скорости переключения не меняются, из чего вы делаете вывод, что установка этой скорости в HAL не имеет никакого практического применения. Но этот параметр координально не влияет на ту скорость переключения GPIO, которую вы замеряли. Потому что скорости GPIO_SPEED_FREQ_LOW и GPIO_SPEED_FREQ_HIGH отвечают за скорость нарастания (или спада) фронта конкретного импульса, т.е. скорость перехода с нулевого состояния до напряжения питания. Так говорит автор приведенной книги. И эту скорость в своих осциллограммах он характеризует частотой. Эта частота равна 1/дельтаT, где дельтаТ - время перехода с нулевого состояния до напряжения питания. Мы говорим с вами о разных скоростях, а в видео вы принимаете их как одно понятие где-то на 28й минуте, либо я что-то не так понял.
@@ДмитрийКарасёв-и2ч нельзя время, между двумя фронтами характеризовать скоростью, блин ну это неправильно. Это время и время, малое большое, а перключение HIGH|LOW характеризуется скоростью, Гц-ми например, или раз/сек. Там автор в книге сам не совсем корректно это назвал. Щупы выдают затухание на реактивном сопротивлении, это влияет на фронты, завалы, но не на скорость как таковую же, нормальные щупы с запасом по полосе не вносят значимых искажений.
@@NRelectronics Что ж, может быть. Мне самому не нравятся все эти непонятки, и я недостаточно компетентен, чтобы спорить, но мне "понравилось" его объяснение на счет кривости названия понятия и проведенные эксперименты. В любом случае, в дальнейшем буду разбираться в официальной документации по HAL и выясню подробности этого вопроса.
@@ДмитрийКарасёв-и2ч так а что тогда у меня в видео неправильно?)))
Спасибо, хорошее видео!
Использую cmsis, кончено это долго, но стал хорошо разбираться в "железной" составляющей контроллера)
Пожалуйста!) Не забывайте про лайки и конструктивные предложения ;-) Как Ваши успехи в освоении МК?
6:53 правильно будет сказать "за одну инструкцию" и "за три инструкции". Одна инструкция может выполняться от 1 до 3 машинных тактов на процессоре Cortex-M3, в зависимости от инстркуций, идущих перед ней
22:51 На линии 106 вы перезаписываете все значения регистра ODR, цикла чтение-модификация-запись, о котором вы говорите там нет. Увеличение скорости при записи в регистр BSRR в сравнении с ODR, никак не зависит от самих регистров, потому что процессору всё равно куда вы записываете - это для него совершенно одинаковые ячейки памяти (с разными адресами, естественно). Ускорение связано с тем, что компилятор выгенерировал немного другую последовательность инструкций для этих двух примеров, потому что вы записываете другие значения (нужно смотреть листинг, чтобы узнать в чём конкретно отличие).
Спасибо за корректный и осмысленный ответ. С вами согласен. Хотелось сравнить библиотеки и команды выполнения. Это показательно конечно. Компилятор вносит свои не малые три копейки. Так и получается компилятором выполнение ODR более долгое чем BSRR. Все подтверждается.
Верно сказано. 3 операции при использовании регистра ORD - это 1-чтение значения, 2-наложение битовой маски для изменения только нужного бита, 3-запись нового значения в регистр. В случае с BSRR это всего одна операция - снятие или установка бита. За счёт этого и достигается ускорение.
К этому же относится и атомарность. Если в первом случае у нас произойдёт прерывание и в нём поменяем значение порта, то накладывать маску и записывать обратно мы уже будет совершенно не то значение, которое сейчас находится в порте. В случае если мы делаем это всё с помощью регистра BSRR, мы делаем это за одну инструкцию, которую не сможет никто прервать, и гарантированно получим в регистре то, что хотели. Это и есть атомарность.
В примере с F4 Вы как раз при работе с регистром ODR делаете верно, читаете, накладываете маску (инвертируете) и записываете ( хоть и одной строкой кода), по этому все рассчёты сходятся. А в примере с f1 просто пишете в регистр значения, но не читаете из него.
Ну а значения "скорости" порта отвечают не за прямую скорость, а за скорость нарастания и спада импульса.
Спасибо за ваши труды!
Все для вас) не забывайте про лайки для других зрителей)
Провел тот же самый эксперимент с синий таблеткой, результат на cmsis скорость порта 2,8MHZ, HAL 788KHZ, а 8MHZ генерирует четко, очень разный результат получился почему то .
Очень мало что-то у Вас.
@@NRelectronics Сам удивился, причем что через регистр ODR что через BSRR 2,8MHZ выдает.
Выключите любую оптимизацию компилятора и попробуйте.
Хотелось бы все-таки видеть cubemx IDE, раз уж она вышла, зачем ставить кейл.
На вкус и цвет как говорится... Сейчас планирую и продумываю одну ветку ещё по STM32, там будет CubeIDE.
Кейл надежен, кубиде эклипсоподобная система со своей "надежностью". Кто работал и там и там поймет о чем я.
Еще на 46:30 немного удивился почему Вы просто не включили режим AC на осциллографе? На самом деле все видео нужно было с режимом AC работать. Просто постоянная составляющая по сути только мешала
NR.electronics Буду смотреть обязательно!
@@remontlive Спасибо! Не забывайте про лайки, чтобы поднять видео в поиске для других зрителей.
2:52 Output Data Register. ODR - это один из регистров GPIO, который содержит все выходные состояния контактов порта GPIO.
Сетресет на опеределённом выводе это что.
Есть так же GPIO IDR- Input Data Register
Согласитесь что так намного понятней.
SET установ 1, RESET сброс. Понятно хоть это?
@@NRelectronics Мне понятно.
Но я нашёл описание в инете.
@@namename2031 в RM все достаточно четко и нормально расписано. Нужно только понять.
Я вас неирвирую своими постами?
В принципе мне не принципиально, могу и не писать.
Думал может чем то поделюсь что замечаю и сам запоминаю лучше если пишу.
@@namename2031 просто вы не внимательно совсем смотрите, и одно из замечаний не корректное, не в формате вас как зрителя. Пишите если так легче учиться, я подправлю где нужно, или удалю))
Ух ты вот это урок , но есть нюанс с которым я как то столкнулся , если используем библиотеку HAL то можно и CubeMX использовать , а вот если использовать CMSIS то CubeMX лучьше не использовать , так как некоторые отладочные платы на примере NUCLEO тактируються от Stlin-Ka , и CubeMX выставляет там сои битики , так что если используем CMSIS и CubeMX то лучьше проверить что установленно , я уже просто сталкивался с подобной проблемой
Спасибо за совет. С нуклео не работал, учту для себя. Тактирование там МК осуществляется через вывод МСО отладчика встроенного читал. Технически нормуль. Видимо накладывается это на более "правильную" инициализацию RCC тактирование.
Спасибо за интересное и полезное видео. Только обратите внимание, что при разных скоростях GPIO выходной каскад работает в разных токовых режимах.Это прекрасно видно по выбросу на фронтах 30:20. И сравните с 21:13. Соответственно должно быть разное потребление контроллером.
Спасибо,стараюсь ради зрителей! Так то может, ток потребления не замерял, не так это интересно. Скорость интересна.
Об этом и писал @user-fe6on9xu4w
Видео всё равно зачётное! +
Если есть сомнения в скорости , можно на вкладке ассемблера посмотреть за сколько команд происходит действие. Да и оптимизация может играть злую шутку. Видео хорошее , но осцилограф по частоте лучше с запасом в 10 раз
Согласен полностью на счет осциллографа, но другого нет и в 500МГц для дома не подъемно будет стоить. Есть урок 10 и там на ассемблере все получилось ;-)
Понижу оптимизацию до О0 и отпишусь.
Оптимизация на -О0 только уменьшила частоту на всех МК. На -O3 частота сигналов максимальная.
А вы могли бы записать пару тройку уроков кодинга на регистрах? С язык.
Просто после Atmel Studio тяжело хал воспринимать
Всё возможно. Только сейчас хочется делать совсем другое.
Очень хорошо!
Я по кусочкам смотрю видео , и вот назрел вопрос по скорости ногодрыга так называемого, 36 мГц я так и не смог добиться , а вот таймерами смог спокойно , в том числе с 50 % заполнением шим ,другие функции таймеров еще пока что изучаю , так что тут нужно искать где собака зарыта , скорее всего в HAL ?тут нужно отрывать и смотреть где какая проверка проходит
С халом все понятно. В видео хорошо показано на сравнении на кусочках как он работает. На Си я смог получить 36МГц для так называемого "ногодрыга". Таймером конечно удобнее работать.
1:14
4 Гигабайта адресного пространства это да.
Но я совершенно уже запутался сколько Байт находится под каждым из этих адресов.
Если вы найдёте в интернете тему: bit banding th-cam.com/video/IAMabY16PHw/w-d-xo.html
то увидите что каждому адресу bit band региона соответствует 32 адреса региона псевдонимов.
То есть на 1 Адрес который был, есть 32 адреса, а значит 32 бита.
И много где ещё говорится что информация во Flash памяти хранится в 32 битных словах.
Но когда пишешь в IDE и смотришь описание регистров, кажется что на каждый адрес один Байт. Не пойму.
32 бита это 4 байта, а дальше строгая адресация по map memory. Есть регистры на 2 байта, есть на 4 байта. Посмотрите теже GPIO, USART.
@@NRelectronics th-cam.com/video/IAMabY16PHw/w-d-xo.html
4010 0000 - 4000 0000==1 048 576 это 1 Мегабайт адресов
Каждый из этих адресов должен содержать 32 бита. Каждый из адресов.
Так как ровно в 32 раза больше то пространство псевдонимов, на которое ссылается эта 1 мегабайтная область.
Пространство псевдонимов от 4200 0000 до 4400 0000
4400 0000-4200 0000==200 0000== 32 Мб
Повторил для nucleo f411 и для g431. У меня почему-то нет разницы по частоте между ODR и BSRR. С чем может быть связано? 🤔
И какая частота получилась? Разница должна быть, ибо количество тактов разное на каждой команде.
@@NRelectronics для Nucleo f411 HCLK=100МГц: ODR и BSRR 9.1 МГц
для WeAct g431 HCLK=150МГц (170 не выставляются с 8МГц кварцем): ODR и BSRR 12.5 МГц
Вопрос в частоте шины и количестве тактов команды... Можно прикинуть...
@@NRelectronics самое интересное что для F407 (плата DEVE-Box) только что получил такую же картину. ODR и BSRR 14 МГц 🤯
Странно что они равные, bsrr работает атомарно быстрее. Собственно это лишь тест, использовать голый миландр редко когда нужно в мк, нужно данные вкладывать, а это ещё скорость снижает...
1:14
0хFFFF FFFF == 4 294 967 296== 4 Гибибайт.
Один адрес это как в компьютере один Байт?
Под порт А выделяется 1024 адреса. Это 1024 Байта?
Это килобайт. Действительно так много надо для регистров?
Один регистр 32 бит(16 во многих резервировано)==32 бит==4 Байта.
1024/4==256
Получается можно 256 регистров поместить в эту память.
Но регистров я думаю ведь меньше?
Всё так, да меньше. Ну вот такой стандарт распределения памяти
@@NRelectronics На хабре я нашёл такое:
Каждый из регистров имеет свой порядковый номер - адрес. Адрес регистра обозначается 32-битным числом представленным в шестнадцатеричной системе счисления.
---------------------
Если адрессация побайтовая, то как каждый регист может иметь свой адрес? Это адрес начального байта регистра или что?
Вам нужно посмотреть Memory Map например на GPIO или любую другую периферию. Есть начальный адрес и о него для каждой частицы хардвера свой адрес, это начальный адрес + смещение. И всё.
Не подскажите, как в кубеИДЕ найти/установить кнопку "Загрузить ПО в плату"? Всю голову уже сломал, но найти так и не смог =(. Заранее спасибо.
Кнопнка Run. В последнем видео ею пользовался, нужно сначала автоматом подгрузить серийник программатора и эта кнопка будет работать.
@@NRelectronics большое спасибо. Пока досмотрел до нужного момента в видео, благодаря подсказке автора в комментарии, уже сам нашел куда ткнуть нужно).
На всякий случай, чтобы таких вопросов не было потом у людей. В видео про пустой и рабочий проект в IDE на CMSIS показано, как прошивать.
Не за что. Про пустой проект на CMSISe я как раз говорил что зашиваем прошивку в мк этой кнопкой))
@@NRelectronics я до новых видео ещё просто не дошел=). Поэтому был не в курсе.
А, я понял. Думал смотрели. Хорошо что теперь мы разобрались как это делать, удачи в освоении!
Perfekt, Vielen Dank!
Vielen Dank für Ihren Kommentar! Empfehlen Sie den Kanal.
Хорошие ролики, спасибо. Под STM32 еще не чего не писал, но писал под AVR8. Сейчас знакомлюсь, в том числе и по вашим роликам. Мне не понятно, зачем 2 регистра порта для записи, ODR и BSSR, если оба делают одно и тоже? Но за разное время. И как надо было извратится с HAL, что простая запись в регистр отнимает столько времени. И почему с HAL изменение скорости порта не к чему не приводит?
C HALом вот такие накладные расходы, он так сделан, что изменение скорости порта такое низкое... Его только самому переписывать или просто использовать значение регистров
С HALом все понятно, слишком унифицирован, я б сказал ардуиноподобный. Решил на начальном этапе с CMSIS поработать, а дальше видно будет, еще раз спасибо, за то что учите нас.
Да, согласен, ардуиноподобный хал, и своими приколами. На регистрацию все яснее и проще.
Спасибо! Можно ли сделать или будет ли более детальное описание вкладки Clock Configuration и показать как соотносить с даташитом? Пока выглядит как магия.
Пожалуйста. Это уже сделано ранее:
th-cam.com/video/pgm_MphGOjM/w-d-xo.html
@@NRelectronics отлично! Сюда не дошёл ещё.
Следом посмотрите обязательно продолжение:
th-cam.com/video/a8t8mvR5Z88/w-d-xo.html
а потом ещё:
th-cam.com/video/C2knTvdv-KY/w-d-xo.html
Почти все посмотрел. Мне, как новичку, не очень понятно в каких задачах может быть нужны эти эксперименты с тактированием. С точки зрения, больше частота - лучше.
Когда нужно замедлять или использовать определенную частоту? Показано, что реальная частота на выходе все равно другая.
Возможно, просто нужно смотреть дальше. :-)
Это нужно в задачах, когда нужно по серьёзному экономить потребление. Хороший ход занизить тактировпние. Вы невнимательно видео посмотрели, я с 72МГц уменьшил до 36 МГц, а потом вернул также легко обратно. И показал это на длительности свечения светодиода по осциллографу.
Интересует вопрос почему реальное смещение не совпадает с тем, что задает компилятор (при загрузке из ОЗУ)?
0x080004EA 480C LDR r0,[pc,#48] ; @0x0800051C
0x080004EA 480C LDR r0,[pc,#0x30] ; @0x0800051C
offset = 0x0800051C - 0x080004EA = 0x32;
address = 0x080004EA + 30 = 0x0800051A;
diff = 0x0800051C - 0x0800051A = 0х02;
На сколько я понимаю смещение должно быть кратное 4, но тогда почему компилятор не подставляет сразу значение кратное 4?
Вопрос сразу тогда в ARM Holdings ;-)
Подскажите пожалуйста, есть ли способ переключать состояния выходов, при этом не останавливая выполнение кода?
Делаю буфер с шифратором, на несколько мегагерц. Пока идёт вывод, нужно также читать состояния других ножек и писать их в буфер. По коду 72 МГц едва хватит, но если он будет ждать каждого переключения выхода, то скорость будет как у атмеги. Даже плисы рассмотрел, но дорого и большой буфер не сделать.
Изменение состояния это ноль или единица? Алгоритмом задайте как вам нужно и меняйте на здоровье не останавливая код.
@@NRelectronics Я имею в виду, что рассмотренные в видео операции по установке 1 или 0 на выводе занимают очень много процессного времени.
На той же атмеге мы пишем в порт за один такт и сразу же выполняем дальнейший код. А на стм32, как я понимаю, при записи в порт программа ждет переключения ножки, в итоге контроллер будет всё процессорное время ждать переключения.
То есть i++ в вечном цикле будет работать на 72 мгц (без учета перехода), но цикл с инкрементом и переключением ножки уже будет делать инкремент в десятки раз реже. Как этого избежать?
@@MrPusyakaryagin bsrr или brr регистр это производит, изменения состояния, сейчас не вспомню точное название, запись одного значения в регистр один, разве это долго??
Спасибо. А что Вы скажете про библиотеку LL, вместо HAL?
Она считается менее насыщенной скажем так. С меньшим количеством проверок а значит стабильнее. Но на LL не все можно сделать как на HAL, посмотрим Description на эти библиотеку, хал по функционалу шире.
Встречал комбинацию HAL и LL, в LL советуют описывать GPIO , как раз из-за больших задержек в HAL, а можете добавить сравнение скорости работы выводов через LL, к уже имеющимся у Вас HAL и ассемблер ?
Большие задержки при старте МК и инициализации перефирии? Интересно это ж сколько в мс или мкс? При старте это происходит быстро, не думаю что это на что-то вообще может повлиять. Вы когда подаете питание на МК до десяти секунд можете с ним ничего не делать... А тут только инициализации. LLC мне библиотека мало интересна, пока не вижу смысла тратить на нее время.
Здравствуйте. Подскажите с чем может быть связано, делаю как у вас с ф103 но частоты отличаются в меньшую сторону?
Здравствуйте. Тактирование настроили точно как у меня?
@@NRelectronics всё именно так, прочитал в комментариях про оптимизацию с о3 добавилось ещё немного, но всё же меньше чем у вас по частотам. Плюс фронты не такие как у вас.
@@ShaneAMC каким осциллографом измеряли и какая частота получилась по ослику?
@@NRelectronics hantek dso5102p 100MHz. Частоты в зависимости от способа дрыганья отличаются на 10-20% в меньшую сторону от ваших.
Возможно у кого-то из нас ослик не точно измеряет, либо мк на на bluepill не оригинальный, коих много продается к сожалению на Али.
Спасибо за уроки. Вопрс?
GPIOB->BSRR = GPIO_BSRR_BR9; // ((uint32_t)0x02000000)
GPIOB->BSRR = GPIO_BSRR_BS9;
// ((uint32_t)0x00000200)
GPIOB->BRR = GPIO_BRR_BR9;
// ((uint16_t)0x0200)
GPIOB->BRR = GPIO_BSRR_BS9;
// ((uint32_t)0x00000200)
GPIOB->BSRR = (1 BSRR &= ~GPIO_ODR_ODR9; // ((uint16_t)0x0200)
Чем лучше пользоваться выставлять 0 или 1
(GPIOB->ODR ) медленно, и боится прерываний СПАСИБО
Я вас не совсем наверное понял. Единица для установки, нуль для сброса, от необходимости, установка каждого значения скорость одинаковая.
Лучше как вы в начале писали, читабильнее.
@@NRelectronics Спасибо за ответ - Третья строчка кода 16 бит поэтому и задумался. как и что лучше или правильнее.
@@NRelectronics Разобрался
BSRR - BR - 0 на выводе
(32бита)
BSRR - BS - 1 на выводе
(32бита)
---------------------------------------
BRR - (только BR) 1 на выводе
(16бит)
---------------------------------------
ODR - 0.7 мГц ногодрыг (пока прочитает - запишет)
понятно А....
BSRR - BS - 1 на выводе 1,38 мГц ногодрыг
BRR - BR - 1 на выводе 1,7 мГц ногодрыг
почему разница 1,38 и 1,7 - не может быть что бы в 16 битный запись 16 бит происходила чуть быстрее или компилятор как то влияет ??? ведь stm прожевывает 32 бита за тик.
Посмотрите в режиме отладки в окне дизассемблирования, все увидите. Сейчас нет возможности у меня сделать, я на работе.
А скажите пожалуйста про 0x200 равно 9. Где можно на онлайн калькуляторе это проверить? У меня не получается такое значение.Спасибо.
Спасибо за вопрос. Калькулятор в винде переключаете в режим для программистов. А так ручкой можно перевести ;-)
@@NRelectronics Так и делал но девятки не получается)
Так от куда они взялись то?
@@ilhitindustries7499 0x200 = 0b000000100000000. И это значение записывается в регистр ODR.
Воо, теперь понятно. Всем спасибо
Доброго времени суток у меня почемуто вот при этих значениях
GPIOA->ODR = 0x200;
GPIOA->ODR = 0;
частота показывает 12 мГц это нормально или не нормально
А вот при таких значениях
GPIOA->BSRR = GPIO_BSRR_BS9;
GPIOA->BSRR = GPIO_BSRR_BR9;
показывает 8 мГц
что я могу делать не так
или чего то я не понимаю
Если как в видео, то все у вас так, это нормально. Напишите повторение каждой пары раз пятьдесят для каждого случая и померьте частоту, удивитесь ;-)
@@NRelectronics У меня еще ослик ограничен 20 мГц и он у меня не супер быстрый , так что больших частот не увижу , а так посмотрю
@@Aleksandr_Sidorov тогда жалко, тут нужно иметь побольше полосы, причем лучше кратно больше.
Привет есть работка по STM32 ? занимаетесь написанием?
Здравствуйте. Написанием чего или для кого?
Так это предложение поработать или просто интересуетесь?
У меня почему-то команды
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_SET); //High
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_9, GPIO_PIN_RESET); //LOW
и
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_9);
Выдают максимум всего 500 Гц((( у меня STM32F407
Тактирование ставил 168 МГц и 84 МГц...
Почему такое может быть?
Странно,меньше чем у меня на видео... возможно разные у нас тактирования, шина, системная шина, кварц...
500 кГц?
У меня stm32f3 максимум выдает 0.5 МГц.
@@Frutktt вы, что-то написали одно и тоже...
@@NRelectronics всё верно, я хотел уточнить, выше у товарища 500 Гц. Наверное он имел в виду 500 кГц.
500 кГц и 0.5 МГц я написал, чтобы не повторяться)
@@Frutktt вот и я про тоже.
Есть мнение, что фронты ограничены скоростью нарастания ослика. 50мгц меандр не тоже самое что 50мгц синуса. И по "постоянной" составляющей видно что 10+ мгц меандр он не может.
Не скоростью, а полосой пропускания и теоремой Котельникова.
@@NRelectronics ну тут не все так просто) , скорость нарастание напряжение в/мкс связана с полосой пропускания. Понятно что так же связана и с амплитудой (но в тракте она +- постоянная). Так что измерить фронты импульса в 10мгц осликом на 50мгц не выйдет. 16нс для ослика со 125-250msa похоже на правду. Я думаю меандр там лучше чем на экране
@Инженерия от Clor'a я 18МГц измеряю осликом полосой 50МГц, показания нормальные как раз ;-)
@@NRelectronics На осциллографе с полосой пропускания 200MHz и частотой дискретизации 1GS/sec вы нормально (но не идеально) увидите меандр с частотой 20 MHz, с некоторыми оговорками (например измерять его параметры с известной погрешностью) имеющим частоту максимум 4MHz-6,6MHz. Если же Вы занимаетесь разработкой электронных устройств и Вам требуется изучать и измерять переходные процессы на фронтах меандра, вам по минимуму хватит для работы с меандром имеющим частоту в районе 50KHz.
Спасибо за видео ) интересно больше про cmsis смотреть , так как это основы , необдуманно юзать хал - как мне кажется , не правильно .
P.S с вами как то можно связаться ?(почта , телеграм )
Пожалуйста за видео) для инициализации переферии хал удобен, далее лучше самому все писать на CMSIS конечно. Почта nr.electronicss@gmail.com
Hal это быстрый порт готовых решений. Скорость разработки ни кто не отменял
HEX 200==10 0000 0000 бинарный вид
Единица стоит на десятом месте. Нумерация портов начинается ведь с нуля?
Первый порт это 0? Второй порт 1? Третий порт 10?
Если предположить что каждый бит это пин, то тоже не получается.
Здесь 10 0000 0000 единица стоит на десятом месте.
Получается что первый пин начинается с 10? Почему так?
А, ок понял.
Нулевой пин это 0
Первый пин это 10
Второй пин это 100
Третий пин 1000
и.т.д.
10 0000 0000 Это девятый пин, но учитывая что есть нулевой пин.
Хорошо, что сами определились. Это самое ценное в самообразовании.
На мой взгляд сложновато, куча всего создал.... что , зачем. В авр что написал то и получил.
Это еще стмка простая. Сложные не видел, все просто на самом деле, в начале сложновато да.
Не вижу настройки каждого пина для Mode,Pull,Speed,Alternate.
#define GPIO_MODE_INPUT 0x00000000U
Как это приспособить для определённого пина?
То есть настройка пинов порта происходит всех сразу, а не поотдельности.
Как выбирают из 16 ти пинов нужный, чтоб дать модус нужный?
Здесь GPIO_InitStruct.Pin информация сразу о 16 ти пинах передаётся.
Как узнать для какого именно пина я хочу сделать это #define GPIO_MODE_INPUT 0x00000000U
Здесь #define GPIO_MODE_INPUT 0x00000000U ведь нет информации о порядковом номере пина.
Ответы на эти вопросы относятся к регистрам. В плейлисте по CMSIS это есть.