按下C的GPIO按钮

Gui*_*ert 3 c embedded

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

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

我很难理解的程序部分如下:

if(!(GPIOA->IDR & (1<<4)))
  Key=1;
Run Code Online (Sandbox Code Playgroud)

端口4 from GPIOA被设置为带上拉寄存器的输入。按下该按钮后,该信号将到达GND。IDR是输入数据寄存器。

所以我的问题是:

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

PS:我已经知道这(1<<4)是将位1左移四次的按位操作。

emb*_*yle 5

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

我们从表达式开始:

if(!(GPIOA->IDR & (1<<4)))
Run Code Online (Sandbox Code Playgroud)

我们正在使用16位数字来说明这16个引脚。扩展这一点,我们得到:

if(!(GPIOA->IDR & ((0000 0000 0000 0001) << 4)))
Run Code Online (Sandbox Code Playgroud)

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

if(!(GPIOA->IDR & (0000 0000 0001 0000)))
Run Code Online (Sandbox Code Playgroud)

扩展IDR,我将对X不关心?的位使用,对于要测试的未知位使用a:

if(!((XXXX XXXX XXX? XXXX) & (0000 0000 0001 0000)))
Run Code Online (Sandbox Code Playgroud)

接下来,我们有一个&按位与运算符。如果您还记得AND真值表:

&   0 1
    - -
0 | 0 0
1 | 0 1
Run Code Online (Sandbox Code Playgroud)

因此我们有以下操作:

  XXXX XXXX XXX? XXXX
& 0000 0000 0001 0000
---------------------
  0000 0000 000? 0000
Run Code Online (Sandbox Code Playgroud)

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

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

因此,我们有两种可能性:

//Button is pressed
if(!(0000 0000 0000 0000))
Run Code Online (Sandbox Code Playgroud)

要么:

//Button is not pressed
if(!(0000 0000 0001 0000))
Run Code Online (Sandbox Code Playgroud)

现在,重要的是要知道这!逻辑 NOT运算符。用于反转truefalse在条件语句。使用C语言理解这一点也很重要:

逻辑运算符(&&||!等)和条件测试语句(ifwhile)假设零是假的,其他所有的值是true

重点矿

因此,我们真正拥有的是:

//Button is pressed
if(!(false))
Run Code Online (Sandbox Code Playgroud)

要么:

//Button is not pressed
if(!(true))
Run Code Online (Sandbox Code Playgroud)

应用NOT:

//Button is pressed
if(true)
    Key=1;
Run Code Online (Sandbox Code Playgroud)

要么:

//Button is not pressed
if(false)
    Key=1;
Run Code Online (Sandbox Code Playgroud)