Shop OBEX P1 Docs P2 Docs Learn Events
Snippet Needed For 74HC165 Three Pin Hookup — Parallax Forums

Snippet Needed For 74HC165 Three Pin Hookup

idbruceidbruce Posts: 6,197
edited 2011-02-25 05:10 in Propeller 1
Hello Everyone

I am searching for a 74HC165 snippet for a three IO pin hookup. The OBEX has an object, but it utilizes four pins. Any input would be appreciated.

Bruce

Comments

  • idbruceidbruce Posts: 6,197
    edited 2011-02-24 09:26
  • idbruceidbruce Posts: 6,197
    edited 2011-02-24 13:09
    Okay, I have another question which also applies to the 74HC165.

    While reading the input from this shift register, I will be shifting 8 bits into a global variable, during which time only 1 of the 8 available inputs will be valid.

    Can I test for valid input with the following conditions?
    IF Shift_Register_Output == 128 'Binary pattern %10000000 (Button 1 pressed)
        Function1
      ELSEIF Shift_Register_Output == 64 'Binary pattern %01000000 (Button 2 pressed)
        Function2
      ELSEIF Shift_Register_Output == 32 'Binary pattern %00100000 (Button 3 pressed)
        Function3
      ELSEIF Shift_Register_Output == 16 'Binary pattern %00010000 (Button 4 pressed)
        Function4
      ELSEIF Shift_Register_Output == 8 'Binary pattern %00001000 (Button 5 pressed)
        Function5
      ELSEIF Shift_Register_Output == 4 'Binary pattern %00000100 (Button 6 pressed)
        Function6
      ELSEIF Shift_Register_Output == 2 'Binary pattern %00000010 (Button 7 pressed)
        Function7
      ELSEIF Shift_Register_Output == 1 'Binary pattern %00000001 (Button 8 pressed)
        Function8
    
  • DavidMDavidM Posts: 630
    edited 2011-02-24 14:28
    Heres my code, for both the 165 & the 595 shift registers
    CON
        Input = 0 , Output = 1, Low = 0, High = 1, Off = 0, On = 1 , NoEnablePin = -1
       
    PUB Out ( OutputLatchPin, OutputDataPin, OutputClockPin, OutputEnablePin, OutputBits, OutputByteValue )
      
        DIRA [OutputLatchPin] := Output                             'SET the LATCH Pin to OUTPUT 
        OUTA [OutputLatchPin] := Low                                'TOGGLE the LATCH Pin OFF
    
        DIRA [OutputDataPin]  := Output                             'SET the DATA Pin to OUTPUT 
        OUTA [OutputDataPin]  := Low                                'TOGGLE the DATA Pin OFF
    
        DIRA [OutputClockPin] := Output                             'SET the CLOCK Pin to OUTPUT
        OUTA [OutputClockPin] := Low                                'TOGGLE the CLOCK Pin OFF
      
        REPEAT OutputBits                                           'Start REPEAT LOOP for vNoOfBits ie 8  
                                                     
          OUTA [OutputDataPin]  := OutputByteValue >> (OutputBits-1)'SET the DATA pin to the first bit
          OutputByteValue       := OutputByteValue << 1             'SHIFT the BYTEVALUE to the Next Bit 
          OUTA [OutputClockPin] := High                             'TOGGLE the CLOCK Pin ON
          OUTA [OutputClockPin] := Low                              'TOGGLE the CLOCK Pin OFF
          WAITCNT(1_000 + CNT)                                      'WAIT for some time and REPEAT      
    
        OUTA [OutputLatchPin]   := High                             'TOGGLE the LATCH Pin On
        WAITCNT(1_000 + CNT)
        OUTA [OutputLatchPin]   := Low
         
        IF OutputEnablePin <> NoEnablePin                           '-1 = Dont use the ENABLE Pin, > -1 = Use the enbale Pin
           DIRA [OutputEnablePin] := Output                         'SET the ENABLE Pin to OUTPUT 
           OUTA [OutputEnablePin] := Low                            'SET the ENABLE Pin OFF, THIS STAYS OFF FOREVER!
    
    PUB In ( InputLoadPin, InputDataPin, InputClockPin, InputBits ) : InputByteValue | InputInBit
    
        InputByteValue:=0
          
        DIRA [InputLoadPin]  := Output                              'SET the LOAD Pin to OUTPUT 
        OUTA [InputLoadPin]  := Low                                 'TOGGLE the LOAD Pin OFF
        WAITCNT(1000 + CNT)                                         'Wait for some time
        OUTA [InputLoadPin]  := High                                'TOGGLE the LOAD Pin ON 
      
        DIRA [InputDataPin]  := Input                               'Set DATA Pin to INPUT
    
        DIRA [InputClockPin] := Output                              'SET the CLOCK Pin to OUTPUT
        OUTA [InputClockPin] := Low                                 'TOGGLE the CLOCK Pin OFF
    
        REPEAT InputBits                                            'Start REPEAT LOOP for vNoOfBits ie 8  
                                                     
          InputInBit           := INA[InputDataPin]                 'READ the DATA pin (bit value 1 or 0)
          InputByteValue       := (InputByteValue << 1) + InputInBit'SHIFT Left and Add to the BYTEVALUE the Next Bit 
          OUTA [InputClockPin] := High                              'TOGGLE the CLOCK Pin ON
          OUTA [InputClockPin] := Low                               'TOGGLE the CLOCK Pin OFF
          WAITCNT(1000 + CNT)                                       'WAIT for some time and REPEAT
    

    to use ( for getting a button pressed)


    vButtonPressed := Shift.In(InputLoadPin, InputDataPin, InputClockPin, InputBits)

    Use the case statement for checking against the button values INSTEAD of the multiple if statements


    regards

    Dave M
  • JonnyMacJonnyMac Posts: 9,208
    edited 2011-02-24 16:47
    The case structure is easier on the eyes.
    case Shift_Register_Output
        128 : Function1
         64 : Function2
         32 : Function3
         16 : Function4
          8 : Function5
          4 : Function6
          2 : Function7
          1 : Function8
    
  • idbruceidbruce Posts: 6,197
    edited 2011-02-24 16:50
    Thanks for answering Jon

    Was my assumption was correct, that I could take those bits (as a byte) and compare it to the decimal values stated? I am assuming that I can, because your reply contains the same values.

    Bruce
  • JonnyMacJonnyMac Posts: 9,208
    edited 2011-02-24 17:45
    I'm working under the assumption that Shift_Register_Output is a variable that you just read from the shift register. Keep in mind that numbers are numbers, and number systems are only for the convenience of humans; internally it's all the same to the microcontroller.

    128 == $80 == %1000_0000

    The Propeller IDE doesn't care which format you use. For binary inputs like you're using, I tend to use binary formatting. Had I written the code I would have done this:
    case Shift_Register_Output
        %1000_0000 : Function1
        %0100_0000 : Function2
        %0010_0000 : Function3
        %0001_0000 : Function4
        %0000_1000 : Function5
        %0000_0100 : Function6
        %0000_0010 : Function7
        %0000_0001 : Function8
    

    My original point is that case is easier to follow (and probably generates the same amount of code).
  • idbruceidbruce Posts: 6,197
    edited 2011-02-24 17:46
    Okay thanks Jon

    I definitely appreciate it.

    Bruce
  • idbruceidbruce Posts: 6,197
    edited 2011-02-24 18:20
    Hey Jon

    I missed half of that when I first read it. That is definitely a whole neater than a bunch of IF's, and I guess a binary comparison makes a lot more sense also. Thanks again Jon.

    Bruce
  • DavidMDavidM Posts: 630
    edited 2011-02-24 19:05
    You can make it even easier to read ( in a few months time) by declaring CONSTANTS for your buttons at the top of your object.
    CON
        Button1 := %1000_0000 
        Button2 := %0100_0000
        Button3 := %0010_0000 
        Button4 := %0001_0000 
        Button5 := %0000_1000
        Button6 := %0000_0100 
        Button7 := %0000_0010 
        Button8 := %0000_0001
    
    then to use them
    
    
    PUB Main
    
        ButtonPressed := Shift.In (InputLoadPin, InputDataPin, InputClockPin, InputBits) 
    
        CASE ButtonPressed
    
        Button1 : Function1
        Button2 : Function2
        Button3 : Function3
        Button4 : Function4
        Button5 : Function5
        Button6 : Function6
        Button7 : Function7
        Button8 : Function8
    
    

    PS Did you use my Shift register code? It uses 3 pins ( as you were asking for)

    regards

    Dave M
  • idbruceidbruce Posts: 6,197
    edited 2011-02-24 19:28
    DavidM

    I really like your constant idea for the buttons, I will use that idea. As for the shift register, I used Jon's code, because your code was using an extra variable for the individual bits. Additionally, it looks as though your 595 code uses four pins. For a 595, here is what I use:
    PUB RetractSpringRemover(nSteps, nStepDelay)
      Coil_Index := 4
      repeat nSteps     
      
        Coil_Index++
        if Coil_Index > 7
          Coil_Index := 4
        HC595_Data_Block := Coil_Array[Coil_Index]
          
        ' Write 8 bits of data.  Data byte is output MSB first.    
        repeat 8 'shift out 8 bits
          outa[Serial_Data] := HC595_Data_Block 'shift out next bit
          outa[Clock] ~ 'clock low then high then to cycle the bit out
          outa[Clock] ~~ 
          waitcnt(nStepDelay + cnt)       
          HC595_Data_Block >>= 1 'shift next bit
        outa[Latch]~ 'cycle low-high-low to cycle the latch
        outa[Latch]~~ 'toggle the Latch pin to latch the output
        outa[Latch]~
        
      DeenergizeCoils
    

    But I do appreciate your effort and code. Thank you David.

    Bruce
  • DavidMDavidM Posts: 630
    edited 2011-02-24 19:47
    idbruce wrote: »
    I used Jon's code, because your code was using an extra variable for the individual bits.

    Hi Bruce,

    If you use more than 1 shift register you need define the no of bits to get from the device's. It's usually 8bits per chip.

    I use many shift registers daisy chained together, and on some of my boards I use multiple sets, So By using the ONE very simple Object, you can refer to ( use) and no of devices, Just put 8 in the place of the variable.

    I do encourage you to use more GENERIC CODE, It looks like that code is for a specific purpose. Also I can't see the PIN Definitions for the shift register?

    Also, ALWAY use CONSTANTS for ALL your pin definitions and any other hardware, such as buttons. leds, modes etc,It makes coding much more READABLE, RELIABLE & REUSABLE, as you only need to change the value of a constant ONCE, especially if you use that constant in more than one place.

    One other thing, regarding constants, Did you notice the use of "Input", "Output", "High" , "Low" etc, I Alway do this for ALL My projects, and all my objects, So that I can easily read these states in my code, much better than 1, 0, ~, ~~ etc

    regards

    Dave M
  • idbruceidbruce Posts: 6,197
    edited 2011-02-25 05:10
    DavidM

    I must say that all makes perfect sense. It sounds like you have a good head on your shoulders for programming microcontrollers :)

    Over the last several months, I have been using constants a lot more than in the past, and I imagine that I will continue in that direction. However, I must say that I am also becoming accustomed to seeing and quickly understanding the ~ and ~~. In the past, I used HIGH and LOW, but I found that I save coding time by using the symbols instead.

    I definitely need to start incorporating case statements in my code, because it is easier to write and read. Considering I started with no knowledge of Spin when I began this current major programming endeavor, all of my code needs to go through the refining and beautification processes :(

    Anyhow, thanks for your advice David.

    Bruce

    P.S.
    I do encourage you to use more GENERIC CODE
    Jon keeps telling me the same thing :) However, in my defense, that code was written over two years ago, and yes it was application specific. That code was for controlling a stepper motor with a 595, which has since been replaced with a Gecko G251 Stepper Driver.
Sign In or Register to comment.