Difference between revisions of "Bitmasking Tutorial"
(→Unions) |
Proj user14 (talk | contribs) |
||
(10 intermediate revisions by one other user not shown) | |||
Line 22: | Line 22: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | <br/> | ||
== Bit RESET == | == Bit RESET == | ||
To reset a bit, the logic is similar, but instead of '''OR'''ing a bit, we will AND a bit. '''Remember that AND gate resets a bit if you AND it with 0 so we need to use a tilde (~) to come up with the correct logic: | To reset a bit, the logic is similar, but instead of '''OR'''ing a bit, we will AND a bit. '''Remember that AND gate resets a bit if you AND it with 0 so we need to use a tilde (~) to come up with the correct logic: | ||
Line 41: | Line 42: | ||
REG &= ~( (1 << 21) | (1 << 23) ); | REG &= ~( (1 << 21) | (1 << 23) ); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
<br/> | <br/> | ||
− | |||
== Bit checking == | == Bit checking == | ||
Suppose you want to wait for a register's bit#7 to set: | Suppose you want to wait for a register's bit#7 to set: | ||
Line 64: | Line 65: | ||
while(REG & (1 << 9)); | while(REG & (1 << 9)); | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
<br/> | <br/> | ||
Line 72: | Line 74: | ||
* GPIO read: IOPIN register | * GPIO read: IOPIN register | ||
* GPIO write: IOPIN register | * GPIO write: IOPIN register | ||
+ | |||
+ | Each bit of FIODIR1 corresponds to each external pin of PORT1. So, bit0 of FIODIR1 controls direction of physical pin P1.0 and bit31 of FIODIR2 controls physical pin P2.31. Similarly, each bit of IOPIN1 or IOPIN2 controls output high/low of physical ports P1 and P2. IOPIN not only allows you to set an output pin, but it allows you to read input values as sensed on the physical pins. | ||
Suppose a switch is connected to GPIO Port P1.14 and an LED is connected to Port P1.15. Note that if a bit is set of FIODIR register, the pin is OUTPUT otherwise the pin is INPUT. '''So... 1=OUTPUT, 0=INPUT''' | Suppose a switch is connected to GPIO Port P1.14 and an LED is connected to Port P1.15. Note that if a bit is set of FIODIR register, the pin is OUTPUT otherwise the pin is INPUT. '''So... 1=OUTPUT, 0=INPUT''' | ||
+ | |||
<syntaxhighlight lang="c"> | <syntaxhighlight lang="c"> | ||
// Set P1.14 as INPUT for the switch: | // Set P1.14 as INPUT for the switch: | ||
LPC_GPIO1->FIODIR &= ~(1 << 14); | LPC_GPIO1->FIODIR &= ~(1 << 14); | ||
− | // Set P1. | + | // Set P1.15 as OUTPUT for the LED: |
LPC_GPIO1->FIODIR |= (1 << 15); | LPC_GPIO1->FIODIR |= (1 << 15); | ||
Line 91: | Line 96: | ||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
+ | |||
<br/> | <br/> | ||
LPC also has dedicated registers to set or reset an IOPIN with hardware AND and OR logic: | LPC also has dedicated registers to set or reset an IOPIN with hardware AND and OR logic: | ||
− | |||
− | |||
<syntaxhighlight lang="c"> | <syntaxhighlight lang="c"> | ||
− | + | if(LPC_GPIO1->FIOPIN & (1 << 14)) { | |
− | + | LPC_GPIO1->IOSET = (1 << 15); // No need for |= | |
− | { | + | } |
− | + | else { | |
− | + | // Else turn off the LED: | |
− | + | LPC_GPIO1->IOCLR = (1 << 15); // No need for &= | |
− | + | } | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | } | ||
− | |||
− | / | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
</syntaxhighlight> | </syntaxhighlight> | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
<br/> | <br/> | ||
+ | == Read More == | ||
+ | You can read the advanced bit-masking over at the [[Bit Structures | Bit structure and union page]] |
Latest revision as of 11:21, 18 December 2016
Bit-masking is a technique to selectively modify individual bits without affecting other bits.
Bit SET
To set a bit, we need to use the OR operator. This is just like an OR logical gate you should've learnt in Digital Design course. To set a bit, you would OR a memory with a bit number and the bit number with which you will OR will end up getting set.
// Assume we want to set Bit#7 of a register called: REG
REG = REG | 0x80;
// Let's set bit#31:
REG = REG | 0x80000000;
// Let's show you the easier way:
// (1 << 31) means 1 gets shifted left 31 times to produce 0x80000000
REG = REG | (1 << 31);
// Simplify further:
REG |= (1 << 31);
// Set Bit#21 and Bit# 23:
REG |= (1 << 21) | (1 << 23);
Bit RESET
To reset a bit, the logic is similar, but instead of ORing a bit, we will AND a bit. Remember that AND gate resets a bit if you AND it with 0 so we need to use a tilde (~) to come up with the correct logic:
// Assume we want to reset Bit#7 of a register called: REG
REG = REG & 0x7F;
REG = REG & ~(0x80); // Same thing as above, but using ~ is easier
// Let's reset bit#31:
REG = REG & ~(0x80000000);
// Let's show you the easier way:
REG = REG & ~(1 << 31);
// Simplify further:
REG &= ~(1 << 31);
// Reset Bit#21 and Bit# 23:
REG &= ~( (1 << 21) | (1 << 23) );
Bit checking
Suppose you want to wait for a register's bit#7 to set:
// One way:
while( (1<<7) != (REG & (1 << 7))) {
};
// Easier way:
while( ! (REG & (1 << 7)) );
Now let's work through another example in which we want to wait until bit#9 is 0
// One way:
while(REG & (1 << 9) != 0);
// Easier way:
while(REG & (1 << 9));
GPIO Example of LPC17xx
In this example, we will work with an imaginary circuit of a switch and an LED. For a given port, the following registers will apply:
- GPIO selection: PINSEL register (not covered by this example)
- GPIO direction: DIR (direction) register
- GPIO read: IOPIN register
- GPIO write: IOPIN register
Each bit of FIODIR1 corresponds to each external pin of PORT1. So, bit0 of FIODIR1 controls direction of physical pin P1.0 and bit31 of FIODIR2 controls physical pin P2.31. Similarly, each bit of IOPIN1 or IOPIN2 controls output high/low of physical ports P1 and P2. IOPIN not only allows you to set an output pin, but it allows you to read input values as sensed on the physical pins.
Suppose a switch is connected to GPIO Port P1.14 and an LED is connected to Port P1.15. Note that if a bit is set of FIODIR register, the pin is OUTPUT otherwise the pin is INPUT. So... 1=OUTPUT, 0=INPUT
// Set P1.14 as INPUT for the switch:
LPC_GPIO1->FIODIR &= ~(1 << 14);
// Set P1.15 as OUTPUT for the LED:
LPC_GPIO1->FIODIR |= (1 << 15);
// Read value of the switch:
if(LPC_GPIO1->FIOPIN & (1 << 14)) {
// Light up the LED:
LPC_GPIO1->FIOPIN |= (1 << 15);
}
else {
// Else turn off the LED:
LPC_GPIO1->FIOPIN &= ~(1 << 15);
}
LPC also has dedicated registers to set or reset an IOPIN with hardware AND and OR logic:
if(LPC_GPIO1->FIOPIN & (1 << 14)) {
LPC_GPIO1->IOSET = (1 << 15); // No need for |=
}
else {
// Else turn off the LED:
LPC_GPIO1->IOCLR = (1 << 15); // No need for &=
}
Read More
You can read the advanced bit-masking over at the Bit structure and union page