【问题标题】:GPIO button pressing in C按下 C 中的 GPIO 按钮
【发布时间】:2013-11-06 19:00:57
【问题描述】:

我在嵌入式领域相对较新,所以我可能是一个小新手问这个问题。

我无法理解 C 语言示例程序的语法,该程序检查是否按下按钮,如果按下则打开 LED。我正在使用 STM32F207VCT6 (Cortex-M3) 微控制器。

我无法理解的程序部分如下:

if(!(GPIOA->IDR & (1<<4)))
  Key=1;

GPIOA 的端口 4 设置为带上拉寄存器的输入。一旦按下按钮,来自按钮的信号就会进入 GND。 IDR 是输入数据寄存器。

所以我的问题是:

我不明白这段代码为什么需要if 语句中的非符号!。而且我不知道在if 内部进行了什么比较,因为没有相等的符号。有人可以帮我吗?

PS:我已经知道(1&lt;&lt;4) 是位 1 左移四次的按位运算。

【问题讨论】:

    标签: c embedded


    【解决方案1】:

    STM32F207VCT6 中每个端口有 16 个引脚。此操作试图确定端口 A 的单个引脚(4 号)的状态。让我们展开每个部分以更好地了解发生了什么。

    我们从表达式开始:

    if(!(GPIOA->IDR & (1<<4)))
    

    我们正在使用 16 位数字来计算 16 个引脚。展开这个我们得到:

    if(!(GPIOA->IDR & ((0000 0000 0000 0001) << 4)))
    

    您已经知道&lt;&lt; 是按位左移。应用这个我们得到:

    if(!(GPIOA->IDR & (0000 0000 0001 0000)))
    

    扩展IDR,我将使用X 来表示我们不关心的位,并使用? 来表示我们正在测试的未知位:

    if(!((XXXX XXXX XXX? XXXX) & (0000 0000 0001 0000)))
    

    接下来我们有一个&amp;,它是按位与运算符。如果你还记得你的 AND 真值表:

    &   0 1
        - -
    0 | 0 0
    1 | 0 1
    

    所以我们有操作:

      XXXX XXXX XXX? XXXX
    & 0000 0000 0001 0000
    ---------------------
      0000 0000 000? 0000
    

    如果端口 A 中的第 4 位是0,则结果将为0000 0000 0000 0000。如果端口 A 中的第 4 位是1,则结果将为0000 0000 0001 0000

    如果按下开关,输入将被拉至 GND,位 4 将设置为0。如果开关未按下,则内部上拉电阻会将输入拉高,并将第 4 位设置为1

    所以我们有两种可能:

    //Button is pressed
    if(!(0000 0000 0000 0000))
    

    或者:

    //Button is not pressed
    if(!(0000 0000 0001 0000))
    

    现在重要的是要了解!逻辑 NOT 运算符。在条件语句中反转 truefalse。同样重要的是要了解C language

    逻辑运算符(&amp;&amp;||! 等)和条件测试 语句 (if, while) 假设零为假,所有其他 值是真实的

    强调我的

    所以我们真正拥有的是:

    //Button is pressed
    if(!(false))
    

    或者:

    //Button is not pressed
    if(!(true))
    

    应用 NOT:

    //Button is pressed
    if(true)
        Key=1;
    

    或者:

    //Button is not pressed
    if(false)
        Key=1;
    

    【讨论】:

      【解决方案2】:
      if(!(GPIOA->IDR & (1<<4))) Key=1;
      

      等价于

      if((GPIOA->IDR & (1<<4)) == 0) Key=1;
      

      在 C 中,!E 等价于 E == 0

      所以这里基本上,如果GPIOA-&gt;IDR的第4位的值为0,则执行Key = 1;语句。

      【讨论】:

      • 这里可能缺少的另一个理解是由于上拉,输入正在反转。换句话说,当按下开关时,GPIO 输入处会出现逻辑 0。
      【解决方案3】:

      假设 GPIOA->IDR 是一个字节。

      [1111 1111] would infer that no GIPOA->IDR bits are cleared (grounded)
      [1111 1111] & [0000 1000] = 0000 1000 => != 0
      If the button was pressed...
      [1111 0111] & [0000 1000] = 0000 0000 => == 0
      

      鲍勃是你的叔叔。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-05-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-31
        • 1970-01-01
        相关资源
        最近更新 更多