I'm relatively new in the embedded world, so I may be a little newbie asking this.
I'm having trouble to understand the syntax of an example program in C that checks if a button is pressed and then turning a LED on if so. I'm using a STM32F207VCT6 (Cortex-M3) microcontroller.
The part of the program that I'm having trouble to understand is the following:
if(!(GPIOA->IDR & (1<<4)))
Key=1;
Port 4 from GPIOA is set to be an input with pull-up register. The signal from the button goes to GND once it's pressed. IDR is the input data register.
So my question is:
I don't understand in this code why the NOT symbol, !, inside the if statement is needed. And I do not know what comparison is being made inside the if, since there is no sign of equal. Can someone help me with that?
PS: I already know that (1<<4) is the bit-wise operation for left shifting the bit 1 four times.
There are 16 pins per port in the STM32F207VCT6. This operation is trying to determine the state of a single pin, number 4, of port A. Let's expand each part to better understand what is going on.
We start with the expression:
if(!(GPIOA->IDR & (1<<4)))
We're working with a 16-bit number to account for the 16 pins. Expanding this we get:
if(!(GPIOA->IDR & ((0000 0000 0000 0001) << 4)))
You already know that << is a bitwise left shift. Applying this we get:
if(!(GPIOA->IDR & (0000 0000 0001 0000)))
Expanding the IDR, I will use X's for bits that we don't care about and a ? for the unknown bit we are testing for:
if(!((XXXX XXXX XXX? XXXX) & (0000 0000 0001 0000)))
Next we have a & which is the bitwise AND operator. If you remember your AND truth table:
& 0 1
- -
0 | 0 0
1 | 0 1
So we have the operation:
XXXX XXXX XXX? XXXX
& 0000 0000 0001 0000
---------------------
0000 0000 000? 0000
If Bit 4 in Port A is a 0, the the result will be 0000 0000 0000 0000. If Bit 4 in Port A is a 1, the the result will be 0000 0000 0001 0000.
If the switch is pressed, the input will be pulled to GND and Bit 4 will be set to 0. If the switch is unpressed, then the internal pull-up will pull the input high and Bit 4 will be set to 1.
So we have two possibilities:
//Button is pressed
if(!(0000 0000 0000 0000))
Or:
//Button is not pressed
if(!(0000 0000 0001 0000))
Now it's important to understand that ! is the Logical NOT operator. Which inverts true and false in conditional statements. It is also important to understand that in the C language:
Logical operators (
&&,||,!, etc.) and condition-testing statements (if,while) assume that zero is false and all other values are true.
Emphasis mine
So what we really have is:
//Button is pressed
if(!(false))
Or:
//Button is not pressed
if(!(true))
Applying the NOT:
//Button is pressed
if(true)
Key=1;
Or:
//Button is not pressed
if(false)
Key=1;
if(!(GPIOA->IDR & (1<<4))) Key=1;
is equivalent to
if((GPIOA->IDR & (1<<4)) == 0) Key=1;
In C, !E is equivalent to E == 0.
So here basically, Key = 1; statement is executed if the value of bit 4 of GPIOA->IDR is 0.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With