NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » OR gate?

March 27, 2011
by SpaceGhost
SpaceGhost's Avatar

I'm need a program snippet that would act as a four-input type of "OR" gate (hope I've described that right). What I need is -

Programming that sinks one output (lets say, PB5) IF one of four inputs is activated (grounded). Something like:

If input PB1, or PB2, or PB3, or PB4 is low -

Activate (sink) PB5.

I would really like to learn a proper way to do this. Any suggestions that anyone could offer of course is most appreciated.

Dave

March 27, 2011
by esoderberg
esoderberg's Avatar

Perhaps:

if(~(PINB&0x1E))PORTB &= ~(1<<PB5);
March 27, 2011
by SpaceGhost
SpaceGhost's Avatar

For some reason, I'm not getting this to work.

I tried it this way too -

   if (~(PINB&0x1E))

    { PORTB &= ~(1<<PB5);

    }

but it didn't work either. Both ways loaded with no errors.

March 27, 2011
by esoderberg
esoderberg's Avatar

SG,

I assume you set the pins up as output/input as required? If not read pg. 62 of NK guide.

Eric

March 27, 2011
by SpaceGhost
SpaceGhost's Avatar

I have an LED cathode on PB5 (pin 19), anode to (+) rail, and I have a wire on the (-) power rail that I'm using to connect to the inputs PB1-PB4 (pins 15-18). Pretty simple set up, and here's the simple code -

 int main() {

    // set SINKING OUTPUT
  DDRB |= (1<<PB5);

    // set SINKING INPUTs
  DDRB &= ~(1<<PB1); 
  DDRB &= ~(1<<PB2);
  DDRB &= ~(1<<PB3);   
  DDRB &= ~(1<<PB4);

// turn on the internal resistors for the input pins
  PORTB |= (1<<PB1);
  PORTB |= (1<<PB2);
  PORTB |= (1<<PB3);
  PORTB |= (1<<PB4);

while(1) {

    if(~(PINB&0x1E))PORTB &= ~(1<<PB5);

    }

   return 0;

}

Trying to get this part working before I incorporate it into something else.

March 27, 2011
by esoderberg
esoderberg's Avatar

Maybe it needs a logical not, vice a bitwise not, in the if statement:

if(!(PINB&0x1E))PORTB &= ~(1<<PB5);

Also above will work like a latch, if you want PB5 to go back high if none of other PB inputs low than:

if(!(PINB&0x1E))PORTB &= ~(1<<PB5); else PORTB |= (1<<PB5);
March 27, 2011
by SpaceGhost
SpaceGhost's Avatar

Tried it like this -

 int main() {

    // set SINKING OUTPUT
  DDRB |= (1<<PB5);

    // set SINKING INPUTs
  DDRB &= ~(1<<PB1); 
  DDRB &= ~(1<<PB2);
  DDRB &= ~(1<<PB3);   
  DDRB &= ~(1<<PB4);

   // turn on internal resistors for input pins
  PORTB |= (1<<PB1);
  PORTB |= (1<<PB2);
  PORTB |= (1<<PB3);
  PORTB |= (1<<PB4);

while(1) {

    if(!(PINB&0x1E))PORTB &= ~(1<<PB5); else PORTB |= (1<<PB5);

    }

   return 0;

}

still didn't work.

I'm wanting the LED to turn on if any of the inputs are closed to the negative supply. I would like for the LED to turn back off if all input switches are open.

March 27, 2011
by SpaceGhost
SpaceGhost's Avatar

Just tried it with

if(!(PINB&0x1E))PORTB &= ~(1<<PB5);

in the while(1) loop.. No luck either.

March 27, 2011
by esoderberg
esoderberg's Avatar

Crap, my logic was bad. How about:

if((~PINB)| 0x1E))PORTB &= ~(1<<PB5);

So if PINB = 11100001 then ~PINB=00011110 and (~PINB)| 0x1E) = 00011110 | 0x1E = 00011110 | 00011110 = 00011110 which should give logical one.

March 27, 2011
by SpaceGhost
SpaceGhost's Avatar

Okay, I will try that too... Lot more compact than what I have just came up with.

This works -

 int main() {

    // set SINKING OUTPUT
  DDRB |= (1<<PB5);

    // set SINKING INPUTs
  DDRB &= ~(1<<PB1); 
  DDRB &= ~(1<<PB2);
  DDRB &= ~(1<<PB3);   
  DDRB &= ~(1<<PB4);

   // turn on internal resistors for input pins
  PORTB |= (1<<PB1);
  PORTB |= (1<<PB2);
  PORTB |= (1<<PB3);
  PORTB |= (1<<PB4);

  // declare the variable to represent each input
  uint8_t a;
  uint8_t b;
  uint8_t c;
  uint8_t d;

while(1) {

    a = (PINB & (1<<PB1)) >> PB1;
    b = (PINB & (1<<PB2)) >> PB2;
    c = (PINB & (1<<PB3)) >> PB3;
    d = (PINB & (1<<PB4)) >> PB4;

    if ((a == 0)||(b == 0)||(c == 0)||(d == 0)) {

    PORTB &= ~(1<<PB5); // Output ON

    }

    else {

    PORTB |= (1<<PB5);

    }

    }

   return 0;

}

but I will try your code too, and report back. Thank you very much for your help!

Dave

March 27, 2011
by SpaceGhost
SpaceGhost's Avatar

With

if((~PINB)| 0x1E))PORTB &= ~(1<<PB5);

in the while(1) loop, the program would not load.

but with

if((~PINB)|(0x1E))PORTB &= ~(1<<PB5);

in the while(1) loop, the program loaded but did not work...

Dave

March 27, 2011
by esoderberg
esoderberg's Avatar

After running in circles on this one I had to run it myself. This works:

if ((~PINB)&0x1E) PORTB &= ~(1<<PB5);
else PORTB |= (1<<PB5);

My original input had the ~ on PINB&0x1E vice just on PINB as it needed to be

March 27, 2011
by SpaceGhost
SpaceGhost's Avatar

Yes sir, this one works! Much simpler and compact code than what I had working - I thank you very much.

Would you, um, mind explaining it a little, if you have time? (we were on this a while, lol)

Thanks,

Dave

March 27, 2011
by esoderberg
esoderberg's Avatar

Dave,

It sure took me longer than it should have to figure it out.

Here's the logic:
We want a logical yes to a low state on your input pins so we ~PINB. Using the ~, if any of the 1-4 PINB bits is brought low as your input, they will be high in ~PINB. If we wanted to take action with any PINB low we could then just say if (~PINB)then take action. Note, any non-zero value inside of the if statement gives a logical 1. But you only wanted PB1-4 as input so that is why the &0x1E part. 0x1E is 00011110. What this does is allow you to ignore any input on PINB on pins PB7,6,5,1 because any of those bits when & 0x1E will be zero.

Eric

Post a Reply

Please log in to post a reply.

Did you know that LEDs (light emitting diodes) only conduct current in one direction, like normal diodes? Learn more...