Подойдет ли мое решение для адресации 8-битной шины с использованием BSRR и BRR? - PullRequest
2 голосов
/ 30 июня 2019

Я установил 8-битную шину (PD0: PD7) на микроконтроллере stm32 для отправки адресов другому чипу (0: 255).Меня интересует, будет ли функция, подобная ниже, работать для быстрой смены адресов.Я не смог найти пример, показывающий, что регистр равен целому числу, поэтому я хочу подтвердить, что он будет работать.Мне нужна функция, которой я дам целочисленное значение для адреса (0: 255), и он установит 8 выводов шины с этим значением:

void chipbus(uint16_t bus8){
   GPIOD->regs->BSRR = bus8;      // set all the '1' in bus8 to high
   GPIOD->regs->BRR = 255-bus8;   // 255-bus8 inverts the 8 bits
                                  // BRR to set the new '1' to low
}

Если это решение работает, яЛюбопытно также, если я переключу шину на порты PD5: PD12 будет работать моя функция как:

void chipbus(uint16_t bus8){
   GPIOD->regs->BSRR = bus8*32;      // set all '1' in bus8 to high
                                     // multiply by 32 to shift 5 bits/pins
   GPIOD->regs->BRR = (255-bus8)*32; // 255-bus8 inverts the 8 bits
                                     // BRR to set the new '1' to low
}

Спасибо!

Ответы [ 3 ]

1 голос
/ 30 июня 2019

Да, оба должны работать.Тем не менее, более узнаваемой, но эквивалентной формулировкой будет:

void chipbus(uint16_t bus8) {
  GPIOD->regs->BSRR = bus8; // set all the '1' in bus8 to high
  GPIOD->regs->BRR = (~bus8) & 0xFF; // inverts the 8 bits // BRR to set the new '1' to low
}

void chipbus(uint16_t bus8) {
  GPIOD->regs->BSRR = bus8<<5; // set all '1' in bus8 to high, shift 5 bits
  GPIOD->regs->BRR = ((~bus8)&0xFF)<<5; // inverts the 8 bits
}

Но есть еще более быстрый путь.BSRR - это 32-битный регистр, который можно устанавливать и сбрасывать.Вы можете объединить два доступа для записи в один:

void chipbus(uint16_t bus8) {
  GPIOD->regs->BSRR =
    (bus8<<5) | (((~bus8) & 0xFF) << (16+5));
}

Удачи!

1 голос
/ 30 июня 2019

Да, это определенно сработает. Однако, как отметили другие, рекомендуется устанавливать выходы в одной операции.

Используя полный 32-битный регистр BSRR, это можно сделать без инвертирования битов данных:

GPIOD->regs->BSRR = bus8 | (0xFF << 16);

или

GPIOD->regs->BSRR = (bus8 << 5) | (0xFF << (16 + 5));

, поскольку BSRR обладает функциональностью для установки некоторых битов и сброса некоторых других в одной операции записи, а когда установлены биты установки и сброса для конкретного вывода, выводом становится 1.

enter image description here

0 голосов
/ 30 июня 2019

Я бы не рекомендовал использовать этот подход. Запись в BSRR и BRR как два отдельных шага означает, что шина перейдет в непреднамеренное состояние, в котором некоторые биты все еще установлены из предыдущего значения.

Вместо этого рассмотрите возможность записи непосредственно в регистр выходных данных GPIO (ODR). Если вам нужно сохранить исходное значение старших бит в порту, вы можете сделать это на стороне процессора:

GPIOD->regs->ODR = (GPIOD->regs->ODR & 0xff00) | (bus8 & 0x00ff);
...