xintrea 0 3 мая, 2022 Опубликовано 3 мая, 2022 (изменено) · Жалоба Привет, народ! Заметил такую странность, которую не знаю как объяснить. Плата STM32F103C8T6 (Blue Pill) Я хотел сделать мигание светодиодом на ноге A0 при инициализации контроллера на 72MHz. Взял сделанный ранее проект и стал его упрощать. И вот когда оставил в проекте, по-сути, только: - инициализацию на 72Mhz - включение тактирования портов - настройку пина A0, то заметил, что код мигания стал работать медленнее! Т. е. мигание, сделанное в бесконечном цикле, стало в 1.5-2 раза медленнее, чем было до. Я стал разбираться, что могло на это повлиять. И вернул вызов ненужной функции, в которой инициализировались пины A8, A9, B3, B4, B6, B7. И о чудо, мигание стало опять быстрым! Повторюсь, в этой функции делается только инициализация пинов, и она вызывается один раз в начале программы, ничего более. Вот полный код: https://pastebin.com/Z7d0LZif А вот код функции, которая "разгоняет" выполнение кода: // Настройка пинов A8, A9, B3, B4, B6, B7 void otherPortInit(void) { // Для начала сброс конфигурации всех используемых портов в ноль GPIOA->CRH &= ~(GPIO_CRH_MODE8 | GPIO_CRH_CNF8); GPIOA->CRH &= ~(GPIO_CRH_MODE9 | GPIO_CRH_CNF9); GPIOB->CRL &= ~(GPIO_CRL_MODE3 | GPIO_CRL_CNF3); GPIOB->CRL &= ~(GPIO_CRL_MODE4 | GPIO_CRL_CNF4); GPIOB->CRL &= ~(GPIO_CRL_MODE6 | GPIO_CRL_CNF6); GPIOB->CRL &= ~(GPIO_CRL_MODE7 | GPIO_CRL_CNF7); uint32_t mode; uint32_t cnf; mode=0b11; // Режим выхода, с максимальной частотой 50 МГц cnf=0b00; // Режим push-pull GPIOA->CRH |= (mode << GPIO_CRH_MODE8_Pos) | (cnf << GPIO_CRH_CNF8_Pos); GPIOA->CRH |= (mode << GPIO_CRH_MODE9_Pos) | (cnf << GPIO_CRH_CNF9_Pos); mode=0b00; // Режим входа cnf=0b01; // Режим плавающего входа, подтяжки нет GPIOB->CRL |= (mode << GPIO_CRL_MODE3_Pos) | (cnf << GPIO_CRL_CNF3_Pos); GPIOB->CRL |= (mode << GPIO_CRL_MODE4_Pos) | (cnf << GPIO_CRL_CNF4_Pos); GPIOB->CRL |= (mode << GPIO_CRL_MODE6_Pos) | (cnf << GPIO_CRL_CNF6_Pos); GPIOB->CRL |= (mode << GPIO_CRL_MODE7_Pos) | (cnf << GPIO_CRL_CNF7_Pos); } Я не могу эту вещь объяснить. Почему настройки пинов, которые не используются в коде, так странно влияют на скорость выполнения программы контроллером? Мало того, в базовом проекте, на точно таком же коде я обнаружил обратный эффект: вызов этой функции инициализации портов замедляет мигание, а комментирование ее вызова - ускоряет. В общем, я в недоумении. Я вообще не ожидал, что такое поведение возможно. Это тормозит разработку домашнего проекта, потому то в нем критична реакция на сигналы длительностью ~500нс, и тут я вижу, что тупой бесконечный цикл работает с разной скоростью в зависимости от инициализации неиспользуемых портов. Вопрос 1: Как единственный вызов этой функции может влиять на скорость выполнения основного цикла? Вопрос 2: Почему вызов этой функции может давать строго обратный эффект? Изменено 3 мая, 2022 пользователем xintrea Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 3 мая, 2022 Опубликовано 3 мая, 2022 · Жалоба Сравните листинги функций msDelay для разных сборок. От того, как компилятор их реализует многое будет зависеть. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xintrea 0 3 мая, 2022 Опубликовано 3 мая, 2022 · Жалоба 16 minutes ago, adnega said: Сравните листинги функций msDelay для разных сборок. От того, как компилятор их реализует многое будет зависеть. Опции компиляции всех проектов у меня одинаковые. Оптимизация везде -Os и все. Или хотите сказать, что в разном окружающем коде компилятор будет по-разному компилировать msDelay? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 3 мая, 2022 Опубликовано 3 мая, 2022 · Жалоба 21 минуту назад, xintrea сказал: Опции компиляции всех проектов у меня одинаковые. Оптимизация везде -Os и все. Или хотите сказать, что в разном окружающем коде компилятор будет по-разному компилировать msDelay? Я другого объяснения придумать не могу, и это легко проверить. Кста, про скорость, вроде -03, а -Os это про размер. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xintrea 0 3 мая, 2022 Опубликовано 3 мая, 2022 (изменено) · Жалоба 1 hour ago, adnega said: Сравните листинги функций msDelay для разных сборок. От того, как компилятор их реализует многое будет зависеть. В общем, проверил. Функция msDelay() в обеих случаях закомпилилась одинаково, байт в байт: 24 minutes ago, adnega said: Кста, про скорость, вроде -03, а -Os это про размер. Я же для микроконтроллера компилю, по дефолту оптимизация по размеру. Изменено 3 мая, 2022 пользователем xintrea Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 69 3 мая, 2022 Опубликовано 3 мая, 2022 · Жалоба 22 minutes ago, xintrea said: Функция msDelay() в обеих случаях закомпилилась одинаково, байт в байт Вот только адреса разные. Скорость выполнения зависит от смещения кода в 64 (или 128?) битном блоке. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 27 3 мая, 2022 Опубликовано 3 мая, 2022 · Жалоба Проверяйте настройку тактовой системы. ф. int clockInit(void) даже возвращает ошибки, обработку которых я не увидел. Тем более на предельных режимах тактовой. Неплохо было бы убедиться аппаратно, что тактовая реально установилась на 72MHz. Возможно "играет рояль" то, что комментируемая строка вносит задержку после кода инициализации. В цикле мигалки уменьшите или увеличьте значения задержек в 2 раза, проконтролируйте что частота мигания также увеличилась (уменьшилась) в 2 раза. Используйте осциллограф на светодиоде, тк может оказаться, что "мигание" это ШИМ. ps 1 hour ago, xintrea said: . . . Это тормозит разработку домашнего проекта, потому то в нем критична реакция на сигналы длительностью ~500нс, и тут я вижу, что тупой бесконечный цикл работает с разной скоростью в зависимости от инициализации неиспользуемых портов. . . . Я конечно сильно извиняюсь, не мое это дело, но Вы собираетесь события с порядком "длительности" 500ns фиксировать методом опроса ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xintrea 0 3 мая, 2022 Опубликовано 3 мая, 2022 · Жалоба 48 minutes ago, k155la3 said: Проверяйте настройку тактовой системы. ф. int clockInit(void) даже возвращает ошибки, обработку которых я не увидел. Тем более на предельных режимах тактовой. Неплохо было бы убедиться аппаратно, что тактовая реально установилась на 72MHz. Да, там реально 72MHz устанавливается. Функция инициализации такая же как и здесь: https://webhamster.ru/mytetrashare/index/mtb0/1649356037vhemuctihu и на ноге 12 в этом коде реально 60нс на осциллографе видно. 48 minutes ago, k155la3 said: Возможно "играет рояль" то, что комментируемая строка вносит задержку после кода инициализации. Где про обязательность задержки можно прочитать? Что-то в даташите не нашел таких ограничений. 48 minutes ago, k155la3 said: В цикле мигалки уменьшите или увеличьте значения задержек в 2 раза, проконтролируйте что частота мигания также увеличилась (уменьшилась) в 2 раза. Да, частота видимых миганий изменяется в двое. 48 minutes ago, k155la3 said: Используйте осциллограф на светодиоде, тк может оказаться, что "мигание" это ШИМ. Ну какой ШИМ, там же просто включется-выключется нога с задержкой. 48 minutes ago, k155la3 said: Я конечно сильно извиняюсь, не мое это дело, но Вы собираетесь события с порядком "длительности" 500ns фиксировать методом опроса ? Можете предложить другой метод? На таком оборудовании через прерывания ловить события не получится, потому что только на вход в прерывание больше 500нс уходит. Если приплюсовать сюда выход и задержку прохода сигнала прерывания, то получится что с прирываниями работать вообще не вариант. А методом опроса можно ловить события, и еще 15-25 тактов останется на логику, а мне больше и не надо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 3 мая, 2022 Опубликовано 3 мая, 2022 · Жалоба 6 минут назад, xintrea сказал: Можете предложить другой метод? А что за сигнал/обработка? Таймеры/FPGA/CPLD/рассыпуха ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 4 мая, 2022 Опубликовано 4 мая, 2022 · Жалоба 8 часов назад, xintrea сказал: Или хотите сказать, что в разном окружающем коде компилятор будет по-разному компилировать msDelay? Учитесь использовать таймер для учёта и выдержки временных интервалов. Иначе всё время будете спотыкаться о такие "чудеса". 5 часов назад, xintrea сказал: Можете предложить другой метод? Пока не расскажете о решаемой задаче, никто ничего путного предложить не сможет. Судя по вашему описанию - движетесь в неверном направлении. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Eddy_Em 2 4 мая, 2022 Опубликовано 4 мая, 2022 · Жалоба 8 hours ago, xintrea said: методом опроса можно ловить события Лучше уж таймер настроить в режиме измерения длительности входного импульса. Запустил, через миллисекунду проверил. Если ноль - события не было... А еще лучше - правильно сформулировать свою задачу. Возможно, ее можно решить простым способом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 27 4 мая, 2022 Опубликовано 4 мая, 2022 · Жалоба 9 hours ago, xintrea said: Где про обязательность задержки можно прочитать? Что-то в даташите не нашел таких ограничений. Это не "обязательность", а симптом вашей проблемы. Все-таки, как с кодом результата работы ClockInit(), то что в Вашей ссылке // Настройка тактирование системы от внешнего кварца // через PLL на максимально возможных частотах. // Внешний кварц должен быть на 8МГц // Возвращает: // 0 - завершено успешно // 1 - не запустился кварцевый генератор // 2 - не запустился PLL // Итоговая настройка делается на 72МГц int ClockInit(void) Если уж решать задачу "тупо и в лоб", залазите в otherPortInit() и блочно/построчно отлавливаете что влияет на "симптом". То что "функция инициализации такаяже как здесь" не гарантирует, что она корректно работает. На какой пин процессора подключен светодиод ? (проверить прозвонкой) д.б. на PC13 пин процессора 2. Другой метод можно предложить, но для этого нужно, как писали выше, описание входных сигналов - а именно частота их возникновения и длительность. Ну, и количество линий. А использовать такой процессор в режиме опроса "негуманно". Ну, еслиб это был у вас 8-разрядный контроллер с 64 бит RAM и 256 байт программной памяти ... без прерываний .... без таймера .... тогда может быть да, режим "опроса" со-скрипом подходит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
xintrea 0 4 мая, 2022 Опубликовано 4 мая, 2022 (изменено) · Жалоба 18 hours ago, jcxz said: Пока не расскажете о решаемой задаче, никто ничего путного предложить не сможет. Я пытаюсь сделать эмулятор ПЗУ для клона Радио-86РК. Он подключается в разъем, на который выведена ША а ШД этого компьютера, и еще несколько системных сигналов. Под подключаемые внешние модули (эмулятор ПЗУ-это и есть внешний модуль) в компьютере отведено адресное пространство 8000h-BFFFh (объем 16Кб). Задача эмулятора ПЗУ - держать пины ШД, к котором подключен контроллер STM, в высокоимпендансном состоянии, и следить за адресом на ША. Если адрес попадает в обслуживаемый эмулятором диапазон, и приходит сигнал на чтение, пины ШД переводятся в состояние выхода и на них выставляется нужный байт. Длительность сигнала на чтение - 500нс. Все. 14 hours ago, k155la3 said: Ну, еслиб это был у вас 8-разрядный контроллер с 64 бит RAM и 256 байт программной памяти ... без прерываний .... без таймера .... тогда может быть да, режим "опроса" со-скрипом подходит. Такой контроллер не подойдет, одна только эмулируемая прошивка будет занимать 16Кб программной памяти. Изменено 4 мая, 2022 пользователем xintrea Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Eddy_Em 2 5 мая, 2022 Опубликовано 5 мая, 2022 (изменено) · Жалоба Возьми МК с FSMC. По-другому ты ничего не добьешься: изменение состояния ног при помощи ODR/BSR/BSRR будет медленней и менее надежно, чем при помощи FSMC, таймера либо другой периферии! P.S. вот здесь у меня отлично работала адресная светодиодная лента на WS2815 при помощи таймера с DMA (длительности импульсов в 333нс и 667нс). Ногодрыгом так не сделать. Изменено 5 мая, 2022 пользователем Eddy_Em Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Edit2007 3 5 мая, 2022 Опубликовано 5 мая, 2022 · Жалоба Можно использовать двухпортовое ОЗУ (или гибрид SPI - параллельная шина). С одной стороны МК грузит прошивку (легко обновлять), с другой стороны ее вычитывает клон (минимальные аппаратные издержки). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться