1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

programming a byte on one pin

Discussion in 'Microcontrollers' started by MrDEB, Nov 4, 2012.

  1. MrDEB

    MrDEB Active Member

    Joined:
    Apr 16, 2007
    Messages:
    4,364
    Likes:
    22
    I have a CONST array written in Swordfish and am experimenting using TLC5916 as the constant sink but I need to input my data for the LED display in serial form. Is there a way to just use
    PORTA.1 = %00000111 then go with portA.bits(x) = SDI or something similar??
    am trying to use the timing diagram to get the TLC5916 to operate correctly.
    If I can put the byte on one pin instead of 8 it would cut down on my pin usage.
     
  2. JonSea

    JonSea Well-Known Member

    Joined:
    Oct 1, 2012
    Messages:
    1,118
    Likes:
    90
    Location:
    Seattle, WA
    Oh vey ist mir.
     
  3. blueroomelectronics

    blueroomelectronics Well-Known Member

    Joined:
    Jan 21, 2007
    Messages:
    12,536
    Likes:
    168
    Location:
    Toronto, Canada
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. JonSea

    JonSea Well-Known Member

    Joined:
    Oct 1, 2012
    Messages:
    1,118
    Likes:
    90
    Location:
    Seattle, WA

    Swordfish Basic has several commands to shift data out in a serial stream. Check the documentation.

    There are a number of things you must consider but this is all simple programming:

    1. Number of bits to shift

    2. The order of the bits - MSB or LSB

    3. Rising or falling edge detect


    If you are going to any chance of making this work, you need to read and understand the Swordfish documentation AND appropriate tutorial material.
     
  6. MrDEB

    MrDEB Active Member

    Joined:
    Apr 16, 2007
    Messages:
    4,364
    Likes:
    22
    Researching the SPI

    Am I correct in assuming that I can load all my bytes into the EEprom instead of directly into ports then access the EEprom for my LED data via SPI?
    This would prevent having to use 8 pins vers 1 pin for the bytes then use the SPI?
    NEW ground for me to be sure
     
  7. JonSea

    JonSea Well-Known Member

    Joined:
    Oct 1, 2012
    Messages:
    1,118
    Likes:
    90
    Location:
    Seattle, WA
    Please read the documentation for the shift command in Swordfish.

    You will need 4 pins:

    1. Clock

    2. Data

    3. Latch (I think the data sheet specifies this as LE)

    4. /OE (output enable)

    Using the shift command, you'll specify a value representing which of the eight output bits you want on, where 0 = on and 1 = off. %00001111 would turn the first four outputs on, the second four outputs off.

    After the shift command, you strobe LE from low to high and back to low to latch the data to the output bits.

    /OE will be low to enable the output. You may be able to leave it continuously low, or you may take it high to shut off the outputs. Remember, the slash means it's active low.


    Follow the format of the shift command in the Swordfish documentation. I don't have it here or I would explain it.

    There is no need to store anything in EEPROM.
     
  8. JonSea

    JonSea Well-Known Member

    Joined:
    Oct 1, 2012
    Messages:
    1,118
    Likes:
    90
    Location:
    Seattle, WA
    You have to include the shift module:

    Include "shift.bas"

    The command will be either

    OUT (MSB_FIRST,data,8)

    Or

    OUT (LSB_FIRST,data,8)

    Depending on the order you want the bits. It doesn't matter you just have to map the values to send correctly.

    The value 8 is how many bits to shift.
     
  9. MrDEB

    MrDEB Active Member

    Joined:
    Apr 16, 2007
    Messages:
    4,364
    Likes:
    22
    I understand so I don't need the SPI.bas just the shift.bas
    will give it a go
    THANKS
    been pondering this all morning, didn't get much sleep last night. My knee is really giving me problems. Them hydrocodone pills really zap the energy out of you.
    THANKS again
     
  10. MrDEB

    MrDEB Active Member

    Joined:
    Apr 16, 2007
    Messages:
    4,364
    Likes:
    22
    I hope this is the right one?

    written by Barker
    Code (text):
    {
    ****************************************************************
    *  Name    : Shift Module                                      *
    *  Author  : David John Barker                                 *
    *  Notice  : Copyright (c) 2006 Mecanique                      *
    *          : All Rights Reserved                               *
    *  Date    : 04/02/2006                                        *
    *  Version : 1.5                                               *
    *  Notes   :                                                   *
    *          :                                                   *
    ****************************************************************
    }
    module Shift

    // import modules...
    include "utils.bas"
    include "system.bas"

    // shiftin modes...
    public const
       MSB_PRE = $00,       // MSB first, sample before clock
       MSB_POST = $02,      // MSB first, sample after clock
       LSB_PRE = $01,       // LSB first, sample before clock
       LSB_POST = $03       // LSB first, sample after clock

    // shiftout modes...
    public const
       LSB_FIRST = $00,     // LSB first
       MSB_FIRST = $01      // MSB first

    // a pin structure...
    structure TPin
       Address as word
       Pin as byte
       PinMask as byte
    end structure  

    // local working variables...
    dim
       FDataIn as TPin,
       FDataOut as TPin,
       FClock as TPin

    // maximum shift size can be 8, 16 or 32 bits. Using a smaller
    // maximum shift size will reduce code overhead. The default
    // is 16 bits.
    #if IsOption(SHIFT_MAX) and not (SHIFT_MAX in (8, 16, 32))
       #error SHIFT_MAX, "Invalid option. MAX must be 8, 16 or 32 bits."
    #endif
    #option SHIFT_MAX = 16
       
    #if SHIFT_MAX = 8
    type TType = byte
    #elseif SHIFT_MAX = 16
    type TType = word
    #else
    type TType = longword
    #endif

    // delay speed of shift clock....
    #if IsOption(SHIFT_CLOCK) and not (SHIFT_CLOCK in (1, 2))
       #error SHIFT_CLOCK, "Invalid option. CLOCK must be 1 or 2 (us)."
    #endif
    #option SHIFT_CLOCK = 1
    {
    ****************************************************************************
    * Name    : ToggleClock (PRIVATE)                                          *
    * Purpose : Toggle the shift clock.                                        *
    *         : The default minimum clock width will be 1us for frequencies    *
    *         : above 4MHz. For 4Mhz and below, the minimum clock width will   *
    *         : be 2us. Using the #define SHIFT_CLOCK = 2US option will force  *
    *         : a minimum clock width of 2us for all frequencies. NOTE : These *
    *         : figures assume a perfect clock. A plus or minus variation of   *
    *         : the clock width will be observed for all real world clock      *
    *         : frequencies that deviate from the theoretical ideal            *
    ****************************************************************************
    }
    inline sub ToggleClock()
       // toggle clock...
       INDF1 = INDF1 xor FClock.Pin
       
       // force minimum 2us...  
       #if SHIFT_CLOCK = 2
       #if _clock >= 8
       delayus(1)
       #endif
       #endif
       
       // burn 8...
       #if _clock > 36
       asm-
       bra $ + 2
       bra $ + 2
       bra $ + 2
       bra $ + 2  
       end asm
       
       // burn 7...
       #elseif _clock > 32
       asm-
       bra $ + 2
       bra $ + 2
       bra $ + 2
       Nop
       end asm
       
       // burn 6...
       #elseif _clock > 28
       asm-
       bra $ + 2
       bra $ + 2
       bra $ + 2
       end asm
       
       // burn 5...
       #elseif _clock > 24
       asm-
       bra $ + 2
       bra $ + 2
       Nop
       end asm
       
       // burn 4...
       #elseif _clock > 20
       asm-
       bra $ + 2
       bra $ + 2
       end asm
       
       // burn 3...
       #elseif _clock > 16
       asm-
       bra $ + 2
       Nop
       end asm
       
       // burn 2...
       #elseif _clock > 12
       asm-
       bra $ + 2
       end asm
       
       // burn 1...
       #elseif _clock > 8
       asm-
       Nop
       end asm
       #endif
       
       // toggle clock...
       INDF1 = INDF1 xor FClock.Pin
    end sub  
    {
    ****************************************************************************
    * Name    : MakeOutput(PRIVATE)                                            *
    * Purpose : Make the data pin an output. Data out address points to latch  *
    *         : so just offset by 9                                            *
    ****************************************************************************
    }
    inline sub MakeOutput()
       FSR1 = FDataOut.Address + 9
       INDF1 = INDF1 and FDataOut.PinMask
    end sub  
    {
    ****************************************************************************
    * Name    : MakeInput (PRIVATE)                                            *
    * Purpose : Make the data pin an input. Data in address points to port     *
    *         : so offset by 18                                                *
    ****************************************************************************
    }
    inline sub MakeInput()
       FSR1 = FDataIn.Address + 18
       INDF1 = INDF1 or FDataIn.Pin
    end sub
    {
    ****************************************************************************
    * Name    : LoadDataInAndClockAddr (PRIVATE)                               *
    * Purpose : Load the data and clock pin address into FSR(x)                *
    ****************************************************************************
    }
    inline sub LoadDataInAndClockAddr()
       FSR0 = FDataIn.Address
       FSR1 = FClock.Address
    end sub  
    {
    ****************************************************************************
    * Name    : LoadDataOutAndClockAddr (PRIVATE)                              *
    * Purpose : Load the data and clock pin address into FSR(x)                *
    ****************************************************************************
    }
    inline sub LoadDataOutAndClockAddr()
       FSR0 = FDataOut.Address
       FSR1 = FClock.Address
    end sub  
    {
    ****************************************************************************
    * Name    : SetInput                                                       *
    * Purpose : Sets the shift data in pin                                     *
    ****************************************************************************
    }
    public sub SetInput(byref pDataPin as bit)
       FDataIn.Address = addressof(pDataPin)     // point address to port
       FDataIn.Pin = bitof(pDataPin)
       FDataIn.PinMask = not FDataIn.Pin
    end sub
    {
    ****************************************************************************
    * Name    : SetOutput                                                      *
    * Purpose : Sets the shift data out clock pin.                             *
    ****************************************************************************
    }
    public sub SetOutput(byref pDataPin as bit)
       FDataOut.Address = addressof(pDataPin) + 9 // point address to latch
       FDataOut.Pin = bitof(pDataPin)
       FDataOut.PinMask = not FDataOut.Pin
    end sub
    {
    ****************************************************************************
    * Name    : Set                                                            *
    * Purpose : Sets the clock pins. An optional idle high determines if the   *
    *         : clock pin idles high or low. The default is to idle low        *
    *         : The clock address points to a port latch                       *
    ****************************************************************************
    }
    public sub SetClock(byref pClockPin as bit,pIdleHigh as boolean = false)
       FClock.Address = addressof(pClockPin) + 9
       FClock.Pin = bitof(pClockPin)
       FClock.PinMask = not FClock.Pin  
       
       // set clock idle mode...
       FSR1 = FClock.Address
       if pIdleHigh then
          INDF1 = INDF1 or FClock.Pin
       else
          INDF1 = INDF1 and FClock.PinMask  
       endif
       
       // make clock pin an output...
       inc(FSR1,9)
       INDF1 = INDF1 and FClock.PinMask
    end sub
    {
    ****************************************************************************
    * Name    : Out                                                            *
    * Purpose : Shift out a value by pShift bits. Date values can be up to 32  *
    *         : bits in size. Mode can be either LSB_FIRST or MSB_FIRST        *
    ****************************************************************************
    }
    public sub Out(pMode as byte,pData as TType, pShift as byte)
       
       // set data pin to output and load
       // data and clock address...
       MakeOutput
       LoadDataOutAndClockAddr
       
       // MSB first...
       if pMode.0 = 1 then
          pData = Reverse(pData, pShift)
       endif
       
       // shift out...  
       while pShift > 0
          if pData.0 = 0 then
             INDF0 = INDF0 and FDataOut.PinMask
          else
             INDF0 = INDF0 or FDataOut.Pin
          endif      
          ToggleClock
          pData = pData >> 1
          dec(pShift)
       wend
       ClrWDT
    end sub
    {
    ****************************************************************************
    * Name    : In                                                             *
    * Purpose : Shift in a value by pShift bits. Date values can be up to 32   *
    *         : bits in size. Mode can be MSB_PRE, MSB_POST, LSB_PRE or        *
    *         : LSB_POST                                                       *
    ****************************************************************************
    }
    public function In(pMode as byte, pShift as byte) as TType
       dim Index as byte

       // set data pin to input and load
       // data and clock address...
       MakeInput
       LoadDataInAndClockAddr
       
       // shift in...
       Result = 0
       Index = pShift
       while Index > 0
          Result = Result << 1
         
          // sample before clock...
          if pMode.1 = 0 then
             if (INDF0 and FDataIn.Pin) = 0 then
                Result.0 = 0
             else
                Result.0 = 1
             endif      
             ToggleClock
         
          // sample after clock...
          else
             ToggleClock
             if (INDF0 and FDataIn.Pin) = 0 then
                Result.0 = 0
             else
                Result.0 = 1
             endif      
          endif  
          dec(Index)
       wend
       
       // LSB first...
       if pMode.0 = 1 then
          Result = Reverse(Result,pShift)
       endif
       ClrWDT  
    end function

     
     
  11. JonSea

    JonSea Well-Known Member

    Joined:
    Oct 1, 2012
    Messages:
    1,118
    Likes:
    90
    Location:
    Seattle, WA
    As I said, read the documentation. It's all there.

    Note, as shown in the documentation, you must define the data (out) pin and the clock pin.

    This is as helpful as I am going to be.
     
  12. MrDEB

    MrDEB Active Member

    Joined:
    Apr 16, 2007
    Messages:
    4,364
    Likes:
    22
    I read through the documentation, changed the array size to 8
    using a tap-28 for testing out the code.
     
  13. JonSea

    JonSea Well-Known Member

    Joined:
    Oct 1, 2012
    Messages:
    1,118
    Likes:
    90
    Location:
    Seattle, WA
    On Brad's Project Forum, MrDEB has made two posts:

    and

    Let me try and explain a little more thoroughly before I smash my head against the floor.

    The Swordfish modules shift.bas and SPI.bas are similar. Shift is more generic, a little easier to use and is the interface used by the constant current sink chip.. Either would work. Just pick one and figure out how it works.

    You don't need to use constant arrays. You seem to ascribe some magic to them that's just not there. If I have any understanding of what you are doing now, the constant current chip is driving the columns. What you need to do is:

    1. Set the data for the rows in column 1.
    2. Turn on column 1.
    3. Delayms(10)
    4. Turn off column 1.

    5. Set the data for the rows in column 2
    6. Turn on column 2.
    7. Delayms(10)
    8. Turn off column 2.

    Repeat this for column 3, 4, 5 and start at top.

    The column commands will be:

    Shift(MSB, %10000000,8) 'Turn on column 1
    Shift(MSB, %00000000,8) 'Turn off all columns

    Shift(MSB, %01000000,8) 'Turn on column 2
    Shift(MSB, %00100000,8) 'Turn on column 3
    Shift(MSB, %00010000,8) 'Turn on column 4
    Shift(MSB, %00001000,8) 'Turn on column 5

    The data for the rows is just as simple. Say you want a right arrow....

    Portx=%10000010 'The top and bottom dots in column 1
    Portx=%01000100 'The 2nd dots in column 2
    Portx=%00101000 'The 3rd dots in column 3
    Portx=%00010000 'The top and bottom dots in column 4
    Portx=%00000000. 'Nothing in column 5

    Make this work and understand it before going all whacko. Putting the values in an array or even defining them as constants is ok after you understand what you're doing.


    I'm sorry I got sucked into trying to help you again. I cannot do this anymore. All of the steps needed have been outlined. Either you can make sense of this or not. For the sake of my sanity, I'm out.
     
    Last edited: Nov 7, 2012
    • Like Like x 1
  14. JonSea

    JonSea Well-Known Member

    Joined:
    Oct 1, 2012
    Messages:
    1,118
    Likes:
    90
    Location:
    Seattle, WA
    Crap....I think the way you are doing the, the row and column data would be reversed...several columns on at a time, one row.

    End of my worry about you or your project. Sorry and good luck.
     
  15. MrDEB

    MrDEB Active Member

    Joined:
    Apr 16, 2007
    Messages:
    4,364
    Likes:
    22
    I read you description and I get a better understanding

    Here is the SHIFT .BAS that I hope to get working but will review your post as I copied the code from what I conjured up.. BIG question is in the Swordfish library reference it has interface (see my code) am assuming these are sub routines I need to add as I did.
    As for the CONST arrays, I plan to start with just one to use for testing to see how this code actually works. Reason for the arrays - easier to see what is going on and use a FOR NEXT loop to access the arrays. Have seen this done and so far it seems easier.
    This posted code compiles correctly, no errors BUT have yet to run it. But first will print out your code flow explaniation and decipher to make heads or tails of what is going on.
    Code (text):
    {
    *****************************************************************************
    *  Name    : UNTITLED.BAS                                                   *
    *  Author  : [select VIEW...EDITOR OPTIONS]                                 *
    *  Notice  : Copyright (c) 2012 [select VIEW...EDITOR OPTIONS]              *
    *          : All Rights Reserved                                            *
    *  Date    : 11/5/2012                                                      *
    *  Version : 1.0                                                            *
    *  Notes   :                                                                *
    *          :                                                                *
    *****************************************************************************
    }
    {
    *****************************************************************************
    *  Name    : UNTITLED.BAS                                                   *
    *  Author  : [select VIEW...EDITOR OPTIONS]                                 *
    *  Notice  : Copyright (c) 2012 [select VIEW...EDITOR OPTIONS]              *
    *          : All Rights Reserved                                            *
    *  Date    : 10/26/2012                                                     *
    *  Version : 1.0                                                            *
    *  Notes   : needs better definition of when pulse train is received                                                               *
    *          :                                                                *
    *****************************************************************************
    }
     Device = 18F2420
    Clock = 8
    Config MCLRE = Off


    '*********************************************************************
    'Includes
    //Include "InternalOscillator.bas"
    Include "shift.bas"
    Include "utils.bas"
    Include "convert.bas"
    Dim sdi As PORTC.6    // data
    Dim clk As PORTC.7
    Dim Latch_E As PORTB.0
    Dim Out_E As  PORTC.3      // output enable
    Dim row1 As PORTB.3       // HIGH  driver chip output

    //Dim led_data As Byte
    Dim sd_out As PORTC.6

    Dim x As Byte
                     
     Const Red_Data(7) As Byte =   (%0010001, %00001010, %00000100 ,%00010001, %00001010,%00000100, %00010001)// 5 colums left to right
     Const R_ows(8) As Byte =      (%00000001, %00000010, %000000100 ,%00001000, %00010000, %00100000, %01000000,%00111110)// 7 rows top to bottom
     { as per timing diagram, clock outputs 8 pulses while output enable(Out_E) is held HIGH
     Latch enable(Latch_E) is held LOW. The data is shifted in one bit per clk pulse.
     }
       Sub load()    
           Out_E = 1               // output enable HIGH
           Shift.Out(LSB_FIRST, $ee,8)
           Out_E=0                 // output enable LOW
           DelayMS(1000)
       End Sub
       
       function get_data() as word
           Out_E = 1               // output enable HIGH
           Shift.Out(LSB_FIRST, red_data(1),8)
           Out_E=0                 // output enable LOW
       end function
     //  INTERFACE?? on Swordfish reference library  
       sub setinput(byref sdi as bit)
       end sub
       sub setoutput(byref sdi as bit)
       end sub
       sub setclock(byref clk as bit)
       end sub        

       
      // start of program
      // set ports as outputs
    TRISA = %00000000
    TRISB = %00000000
    TRISC = %00000000
    SetAllDigital
    shift.setinput(portc.6)
    shift.setoutput(portc.6)
    shift.setclock(portc.7)
    output (portc.5)       //output enable
    output (portb.0)       //latch enable
      load()  


       
         
         
     
         
         
         
       
         


     
     
  16. MrDEB

    MrDEB Active Member

    Joined:
    Apr 16, 2007
    Messages:
    4,364
    Likes:
    22
    In this statement "Shift(MSB, %01000000,8) " I guess that MSB you read the byte in the opposite direction? I have been using %00000011 reading from right to left.
    Is this what MSB defines?
    Going to develop a code as per Jonseas post and hopefully get something working that I can use to experiment with for hands on learning.
     
  17. JonSea

    JonSea Well-Known Member

    Joined:
    Oct 1, 2012
    Messages:
    1,118
    Likes:
    90
    Location:
    Seattle, WA
    Never mind.
     
    Last edited: Nov 7, 2012
  18. JonSea

    JonSea Well-Known Member

    Joined:
    Oct 1, 2012
    Messages:
    1,118
    Likes:
    90
    Location:
    Seattle, WA
    If I was using this chip for the first time, I would start simple. Set all of the anodes high, and switch on one cathode (one bit of this current driver chip) at a time. Once you have figured out how to control this chip, then move on to all the rest.

    The code you have posted here is deficient in more ways than I can count. Yes, it may compile. No, it will not do what you expect in any way, shape or form. If you would post your "best effort" after you have done all you can to make it work, people might be better able to help you.
     
  19. be80be

    be80be Well-Known Member

    Joined:
    Aug 23, 2008
    Messages:
    4,794
    Likes:
    134
    Location:
    morristown,tn
    What was that code to do set some ports and stop is what it's doing
     
    Last edited: Nov 8, 2012
  20. MrDEB

    MrDEB Active Member

    Joined:
    Apr 16, 2007
    Messages:
    4,364
    Likes:
    22
    I got frustrated and decided to start from ground zero (started this at 6am but my wife keeps pulling me off to do other things) so am using the diagram using the 555 as pictured on the bottom of this page http://www.electro-tech-online.com/custompdfs/2012/11/slva346.pdf
    Got tied up with another project but found I wasn't getting any clock pulse from the pic. Need to find out why before going any further. I used a code that flashed 5 rows at a time but not using the shift.bas.
    After I find out why I have no clock pulse and a ground issue will get back to you. Couldn't even get an LED to flash on the Tap-28. It worked before???
    As for the last code I posted, It was using the example code from the Swordfish Library reference but rewritten for my app which I need to debug.
     
  21. JonSea

    JonSea Well-Known Member

    Joined:
    Oct 1, 2012
    Messages:
    1,118
    Likes:
    90
    Location:
    Seattle, WA
    *smashing head into wall with considerable force*

    Excuse me for asking an incredibly stupid question. The linked ap note uses a 555 timer to turn ALL of the outputs on, which has exactly what to do with what you are trying to archeive? Please explain in great detail because one of us is lost and I'd like to think it's not me.

    If I understand your project (and admittedly I may not after hundreds of contradictory posts), you are trying to drive a 5x7 LED matrix array. If this is true and you insist on using the constant current sink, you need to be able to control which bits are on.
     

Share This Page