Привет, народ!
Заметил такую странность, которую не знаю как объяснить. Плата 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: Почему вызов этой функции может давать строго обратный эффект?