Matt Link

Interfacing 595 Shift Register with 7-Segment

Discussion created by Matt Link on Mar 14, 2011
Latest reply on Mar 14, 2011 by bigmac

Hello,

 

I am trying to interface a 595 shift register to drive a 7 segment display as part of my groups senior project.  Our goal is to cascade three shift registers together to make a 3 digit display.  We are going to take body measurements for heartrate and body temperature (and time permitting blood pressure) and display them on the 7 segments.  This means that we will have to drive four, three digit displays.  Is it possible to drive up to four displays using what I have with the dragon board? I have been working on some code for it but am very unsure of the direction I should be taking.  I have been studying the SPI port because that seems to be the way to drive it.  I am using the MC9S12DG256, hcs912 based board.  Here is the code from my main program:

 

 

/****************************************************************
*
*    Senior Project
*    Interfacing 7 segment display
*
****************************************************************/
#include <hidef.h>      /* common defines and macros */
#include "derivative.h"      /* derivative-specific definitions */
#include "delays.h"
#include "spi0util.h"
void set24MHzClock( void );
void delay( void );
void openspi0(void);
void main(void) 
{
  char i;
  unsigned char disp_tab[8][2] = 
        {{0x80,0x7F},{0x40,0x70},{0x20,0x5F},{0x10,0x5B},
         {0x08,0x33},{0x04,0x79},{0x02,0x6D},{0x01,0x30}};
  set24MHzClock( );
  openspi0();   // configure the SPI0 module
 
 while( 1 )
 {
            
    
     DDRK |= 0x40; // configure pin PK7 as output
     while(1) 
     {
         for (i = 0; i < 8; i++) 
         {
             putcspi0(disp_tab[i][0]);  // send out digit select value
             putcspi0(disp_tab[i][1]);  // send out segment pattern 
             PORTK &= ~0x40;              // load value into latch of 74HC595s
             PORTK |= 0x40;               // " 
             delay1_6ms();             // display a digit for 1 ms
         }
     }
   }
 
 
}
/*---------------------------------------------------------------------------
- set24MHzClock
-
- Sets up phase-locked-loop and clock source, etc., for 24 MHz operation
-
- OSC = oscillator clock frequency = 8 MHz
- PLLCLK = Phase-Locked-Loop Clock frequency, which we want to be 24 MHz
- According to the Clock and Reset Generation (CRG) documentation the
-  formula for the PLLCLK based on OSC is:
- PLLCLK = OSC X 2 X (SYNR + 1) / (REFDV + 1)
-OSC (8MHz) must be multiplied by 6 to get 24 MHz, so select values
-for SYNR & REFDV so that (SYNR + 1) / (REFDV + 1) = 3/1 = 3
-This code uses SYNR = 1 & REFDV = 0
----------------------------------------------------------------------------*/
void set24MHzClock(void)
{
     CLKSEL = 0;    // Use crystal oscillator for E clock
     PLLCTL = 0;    // PLL off
     SYNR   = 2;    // Set (SYNR + 1) / (REFDV) = 3 ...
     REFDV  = 0;    // ... see equation in prologue 
     PLLCTL = 0x40; // PLL on
     while( !( CRGFLG & 8) )
     { }            // Wait for lock-up
     CLKSEL = 0x80; // Switch to PLL for system clock
}
/*---------------------------------------------------------------------------
- openspi0
-
----------------------------------------------------------------------------*/
void openspi0(void)
{
     SPI0BR  = 0;    // set baud rate to 12 MHz
     SPI0CR1 = 0x50; // disable SPI interrupt, enable SPI, SCK idle low, shift
                     //   data on rising edge, shift data msb first
     SPI0CR2 = 0x02; // disable bidirection mode, disable SPI in wait mode
     WOMS    = 0;    // enable Port S pull up
}

 

I have included a zipped file with all my work including all my functions, datasheets for the shift register and 7 segment display.  Please take a look, right now I have no guidance software wise on how to do this and will greatly appreciate any help that I can get.

Outcomes