user39194: Arduino Mega 2560 board and SN74HC595 shift register(s). I'm working on a school assignment and having issues getting the shift register(s) working without using Arduino libraries.
I know with the libraries you can use functions such as digitalWrite(....); and shiftOut(dataPin, clockPin, MSBFIRST, bitsToSend);.
For my project, I've set up my individual pins as inputs and outputs, but I am having trouble converting the library code into basic code.
IE:
digitalWrite(latchPin, LOW);

can be rewritten as
DDRB &= ~(1 << DDB1);

where latchPin is the SCK pin.
At this stage in the project, we're just trying to get 8 LEDs lit up using 1 shift register, then 16 using 2 shift registers. Any help in understanding what I need to do or direction in which to look would be appreciated.
Thank you,
Nic
Edit:
This is what I have converted from the void setup from https://www.arduino.cc/en/Tutorial/ShftOut12 :
void setup() {
  //Clear the shift registers prev data, Need a low input to reset registers
  //PORTL0 to first SReg SRCLR, PORTL2 to second SReg SRCLR
  //* See data sheet for sn74hc595 shift registers
  DDRL &= ~((1 << PORTL0) | (1 << PORTL2)); //Pg 100 - 21.2.3
  //Use port L0/L2 for SRCLR pin on SReg
  PORTL |= (1 << PORTL0) | (1 << PORTL2); //Pg 100 - 21.2.3

  //Set OE (Enable) to 0 until after last bit is sent
  DDRL &= ~(1 << PORTL4); //Pg 100 - 21.2.3
  //TODO SPI DELAY HERE USING SPDR pg 199

  //Enable SCK as output to drive RCLK and SRCLK on SR
  DDRB &= ~(1 << DDB1); //Pg 96 - 13.4.6
  PORTB |= (1 << PORTB1); //Pg 96 - 13.4.5

  //Enable MOSI as output to drive SER Input on SR
  DDRB &= ~(1 << DDB0); //Pg 96 - 13.4.6
  PORTB |= (1 << PORTB0); //Pg 96 - 13.4.5

  Serial.begin(9600);
  Serial.println("reset");
}


user-1: My strategy: Write the sketch using the standard Arduino library. The goal is have the LED lit up, as you need. 
Then, change all standard function calls in your sketch (like digitalWrite) with your own (called it digitalWrite2).
Now implement digitalWrite2 using register manipulation.
Pros:

Divide and conquer. You know have two independent smaller problems (LED and registers).
When is time to implement digitalWrite2 you can learn from your classmate how to do that. I bet that they will start with the hard part (register manipulation). 
It makes for a easier debuging. You can compare your own implementation against the standard implementation just by deleting/adding a single "2" in the call.

Of course, taking a look at the Arduino source code will made things trivial :-)
Is that cheating? No, we learn from others, we learn reading other people's code.
Edit: Step by Step Example
Let use Blink to show how to do it:
Original
void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

For the new version I will replace pinMode and digitalWrite for the my own  implementation them. How?
Go to the directory where you put your Arduino binaries, which include the source code. There is a subdirectory with the sources (mine is ~/bin/arduino-1.8.3/hardware/arduino/avr/cores/arduino).
There is a file (wiring_digital.c) where I found the source code for pinMode and digitalWrite. Without any shame, I copy-paste and rename. 
Note: the original includes a call to turnOffPWM, which I simply comment out, because we will not use it here and I want to cut it short.
That's all.
New version 
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode2(LED_BUILTIN, OUTPUT);
}

void loop() {
  digitalWrite2(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite2(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

void pinMode2(uint8_t pin, uint8_t mode)
{
  uint8_t bit = digitalPinToBitMask(pin);
  uint8_t port = digitalPinToPort(pin);
  volatile uint8_t *reg, *out;

  if (port == NOT_A_PIN) return;

  // JWS: can I let the optimizer do this?
  reg = portModeRegister(port);
  out = portOutputRegister(port);

  if (mode == INPUT) { 
    uint8_t oldSREG = SREG;
                cli();
    *reg &= ~bit;
    *out &= ~bit;
    SREG = oldSREG;
  } else if (mode == INPUT_PULLUP) {
    uint8_t oldSREG = SREG;
                cli();
    *reg &= ~bit;
    *out |= bit;
    SREG = oldSREG;
  } else {
    uint8_t oldSREG = SREG;
                cli();
    *reg |= bit;
    SREG = oldSREG;
  }
}

void digitalWrite2(uint8_t pin, uint8_t val)
{
  uint8_t timer = digitalPinToTimer(pin);
  uint8_t bit = digitalPinToBitMask(pin);
  uint8_t port = digitalPinToPort(pin);
  volatile uint8_t *out;

  if (port == NOT_A_PIN) return;

  // If the pin that support PWM output, we need to turn it off
  // before doing a digital write.
  // if (timer != NOT_ON_TIMER) turnOffPWM(timer); By Look Alterno

  out = portOutputRegister(port);

  uint8_t oldSREG = SREG;
  cli();

  if (val == LOW) {
    *out &= ~bit;
  } else {
    *out |= bit;
  }

  SREG = oldSREG;
}



user4143: The main problem you seem to have is how to implement shiftOut. Well, that's actually quite simple once you understand how shiftOut actually works.
You already know how to set a pin HIGH or LOW - all you lack from that is the concept of time.
All shiftOut does is set the clock and data pins HIGH and LOW at the right time.
It's simply a case of:

Set the DATA pin to HIGH or LOW depending on the bit value to send
Set the CLOCK pin HIGH
Set the CLOCK pin LOW
Go back to 1 for 8 iterations total.

Getting the bit value from a byte can be done with boolean operators & and <<
The basic shiftOut code looks like this:
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
{
    uint8_t i;

    for (i = 0; i < 8; i++)  {
        if (bitOrder == LSBFIRST)
            digitalWrite(dataPin, !!(val & (1 << i)));
        else
            digitalWrite(dataPin, !!(val & (1 << (7 - i))));

        digitalWrite(clockPin, HIGH);
        digitalWrite(clockPin, LOW);
    }
}

Since your bit order is fixed you can reduce that down to this:
void myShiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t val)
{
    uint8_t i;

    for (i = 0; i < 8; i++)  {
        digitalWrite(dataPin, !!(val & (1 << (7 - i))));    
        digitalWrite(clockPin, HIGH);
        digitalWrite(clockPin, LOW);
    }
}

And then you can replace your digitalWrite calls with direct register manipulation.
void myShiftOut(uint8_t val)
{
    uint8_t i;

    for (i = 0; i < 8; i++)  {
        if (val & (1 << (7 - i))) {
            PORTB |= (1 << PORTB0);  // Data 1
        } else {
            PORTB &= ~(1 << PORTB0); // Data 0
        }
        PORTB |= (1 << PORTB1);      // Clock HIGH
        PORTB &= ~(1 << PORTB1);     // Clock LOW
    }
}

Note that this code will now run considerably faster than the bloaty digitalWrite based version - so you may find it's now too fast. You may need to include some short delays around the clock HIGH and clock LOW lines. Depending on how long they need to be you could write a little delay loop to introduce a short delay:
void delayLoop(uint32_t iterations) {
    while ((--iterations) > 0) {
        asm volatile("nop");
    }
}

That will delay for iterations clock cycles plus the time taken to do the loop and call the function.  For very short delays it may be better to just insert a few nop instructions:
PORTB |= (1 << PORTB1);      // Clock HIGH
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
PORTB &= ~(1 << PORTB1);     // Clock LOW
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");


39194: <p>Arduino Mega 2560 board and SN74HC595 shift register(s). I'm working on a school assignment and having issues getting the shift register(s) working without using Arduino libraries.</p>

<p>I know with the libraries you can use functions such as <code>digitalWrite(....);</code> and <code>shiftOut(dataPin, clockPin, MSBFIRST, bitsToSend);</code>.</p>

<p>For my project, I've set up my individual pins as inputs and outputs, but I am having trouble converting the library code into basic code.</p>

<p>IE:</p>

<pre><code>digitalWrite(latchPin, LOW);
</code></pre>

<p>can be rewritten as</p>

<pre><code>DDRB &amp;= ~(1 &lt;&lt; DDB1);
</code></pre>

<p>where <code>latchPin</code> is the <code>SCK</code> pin.</p>

<p>At this stage in the project, we're just trying to get 8 LEDs lit up using 1 shift register, then 16 using 2 shift registers. Any help in understanding what I need to do or direction in which to look would be appreciated.</p>

<p>Thank you,</p>

<p>Nic</p>

<p>Edit:</p>

<p>This is what I have converted from the void setup from <a href="https://www.arduino.cc/en/Tutorial/ShftOut12" rel="nofollow noreferrer">https://www.arduino.cc/en/Tutorial/ShftOut12</a> :</p>

<pre><code>void setup() {
  //Clear the shift registers prev data, Need a low input to reset registers
  //PORTL0 to first SReg SRCLR, PORTL2 to second SReg SRCLR
  //* See data sheet for sn74hc595 shift registers
  DDRL &amp;= ~((1 &lt;&lt; PORTL0) | (1 &lt;&lt; PORTL2)); //Pg 100 - 21.2.3
  //Use port L0/L2 for SRCLR pin on SReg
  PORTL |= (1 &lt;&lt; PORTL0) | (1 &lt;&lt; PORTL2); //Pg 100 - 21.2.3

  //Set OE (Enable) to 0 until after last bit is sent
  DDRL &amp;= ~(1 &lt;&lt; PORTL4); //Pg 100 - 21.2.3
  //TODO SPI DELAY HERE USING SPDR pg 199

  //Enable SCK as output to drive RCLK and SRCLK on SR
  DDRB &amp;= ~(1 &lt;&lt; DDB1); //Pg 96 - 13.4.6
  PORTB |= (1 &lt;&lt; PORTB1); //Pg 96 - 13.4.5

  //Enable MOSI as output to drive SER Input on SR
  DDRB &amp;= ~(1 &lt;&lt; DDB0); //Pg 96 - 13.4.6
  PORTB |= (1 &lt;&lt; PORTB0); //Pg 96 - 13.4.5

  Serial.begin(9600);
  Serial.println("reset");
}
</code></pre>
 -1: <p>My strategy: Write the sketch using the standard Arduino library. The goal is have the LED lit up, as you need. </p>

<p>Then, change all standard function calls in your sketch (like <code>digitalWrite</code>) with your own (called it <code>digitalWrite2</code>).</p>

<p>Now implement <code>digitalWrite2</code> using register manipulation.</p>

<p>Pros:</p>

<ul>
<li>Divide and conquer. You know have two independent smaller problems (LED and registers).</li>
<li>When is time to implement digitalWrite2 you can learn from your classmate how to do that. I bet that they will start with the hard part (register manipulation). </li>
<li>It makes for a easier debuging. You can compare your own implementation against the standard implementation just by deleting/adding a single "2" in the call.</li>
</ul>

<p>Of course, taking a look at the Arduino source code will made things trivial :-)
Is that cheating? No, we learn from others, we learn reading other people's code.</p>

<p><strong>Edit: Step by Step Example</strong></p>

<p>Let use Blink to show how to do it:</p>

<p><strong>Original</strong></p>

<pre><code>void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop() {
  digitalWrite(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}
</code></pre>

<p>For the new version I will replace <code>pinMode</code> and <code>digitalWrite</code> for the my own  implementation them. How?</p>

<p>Go to the directory where you put your Arduino binaries, which include the source code. There is a subdirectory with the sources (mine is ~/bin/arduino-1.8.3/hardware/arduino/avr/cores/arduino).</p>

<p>There is a file (wiring_digital.c) where I found the source code for <code>pinMode</code> and <code>digitalWrite</code>. Without any shame, I copy-paste and rename. </p>

<p>Note: the original includes a call to <code>turnOffPWM</code>, which I simply comment out, because we will not use it here and I want to cut it short.</p>

<p>That's all.</p>

<p><strong>New version</strong> </p>

<pre><code>void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode2(LED_BUILTIN, OUTPUT);
}

void loop() {
  digitalWrite2(LED_BUILTIN, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(1000);                       // wait for a second
  digitalWrite2(LED_BUILTIN, LOW);    // turn the LED off by making the voltage LOW
  delay(1000);                       // wait for a second
}

void pinMode2(uint8_t pin, uint8_t mode)
{
  uint8_t bit = digitalPinToBitMask(pin);
  uint8_t port = digitalPinToPort(pin);
  volatile uint8_t *reg, *out;

  if (port == NOT_A_PIN) return;

  // JWS: can I let the optimizer do this?
  reg = portModeRegister(port);
  out = portOutputRegister(port);

  if (mode == INPUT) { 
    uint8_t oldSREG = SREG;
                cli();
    *reg &amp;= ~bit;
    *out &amp;= ~bit;
    SREG = oldSREG;
  } else if (mode == INPUT_PULLUP) {
    uint8_t oldSREG = SREG;
                cli();
    *reg &amp;= ~bit;
    *out |= bit;
    SREG = oldSREG;
  } else {
    uint8_t oldSREG = SREG;
                cli();
    *reg |= bit;
    SREG = oldSREG;
  }
}

void digitalWrite2(uint8_t pin, uint8_t val)
{
  uint8_t timer = digitalPinToTimer(pin);
  uint8_t bit = digitalPinToBitMask(pin);
  uint8_t port = digitalPinToPort(pin);
  volatile uint8_t *out;

  if (port == NOT_A_PIN) return;

  // If the pin that support PWM output, we need to turn it off
  // before doing a digital write.
  // if (timer != NOT_ON_TIMER) turnOffPWM(timer); By Look Alterno

  out = portOutputRegister(port);

  uint8_t oldSREG = SREG;
  cli();

  if (val == LOW) {
    *out &amp;= ~bit;
  } else {
    *out |= bit;
  }

  SREG = oldSREG;
}
</code></pre>

<p><a href="https://i.stack.imgur.com/42ffW.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/42ffW.jpg" alt="Pablo Picasso"></a></p>
 4143: <p>The main problem you seem to have is how to implement <code>shiftOut</code>. Well, that's actually quite simple once you understand how <code>shiftOut</code> actually works.</p>

<p>You already know how to set a pin HIGH or LOW - all you lack from that is the concept of <em>time</em>.</p>

<p>All <code>shiftOut</code> does is set the clock and data pins HIGH and LOW at the right <em>time</em>.</p>

<p>It's simply a case of:</p>

<ol>
<li>Set the DATA pin to HIGH or LOW depending on the bit value to send</li>
<li>Set the CLOCK pin HIGH</li>
<li>Set the CLOCK pin LOW</li>
<li>Go back to 1 for 8 iterations total.</li>
</ol>

<p>Getting the bit value from a byte can be done with boolean operators <code>&amp;</code> and <code>&lt;&lt;</code></p>

<p>The basic <code>shiftOut</code> code looks like this:</p>

<pre><code>void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
{
    uint8_t i;

    for (i = 0; i &lt; 8; i++)  {
        if (bitOrder == LSBFIRST)
            digitalWrite(dataPin, !!(val &amp; (1 &lt;&lt; i)));
        else
            digitalWrite(dataPin, !!(val &amp; (1 &lt;&lt; (7 - i))));

        digitalWrite(clockPin, HIGH);
        digitalWrite(clockPin, LOW);
    }
}
</code></pre>

<p>Since your bit order is fixed you can reduce that down to this:</p>

<pre><code>void myShiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t val)
{
    uint8_t i;

    for (i = 0; i &lt; 8; i++)  {
        digitalWrite(dataPin, !!(val &amp; (1 &lt;&lt; (7 - i))));    
        digitalWrite(clockPin, HIGH);
        digitalWrite(clockPin, LOW);
    }
}
</code></pre>

<p>And then you can replace your <code>digitalWrite</code> calls with direct register manipulation.</p>

<pre><code>void myShiftOut(uint8_t val)
{
    uint8_t i;

    for (i = 0; i &lt; 8; i++)  {
        if (val &amp; (1 &lt;&lt; (7 - i))) {
            PORTB |= (1 &lt;&lt; PORTB0);  // Data 1
        } else {
            PORTB &amp;= ~(1 &lt;&lt; PORTB0); // Data 0
        }
        PORTB |= (1 &lt;&lt; PORTB1);      // Clock HIGH
        PORTB &amp;= ~(1 &lt;&lt; PORTB1);     // Clock LOW
    }
}
</code></pre>

<p>Note that this code will now run considerably faster than the bloaty <code>digitalWrite</code> based version - so you may find it's now too fast. You may need to include some short delays around the clock HIGH and clock LOW lines. Depending on how long they need to be you could write a little delay loop to introduce a short delay:</p>

<pre><code>void delayLoop(uint32_t iterations) {
    while ((--iterations) &gt; 0) {
        asm volatile("nop");
    }
}
</code></pre>

<p>That will delay for <code>iterations</code> clock cycles plus the time taken to do the loop and call the function.  For very short delays it may be better to just insert a few <code>nop</code> instructions:</p>

<pre><code>PORTB |= (1 &lt;&lt; PORTB1);      // Clock HIGH
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
PORTB &amp;= ~(1 &lt;&lt; PORTB1);     // Clock LOW
asm volatile("nop");
asm volatile("nop");
asm volatile("nop");
</code></pre>
