Submitted by:
Glenn Clark
VersaTech Electronics
Based on Paul Via's Christmas Star Project
Based on a circuit suggestion by Scott Edwards
Updates:
(2-2-2018)
Uploaded newer code files to support later TICkit and Hubbub processors. These code samples also have many more patterns. Support for TICkit 63, and Hubbub 78 and Hubbub 98 processors. P.S. to use the newer code samples your TICkit IDE program may also need to be updated. See here
This project is particularly suitable as an educational project. It is multi-faceted in the sense that it can simply be a construction project initially, but can turn into a very challenging programming exercise if/when a person wants to modify the LED patterns. The very tangible I/O of this project (the blinking lights) provides a nice sense of accomplishment when you get it working.
In this application note we use a MAX7219 to control an array of LED's arranged in a Star pattern. This application differs from AN028 in that it uses dedicated hardware in the TICkit 62 to implement the 3-wire bus to the MAX7219. This hardware, called the SSP, will clock out 8 bits of data at rates up to 1.5 MHz making the transfer of a byte instantaneous for the time scale of the TICkit interpreter.
Also, this application has hooks for utilizing the CCP output (PWM) of the TICkit for playing music in background while the star pattern executes. A complete layout is included in the project zip file, AN035.ZIP. Protean Logic Inc. carries this PCB, if you want to build this app-note as a Christmas project. See ordering info for details
The physical layout of the Star PCB is as shown

The controller components mount on the top side of the board while the 60 LED's mount on the bottoms side of the board. The speaker can mount on either side of the board as it suits your taste. The 16 pin pad pattern labeled "Conn" can be used to connect this PCB to Paul Via's original circuit based on the STAMP II if just want a PCB for the LED pattern.
Likewise, the star processor circuitry can be used to drive optical isolators instead of visible LED's. To do this, simply leave the LED's unpopulated and hook into the digit and segment connections of the "Conn" 16 pin socket. This provides an easy way to drive a large array of high power lamps, AC or DC.
The circuitry for this project is very straight forward with no "tricks" to speak of. The schematic below shows how the TICkit Interpreter IC is wired up to the 7219 and how the LED matrix is wired. The 7219 is a COMMON CATHODE driver, so if you use any sort of pre-wired array, remember to get one compatible with common cathode.

The program to control this display is remarkably simple. The LED's have prudently been placed in ascending order by Mr. Via in his original design. This allows a simple set of functions in FBASIC to map an LED number (0 to 59) into the segment and digit matrix of the 7219. Functions led_on(), led_off(), string_on(), and string_off() allow control of a single LED or a range of LED's. Because the LED's are all in "order" an arm or point of the star can be controlled simply by specifying a range of beginning and ending LED number.
Mr. Via, in his original application implemented a large suite of LED patterns. So far, I am only implementing 3 patterns in this application note. I have included Mr. Via's original STAMP II code in the zip, so those of you who are industrious can attempt to implement his entire suite of patterns.
; Christmas star pattern generator
; Based on PAUL VIA's Christmas star project
; This version of the 7219 interface uses the SSP hardware to send data very
; fast.
DEF tic62_c
LIB fbasic.lib
DEF max7219_data pin_a5
DEF max7219_clk pin_a3
GLOBAL byte max7219_load pin_a4
DEF max7219_dig0 0x01b
DEF max7219_dig1 0x02b
DEF max7219_dig2 0x03b
DEF max7219_dig3 0x04b
DEF max7219_dig4 0x05b
DEF max7219_dig5 0x06b
DEF max7219_dig6 0x07b
DEF max7219_dig7 0x08b
DEF max7219_decode 0x09b
DEF max7219_intens 0x0Ab
DEF max7219_limit 0x0Bb
DEF max7219_shutdn 0x0Cb
DEF max7219_test 0x0Fb
GLOBAL byte eight 8b ; These constants implemented as globals for speed
GLOBAL byte sixty 60b
GLOBAL byte zero 0b
DEF ssp_mode_div4 0y00000000b ; SPI master clk = OSC/4
DEF ssp_mode_div16 0y00000001b ; SPI master clk = OSC/16
DEF ssp_mode_div64 0y00000010b ; SPI master clk = OSC/64
DEF ssp_mode_divtmr2 0y00000011b ; SPI master clk = OSC/timer2
DEF ssp_mode_slave 0y00000100b ; SPI slave /SS enabled
DEF ssp_mode_slavd 0y00000101b ; SPI slave /SS disabled
GLOBAL byte each_dig[8b] 0b 0b 0b 0b 0b 0b 0b 0b
GLOBAL byte to_seg[8b] 0x80b,0x40b,0x20b,0x10b,0x08b,0x04b,0x02b,0x01b
GLOBAL byte digit
GLOBAL byte segment
GLOBAL byte repeats
FUNC none max7219_send
PARAM byte max_regis
PARAM byte max_data
BEGIN
pin_low( max7219_load )
ssp_buffer_set( max_regis )
ssp_buffer_set( max_data )
pin_high( max7219_load )
ENDFUN
FUNC none led_on ; turn specified LED on and leave the rest unchanged
PARAM byte led_number
BEGIN
=( digit, /( led_number, eight ))
=( segment, to_seg[ %( led_number, eight ) ] )
=( segment, b_or( segment, each_dig[ digit ] ))
=( each_dig[ digit ], segment )
++( digit )
max7219_send( digit, segment )
ENDFUN
FUNC none led_off ; turn specified LED off and leave the rest unchanged
PARAM byte led_number
BEGIN
=( digit, /( led_number, eight ))
=( segment, b_not( to_seg[ %( led_number, eight ) ] ))
=( segment, b_and( segment, each_dig[ digit ] ))
=( each_dig[ digit ], segment )
++( digit )
max7219_send( digit, segment )
ENDFUN
FUNC none string_on ; turn string of LED's on at specified beginning and end
PARAM byte start_led
PARAM byte end_led
LOCAL byte cur_led
LOCAL byte cur_seg
BEGIN
=( cur_led, start_led )
=( digit, /( cur_led, eight ))
REP
=( segment, each_dig[ digit ] )
=( cur_seg, to_seg[ %( cur_led, eight ) ] )
WHILE cur_seg
=( segment, b_or( segment, cur_seg ))
=( cur_seg, >>( cur_seg ))
++( cur_led )
UNTIL >( cur_led, end_led )
=( each_dig[ digit ], segment )
++( digit )
max7219_send( digit, segment )
UNTIL >( cur_led, end_led )
IF ==( end_led, sixty )
=( each_dig[ zero ], b_or( each_dig[ zero ], 0x80b ))
max7219_send( 1b, each_dig[ zero ] )
ENDIF
ENDFUN
FUNC none string_off ; turn string of LED's off at specified beginning and end
PARAM byte start_led
PARAM byte end_led
LOCAL byte cur_led
LOCAL byte cur_seg
BEGIN
=( cur_led, start_led )
=( digit, /( cur_led, eight ))
REP
IF ==( cur_led, sixty )
=( digit, zero )
=( segment, each_dig[ digit ] )
=( cur_seg, 0x80b )
ELSE
=( segment, each_dig[ digit ] )
=( cur_seg, to_seg[ %( cur_led, eight ) ] )
ENDIF
WHILE cur_seg
=( segment, b_and( segment, b_not( cur_seg )))
=( cur_seg, >>( cur_seg ))
++( cur_led )
UNTIL >( cur_led, end_led )
=( each_dig[ digit ], segment )
++( digit )
max7219_send( digit, segment )
UNTIL >( cur_led, end_led )
IF ==( end_led, sixty )
=( each_dig[ zero ], b_and( each_dig[ zero ], 0x7fb ))
max7219_send( 1b, each_dig[ zero ] )
ENDIF
ENDFUN
FUNC none zoom
PARAM word on_period
PARAM byte repeats
LOCAL byte led_num
BEGIN
WHILE repeats
=( led_num, zero )
REP
led_on( led_num )
delay( on_period )
led_off( led_num )
++( led_num )
UNTIL ==( led_num, sixty )
--( repeats )
LOOP
ENDFUN
FUNC none stick_cw
PARAM word on_stick
PARAM byte repeats
BEGIN
WHILE repeats
string_on( 1b, 6b )
string_off( 54b, 59b )
delay( on_stick )
string_on( 7b, 12b )
string_off( 0b, 5b )
delay( on_stick )
string_on( 13b, 18b )
string_off( 6b, 11b )
delay( on_stick )
string_on( 19b, 24b )
string_off( 12b, 17b )
delay( on_stick )
string_on( 25b, 30b )
string_off( 18b, 23b )
delay( on_stick )
string_on( 31b, 36b )
string_off( 24b, 29b )
delay( on_stick )
string_on( 37b, 42b )
string_off( 30b, 35b )
delay( on_stick )
string_on( 43b, 48b )
string_off( 36b, 41b )
delay( on_stick )
string_on( 49b, 54b )
string_off( 42b, 47b )
delay( on_stick )
string_on( 55b, 60b )
string_off( 48b, 53b )
--( repeats )
LOOP
ENDFUN
FUNC none flash
LOCAL byte frameno
BEGIN
=( frameno, 1b )
REP
=( digit, 1b )
REP
max7219_send( digit, 0b )
++( digit )
UNTIL ==( digit, 9b )
delay( 500 )
=( digit, 1b )
REP
max7219_send( digit, 0xffb )
++( digit )
UNTIL ==( digit, 9b )
delay( 500 )
++( frameno )
UNTIL ==( frameno, 7b )
ENDFUN
FUNC none main
BEGIN
; start by initializing the display
pin_high( max7219_load )
pin_low( max7219_clk )
pin_low( max7219_data )
ssp_cont_set( ssp_con_enable | ssp_mode_div64 | ssp_con_clken )
max7219_send( max7219_decode, 0y00000000b ) ; numeric decode
IF pin_in( pin_a1 )
max7219_send( max7219_intens, 0y00000100b )
ELSE
max7219_send( max7219_intens, 0y00001111b ) ; full brightness
ENDIF
max7219_send( max7219_limit, 0y00000111b ) ; all rows (digits) on
max7219_send( max7219_shutdn, 0y00000001b ) ; normal operation
max7219_send( max7219_test, 0y00000001b ) ; test in progress
delay( 5 ) ; 5ms of LED test ( bright regardless of jumper )
max7219_send( max7219_test, 0y00000000b ) ; no test in progress
REP
flash()
zoom( 10, 10b )
stick_cw( 10, 10b )
LOOP
ENDFUN
If you would like to order a PCB or a kit of parts from Protean Logic Inc. use
the print out the order form, fill in the
part number of the item(s) you want and FAX it to (303) 828 9316. We ship
priority mail so you should get the package in 3 business days. In the
kits below, the EEprom comes programmed with the sample program. If you
wish to modify the LED pattern or experiment in any other way, you will
need to download the TICkit shareware tools and purchase/make a download
cable. Or you can purchase a full development kit which contains a TICkit
manual and suitable wall wart power supply for the Star project for $45.
The Star project is available assembled or as a kit in the Board level products part of this web site.
Protean Logic Inc. Copyright 02/02/18 Top of Page