【问题标题】:How can i use IDR我如何使用 IDR
【发布时间】: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-&gt;IDR |= (1U &lt;&lt; 1) 的结果永远是“真”。
  • 你说的对。但是有 16 个 IDR 寄存器。我的按钮是 IDR1 我怎么能看到 IDR1?
  • 我只是在这里猜测,但使用 bitwise 和 &amp; 来检查该位是否已设置?如(GPIOA-&gt;IDR &amp; (1U &lt;&lt; 1)) == (1U &lt;&lt; 1)?不过要小心,因为按下和保持该按钮将迅速增加ButtonPress。您可能想为按钮本身添加一个状态,因此您只在按下按钮时增加一次ButtonPress,并在释放按钮时重置状态。

标签: c embedded stm32 state-machine


【解决方案1】:

您正在尝试使用此行写入 IDR

if( GPIOA->IDR |= (1U << 1) )

由于 IDR 是只读的,因此该语句的计算结果始终为 false。

相反,您应该使用:

if (GPIOA->IDR & GPIO_PIN_1) { // GPIO_PIN_1 is a macro for (1U << 1)
    ButtonPress++;
}

评估 GPIOA 引脚 1 的值。

【讨论】:

    猜你喜欢
    • 2021-02-09
    • 2018-08-30
    • 2016-11-14
    • 1970-01-01
    • 1970-01-01
    • 2020-08-01
    • 1970-01-01
    • 2010-12-29
    • 2011-02-06
    相关资源
    最近更新 更多