|
|||||||
Что быстрее: работа с регистрами CRL/CRH напрямую или через переменную?
Время создания: 09.05.2022 23:30
Текстовые метки: stm32, bluepill, регистры, CRL, CRH, режим, переключение, чтение, запись, ножка, пин
Раздел: Компьютер - Аппаратное обеспечение - Микроконтроллеры ARM
Запись: xintrea/mytetra_syncro/master/base/1652128251j46n4j3eus/text.html на raw.github.com
|
|||||||
|
|||||||
Иногда надо сделать на STM32 такое устройство, в котором режим ножек будет постоянно переключаться. Обычно режим ножки выставляется один раз в начале программы, и дальше ножка используется только в этом режиме. В STM32 даже не предусмотрено механизма быстрой установки режимов, как это сделано для значений портов через регистры BSRR/BRR. Зачем же может понадобиться постоянное переключение режима работы ножки? Например, если ножка подключается к какому-то цифровому устройству, и через нее должны выводиться сигналы только при наступлении определенного события (например, когда устройство обращается на чтение к STM-ке с помощью отправки сигнала по другой ножке). А все остальное время ножка должна находиться в неком режиме, чтобы не мешать работе подключенного устройства. Этот некий режим - режим Input, в котором STM-ка никак не может повлиять на значение сигнала на ножке, а может только его считывать (если это необходимо) Получается, что для вывода сигнала ножка должна переключиться в режим Output, а когда ножка не должна ничего передавать, она должна переключиться в режим Input. Установка режима ножки обычно происходит следующими этапами:
Описанные действия можно сделать следующим кодом (на примере пина B15): // Режим MODE и CNF, которые надо установить const uint32_t mode=0b11; // Режим выхода с максимальной частотой 50 МГц const uint32_t cnf=0b00; // Двухтактный выход (Output push-pull) // Обнуление битов режима GPIOB->CRH &= ~(GPIO_CRH_MODE15_Msk | GPIO_CRH_CNF15_Msk); // Установка режима GPIOB->CRH |= (mode << GPIO_CRH_MODE15_Pos) | (cnf << GPIO_CRH_CNF15_Pos); Здесь видно, что происходит считывание регистра GPIOB->CRH, выставление нулей в нужных местах, потом его запись, затем снова считывание, выставление битов режимов и запись. И возникает вопрос: а максимально ли быстро происходит этот процесс? Можно ли его хоть немного, но ускорить? Что если один раз считать значение регистра, подготовить нужное, и один раз записать в регистр? Будет ли такое решение работать быстрее? Измерения на оциллографе показывают, что да. Следующий код работает примерно на 5% быстрее, чем предыдущий: // Режим MODE и CNF, которые надо установить const uint32_t mode=0b11; // Режим выхода с максимальной частотой 50 МГц const uint32_t cnf=0b00; // Двухтактный выход (Output push-pull) // Переменная для хранения настроек регистра // В нее считывается значение регистра управления CRH. uint32_t statusB=GPIOB->CRH; // Обнуление битов режима во временной переменной statusB &= ~(GPIO_CRH_MODE15_Msk | GPIO_CRH_CNF15_Msk); // Установка режима GPIOB->CRH = statusB | (mode << GPIO_CRH_MODE15_Pos) | (cnf << GPIO_CRH_CNF15_Pos); Получается, что работа с памятью ОЗУ происходит несколько быстрее, чем работа с регистрами состояния портов. |
|||||||
Так же в этом разделе:
|
|||||||
|
|||||||
|