我在stm32单片机上设置了一个8位总线on (PD0:PD7),以便将地址发送到另一个芯片(0:255)。我感兴趣的是,如果像下面这样的函数可以快速更改地址。我找不到直接显示register等于integer的示例,所以我想确认它是否有效。我需要一个函数,我将给它一个整数值作为地址(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
}谢谢!
发布于 2019-06-30 14:23:10
是的,两者都应该可以工作。然而,一个更容易识别但等效的表述是:
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));
}快乐的比特-小提琴!
发布于 2019-06-30 14:41:43
是的,它肯定能行得通。但是,正如其他人所指出的,建议在单个操作中设置输出。
利用完整的32位BSRR寄存器,无需反转数据位即可完成此操作:
GPIOD->regs->BSRR = bus8 | (0xFF << 16);或
GPIOD->regs->BSRR = (bus8 << 5) | (0xFF << (16 + 5));由于BSRR具有在一次写入操作中设置某些位和复位某些位的功能,并且当特定引脚的置位和复位位都已置位时,输出将变为1。

发布于 2019-06-30 14:16:57
我不推荐使用这种方法。作为两个独立的步骤写入BSRR和BRR意味着总线将过渡到非预期状态,其中某些位仍从先前的值设置。
相反,可以考虑直接写入GPIO输出数据寄存器(ODR)。如果您需要保留端口中高位的原始值,您可以在CPU端执行此操作:
GPIOD->regs->ODR = (GPIOD->regs->ODR & 0xff00) | (bus8 & 0x00ff);https://stackoverflow.com/questions/56822789
复制相似问题