【发布时间】:2022-11-23 04:54:58
【问题描述】:
我正在尝试制作一个带有按钮的状态机。当我按下按钮时,状态会改变。但我无法从 IDR 读取按钮。我怎样才能用 IDR 读取按钮? if( GPIOA->IDR |= (1U << 1) ) 我认为这部分有问题或者我应该启用一些寄存器或时钟?
`
int main(void) {
uint32_t ButtonPress = 0;
/* Enable GPIOA clock */
RCC->IOPENR |= (1U << 0);
/* Setup PA0 as output */
GPIOA->MODER &= ~(3U << 2*0);
GPIOA->MODER |= (1U << 2*0);
/* Setup PA1 as input */
GPIOA->MODER &= ~(3U << 2*1);
GPIOA->MODER |= (0U << 2*1);
/* Setup PA1 as Button1 */
// GPIOA->IDR |= (1U << 1);
while(1) {
if( GPIOA->IDR |= (1U << 1) )
ButtonPress++;
if(ButtonPress == 0)
/* Turn off LED */
GPIOA->ODR ^= (1U << 0);
else if(ButtonPress == 1){
/* Turn on LED 2sec interval */
GPIOA->ODR |= (1U << 0);
delay(LEDDELAY);
delay(LEDDELAY);
GPIOA->ODR ^= (1U << 0);
delay(LEDDELAY);
delay(LEDDELAY);
}
else if(ButtonPress == 2){
/* Turn on LED 1sec interval */
GPIOA->ODR |= (1U << 0);
delay(LEDDELAY);
GPIOA->ODR ^= (1U << 0);
delay(LEDDELAY);
}
else if(ButtonPress == 3){
/* Turn on LED 0.5sec interval */
GPIOA->ODR |= (1U << 0);
delay(LEDDELAY/2);
GPIOA->ODR ^= (1U << 0);
delay(LEDDELAY/2);
}
else if(ButtonPress == 4){
/* Turn on LED 0.1sec interval */
GPIOA->ODR |= (1U << 0);
delay(LEDDELAY/10);
GPIOA->ODR ^= (1U << 0);
delay(LEDDELAY/10);
}
else if(ButtonPress == 5){
/* Turn on LED */
GPIOA->ODR |= (1U << 0);
}
else
/* Button Reset */
ButtonPress = 0;
}
return 0;
}
`
我正在尝试制作一个带有按钮的状态机。当我按下按钮时,状态会改变。但我无法从 IDR 读取按钮。
【问题讨论】:
-
为什么使用
|=?那就是赋值,GPIOA->IDR |= (1U << 1)的结果永远是“真”。 -
你说的对。但是有 16 个 IDR 寄存器。我的按钮是 IDR1 我怎么能看到 IDR1?
-
我只是在这里猜测,但使用 bitwise 和
&来检查该位是否已设置?如(GPIOA->IDR & (1U << 1)) == (1U << 1)?不过要小心,因为按下和保持该按钮将迅速增加ButtonPress。您可能想为按钮本身添加一个状态,因此您只在按下按钮时增加一次ButtonPress,并在释放按钮时重置状态。
标签: c embedded stm32 state-machine