NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » Completely Confused with Shift registers

December 12, 2011
by missle3944
missle3944's Avatar

Hi everyone.

I'm completely and utterly confused with my 74hc595 shift register. I'm using Ricks 7 segment LED driver code. I altered it to only suit 1 shift register. My question is why is it outputting 11111111 instead of just 111111001. I also don't understand why there is a counter on shift register code? I'm really frustrated at this.

Heres the code snippet for it

/*****************************************************************************
 *  Description  : SPI I/O Using 74HC595 8-bit shift registers
 *                 with output latch to drive 7 Seg Displays
 *  Author       : RS
 *  Target       : ATMega328 (ATMega168 with simple modification)
 ****************************************************************************/
#define F_CPU 14745600
#include <avr/io.h>
#include "../libnerdkits/delay.h"
#include "../libnerdkits/io_328p.h"  // REMOVE FOR ATMEGA168

#define SPI_PORT PORTB
#define SPI_DDR  DDRB
#define SPI_CS   PB2

// Define connections for 7 Segment common Anode Display
// Connected to QB Thru QH on 74HC595
//
// Segment  Connection
//             Q0    (Not Connected)
//    a        Q1
//    b        Q2
//    c        Q3
//    d        Q4
//    e        Q5
//    f        Q6
//    g        Q7

#define DISP_ONE    0b11110010
#define DISP_TWO    0b01001000
#define DISP_THREE  0b01100000
#define DISP_FOUR   0b00110010
#define DISP_FIVE   0b00100100
#define DISP_SIX    0b00000110
#define DISP_SEVEN  0b11110000
#define DISP_EIGHT  0b00000000
#define DISP_NINE   0b00110000
#define DISP_ZERO   0b10000000
#define DISP_BLANK  0b11111110

void SPI_Write(unsigned char dataout)
{

  // Start transmission (MOSI)
  SPDR = dataout;

  // Wait for transmission to finish
  while(!(SPSR & (1<<SPIF)));

}

void SPI_Latch(void)
{
  // Latch the Output using rising pulse to the RCK Pin
  SPI_PORT |= (1<<SPI_CS);

   // Hold pulse for 1 micro second
   delay_us(1);

  // Disable Latch
  SPI_PORT &= ~(1<<SPI_CS);
}

int main(void)
{
  uint8_t ones, tens, hund, thou;
  uint16_t cnt, temp;

  // Set the PORTD as Output:
  DDRD=0xFF;
  PORTD=0x00;

  // Initial the AVR ATMega168 SPI Peripheral

  // Set MOSI and SCK as output, others as input
  SPI_DDR = (1<<PB3)|(1<<PB5)|(1<<PB2);

  // Latch Disable (RCK Low)
  SPI_PORT &= ~(1<<SPI_CS);

  // Enable SPI, Master, set clock rate fck/2 (maximum)
  SPCR = (1<<SPE)|(1<<MSTR);
  SPSR = (1<<SPI2X);

  // Reset the 74HC595 registers
  SPI_Write(DISP_BLANK);
  SPI_Write(DISP_BLANK);
  SPI_Latch();

  for(;;) {

    for(cnt=1;cnt<9;cnt++)
      {

        // Send ouput for rightmost digit (ones

if(cnt==1) SPI_Write(DISP_ONE);
delay_ms(1000);        
if(cnt==2) SPI_Write(DISP_TWO);
        if(cnt==3) SPI_Write(DISP_THREE);

    // Latch all registers

    SPI_Latch();

    delay_ms(1000);
  }

}
  return 0;

}

December 13, 2011
by Rick_S
Rick_S's Avatar

The counter is there to change the number on the display. What type of display do you have? Is your shift register connected to the display as described? How is your micro-controller connected to the shift register?

Rick

December 13, 2011
by missle3944
missle3944's Avatar

Rick,

Yes it is. My 7 Segment led display is common anode but I think it is more of an issue of the shift register. Once I loaded the code and flipped the programming switch every pin went high. I even used LEDs on each pin to debug and each one was lit. I'm confused. I have the wiring correct. I wires coming out of pb2 pb3 and pb5 as in your picture going to the 595 correctly.

-Dan

December 13, 2011
by BobaMosfet
BobaMosfet's Avatar

missle3944-

Have you looked at the datasheet? Did it make sense? You need to understand that a shift-register (74HC595 in particular) is a serial to parallel device, right? It expects you to drive data into it using a "clock", 1 bit at a time, before you can expect it to output a parallel value in the following cycle(s).

BM

December 13, 2011
by missle3944
missle3944's Avatar

BM,

Thanks for the tip. Can you explain what this means to me? Because it sounds like the problem I'm having.

When the output-enable (OE) input is high, the outputs are in the high-impedance state.

-Dan

December 14, 2011
by Rick_S
Rick_S's Avatar

OE being high means the outputs are not connected IE High impedance or "floating". That is why pin 13 (OE) is tied low.

Just to make sure you traced the wires correctly, the connection between the micro and the 595 should be

MICRO           595
PB2 (16)        Latch Clock (12)
PB3 MOSI (17)   A Serial Data Input (14)
PB5 SCK (19)    Shift Clock (11)

The other 595 connections should be:

Pins 10 & 16 to VCC

Pins 8 & 13 to GND

Pins 1 thru 7 and 14 as outputs.

In single configuration pin 9 does not need connected - it is a serial output for overflow data that would chain to the (A Serial Input (14)) of the next shift register.

Hope that helps a bit with the wiring in case it is what is messing you up.

Rick

December 17, 2011
by Rick_S
Rick_S's Avatar

Dan, ever get this working??

December 18, 2011
by missle3944
missle3944's Avatar

Rick,

It kinda works, but I have question on least significant bits. Does the least significant bit mean that

 00000001

that the 1 would be placed in pin Q7 or Q0 on the 595?

-Dan

December 18, 2011
by Rick_S
Rick_S's Avatar

I'm pretty sure it would end up driving Q0 the way that program was written. That was why Q0 was not connected in the program and it was always off in the byte for each digit.

Rick.

December 18, 2011
by missle3944
missle3944's Avatar

Got it!

Thanks Rick. So far it just counts up to 3 but I'll improve it.

-Dan

December 18, 2011
by missle3944
missle3944's Avatar

1 More thing,

I have another problem that is stumping me, I am trying to display the temperature on 2 seven seg displays. I'm confused on how to get the ones to display and the tens. I'm using your code segment

ones = cnt%10;
        temp = cnt/10;
        tens = temp%10;

For some reason the display shows 32. And the temp is about 63 degrees. I dont know if it is displaying the 3 and mabey a decimal point 2. I've modified it to my code which is

ones = temp8%10;
        temp = temp8/10;

-Dan tens = temp%10;

December 19, 2011
by Rick_S
Rick_S's Avatar

I'd have to see the rest of your code to know what is going on. Just to be sure we are on the same page though, you do know what modulus math "%" does here correct?

In case you don't, you can think of it as calculating the remainder in a division formula.

For instance 63%10 would be equivalent to 63/10 = 6 remainder 3 so 3 would be the modulus.

If we are using integer math, there is no decimal portion so when I did my formula's you referenced, if cnt were equal to 63 the math would play out like this:

ones = 63%10  (=3)
temp = 63/10  (=6)
tens = 6%10   (=6)

So after all was said and done, tens would be 6 and ones would be 3. If you are seeing something different on the display, either something isn't wired correctly, the bytes defining your digits are wrong, or the integer (cnt) isn't providing you with the number you think it is. Or maybe something I'm not thinking of right now. Wink

Rick

December 19, 2011
by missle3944
missle3944's Avatar

Heres my full code

/*****************************************************************************
 *  Description  : SPI I/O Using 74HC595 8-bit shift registers
 *                 with output latch to drive 7 Seg Displays
 *  Author       : RS
 *  Target       : ATMega328 (ATMega168 with simple modification)
 ****************************************************************************/
#define F_CPU 14745600
#include <avr/io.h>
#include "../libnerdkits/delay.h"
#include "../libnerdkits/io_328p.h"  // REMOVE FOR ATMEGA168

#define SPI_PORT PORTB
#define SPI_DDR  DDRB
#define SPI_CS   PB2

// Define connections for 7 Segment common Anode Display
// Connected to QB Thru QH on 74HC595
//
// Segment  Connection
//             Q0    (Not Connected)
//    a        Q1
//    b        Q2
//    c        Q3
//    d        Q4
//    e        Q5
//    f        Q6
//    g        Q7

#define DISP_ONE    0b11110010
#define DISP_TWO    0b01001000
#define DISP_THREE  0b01100000
#define DISP_FOUR   0b00110010
#define DISP_FIVE   0b00100100
#define DISP_SIX    0b00000110
#define DISP_SEVEN  0b11110000
#define DISP_EIGHT  0b00000000
#define DISP_NINE   0b00110000
#define DISP_ZERO   0b10000000
#define DISP_BLANK  0b11111110

void adc_init() {
  // set analog to digital converter
  // for external reference (5v), single ended input ADC0
  ADMUX = 0;

  // set analog to digital converter
  // to be enabled, with a clock prescale of 1/128
  // so that the ADC clock runs at 115.2kHz.
  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);

  // fire a conversion just to get the ADC warmed up
  ADCSRA |= (1<<ADSC);
}

uint16_t adc_read() {
  // read from ADC, waiting for conversion to finish
  // (assumes someone else asked for a conversion.)
  // wait for it to be cleared
  while(ADCSRA & (1<<ADSC)) {
    // do nothing... just hold your breath.
  }
  // bit is cleared, so we have a result.

  // read from the ADCL/ADCH registers, and combine the result
  // Note: ADCL must be read first (datasheet pp. 259)
  uint16_t result = ADCL;
  uint16_t temp = ADCH;
  result = result + (temp<<8);

  // set ADSC bit to get the *next* conversion started
  ADCSRA |= (1<<ADSC);

  return result;
}

double sampleToFahrenheit(uint16_t sample) {
  // conversion ratio in DEGREES/STEP:
  // (5000 mV / 1024 steps) * (1 degree / 10mV)
  //    ^^^^^^^^^^^      ^^^^^^^^^^
  //     from ADC         from LM34
  return sample * (5000.0 / 1024.0 / 10.0);  
}

void SPI_Write(unsigned char dataout)
{

  // Start transmission (MOSI)
  SPDR = dataout;

  // Wait for transmission to finish
  while(!(SPSR & (1<<SPIF)));

}

void SPI_Latch(void)
{
  // Latch the Output using rising pulse to the RCK Pin
  SPI_PORT |= (1<<SPI_CS);

   // Hold pulse for 1 micro second
   delay_us(1);

  // Disable Latch
  SPI_PORT &= ~(1<<SPI_CS);
}

int main(void)
{
  uint8_t ones, tens, hund, thou, temp8;
  uint16_t cnt, temp;

// start up the Analog to Digital Converter
  adc_init();

// Set the PORTD as Output:
  DDRD=0xFF;
  PORTD=0x00;

  // Initial the AVR ATMega168 SPI Peripheral

  // Set MOSI and SCK as output, others as input
  SPI_DDR = (1<<PB3)|(1<<PB5)|(1<<PB2);

  // Latch Disable (RCK Low)
  SPI_PORT &= ~(1<<SPI_CS);

  // Enable SPI, Master, set clock rate fck/2 (maximum)
  SPCR = (1<<SPE)|(1<<MSTR);
  SPSR = (1<<SPI2X);

  // Reset the 74HC595 registers
  SPI_Write(DISP_BLANK);
  SPI_Write(DISP_BLANK);
  SPI_Latch();
  uint16_t last_sample = 0;
  double this_temp;
  double temp_avg;
  uint8_t i;

while(1){
temp8 = temp_avg;
temp_avg = 0.0;
    for(i=0; i<100; i++) {
      last_sample = adc_read();
      this_temp = sampleToFahrenheit(last_sample);

      // add this contribution to the average
      temp_avg = temp_avg + this_temp/100.0;
    }

for (cnt=1;cnt<1000;cnt++) 
{

        ones = temp8%10;
        temp = temp8/10;
        tens = temp%10;

delay_ms(1000);
// Send ouput for rightmost digit (ones)

        if(ones==0) SPI_Write(DISP_ZERO);
        if(ones==1) SPI_Write(DISP_ONE);
        if(ones==2) SPI_Write(DISP_TWO);
        if(ones==3) SPI_Write(DISP_THREE);
        if(ones==4) SPI_Write(DISP_FOUR);
        if(ones==5) SPI_Write(DISP_FIVE);
        if(ones==6) SPI_Write(DISP_SIX);
        if(ones==7) SPI_Write(DISP_SEVEN);
        if(ones==8) SPI_Write(DISP_EIGHT);
        if(ones==9) SPI_Write(DISP_NINE);

        // Send outut for tens digit

        if(tens==0) SPI_Write(DISP_ZERO);
        if(tens==1) SPI_Write(DISP_ONE);
        if(tens==2) SPI_Write(DISP_TWO);
        if(tens==3) SPI_Write(DISP_THREE);
        if(tens==4) SPI_Write(DISP_FOUR);
        if(tens==5) SPI_Write(DISP_FIVE);
        if(tens==6) SPI_Write(DISP_SIX);
        if(tens==7) SPI_Write(DISP_SEVEN);
        if(tens==8) SPI_Write(DISP_EIGHT);
        if(tens==9) SPI_Write(DISP_NINE);

    // Latch all registers

    SPI_Latch();

    delay_ms(100);
}

 }

  return 0;
  }
December 20, 2011
by Rick_S
Rick_S's Avatar

Dan, since you are not displaying a counter on your 7 segment display, you don't need the counter loop. That aside, do you have your two shift registers wired correctly to the display? Meaning, is the shift register closest to your microcontroller connected to the one's or the 10's digit? The shift registers chain their data so the 1st byte is sent into the 1st shift register in the chain. Then when the second byte is sent, byte 1 will shift into the 2nd shift register and the 2nd byte goes into the 1st one. As a result, the last shift register should have the one's digit and the 1st would be your ten's.

I have to look farther at it but for now I have to head off to work. On a last note, I did notice a lot of data type conversions going on but I don't know if that would cause your problem.

Rick

December 21, 2011
by missle3944
missle3944's Avatar

Rick,

It works!!!!! I removed the counter and it works fine. Now I just need to add tenths and hundredths spot for the 7 segment display. Thanks a ton!

Here's a pic of my setup .

I also got a Texas instruments sample of a i2c temperature sensor. Hopefully I can use your wii nunchuck 12c code for it. The chip looks pretty simple on the datasheet.

.

-Dan

December 21, 2011
by missle3944
missle3944's Avatar

I'm just waiting on the headers for the i2c temp sensor. I bought a ton of stuff from Thailand so it will be 4 or 5 more days probably.

-Dan

December 21, 2011
by missle3944
missle3944's Avatar

How would I display a decimal on the display because you cannot use the modulo operator with a double floating point number. I've converted temp * 10 to equal temp8 but I have no idea how to isolate any number on it because it has more than 3 digits.

-Dan

December 21, 2011
by Rick_S
Rick_S's Avatar

If you want to do two place decimal, just multiply by 1000 and use a uint16_t for your data type. So if your temperature were 63.56 degrees, you would end up with 6356 then you could use all 4 digits as I did in the original counter program I had written. You could just hard wire the decimal point between the 2nd and 3rd digit.

As for the temperature sensor, you might want to look at the I2C code I have on here for the real time clock IC with temperature. Also for I2C routines, Noter has some good postings (haven't seen him around in a while though), or you can search the web for Peter Fleury I've used his AVR I2C libraries and they work quite well.

Glad to see it going Thumbs Up

Rick

December 21, 2011
by missle3944
missle3944's Avatar

Rick,

I tried multiplying the temp_avg by 1000 and I get just a big jumble of numbers. It jumps from 50 to 91 then to 30. This is really weird. Here's my code if anything looks wrong.

/*****************************************************************************
 *  Description  : SPI I/O Using 74HC595 8-bit shift registers
 *                 with output latch to drive 7 Seg Displays
 *  Author       : RS
 *  Target       : ATMega328 (ATMega168 with simple modification)
 ****************************************************************************/
#define F_CPU 14745600
#include <avr/io.h>
#include "../libnerdkits/delay.h"
#include "../libnerdkits/io_328p.h"  // REMOVE FOR ATMEGA168
 #include "../libnerdkits/uart.h"
#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"
#include "../libnerdkits/uart.h"
#include <stdio.h>
#include <math.h>

#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <inttypes.h>

#include "../libnerdkits/delay.h"
#include "../libnerdkits/lcd.h"
#include "../libnerdkits/uart.h"
#define SPI_PORT PORTB
#define SPI_DDR  DDRB
#define SPI_CS   PB2

// Define connections for 7 Segment common Anode Display
// Connected to QB Thru QH on 74HC595
//
// Segment  Connection
//             Q0    (Not Connected)
//    a        Q1
//    b        Q2
//    c        Q3
//    d        Q4
//    e        Q5
//    f        Q6
//    g        Q7

#define DISP_ONE    0b11110010
#define DISP_TWO    0b01001000
#define DISP_THREE  0b01100000
#define DISP_FOUR   0b00110010
#define DISP_FIVE   0b00100100
#define DISP_SIX    0b00000110
#define DISP_SEVEN  0b11110000
#define DISP_EIGHT  0b00000000
#define DISP_NINE   0b00110000
#define DISP_ZERO   0b10000000
#define DISP_BLANK  0b11111110

void adc_init() {
  // set analog to digital converter
  // for external reference (5v), single ended input ADC0
  ADMUX = 0;

  // set analog to digital converter
  // to be enabled, with a clock prescale of 1/128
  // so that the ADC clock runs at 115.2kHz.
  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);

  // fire a conversion just to get the ADC warmed up
  ADCSRA |= (1<<ADSC);
}

uint16_t adc_read() {
  // read from ADC, waiting for conversion to finish
  // (assumes someone else asked for a conversion.)
  // wait for it to be cleared
  while(ADCSRA & (1<<ADSC)) {
    // do nothing... just hold your breath.
  }
  // bit is cleared, so we have a result.

  // read from the ADCL/ADCH registers, and combine the result
  // Note: ADCL must be read first (datasheet pp. 259)
  uint16_t result = ADCL;
  uint16_t temp = ADCH;
  result = result + (temp<<8);

  // set ADSC bit to get the *next* conversion started
  ADCSRA |= (1<<ADSC);

  return result;
}

double sampleToFahrenheit(uint16_t sample) {
  // conversion ratio in DEGREES/STEP:
  // (5000 mV / 1024 steps) * (1 degree / 10mV)
  //    ^^^^^^^^^^^      ^^^^^^^^^^
  //     from ADC         from LM34
  return sample * (5000.0 / 1024.0 / 10.0);  
}

void SPI_Write(unsigned char dataout)
{

  // Start transmission (MOSI)
  SPDR = dataout;

  // Wait for transmission to finish
  while(!(SPSR & (1<<SPIF)));

}

void SPI_Latch(void)
{
  // Latch the Output using rising pulse to the RCK Pin
  SPI_PORT |= (1<<SPI_CS);

   // Hold pulse for 1 micro second
   delay_us(1);

  // Disable Latch
  SPI_PORT &= ~(1<<SPI_CS);
}

int main(void)
{
  uint8_t ones, tens, hund, thou;
  uint16_t cnt, temp, temp8;
 // start up the serial port

  // start up the LCD
  lcd_init();
  FILE lcd_stream = FDEV_SETUP_STREAM(lcd_putchar, 0, _FDEV_SETUP_WRITE);
  lcd_home();

uart_init();
  FILE uart_stream = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
  stdin = stdout = &uart_stream;

// start up the Analog to Digital Converter
  adc_init();

// Set the PORTD as Output:
  DDRD=0xFF;
  PORTD=0x00;

  // Initial the AVR ATMega168 SPI Peripheral

  // Set MOSI and SCK as output, others as input
  SPI_DDR = (1<<PB3)|(1<<PB5)|(1<<PB2);

  // Latch Disable (RCK Low)
  SPI_PORT &= ~(1<<SPI_CS);

  // Enable SPI, Master, set clock rate fck/2 (maximum)
  SPCR = (1<<SPE)|(1<<MSTR);
  SPSR = (1<<SPI2X);

  // Reset the 74HC595 registers
  SPI_Write(DISP_BLANK);
  SPI_Write(DISP_BLANK);
  SPI_Latch();
  uint16_t last_sample = 0;
  double this_temp;
  double temp_avg;
  uint8_t i;

while(1){
temp8 = temp_avg * 1000;

temp_avg = 0.0;
    for(i=0; i<100; i++) {
      last_sample = adc_read();
      this_temp = sampleToFahrenheit(last_sample);

      // add this contribution to the average
      temp_avg = temp_avg + this_temp/100.0;
    }

  printf_P(PSTR("%.2f degrees F \r\n"), temp_avg);

        ones = temp8%10;
        temp = temp8/10;
        tens = temp%10;
        temp = temp/10;
        hund = temp%10;
        thou = temp/10;

delay_ms(300);
// Send ouput for rightmost digit (ones)

        if(ones==0) SPI_Write(DISP_ZERO);
        if(ones==1) SPI_Write(DISP_ONE);
        if(ones==2) SPI_Write(DISP_TWO);
        if(ones==3) SPI_Write(DISP_THREE);
        if(ones==4) SPI_Write(DISP_FOUR);
        if(ones==5) SPI_Write(DISP_FIVE);
        if(ones==6) SPI_Write(DISP_SIX);
        if(ones==7) SPI_Write(DISP_SEVEN);
        if(ones==8) SPI_Write(DISP_EIGHT);
        if(ones==9) SPI_Write(DISP_NINE);

        // Send outut for tens digit

        if(tens==0) SPI_Write(DISP_ZERO);
        if(tens==1) SPI_Write(DISP_ONE);
        if(tens==2) SPI_Write(DISP_TWO);
        if(tens==3) SPI_Write(DISP_THREE);
        if(tens==4) SPI_Write(DISP_FOUR);
        if(tens==5) SPI_Write(DISP_FIVE);
        if(tens==6) SPI_Write(DISP_SIX);
        if(tens==7) SPI_Write(DISP_SEVEN);
        if(tens==8) SPI_Write(DISP_EIGHT);
        if(tens==9) SPI_Write(DISP_NINE);

    // Latch all registers

    SPI_Latch();

    delay_ms(100);

 }

  return 0;
  }
December 21, 2011
by missle3944
missle3944's Avatar

HAHA,Gosh I cant believe I forgot to paste in the other if statements.Anyway,I'm almost there. Its showing 50 degrees when the UART shows 70. That's weird. I'll keep at it.

-Dan

December 21, 2011
by missle3944
missle3944's Avatar

Rick,

I finally got it. Thanks a ton. Instead of multiplying temp_avg by 1000 I multiplied it by 100.

-Dan

December 22, 2011
by Rick_S
Rick_S's Avatar

Yep, 100 would be correct. Don't know what I was thinking. Embarrassed

I'm glad you got it working. It always feels good to see something come to life especially when the road to get there wasn't necessarily an easy one. That is one of the great things about the type of learning promoted with the NerdKit. When you learn as you do, you tend to remember much better than if you are just given everything from the start. I bet you now have a much better understanding of shift registers.

Do you have a specific project in mind or are you just experimenting?

Rick

December 22, 2011
by missle3944
missle3944's Avatar

Rick,

My parents thought it would be cool to have the MCU take a temperature every hour and send an email. So I was thinking I would use the email module in python, but I'm still in the experimentation phase of that. I haven't gotten anything to work yet. I've tested it on ubuntu and windows. I have successfuly made the nerdkit record the temp in the eeprom every 30 seconds, and that can easily be addapted for 1 hour.

I could always just have the python script listen to the com port and send an email every hour with a temp reading.

I was also thinking of having the temp every hour being stored in the eeprom and then going back and reading it with a push button in some sort of read mode. I can use the on board eeprom but I will have to create an array most likely for that lookup table of some sort. I'm not to skilled in arrays so I will have to sharpen my skills online.

-Dan

August 17, 2016
by BobaMosfet
BobaMosfet's Avatar

@Dan

You originally asked me:
When the output-enable (OE) input is high, the outputs are in the high-impedance state.

I apologize for not responding in a timely fashion but am doing so now in case a) it's still of interet to you, and b) it might be for someone else who finds this forum while it's still around.

The answer to your question: When OE is high, the outputs ignore anything from the latch register. This is by design so that the shift register can be loaded and then that data loaded into the latch registers. Once everything is ready, output is enabled and the latch register states are presented to the outputs Qa-Qh.

Post a Reply

Please log in to post a reply.

Did you know that you can build a circuit to convert the "dit" and "dah" of Morse code back into letters automatically? Learn more...