This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

SN74HC595: SRCLR does not seem to actually clear the shift register when SRCLK is held HIGH

Part Number: SN74HC595


Hi there,

I have got a small problem - either in my understanding of the documentation or with the documentation itself [www.ti.com/lit/ds/symlink/sn74hc595.pdf] - only I will use the names of the pins with inverted functionality without overlines [i.e. by writing "SRCLR high" I mean, that "\overline{SRCL}" is high].

Regarding my setup: I use an Arduino Uno at 5V and 16MHz [Atmega328p] to control a GM1803XYF E4 SN74HC595N.

My findings are:

- When 1:

- OE low, RCLK high, SRCLK high, SRCLR high and 0xff on the outputs

- I can now make SRCLR low, RCLK low, RCLK high -> 0x00 at outputs [which is fine]

  Following that I can make SRCLR high, RCLK low, RCLK high -> 0xff at outputs [which is unexpected]

- When 2:

- OE low, RCLK high, SRCLK low, SRCLR high and 0xff on the outputs

- I can now make SRCLR low, RCLK low, RCLK high -> 0x00 at outputs [which is fine]

  Following that I can make SRCLR high, RCLK low, RCLK high -> 0x00 at outputs [which is expected]

Is it correct that SRCLK has to be low for SRCLR to have a permanent effect? Did I not read so in the documentation? Are my parts faulty? Or did I do something wrong?

I hope, I could make myself sufficiently clear - if not, please don't hesitate to ask anything.

Best regards,

Johannes

  • As shown in table 1, only the positive edge on SRCLK matters; the state of SRCLK should not have any other effect.

    Please show the Arduino code that generates the high SRCLK signal while pulling SRCLR low.

  • Good evening,

    as my code is somewhat complex, I would like to only give the following excerpt:

        // supply voltage
        GND::setType(AvrInputOutput::OUTPUT_LOW);
        VCC::setType(AvrInputOutput::OUTPUT_HIGH);

        // pin setup
        nOE::setType(AvrInputOutput::OUTPUT_LOW); // enable  output
        RCLK::setType(AvrInputOutput::OUTPUT_HIGH);
        SRCLK::setType(AvrInputOutput::OUTPUT_HIGH);
        nSRCLR::setType(AvrInputOutput::OUTPUT_HIGH); // do not clear

        // shift in 0xff
        SER::setType(AvrInputOutput::OUTPUT_HIGH);
        for (uint8_t pinNumber = 0; pinNumber < 8; ++pinNumber)
        {
            SRCLK::clearPort();
            SRCLK::setPort();
        }
        // clear SER
        SER::clearPort();
        // show shift-in value
        RCLK::clearPort();
        RCLK::setPort();

        // ---------------
        // now clear the shift register
        nSRCLR::clearPort();

        // <- here Q_H' is cleared, as expected

        // show cleared
        RCLK::clearPort();
        RCLK::setPort();

        // <- here the Q_x are cleared, as expected

        // should be cleared now, so take away the clear-signal
        nSRCLR::setPort();

        // <- here however Q_H' goes HIGH again

        // show cleared
        RCLK::clearPort();
        RCLK::setPort();

        // <- and here all Q_x are HIGH as well

    which is exactly, what I wrote above in words.

    For a full reference please refer to [corresponding to point 1 above]:    https://github.com/JohannesWilde/DeviceTester/tree/0b39a81d8c360dd6e9495e3b7ddeeceefea3a625/src

    A very slightly modified version that works as expected can be found here [corresponding to point 2 above]:   https://github.com/JohannesWilde/DeviceTester/tree/ShiftRegister74HC595TestingWorking/src


    I will also attach the produced assembler code [compiled with -O3 instead of -Os for clarity] for the not-working example [point 1] below - in order to understand this one will however first have to know the following connections:

    GND         -> D9         -> B1
    nSRCLR  -> D11      -> B3
    SRCLK    -> D12      -> B4
    RCLK       -> D13      -> B5
    nOE          -> A0         -> C0
    SER          -> A1         -> C1
    VCC          -> A3        -> C3

    and that for sbi [set bit in I/O register] and cbi [clear bit in I/O register] the register addresses are as follows:

    Register | DDR  | PORT | PIN

    B             |   0x04 |  0x05  |   0x03

    C             |   0x07 |  0x08  |  0x06

    - but then one can see for sure, that the compiled code does what I expected it to do:

    0000007a <main>:
      7a:    45 9a           sbi    0x08, 5    ; 8    <- Port C5 HIGH <- enables my leds on the shiftregister
      7c:    21 9a           sbi    0x04, 1    ; 4    <- Ddr B1 HIGH <- GND output
      7e:    29 98           cbi    0x05, 1    ; 5    <- Port B1 HIGH <- GND high
      80:    3b 9a           sbi    0x07, 3    ; 7    <- DDR C3 HIGH <- VCC output
      82:    43 9a           sbi    0x08, 3    ; 8    <- Port C3 HIGH <- VCC high
      84:    38 9a           sbi    0x07, 0    ; 7
      86:    40 98           cbi    0x08, 0    ; 8    <- C0 Output LOW <- nOE LOW     <- output enabled
      88:    25 9a           sbi    0x04, 5    ; 4
      8a:    2d 9a           sbi    0x05, 5    ; 5    <- B5 Output HIGH    <- RCLK HIGH
      8c:    24 9a           sbi    0x04, 4    ; 4
      8e:    2c 9a           sbi    0x05, 4    ; 5    <- B4 Output HIGH     <- SRCLK HIGH
      90:    23 9a           sbi    0x04, 3    ; 4
      92:    2b 9a           sbi    0x05, 3    ; 5    <- B3 Output HIGH     <- nSRCLR HIGH     <- don't clear the ShiftRegister
      94:    39 9a           sbi    0x07, 1    ; 7
      96:    41 9a           sbi    0x08, 1    ; 8    <- C1 Output HIGH     <- SER HIGH
      98:    2c 98           cbi    0x05, 4    ; 5    <- Port B4  LOW           <- SRCLK LOW
      9a:    2c 9a           sbi    0x05, 4    ; 5    <- Port B4 HIGH           <- SRCLK HIGH
      9c:    2c 98           cbi    0x05, 4    ; 5
      9e:    2c 9a           sbi    0x05, 4    ; 5    <- second time
      a0:    2c 98           cbi    0x05, 4    ; 5
      a2:    2c 9a           sbi    0x05, 4    ; 5    <- third time
      a4:    2c 98           cbi    0x05, 4    ; 5
      a6:    2c 9a           sbi    0x05, 4    ; 5    <- fourth time
      a8:    2c 98           cbi    0x05, 4    ; 5
      aa:    2c 9a           sbi    0x05, 4    ; 5    <- fifth time
      ac:    2c 98           cbi    0x05, 4    ; 5
      ae:    2c 9a           sbi    0x05, 4    ; 5    <- sixth time
      b0:    2c 98           cbi    0x05, 4    ; 5
      b2:    2c 9a           sbi    0x05, 4    ; 5    <- seventh time
      b4:    2c 98           cbi    0x05, 4    ; 5
      b6:    2c 9a           sbi    0x05, 4    ; 5    <- eightth time    ---    now 0xff should be shifted in
      b8:    41 98           cbi    0x08, 1    ; 8    <- Port C1 LOW    <- SER LOW
      ba:    2d 98           cbi    0x05, 5    ; 5    <- Port B5 LOW     <- RCLK LOW
      bc:    2d 9a           sbi    0x05, 5    ; 5    <- Port B5 HIGH     <- RCLK HIGH     --- now visible on outputs Q_x that 0xff internally
      be:    2b 98           cbi    0x05, 3    ; 5    <- Port B3 LOW     <- nSRCLR  LOW     <- this should clear the shift register
      c0:    2d 98           cbi    0x05, 5    ; 5    <- Port B5 LOW
      c2:    2d 9a           sbi    0x05, 5    ; 5    <- Port B5 HIGH     <- RCLK HIGH     --- now visible on outputs Q_x that 0x00 internally
      c4:    2b 9a           sbi    0x05, 3    ; 5    <- Port B3 HIGH     <- nSRCLR  HIGH     <- this should leave the shift-register cleared, right?
      c6:    2d 98           cbi    0x05, 5    ; 5    <- Port B5 LOW
      c8:    2d 9a           sbi    0x05, 5    ; 5    <- Port B5 HIGH     <- RCLK HIGH     --- now visible on outputs Q_x that 0xff internally and Q_H' is HIGH as well
      ca:    80 e0           ldi    r24, 0x00    ; 0  <- Atmega 328p cleaning up its registers...
      cc:    90 e0           ldi    r25, 0x00    ; 0
      ce:    08 95           ret

    Thanks again for any further thoughts.

    Greetings,

    Johannes

    PS: Attached the produced Assembler code for the non-working case in readable [.lst] and flashable [.hex  - e.g. via avrdude] formats:

    6545.HexAndAssemblerFiles.zip

  • Your code looks OK. (But in the "Working" branch, SRCLK should be initialized low.)

    I have no 595 here to test it, but as far as I can see, what you describe should not be possible according to the datasheet.

    Wild guess: try resetting the device before you shift in anything.

  • Hi again,

    yes SRCLK should have been initialized LOW - thanks.

    And thanks for your thoughts thus far.

    Maybe someone else has got a 595 and can test whether they can reproduce my experienced behaviour?

    Greetings,

    Johannes

  • PS: I would like to add, that the used Arduino Uno is running at 16MHz [i.e. 62.5ns per clock] - I however tried to introduce more than 1s of delay after pulling LOW the nSRCLR pin - without noticing any other effect besides a delay. Also the 16MHz are much below the specified maximum working frequency of the 595 [20ns required for nSRCLR to be low].
  • Hi Johannes,
    Can you also provide a schematic of the HC595 and associated connections? I don't need to see your whole board, but it would be helpful to see how all the signals coming into the device are wired and if there's anything else on there (for example, a half meter of coax can make a massive difference in signal integrity).

    I've used the HC595 in many applications personally, and I've seen it used by many of our customers. The most common mistake I see is a slow or noisy (nonmonotonic) input to the clock pin, usually caused by either passive filtering (RC) or relatively long transmission lines (> 25cm).
  • Hello Emrys,
    maybe I was somewhat ambiguous with my previous choice of words - with "clock" I meant the clock in my Arduino - the 595 itself is not "clocked" per se. I wanted to only apply a change on the respective pins when needed [please refer to my code examples above].
    But to clarify: I tried setting SRCLK is HIGH, then wait a second, then setting SRCLR LOW, then wait a second, ... - to no avail.

    And also, the only difference to my working example above [2.] is that that SRCLK is HIGH and not LOW while I pull SRCLR LOW - and while SRCLR is pulled low Q_H' and the outshifted Q_x do read LOW. So I would not suspect it to be a signal issue.

    If you still think seeing my breadboard would help in any way, please say so, then I will try to upload a photo. It does not look nice - it is a handwired breadboard with copper wires used to connect the correct pins - but for my purposes it does work [at least that is what I think].

    Thanks for your time,
    Johannes
  • Hi Johannes,
    Yes, I understand what you meant.

    The SRCLK pin of the 595 is also a clock pin, as is the RCLK pin -- triggering on the rising edge of the input signal. When I say "clock pin" I'm talking about the SRCLK or RCLK pins of the 595 device. Slow or noisy signals can cause multiple triggers that will produce incorrect outputs.

    To be clear, a "slow" signal is a signal that has a rise or fall time of larger than ~100ns. This is most typically found through measurement (oscilloscope shots of the signals) or calculated from schematic values and layout parasitics.
  • Hey Johannes,
    I just wanted to check with you to see if you have had any luck in troubleshooting this issue on your end.
  • Hi Emrys,
    as this is a for a personal project I could not find the time during the last days. If I find the time, I will upload a picture of my hardware - and if you then expect capacitances to be a problem, maybe even can check signals on an oscilloscope.
    But for now I chose to use the method described in point 2. in my first post - when SRCLK is held LOW the 595 clears as expected.
    Greetings,
    Johannes
  • I understand completely - I also have personal projects at home that sometimes sit on my workbench, untested, for weeks.

    I'll mark this thread as TI thinks resolved for now, but if you have additional info or other questions, please come back any time.  The thread will automatically lock after a few weeks without any posts, but you can use the +Ask a related question button in the top right corner of the forum to continue the thread later.