{
****************************************************************
* 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
If I understand your question correctly, it was suggested to use the shift.bas in swordfish. The data is from the CONST arrays. For the "data" using wireless I am going with the HT12E and HT12D chips.
I tried using a "BIT BANG" approach to shifting the TLC5916 regesters but no luck. bad idea. Even contemplated using SPI but Jon over at DDIY suggested using SHIFT.bas. Hav't got that far yet but will start "hacking" today.
After reading I believe your right. I need to store the bytes of data somewhere so I can input into the TLC5916 bit by bit. Going with the method of loading the bytes into a PORT would use 8 pins.
BUT it was suggested to go with the sHIFT.bas instead of SPI. WHY?? no clue but will give it a go.
{
*****************************************************************************
* 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()
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?
We use cookies and similar technologies for the following purposes:
Do you accept cookies and these technologies?