HW-179 8-Digit 7-Segment LED Display (Cascaded MAX7219s)


+ Reply to Thread
Results 1 to 3 of 3
  1. #1
    Join Date
    Nov 2019
    Posts
    19

    Default HW-179 8-Digit 7-Segment LED Display (Cascaded MAX7219s)

    My earlier post provided sample code for a single HW-179 8-digit 7-segment LED display. The MAX7219 provides for a cascade configuration such that multiples of 8-digit displays can be connected to achieve displays having a greater number of digits, and is the topic of this post.

    The MAX7219 spec sheet vaguely describes this capability in a couple short paragraphs and in a wiring diagram, but is absent of timing diagrams or command listings. The most revealing clue that conveys exactly how to communicate with cascaded MAX7219 devices is the spec sheet's functional diagram on page 5. Here it shows that address and data is shifted into a 16-bit register over 16 cycles of the SPI clock signal, and that this address and data is subsequently shifted out of this register on the DOUT pin over the next 16 clock cycles into the cascaded MAX7219 whose DIN pin is connected to the first MAX7219's DOUT pin. Particularly important to understanding how this functions is that the 16-bit address and data is strobed into the MAX7219 on the rising edge of the SPI's CS signal, and that a "No-Op" (a 16-bit address and data sequence that is 0xXX0X) inhibits any change in the MAX7219 in whose register it appears.

    Consequently, when the SHIFTOUT command sends two 16-bit quantities within a single CS strobe cycle, each MAX7219 responds to the command that appears in its register when the CS signal rises. For example, with 2 MAX7219s cascaded, the following command sequence could be sent:

    CS = 0
    SHIFTOUT Data, Clock, Mode, [$0105, $0206]
    CS = 1

    Shifting begins with the most significant bit of the first argument in the command, and so after execution, $0105 appears in the second MAX7219 and $0206 appears in the first MAX7219. Referencing the data sheet, these commands result in the number "5" appearing in the second MAX7219's first digit and the number "6" appearing in the first MAX7219's second digit. If either of these arguments is replaced with a No-Op ($0000), then the respective display remains unchanged.

    In the attached code sample, this register 16-bit shifting is exploited in the first section where the MAX7219s are initialized. The first command is the test command $0F01 which causes all segments in all digits to illuminate for 1 second, followed by return to normal operation. When executed from reset, the first MAX7219 goes into this test mode for 1 second while the second MAX7219 remains unlit. Then the first MAX7219 returns to normal and the second MAX7219 enters test mode. With this sample code structured this way, each of the 16-bit initialization commands ripples from the first device to the second, with the final No-Op command ensuring that the last command $0C01 makes it way to the second MAX7219. Thus, all 6 initialization commands are entered into both MAX7219s.

    Alternately, each of these initialization commands could contain the argument twice -- for example [$0F01, $0F01], which would cause both display modules to simultaneously light up in test mode. Using this technique, the final No-Op command can be eliminated.

    The sample code provided here extends the demo of my earlier post by creating the same progressive display counting, starting with the right-hand most digit on the second display and proceeding through the the left-hand most digit of the first display. Notice that the difference between the two code loops that apply to the two display modules is the exchange of the position of the No-Op argument in the SHIFTOUT command. This technique allows a number to be placed in any digit position on either display module.

    Code:
    '****************************************************************
    '*  Name    : MAX7219_Cascade_8-Digit_7-Segment_Demo.BAS        *
    '*  Author  : Roberts                                           *
    '*  Notice  : Copyright (c) 2021                                *
    '*          : All Rights Reserved                               *
    '*  Date    : 10/6/2021                                         *
    '*  Version : 1.0                                               *
    '*  Notes   : Developed on Microchip Curiosity Board with       *
    '*          : PIC16F183456 uC and the HW-179 8-digit/7-segment  *
    '*          : display driven by the MAX7219 driver via 3-wire   *
    '*          : SPI interface, set to operate at 5 VDC.           *
    '****************************************************************
    '
    ' This brief demo program writes the digits 0 thru 9 and "-" to two HW-179 8-digit 7-segment LED displays based on the
    ' MAX7219 interface driver.  The code includes the initialization sequence that (a) sets the decode mode to BCD,
    ' (b) sets the LED intensity to half-scale (8/16), (c) sets all 8 digits active, and (d) activates the displays.
    ' During initialization, the code sets the test mode active for 1 second (e.g., all digits and all segments lit). This
    ' initialization is structured such that each command ripples from the first display to the second.
    ' Then all digits are cleared, and counting begins with the right-hand most digit on the second display.  Each digit
    ' counts from 0 to 9 and then "-", and the counting progresses to the left one digit at a time.  Once all 8 digits are
    ' showing "-", counting progresses to the first display and repeats the same sequence.  After all digit positions have
    ' counted, the program cycles back to clearing the display and repeats.
    ' Data is sent to the displays using PBP's SHIFTOUT command.  The code demonstrates how commands are structured to 
    ' send data to one display while holding the other display unchanged. 
    '
    '****************************************** PIC16F18346 Initialization *************************************************                                                 
    '************************************** Configuration File for the PIC 16F18346 ****************************************
    #CONFIG
        __config _CONFIG1, _FEXTOSC_OFF & _RSTOSC_HFINT32 & _CLKOUTEN_OFF & _CSWEN_ON & _FCMEN_ON
        __config _CONFIG2, _MCLRE_ON & _PWRTE_OFF & _WDTE_ON & _LPBOREN_OFF & _BOREN_ON & _BORV_LOW & _PPS1WAY_OFF & _STVREN_ON & _DEBUG_OFF
        __config _CONFIG3, _WRT_OFF & _LVP_OFF
        __config _CONFIG4, _CP_OFF & _CPD_OFF
    
    #ENDCONFIG
    @ ERRORLEVEL -306   ; turn off crossing page boundary message
    
    OSCFRQ = 000100    ' Set internal osc to 16MHz
    DEFINE OSC 16        ' Tell PBP that the device will clock at 16MHz (necessary for uSec pauses used in bit-banging)
    
    ANSELA = 000000    ' PortA all digital / available pins are A0 through A5 (6 I/O's)
    TRISA = 000000   ' PortA all outputs
    '
    '************************** Initialization and Variable Declarations *****************************************
    '
    ' SPI signals use LATx.x assignments to prevent read/modify/write conflicts on a single I/O port
    CS  Var LATA.2  ' uC chip select output pin
    SCK Var LATA.4  ' uC clock out pin
    SI  Var LATA.5  ' uC data out / LCD Data in pin
    '
    '
    i VAR WORD       ' loop counter variable
    j VAR byte       ' loop counter variable
    CS = 1           ' Disable SPI device select CS for OLED 
    '
    '************************* Initialize the display parameters by sending 16-bit constants **********************
    '                (See MAX7219 spec sheet for tables listing full range of initialization values)
    
        CS = 0
        SHIFTOUT SI, SCK, 1, [$0F01\16]         'Test display - illuminate all segments & all digits     
        CS = 1    
        PAUSE 1000                              'hold for 1 second
        
        CS = 0
        SHIFTOUT SI, SCK, 1, [$0F00\16]         'Return to normal display mode
        CS = 1    
        PAUSE 1000                              'Pause 1 second
    
        CS = 0
        SHIFTOUT SI, SCK, 1, [$09FF\16]         'Set decode mode for BCD
        CS = 1                                  '($0900 for no decoding - see MAX7219 spec sheet)
        PAUSE 10
        
        CS = 0
        SHIFTOUT SI, SCK, 1, [$0A01\16]         'Set display intensity to 2/16 brightness
        CS = 1                                  '($0A00 for minimum brightness / $0A0F for maximum brightness)
        PAUSE 10
        
        CS = 0
        SHIFTOUT SI, SCK, 1, [$0B07\16]         'All 8 digits active
        CS = 1                                  '($0B01 for only digit 1 active - see MAX7219 spec sheet)
        PAUSE 10
        
        CS = 0
        SHIFTOUT SI, SCK, 1, [$0C01\16]         'Activate display
        CS = 1                                  '($0C00 for powering down the display - see MAX7219 spec sheet)
        PAUSE 10
        
        CS = 0
        SHIFTOUT SI, SCK, 1, [$0000\16]         'Send no-op to complete initialization of 2nd display
        CS = 1 
        
    '********************************************* Main Program ********************************************************** 
    main:                                       
      For i = 1 to 8                            'Clear all 8 digit registers to blank
        CS = 0
        Shiftout SI, SCK, 1, [i,$0F]            'Clear each digit "i" by sending the blank character constant 0x0F
        CS = 1
        pause 10
        
        CS = 0
        SHIFTOUT SI, SCK, 1, [$0000\16]         'Send no-op to complete blanking on 2nd display's 8th digit
        CS = 1 
        pause 10
        
      Next i                                    'hold the display blank for 1 second
      pause 1000
    
     
    'This first nested loop sends digits through the 1st display to the 2nd display:
            
     For j = 1 to 8                             'the variable j is the 8-bit digit address register
      For i = 0 to 10                           'the variable i is the 8-bit data register
        CS = 0
        SHIFTOUT SI, SCK, 1, [j,i,$0000\16]     'Display 0 through 9 and "-" right to left ($0000 is a No-Op)
        CS = 1
        PAUSE 500                               'pause 1/2 second for counting
      next i 
     Next j
         
    'This second nested loop sends digits to the 1st display and inhibits change to the 2nd display:
             
     For j = 1 to 8                             'the variable j is the 8-bit digit address register
      For i = 0 to 10                           'the variable i is the 8-bit data register
        CS = 0
        SHIFTOUT SI, SCK, 1, [$0000\16,j,i]     'Display 0 through 9 and "-" right to left ($0000 is a No-Op)
        CS = 1
        PAUSE 500                               'pause 1/2 second for counting
      Next i 
     Next j        
                                                
     Pause 2000                                 'hold the display for 2 seconds       
                                               
    Goto main

  2. #2
    Join Date
    Nov 2003
    Location
    Greece
    Posts
    3,087

    Default Re: HW-179 8-Digit 7-Segment LED Display (Cascaded MAX7219s)

    Nice piece of work. Thanks for posting.

    Ioannis

  3. #3
    Join Date
    Nov 2019
    Posts
    19

    Default Re: HW-179 8-Digit 7-Segment LED Display (Cascaded MAX7219s)

    Just one further point to fully clarify...

    When there are multiple MAX7219s cascaded -- let's say 4 -- every SHIFTOUT command requires that many arguments in the command, with No-Ops sent to the MAX7219s that are to remain unchanged. For example,

    SHIFTOUT SI, SCK, 1, [$0000\16,$0000\16,$0502\16,$0000\16]

    will send "2" to the 5th digit of the 3rd MAX7219, without disturbing any of the other MAX7219 register contents, and sending

    SHIFTOUT SI, SCK, 1, [$0000\16,$0207\16,$0000\16,$0000\16]

    will send "7" to the 2nd digit of the 2nd MAX7219 without altering the the display sent by the first SHIFTOUT.

Similar Threads

  1. Replies: 0
    Last Post: - 8th October 2021, 17:00
  2. 6 digit - 7 segment display code
    By lerameur in forum mel PIC BASIC Pro
    Replies: 2
    Last Post: - 15th June 2014, 06:36
  3. Replies: 2
    Last Post: - 14th July 2008, 22:11
  4. Replies: 2
    Last Post: - 22nd January 2008, 14:25
  5. Dual 7-Segment LED Display
    By erice1984 in forum Schematics
    Replies: 14
    Last Post: - 2nd July 2007, 23:51

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts