我在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
}
谢谢!
答案 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
。
答案 2 :(得分:0)
我不建议使用这种方法。通过两个单独的步骤写入BSRR和BRR,意味着总线将通过意外状态转换,在该状态下,某些位仍会从前一个值开始设置。
相反,请考虑直接写入GPIO输出数据寄存器(ODR)。如果需要保留端口高位的原始值,则可以在CPU端执行该操作:
GPIOD->regs->ODR = (GPIOD->regs->ODR & 0xff00) | (bus8 & 0x00ff);