Port Manipulation

I have read most of info in the playground. I am having a problem with this code. It pulses pin pc3 properly, but pc0,pc1 and pc2 don’t stay set. Arduino Uno

I have it looping for debug purposes. :slight_smile:

/* this program is used to debug hardware
the pc2,pc1.pc0 select the hardware register

pc3 strobes the data in ( lo hi lo) pulse

port c has 2 functions
-register select
- strobe  -pc4 and pc5 are inputs not used in this example

*/


void setup()
{
	
	DDRC =  B111111;										//init as outputs
	PORTC = B111111;										// set to 3f
	
}
	void loop()                           //repeat every 500 ms for example

	{
		  
		PORTC = (1 << PC0);                //sel hardware port - bits 0,1,2,3
		PORTC = (1 << PC1);
		PORTC = (0 << PC2);
		PORTC = (0 << PC3);					// INIT low

		PORTC = (1 << PC3);					// strobe high 
		delayMicroseconds(100);             //change delay to 2 in final version
		PORTC = (0 << PC3);					// strobe low
		delay(500);

	}

You are setting all 8 bits of the port each time you write to it. If you want any bits to keep their value you have to read the port, modify the one bit you want to change, and write the modified byte back.

That is why the Arduino library has digitalRead() and digitalWrite(). You should ONLY use direct port manipulation on an Arduino if high speed is critical or it is important to read or write more than one bit at the same time.

but pc0,pc1 and pc2 don’t stay set

John is correct that using the higher level functions like bitSet() and bitClear() will keep you out of trouble.
https://www.arduino.cc/en/Reference/BitSet

But, if you are going to use the low level direct Port manipulation than
To set one bit and leave the others alone you need |= (bitwise or equals)

PORTC |= (1 << PC3);

To clear a bit and leave the other alone, you use &= with ! 1 (bitwise and equals not 1)

PORTC &= ~(1 << PC3);

This is the least readable approach, but it shows how all 4 bits can be controlled (manipulated) in one command without bit shifting. The Arduino reference on bitwise operators & and | shows examples how multiple bits are manipulated. This demonstrates what you're looking for, but I would definitely recommend comments here by others when revising your code.

/* this program is used to debug hardware
  the pc2,pc1.pc0 select the hardware register

  pc3 strobes the data in ( lo hi lo) pulse

  port c has 2 functions
  -register select
  - strobe  -pc4 and pc5 are inputs not used in this example
*/

void setup()
{
  DDRC |=  B1111;          // init pc0-3 as outputs
  PORTC |= B0111;          // write pc0-2 HIGH
  PORTC &= B0111;          // write pc3 LOW
}

void loop()                // repeat every 500 ms for example

{ // PORTC  3210
  PORTC |= B1000;          // write pc3 (strobe) HIGH
  delayMicroseconds(100);  //change delay to 2 in final version
  PORTC &= B0111;          // write pc3 (strobe) LOW
  delay(500);
}

Thanks for all the answers. The bitwise and "and" or's is what I was missing. Since this is code for a hardware design speed is important.

I use the mnemonic “SO CAN I” to help remember basic bit functions. “SO”, or “Set a bit with Or”, and “CAN 1”, for “Clear a bit with And Not 1”. It works for me!

Bit shifting (by constant amount) is not a problem. The compiler optimizes constant expressions very well.

the mnemonic is funny thx for the smile - I think I'll need a mnemonic to remember the mnemonic :slight_smile:

from my side, I just remember the truth tables

TRUE OR anything is always TRUE so 1 OR X = 1

FALSE AND anything is always FALSE so 0 AND X = 0