初中生
最后登录1970-1-1
在线时间 小时
注册时间2026-8-21
|
本帖最后由 LryCaulfield 于 2026-10-31 16:51 编辑
可以用GPIOB->ODR &= ~(1 << 0);
但这样有读、算、写3步,如果在读后写前ODR的值就改变了,那么用于计算的旧ODR值就不符合实际,算出的结果是旧ODR.bit0置1,在这读-写期间的改动就没有保留下来。
如(伪代码):
@ 开始时ODR = 0b01
ldr r0, =odr
ldr r0, [r0, #0] @取得ODR旧值0
mvn r1, #1 @取得~(1 << 0)
add r0, r1 @算得0b01 & ~(1 << 0) = 0b00 如果此时有中断处理将ODR改为0b11
ldr r1, =odr
str r0, [r1, #0] @将算得的0 & ~(1 << 0)写入ODR,中断处理做的工作被覆盖
最终我们得到ODR = 0b00,但我们其实希望中断也起作用,即结果为0b10
所以最好用BSRR寄存器GPIOB->BSRR = (1 << 16);或用位段宏GPIOB->BSRR = GPIO_BSRR_BR0;
这样只有1次写操作,由硬件置ODR的位,不会有过时旧值的问题
|
|