How to control a 74HC595 shift register with a PIC microcontroller

The number of pins is often limited on microcontrollers, and when we have a significant number of outputs to control, we can quickly run out of pins. An easy solution to fix this problem is to use a shift register. In this tutorial we’re going to learn how to use a 74HC595 shift register, to output 8 bits of data with only 3 bits from the PIC.

Bill of material

I’ll use a PIC16F88 for this tutorial, as well as the usual components necessary to make it run. You can refer to this article for a reminder on how to use a PIC. We’ll also need a 74HC595, which is a very common shift register.

A bit of shift register theory

Before we build the circuit and write the software, let’s take a look at the datasheet for the HC595 and understand how it works. The pin diagram of the chip is the following:

Pin diagram of the HC595 shift register

The pin functions are:

  • SER: serial input.
  • QA-H: parallel output.
  • QH’: Can be used to daisy chain multiple HC595s. In this case, you can connect QH’ to the SER pin of the next shift register, and it will give you a 16-bit output.
  • OE: Output Enable. Set to 0, the output is enabled, set to 1, it’s disabled. In this tutorial we’ll just connect it to the ground to always activate the output.
  • SRCLR: Output clear. Set it to 0 to clear the output. Here we’ll connect it to the 5V rail.
  • RCLK: Register clock. When set to 1, the pins QA-H will output the values from the registers of the HC595. When set to 0, the new values sent on the SER pin will still be saved in the registers, but the pins QA-H will remain unchanged.
  • SRCLK: Serial clock. Rising edges on this pin will shift data in the registers.

To better understand how to use the shift register, let’s look at its timing diagram and function table:

Timing diagram of the 74HC595
Function table of the 74C595

To sum it up, here is how we’re going to control the HC595 to output a 8-bit value:

  • Send one bit on the SER pin
  • Create a rising edge on the SRCLK pin
  • Repeat for each of the 8 bits
  • After sending the 8 bits, set RCLK to 1 to output the data. RCLK can be set back to 0 afterwards, to prevent any modification until it’s set to 1 again.

Build the circuit

We’ll simply connect the pins SER, RCLK and SRCLK to the pins RA0, RA1 and RA2 of the PIC16F88, as shown below:

PIC16F88 and 74HC595 circuit


We’re going to display a counter going from 0x00 to 0xFF on the LEDs, by increments of 1. First, let’s write a little library for controlling the shift register. It will define the following functions:

The function HC595Init()  will simply set the ports we use as outputs:

The function HC595SendValue()  will output a 8-bit value on the shift register. It gives the option to output it either LSB first, or MSB first.

  • With LSB first, the LSB of the number will be on the pin QA of the shift register, and the MSB will be on the pin QH.
  • With MSB first, it’ll be the opposite, the LSB of the number will be on the pin QH, and the MSB on QA.

The function HC595Clear()  will set the output to 0x00, by writing the value 0x00 on the SER pin just like any other value:

Finally, the functions HC595ToggleClk()  and HC595TriggerOutput()  will respectively create a rising edge on the SRCLK pin to shift data in the shift register, and trigger the output to display the data saved in the registers, by setting RCLK to 1.

Last part of the code, let’s look at the main()  function that will test our library. We’ll simply use a 8-bit counter, and call HC595SendValue()  to send it to the shift register.

Full code

The full code is available on my Github page.


The result of this program is the 74HC595 outputting the value of the counter on the LEDs. It is exactly the same result as if we were using 1 pin of the PIC for each LED, but here we only use 3 pins.

Counter = 43
Counter = 63
Counter = 67

Be the first to comment

%d bloggers like this: