How to interface 8 digits 7-segment with shift register 74HC595 and PIC16F877A

Published by MKDas on

Sometimes, we need to drive multiple displays in line. Sometimes we need to drive multiple numbers from one micro-controller. As micro-controller has a fixed number of pins so it is not possible to configure any circuit to drive 100 digits or even more 7-Segments. That is why we need to use shift registers. In this article, you will see how to use a shift register to interface multiple 7-segment with shift register 74HC595 a micro-controller.

Disclaimer: Electricity is always dangerous. Proper skill is required to work with electricity. Do work at your own risk. The author will not be responsible for any misuse or harmful act or any mistake you make. The contents of this website are unique and copyright protected. Kindly don’t do any nonsensical act copying and claiming it as yours. Most of the articles published here are kept as open-source to help you. Take the knowledge for free and use it, but if you are interested you can buy the ready resources offered here. If you need any help or guide feel free to comment below, the author will try to help you. Thanks.

What is shift registers?

In digital circuits, a shift register is a cascade of flip flops, sharing the same clock, in which the output of each flip-flop is connected to the “data” input of the next flip-flop in the chain, resulting in a circuit that shifts by one position the “bit array” stored in it, “shifting in” the data present at its input and ‘shifting out’ the last bit in the array, at each transition of the clock input. _Wiki.

To know more about shift registers, please visit the wiki page here.

Shift registers are different in type. The most common ones are

  1. Serial in-parallel out
  2. Parallel in – Serial out

There are many types of shift registers, which can not be explained in short articles. Please do some research on this issue over the internet.

About 74HC595 Shift Register:

74HC595 is a serial into parallel-out with latch triggered tri-state shift register. This 16pin shift register is very common in use with a micro-controller as a port extender.

74HC595 shift register [Click to down datasheet]
DIP package

This SIPO shift register has a data input pin (A) where data can be loaded which is controlled by the shift clock. Then one latch clock shifts these data to its output pins according to the 8bit data pattern given serially at the data pin. Output Enable pin (!OE) is active low to enable output of that shift register. And the reset pin is also active low, connecting this reset pin to VDD will keep the operation going on. When we need more outputs, we just connect shift registers in cascade mode. For this, there is a data output (serial data out) pin. This pin will be then connected to the data input pin of the next shift register.

Cascading multiple shift registers

When we need more than 8bit output, we can just use more shift registers. These shift registers are then connected in cascade mode. Serial Data Output of the previous one will be connected to the data input of the next one. Keeping latch clock, shift clock common for each register, we can then get output from all of the shift registers according to our command.

Cascade connection

This is a simple cascade connection for the shift register. Here any type of shift register works almost in the same way. A common clock signal keeps all the shift registers synchronized.

Utilizing micro-controller’s feature to drive shift register:

Each micro-controller has some special feature built-in with it. In this project, we selected a PIC16F877A microcontroller. Smaller micro-controllers can be used if you wish to.

Here, in the MSSP module, we have an opportunity to use the SPI module. This Serial Peripheral Interface has dedicated communicating pins. RC5/SDO, RC4/SDI/SDA & RC3/SCL. Using these pins, we can easily interface any shift registers with a micro-controller.

Circuit diagram:

Utilizing the cascade connecting facilities of 74HC595, we can draw our circuit diagram for driving multiple seven segments.

7-segment with shift register 74HC595
Circuit diagram

Here in this simulation, I did not use any resistor between the shift register and the 7-Segment display. You should use a resistor in a practical circuit. Better using a driver IC if the segment is big. ULN2003A will work fine.

Coding:

Here is the mikroC code for our multi-display project:

/*******************************************************************************
* Program for, Shift Register Display test for multiple digits                 *
* Program Written by_ Engr. Mithun_K_Das, mithun060@gmail.com                  *
* MCU:PIC16F877A; X-Tal: 20MHz; mikroC pro for PIC v6.5.0                      *
* Date: 07-09-2017                                                             *
*******************************************************************************/

Digit_conversion(char digit)
{
   switch(digit)
   {
      case 0: digit = 0x3F; return digit;
      case 1: digit = 0x06; return digit;
      case 2: digit = 0x5B; return digit;
      case 3: digit = 0x4F; return digit;
      case 4: digit = 0x66; return digit;
      case 5: digit = 0x6D; return digit;
      case 6: digit = 0x7D; return digit;
      case 7: digit = 0x07; return digit;
      case 8: digit = 0x7F; return digit;
      case 9: digit = 0x6F; return digit;
   }
}

unsigned long number=0;
int digit=0;
void Disp_number(unsigned long value)
{
   digit = (value/1u)%10;
   SPI_Write(Digit_conversion(digit));
   digit = (value/10u)%10;
   SPI_Write(Digit_conversion(digit));
   digit = (value/100u)%10;
   SPI_Write(Digit_conversion(digit));
   digit = (value/1000u)%10;
   SPI_Write(Digit_conversion(digit));
   digit = (value/10000u)%10;
   SPI_Write(Digit_conversion(digit));
   digit = (value/100000u)%10;
   SPI_Write(Digit_conversion(digit));
   digit = (value/1000000u)%10;
   SPI_Write(Digit_conversion(digit));
   digit = (value/10000000u)%10;
}
void Update_display()
{
  PORTC.F6=1; //one latch clock
  PORTC.F6=0;
}

void InitTimer1()
{
    T1CON         = 0x31;
    TMR1IF_bit    = 0;
    TMR1H         = 0x0B;
    TMR1L         = 0xDC;
    TMR1IE_bit    = 1;
    INTCON        = 0xC0;
}

void Interrupt() iv 0x0004 ics ICS_AUTO
{
  if (TMR1IF_bit)
  {
      TMR1IF_bit = 0;
      TMR1H = 0x0B;
      TMR1L = 0xDC;
      //Enter your code here
      Disp_number(number);
      Update_display();
  }
}



void main()
{
  TRISC = 0x00;
  PORTC = 0x00;
  CMCON = 0x07;
  ADCON1 = 0x07;
  SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV4, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);
  InitTimer1();
  number = 2;
  while(1)
  {
      number+=number;
      Delay_ms(500);
      if(number>99999999)number=2;
  }

}

Code explanation:

Digit_conversion(char digit)
{
   switch(digit)
   {
      case 0: digit = 0x3F; return digit;
      case 1: digit = 0x06; return digit;
      case 2: digit = 0x5B; return digit;
      case 3: digit = 0x4F; return digit;
      case 4: digit = 0x66; return digit;
      case 5: digit = 0x6D; return digit;
      case 6: digit = 0x7D; return digit;
      case 7: digit = 0x07; return digit;
      case 8: digit = 0x7F; return digit;
      case 9: digit = 0x6F; return digit;
   }
}

In this part, digits are converted for 7-Segment. For Common Anode, you need to edit these values.

void Disp_number(unsigned long value)
{
   digit = (value/1u)%10;
   SPI_Write(Digit_conversion(digit));
   digit = (value/10u)%10;
   SPI_Write(Digit_conversion(digit));
   digit = (value/100u)%10;
   SPI_Write(Digit_conversion(digit));
   digit = (value/1000u)%10;
   SPI_Write(Digit_conversion(digit));
   digit = (value/10000u)%10;
   SPI_Write(Digit_conversion(digit));
   digit = (value/100000u)%10;
   SPI_Write(Digit_conversion(digit));
   digit = (value/1000000u)%10;
   SPI_Write(Digit_conversion(digit));
   digit = (value/10000000u)%10;
}

Here, the 8 figure number is split into individual digits and written to the shift register through the SPI module.

void Update_display()
{
  PORTC.F6=1; //one latch clock
  PORTC.F6=0;
}

This is generating a latch clock to throw the input of the shift register to its output pins. After writing all data serially, one latch clock reflects the inputs in output pins.

void Interrupt() iv 0x0004 ics ICS_AUTO
{
  if (TMR1IF_bit)
  {
      TMR1IF_bit = 0;
      TMR1H = 0x0B;
      TMR1L = 0xDC;
      //Enter your code here
      Disp_number(number);
      Update_display();
  }
}

You may not need to use ISR for the periodic updates, but here I used ISR to update the shift registers periodically. This helps to make the display more responsive. You can call these two functions serially to update the shift registers in the while loop.

Disp_number(number);
Update_display();

      number+=number;
      Delay_ms(500);
      if(number>99999999)number=2;

And finally, inside the while loop, this code is used to demonstrate the result in simulation quickly. You can use it in any format you need.

Test result:

In proteus, a simulation result shows how everything works. Check the video here:

Test result

If you understand the concept, you can add almost any number of shift registers and 7-Segment displays you need to. Here is another example where I elaborately used shift registers to interface several Seven Segment displays:

7-segment with shift register 74HC595
The elaborate use of shift register

I’ll write another article on this one later. Anyway, I hope you are well familiar to shift registers now. Can you make one for yourself now? I hope you can. If you can’t and are stuck in middle, feel free to ask me. Thank you very much. Enjoy!

Don’t forget to subscribe for the next update.

Loading

JLCPCB – Only $2 for PCB Prototype (Any Color)

24 Hours fast turnaround, Excellent quality & Unbeatable prices

$18 Welcome Bonus for new registrations Now!!! https://jlcpcb.com


Check this out: 5 coolest multimeters you can buy


MKDas

I'm Mithun K. Das; B.Sc. in EEE from KUET, Bangladesh. Blog: https://labprojectsbd.com. "First, electronics was my passion, then it was my education, and finally, electronics is now my profession." I run my own electronics lab, M's Lab (https://mlabsbd.com). Where I work with the creation of new products from ideas to something in real life. Besides this is my personal blog where I write for hobbyists and newcomers in the electronics arena. I also have a YouTube channel where I publish other helpful videos, you can find the link inside the articles. I always try to keep it simple so that it becomes easy to understand. I hope these will help them to learn electronics and apply the knowledge in their real life.

0 Comments

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *