我的解决方案适用于使用BSRR和BRR的8位总线寻址吗?

时间:2019-06-30 06:08:51

标签: stm32 gpio

我在stm32 MCU的(PD0:PD7)上设置了8位总线,以将地址发送到另一个芯片(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 个答案:

答案 0 :(得分:1)

是的,两者都应该起作用。但是,更可识别但等效的表述为:

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 :(得分:1)

是的,肯定可以。但是,正如其他人指出的那样,建议将输出设置为单个操作。

利用完整的32位BSRR寄存器,可以在不反转数据位的情况下完成此操作:

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

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

因为BSRR具有在单个写操作中设置一些位并重置其他一些功能的功能,并且当设置了特定引脚的置位和重置位时,输出将变为1

enter image description here

答案 2 :(得分:0)

我不建议使用这种方法。通过两个单独的步骤写入BSRR和BRR,意味着总线将通过意外状态转换,在该状态下,某些位仍会从前一个值开始设置。

相反,请考虑直接写入GPIO输出数据寄存器(ODR)。如果需要保留端口高位的原始值,则可以在CPU端执行该操作:

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