Using a MAX7219 with the SSP
to Make a 5-Point (Xmas) Star

Overlay View

; 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

 

Protean Logic Inc. Copyright 05/05/04         Top of Page