Is there silkscreen info' on the reverse side of the board showing the bit numbers that correspond to columns and rows, or something like that?all of the PCB labeling on the reverse side (IC's and components) are listed upright for reference.
{
****************************************************************
* Name : OEM 16x32 Display v1.BAS *
* Author : Mike McLaren, K8LH *
* Notice : Copyright (c) 2007 Micro Applications Consultants *
* : All Rights Reserved *
* Date : 07/16/07 *
* Version : 1.0 *
* Notes : *
* : *
****************************************************************
}
Device = 18F2520
Clock = 20
Dim Display(16) As LongWord ' full 32 bit row size elements
Dim Row As Byte, ' row number, range 0..15
RowPos As Word, ' 16 bit row ring counter
mask As Word ' 16 bit shift register mask
Dim Sin_1 As LATB.0, ' RB0
Sin_2 As LATB.1, ' RB1
Sin_3 As LATB.2, ' RB2
CLK As LATB.3, ' RB3
LAT As LATB.4, ' RB4
STB As LATB.5 ' active low Output Enable
Dim Carry As STATUS.booleans(0)
{
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' scan 1 of 16 rows each 1 msec interrupt '
' '
' 1265 cycles, 253.0 usecs, 25.3% ISR processing "overhead" '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
}
Interrupt TMR2_Interrupt()
PIR1.1 = 0 ' clear Timer 2 interrupt flag
mask = %1000000000000000 ' initialize 16 bit test mask
While mask <> 0 '
LATB = %00010000 ' CLK & STB lo, LAT hi
If RowPos = mask Then '
Sin_1 = 1 ' set row driver SR bit
EndIf '
If (Display(Row).word1 And mask) <> 0 Then
Sin_2 = 1 ' set 1st column driver SR bit
EndIf
If (Display(Row).word0 And mask) <> 0 Then
Sin_3 = 1 ' set 2nd column driver SR bit
EndIf '
CLK = 1 ' clock Sin data bits into SR's
mask = mask >> 1 ' shift the mask bit
Wend '
LAT = 0 ' latch data to driver outputs
LAT = 1 ' reset LAT hi
Row = (Row + 1) Mod 16 ' bump Row for next interrupt
RowPos = RowPos >> 1 ' bump RowPos ring counter bit
If Carry Then '
RowPos.15 = 1 '
EndIf '
End Interrupt
{
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' subroutines '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
}
Sub Init_TMR2()
TMR2 = 0 ' clear TMR2 register
PR2 = 250 - 1 ' 250 * 4 us = 1 ms interrupts
T2CON = %00100101 ' '00100101', 4 usec 'ticks'
' '-0100---', postscale 5:1
' '-----1--', TMR2 on
' '------01', prescale 4:1
PIE1.1 = 1 ' enable Timer 2 interrupts
INTCON.6 = 1 ' enable peripheral interrupts
End Sub
{
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' program '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
}
Row = 0 ' init Row
RowPos = %100000000000000 ' init RowPos ring counter bit
Init_TMR2 ' init TMR2 for 1 msec interrupts
Enable(TMR2_Interrupt) ' enable global interrupts
{ 1st frame }
Display(0) = %11111111111111111111111111111111
Display(1) = %01111111111111111111111111111110
Display(2) = %00111111111111111111111111111100
Display(3) = %00011111111111111111111111111000
Display(4) = %00001111111111111111111111110000
Display(5) = %00000111111111111111111111100000
Display(6) = %00000011111111111111111111000000
Display(7) = %00000001111111111111111110000000
Display(8) = %00000000111111111111111100000000
Display(9) = %00000000011111111111111000000000
Display(10)= %00000000001111111111110000000000
Display(11)= %00000000000111111111100000000000
Display(12)= %00000000000011111111000000000000
Display(13)= %00000000000001111110000000000000
Display(14)= %00000000000000111100000000000000
Display(15)= %00000000000000011000000000000000
{ additional frames }
End
' ==============================================
'
' File...... 16x32LED_v6TEST2.SXB
' Purpose... SX/B interface to AD-501-B
' Author.... Mike McLaren, K8LH / Timothy Gilmore
' Notice.... Copyright (c) 2007 Micro Applications Consultants - All Rights Reserved
' E-mail.... gilmoret@us.saic.com
' Started... 16 JUN 2007
' Updated...
'
' ==============================================
DEVICE SX28, OSCHS3, TURBO, STACKX, OPTIONX 'Use external 20 MHz resonator
FREQ 20_000_000
ID "AD-501-B"
'Device = 18F2520
'Clock = 20
'Dim Display(16) As LongWord ' full 32 bit row size elements
DisplayLo(16) VAR Word
DisplayHi(16) VAR Word
'Dim Row As Byte, ' row number, range 0..15
RowLo VAR Byte
RowHi VAR Byte
'Row_Position As Word, ' 16 bit row ring counter
RowPosition VAR Word
'mask As Word ' 16 bit shift register mask
mask VAR Word
'Dim Sin_1 As LATB.0, ' RB0
' Sin_2 As LATB.1, ' RB1
' Sin_3 As LATB.2, ' RB2
' CLK As LATB.3, ' RB3
' LAT As LATB.4, ' RB4
' STB As LATB.5 ' active low Output Enable
Sin_1 PIN RB.0
Sin_2 PIN RB.1
Sin_3 PIN RB.2
CLK PIN RB.3
LAT PIN RB.4
STB PIN RB.5
' -------------------------------------------------------------------------
INTERRUPT 1000 '1 ms interrupt
' -------------------------------------------------------------------------
GOTO TMR2_Interrupt
' ==============================================
PROGRAM Start
' ==============================================
' -------------------------------------------------------------------------
' Subroutine Declarations
' -------------------------------------------------------------------------
Init_TMR2 SUB
Start:
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' program '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'}
Row = 0 ' init Row
RowPosition = 1 << Row ' init Row_Position ring counter
Init_TMR2 ' init TMR2 for 1 msec interrupts
'Enable(TMR2_Interrupt) ' enable interrupt handler
'{ 1st frame }
'Display(0) = %11111111111111111111111111111111
'Display(1) = %01111111111111111111111111111110
'Display(2) = %00111111111111111111111111111100
'Display(3) = %00011111111111111111111111111000
'Display(4) = %00001111111111111111111111110000
'Display(5) = %00000111111111111111111111100000
'Display(6) = %00000011111111111111111111000000
'Display(7) = %00000001111111111111111110000000
'Display(8) = %00000000111111111111111100000000
'Display(9) = %00000000011111111111111000000000
'Display(10)= %00000000001111111111110000000000
'Display(11)= %00000000000111111111100000000000
'Display(12)= %00000000000011111111000000000000
'Display(13)= %00000000000001111110000000000000
'Display(14)= %00000000000000111100000000000000
'Display(15)= %00000000000000011000000000000000
'WORDS are only 16 bits not 32 so Display(x) needs to be broken into DisplayLO(x) and DisplayHI(x) variables.
'{ additional frames }
End
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' scan 1 of 16 rows each 1 msec interrupt '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'}
'Interrupt TMR2_Interrupt()
' PIR1.1 = 0 ' clear Timer 2 interrupt flag
' mask = %1000000000000000 ' initialize 16 bit test mask
' Row_Position = 1 << Row '
' While mask > 0 ' (16 iterations)
' LATB = %00010000 ' CLK & STB lo, LAT hi
' If Row_Position = mask Then '
' Sin_1 = 1 ' set row driver SR bit
' EndIf '
' If (Display(Row).word0 And mask) > 0 Then
' Sin_2 = 1 ' set 1st column driver SR bit
' EndIf
' If (Display(Row).word1 And mask) > 0 Then
' Sin_3 = 1 ' set 2nd column driver SR bit
' EndIf '
' CLK = 1 ' clock Sin data bits into SR
' mask = mask >> 1 ' shift the mask bit
' Wend '
' CLK = 0 ' reset CLK lo
' LAT = 0 ' latch data to driver outputs
' LAT = 1 ' reset LAT hi
' Row = (Row + 1) Mod 16 ' bump Row for next interrupt
'End Interrupt
'{
TMR2_Interrupt:
'PIR1.1 = 0
mask = %1000000000000000
RowPosition = 1 << RowLo ' Check this also for RowHi ?
DO WHILE mask > 0
RB = %0001000
IF RowPosition = mask THEN
Sin_1 = 1
ENDIF
IF DisplayLo(RowLo).0 THEN
IF mask > 0 THEN 'Check this also for DisplayHi and RowHi ?
Sin_2 = 1
ENDIF
ENDIF
IF DisplayLo(RowLo).1 THEN
IF mask > 0 THEN 'Check this also for DisplayHi and RowHi ?
Sin_3 = 1
ENDIF
Endif
CLK = 1
mask = mask >> 1
LOOP
CLK = 0
LAT = 0
PAUSEUS 50
LAT = 1
ROW = ROW + 1
ROW = ROW // 16 'ROW = (ROW + 1) MOD 16
ISR_Exit:
RETURNINT
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' subroutines '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'}
'Sub Init_TMR2()
' TMR2 = 0 ' clear TMR2 register
' PR2 = 250 - 1 ' 250 * 4 us = 1 ms interrupts
' T2CON = %00100101 ' '00100101', 4 usec 'ticks'
' '-0100---', postscale 5:1
' '-----1--', TMR2 on
' '------01', prescale 4:1
' PIE1.1 = 1 ' enable Timer 2 interrupts
' INTCON.6 = 1 ' enable peripheral interrupts
' INTCON.7 = 1 ' enable global interrupts
'End Sub
'{
Init_TMR2:
TMR2 = 0 '?
PR2 = 250 -1 '?
PR2CON = %00100101 '?
PIE.1 = 1 '?
INTCON.6 = 1 '?
INTCON.7 = 1 '?
RETURN
{
*********************************************************************
* Name : OEM 16x32 Display v3.BAS *
* Author : Mike McLaren, K8LH *
* Notice : Copyright (c) 2007, Micro Applications Consultants *
* : All Rights Reserved *
* Date : 07/21/07 *
* Version : 3.0 *
* Notes : v3 software features PWM brightness control and an *
* : assembly code ISR driver for improved performance *
* : *
*********************************************************************
}
Device = 18F2520
Clock = 16
Dim Display(16) As LongWord, ' full 32 bit row size elements
TempRow As LongWord ' temp 32 bit variable
Dim i As Byte, '
Row As Byte, ' row number, range 0..15
Counter As Byte, ' ISR counter var'
RowPos As Word, ' 16 bit row ring counter
Work0, Work1, Work2 As Word ' 16 bit ISR work registers
{
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' scan 1 of 16 rows each 1 msec interrupt '
' '
' 265 cycles, 53.0 usecs, 5.30% ISR processing "overhead" ' '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
}
Interrupt TMR2_Interrupt()
ASM
SR1 equ 0 ;' SR1 pin RB0 (row SR)
SR2 equ 1 ;' SR2 pin RB1 (column 1 SR)
SR3 equ 2 ;' SR3 pin RB2 (column 2 SR)
CLK equ 3 ;' CLK pin RB3 (all SR's)
LAT equ 4 ;' LAT pin RB4 (all SR's)
bcf PIR1,1 ;' clear Timer 2 interrupt flag
rlncf Row,W ;' row number (0..15) x4
rlncf WREG,W ;'
addlw Display ;'
movwf FSR1L ;' FSR1 = Display(Row).byte0
clrf FSR1H ;'
movff POSTINC1,Work0+0
movff POSTINC1,Work0+1
movff POSTINC1,Work1+0
movff POSTINC1,Work1+1
movff RowPos+0,Work2+0
movff RowPos+1,Work2+1
bsf Counter,4 ;' counter = 16
v0 movlw b'00000010' ;' preload WREG
rlcf Work1+0,F ;' rlcf lo byte
rlcf Work1+1,F ;' rlcf hi byte
rlcf WREG,F ;' pick up b2 (2nd column SR)
rlcf Work0+2,F ;' rlcf lo byte
rlcf Work0+3,F ;' rlcf hi byte
rlcf WREG,F ;' pick up b1 (1st column SR)
rlcf Work2+4,F ;' rlcf lo byte
rlcf Work2+5,F ;' rlcf hi byte
rlcf WREG,F ;' pick up b0 (row SR)
movwf LATB ;' update port, [--010ddd]
bsf LATB,CLK ;' toggle <CLK> [--011ddd]
decfsz Counter,F ;' all 16 iterations?
bra v0 ;' no, branch, else
;'
;' latch 48 bits of new SR data onto the driver IC outputs
;'
bcf LATB,LAT ;' toggle <LAT> [--001ddd]
bsf LATB,LAT ;' toggle <LAT> [--011ddd]
;'
;' advance Row variable and RowPos ring counter for the next cycle
;'
incf Row,W ;' Row++
bcf Row,4 ;' Row = Row % 16 (sort of)
rrcf RowPos+0,W ;' rrcf lo byte into W to preserve C
rrcf RowPos+1,F ;' rrcf hi byte
rrcf RowPos+0,F ;' rrcf lo byte
End ASM
End Interrupt
{
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' init PWM sub '
' '
' the STB inputs on all three 16 bit serial-to-parallel drivers '
' should be connected to the RC2/CCP1 "PWM" output '
' '
' the PWM period (and interrupts) are 1.0 msecs. adjust display '
' brightness by setting PWM duty cycle value in CCPR1L; '
' '
' CCPR1L = 50 ' 20% duty cycle, 80% brightness '
' CCPR1L = 100 ' 40% duty cycle, 60% brightness '
' CCPR1L = 150 ' 60% duty cycle, 40% brightness '
' CCPR1L = 250 '100% duty cycle, Display is off '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
}
Sub Init_PWM()
TMR2 = 0 ' clear TMR2 register
PIR1 = 0 ' clear interrupt flags
T2CON = %00000010 ' '00000010'
' '-0000---', postscale 1:1
' '-----0--', TMR2 off
' '------10', prescale 16:1
' for 4-us Timer 2 'ticks'
PR2 = 250 - 1 ' 250 * 4 us = 1 msec PWM period
' and interrupt rate
CCP1CON = %00001100 ' '00001100'
' '00------', unused bits
' '--00----', duty cycle lsb's
' '----1100', PWM mode
CCPR1L = 25 ' 10% duty cycle, 90% brightness
PIE1.1 = 1 ' enable Timer 2 interrupts
INTCON.6 = 1 ' enable peripheral interrupts
T2CON.2 = 1 ' turn on Timer 2
End Sub
{
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' program '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
}
Row = 0 ' init Row
RowPos = %1000000000000000 ' init RowBit ring counter
Counter = 0 ' init ISR counter var'
ADCON1 = %00001111 ' setup RB3..RB0 to digital mode
PORTB = %00010000 ' setup PORTB (SR <LAT> bit hi)
TRISB = %00000000 ' PORTB all outputs
Init_PWM ' init PWM & Timer 2 interrupts
Enable(TMR2_Interrupt) ' enable global interrupts
{ 1st frame }
Display(0) = %11111111111111111111111111111111
Display(1) = %01111111111111111111111111111110
Display(2) = %00111111111111111111111111111100
Display(3) = %00011111111111111111111111111000
Display(4) = %00001111111111111111111111110000
Display(5) = %00000111111111111111111111100000
Display(6) = %00000011111111111111111111000000
Display(7) = %00000001111111111111111110000000
Display(8) = %00000000111111111111111100000000
Display(9) = %00000000011111111111111000000000
Display(10)= %00000000001111111111110000000000
Display(11)= %00000000000111111111100000000000
Display(12)= %00000000000011111111000000000000
Display(13)= %00000000000001111110000000000000
Display(14)= %00000000000000111100000000000000
Display(15)= %00000000000000011000000000000000
{ additional frames }
For i = 0 To 64
TempRow = Display(15) ' save bottom row temporarily
Display(15) = Display(14) ' downward repeating scroll
Display(14) = Display(13)
Display(13) = Display(12)
Display(12) = Display(11)
Display(11) = Display(10)
Display(10) = Display(9)
Display(9) = Display(8)
Display(8) = Display(7)
Display(7) = Display(6)
Display(6) = Display(5)
Display(5) = Display(4)
Display(4) = Display(3)
Display(3) = Display(2)
Display(2) = Display(1)
Display(1) = Display(0)
Display(0) = TempRow
DelayMS(100) ' delay 100 msecs per change
Next
End
{
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' Sub Brightness(0..100) 0% black to 100% full brightness '
' '
' 15 cycles, 3.75 usecs (16 MHz), including call and return '
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
}
Sub Brightness(pPercent As Byte) ' CCPR1L = (250-(pPercent*2.5))
Dim Temp As Byte '
Temp = pPercent * 2 '
Temp = Temp + (pPercent >> 1) '
CCPR1L = 250 - Temp ' set PWM duty cycle
End Sub '
Brightness(70) ' set brightness to 70% of full
{ display fade-to-black }
i = Level ' copy current 'Level'
While i <> 0 ' fade from 'Level' to black
While Row <> 15 ' sync' to 16 row 'frame'
Wend '
Brightness(i) ' change brightness setting
While Row <> 0 ' wait for row 0
Wend '
i = Integer(i - 5) '
Wend '
Brightness(0) ' force black
tdg8934 said:Mike,
I thank you for your subroutine but I'm not quite following how it is to be applied in the Main routine. I would think brightness is controlled by the current limiting resistors so how is the Brightness control to be applied via software?
Sorry. I assumed that varying the brightness of a single LED using PWM was almost "basic studies" for anyone playing with microcontrollers these days. My first PWM experiment was varying the speed of a 12vdc fan.tdg8934 said:Mike,
I thank you for your subroutine but I'm not quite following how it is to be applied in the Main routine. I would think brightness is controlled by the current limiting resistors so how is the Brightness control to be applied via software?
Thanks again.
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?