# Help w/ bit testing

Discussion in 'C Programming' started by Shawn, Oct 11, 2005.

1. ### ShawnGuest

Hello all...

I'm new to the world of C programming, and am working with an embedded
microcontroller as a hobby. I have a reasonably simple program
running now, but I'm having trouble figuring out how to test for a
specific bit when an interrupt is triggered.

Basically when the interrupt is set, the program reads a register to
determine what caused the interrupt. It could be one or both of 2
values - bit 2 and/or biit 4. Depending on which or both it is, I
want to do different things.

If the hex result of the interrupt register is 0x08, bit 4 is set -
OK, likewise 0x02 would mean bit 2 - again, no problem. 0x10 would
mean both were set.

My question is more of style, and more complicated situations - is the
best way to handle this just with IF statements and test for the 3
different conditions? Likewise, if I want to use some of the other
interrupt conditions, how would I handle circumstances with 5 or 6
different interrupts, and a ton of different possibilities?

Thanks up front for any help from an old guy that is trying to catch
up!

Shawn, Oct 11, 2005

2. ### Guest

Shawn wrote:
> Hello all...
>
> I'm new to the world of C programming, and am working with an embedded
> microcontroller as a hobby. I have a reasonably simple program
> running now, but I'm having trouble figuring out how to test for a
> specific bit when an interrupt is triggered.
>
> Basically when the interrupt is set, the program reads a register to
> determine what caused the interrupt. It could be one or both of 2
> values - bit 2 and/or biit 4. Depending on which or both it is, I
> want to do different things.
>
> If the hex result of the interrupt register is 0x08, bit 4 is set -
> OK, likewise 0x02 would mean bit 2 - again, no problem. 0x10 would
> mean both were set.

Incorrect. 0x10 would be 16 in decimal.
0x08 + 0x02 = 0xA = 0b1010 (binary) = 10 in decimal.

>
> My question is more of style, and more complicated situations - is the
> best way to handle this just with IF statements and test for the 3
> different conditions? Likewise, if I want to use some of the other
> interrupt conditions, how would I handle circumstances with 5 or 6
> different interrupts, and a ton of different possibilities?

I would consider a switch statement.

> Thanks up front for any help from an old guy that is trying to catch
> up!

, Oct 11, 2005

3. ### SkarmanderGuest

Shawn wrote:
> Hello all...
>
> I'm new to the world of C programming, and am working with an
> embedded microcontroller as a hobby. I have a reasonably simple
> program running now, but I'm having trouble figuring out how to test
> for a specific bit when an interrupt is triggered.
>
> Basically when the interrupt is set, the program reads a register to
> determine what caused the interrupt. It could be one or both of 2
> values - bit 2 and/or biit 4. Depending on which or both it is, I
> want to do different things.
>
> If the hex result of the interrupt register is 0x08, bit 4 is set -
> OK, likewise 0x02 would mean bit 2 - again, no problem. 0x10 would
> mean both were set.
>
> My question is more of style, and more complicated situations - is
> the best way to handle this just with IF statements and test for the
> 3 different conditions? Likewise, if I want to use some of the other
> interrupt conditions, how would I handle circumstances with 5 or 6
> different interrupts, and a ton of different possibilities?
>
> Thanks up front for any help from an old guy that is trying to catch
> up!

It completely depends on what you want to do. It's not a C-specific
problem, strictly speaking, just a question of design.

If bit 2 and 4 are set, do you want to perform the actions associated
with bit 2, then those with bit 4, or do you want to do something
completely different altogether? Do you want the option of altering the
actions at runtime for every possible combination of bits? Are the
actions drawn from a small pool of predefined possibilities?

Here's one basic approach, assuming that the conditions are independent
and you do not need runtime flexibility.

#define FOO 0x02
#define BAR 0x08

extern volatile unsigned char global_register;

void handle_interrupt(void) {
if (global_register & FOO) {
/* Actions associated with FOO condition */
}
if (global_register & BAR) {
/* Actions associated with BAR condition */
}
}

If the conditions are interdependent, you could do:

#define FOOBAR (FOO | BAR)

void handle_interrupt(void) {
switch (global_register) {
case FOO: {
/* Actions associated with FOO-only condition, */
}; break;
case BAR: {
/* Actions associated with BAR-only condition */
}; break;
case FOOBAR: {
/* Actions associated with FOO and BAR-condition */
}; break;
default: {
/* Default actions if no predefined condition combinations apply */
}
}

You can even mix these. Here's assuming that FOO and BAR are dependent,
but some BAZ has two independent FOO and BAR conditions:

#define BAZ 0x..

void handle_interrupt(void) {
switch (global_register) {
case FOO: {
/* Actions associated with FOO-only condition */
}; break;
case BAR: {
/* Actions associated with BAR-only condition */
}; break;
case FOOBAR: {
/* Actions associated with FOO and BAR-condition */
}; break;
default: {
if (global_register & BAZ) {
if (global_register & FOO) {
/* Actions associated with BAZ and FOO condition */
}
if (global_register & BAR) {
/* Actions associated with BAZ and BAR condition */
}
} else {
/* Default actions */
}
}

This rapidly gets hard to read, however; I recommend turning the various
branches in functions.

If you want the option of associating handlers for each condition or
combination of condition at runtime, things change yet again, and you'll
want a (possibly dynamic) table of bitmasks. I'll defer this.

Basically, you can get as simple or complicated as you like, depending

S.

Skarmander, Oct 11, 2005
4. ### Kenneth BrodyGuest

Shawn wrote:
>
> Hello all...
>
> I'm new to the world of C programming, and am working with an embedded
> microcontroller as a hobby. I have a reasonably simple program
> running now, but I'm having trouble figuring out how to test for a
> specific bit when an interrupt is triggered.
>
> Basically when the interrupt is set, the program reads a register to
> determine what caused the interrupt. It could be one or both of 2
> values - bit 2 and/or biit 4. Depending on which or both it is, I
> want to do different things.
>
> If the hex result of the interrupt register is 0x08, bit 4 is set -
> OK, likewise 0x02 would mean bit 2 - again, no problem. 0x10 would
> mean both were set.

Actually, bits 4 and 2 (using your 1-relative numbering) set would
be 0x0A (or decimal 10) and not 0x10.

> My question is more of style, and more complicated situations - is the
> best way to handle this just with IF statements and test for the 3
> different conditions? Likewise, if I want to use some of the other
> interrupt conditions, how would I handle circumstances with 5 or 6
> different interrupts, and a ton of different possibilities?
>
> Thanks up front for any help from an old guy that is trying to catch
> up!

One way would be switch:

switch( value & 0x0a )
{
case 0x02:
... only bit 2 set ...
break;
case 0x08:
... only bit 4 set ...
break;
case 0x0a:
... both set ...
break;
case 0:
... neither set ...
break;
}

You mention multiple bits being set. If you have 5 different bits,
do you really need to do 32 different things, or do you need to do
something specific for each bit that is set? If that's the case,
then a series of if's would do it:

if ( value & 0x80 )
{
... bit 8 is set ...
}
if ( value & 0x40 )
{
... bit 7 is set ...
}
if ( value & 0x20 )
{
... bit 6 is set ...
}
... and so on down to 0x01 ...

And, if you really do need 32 different things, then switch/case is
probably the way to go.

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:>

Kenneth Brody, Oct 11, 2005