Синхронизированная настройка PIN -кода

Рик Кимбалл
Ср 28 декабря 2016 г., 21:48
Я наткнулся на интересную особенность регистров GPIO BSRR. Регистр BSRR позволяет изменить регистры как сброс (BSRR_H), так и SET (BSRR_L) для одного и того же вывода в одном операторе C. Вероятно, очевидно для некоторых, но я не видел его упоминания или много использовал много. Что это позволяет вам сделать, так это установить окончательное состояние нескольких выводов с одним оператором C, даже если вы очищаете один и устанавливаете другой. Вам не нужно загружать и изменять, вы просто изменяете. Это экономит несколько циклов и делает атомную настройку PIN -кода.

Вот пример, скажем, вы хотите переключить два булавки на 180 градусов из фазы с одним вызовом. Вы очищаете обе контакты, используя регистр сброса, я использую PA0 и PA1 для этого примера, поэтому вы используете 0B11 для сброса обе контакты, затем вы используете 0B01 для установки PA0, а затем в следующий раз используйте 0B10, чтобы установить PA1 на следующий. void setup() { pinMode(PA0,OUTPUT); pinMode(PA1,OUTPUT); } void loop() { static gpio_reg_map * const _GPIOA = GPIOA->regs; while(1) { _GPIOA->BSRR = 0b11 << 16 | 0b01; delay(1); _GPIOA->BSRR = 0b11 << 16 | 0b10; delay(1); } }

Rogerclark
Ср 28 декабря 2016 г. 22:00
Рик

Вот как Libmaple Core обрабатывает Digitalwrite

https: // github.com/rogerclarkmelbourne/ ... GPIO.H#L92

Рик Кимбалл
Ср 28 декабря 2016 г., 22:06
Хех .. Хорошо, у нас очень эффективное ядро :)

Тем не менее, используя его для синхронизации нескольких булавок на одном порте, похоже, не говорится о многом. Эта функция может пригодиться с вызовом DMA и значениями.

Rogerclark
Ср 28 декабря 2016 г. 22:09
Я посмотрел на это некоторое время назад, так как я убедился в эффективности необходимости переворачивать бит, а затем сделать переключение, поэтому я попробовал несколько других способов сделать это, но все остальное было медленным ;-)

Вы можете сделать синхронизированный настройки битов и сброс, используя регистр ODR, но накладные расходы на чтение REG в первую очередь и маскируют его и т. Д.

Рик Кимбалл
Ср 28 декабря 2016 г., 11:00 вечера
Rogerclark написал:Вы можете сделать синхронизированный настройки битов и сброс, используя регистр ODR, но накладные расходы на чтение REG в первую очередь и маскируют его и т. Д.

Стивестронг
Ср 28 декабря 2016 г. 11:10
Эта функция используется в модулях дисплеев с параллельным управлением 8/16.

victor_pv
Пт 30 декабря 2016 г., 4:34 утра
Рик Кимбалл написал: while(1) { _GPIOA->BSRR = 0b11 << 16 | 0b01; delay(1); _GPIOA->BSRR = 0b11 << 16 | 0b10; delay(1); } }

Рик Кимбалл
Пт 30 декабря 2016 г., 5:17 утра
Да, в этом случае вы можете сделать это так.

Вместе с лучшим использованием может использовать его с динамической переменной данных, и вы не знаете заранее, какие булавки будут на том, что будет отключить. Я мог бы сделать 2 -битную случайную переменную и использовать ее вместо жестко закодированного 0B01, и он все равно будет правильно установить все биты. Это все равно было бы атомным и не потребовать нагрузки и модифицировать.

Может быть, вы хотите использовать счетчик на булавках: void setup() { pinMode(PA0,OUTPUT); pinMode(PA1,OUTPUT); pinMode(PA2,OUTPUT); } void loop() { static gpio_reg_map * const _GPIO = GPIOA->regs; unsigned counter=0; while(1) { _GPIO->BSRR = 0b111 << 16 | counter++ & 0b111; } }

Racemaniac
Пт 30 декабря 2016 г., 7:07
Рик Кимбалл написал:Хех .. Хорошо, у нас очень эффективное ядро :)

Тем не менее, используя его для синхронизации нескольких булавок на одном порте, похоже, не говорится о многом. Эта функция может пригодиться с вызовом DMA и значениями.

victor_pv
Сб 31 декабря 2016 г., 7:11 утра
Рик, я думаю, я понимаю, вы сбрасываете их все "по умолчанию", а затем устанавливаете все, что нужно быть установлено. Вместо того, чтобы специально сбросить некоторые булавки, вы сбросите все и устанавливаете то, что нужно настроить.
Затем набор, 16 нижних битов, имеет приоритет, верно?

Рик Кимбалл
Сб 31 декабря 2016 г. 16:27
да точно

USART (серийный) прерывание