Shop OBEX P1 Docs P2 Docs Learn Events
Controlling a MAX7219 — Parallax Forums

Controlling a MAX7219

KenMKenM Posts: 657
edited 2005-11-18 15:46 in General Discussion
To anybody interested, I am attaching code and instructions on how to use a MAX7219 seven segment display driver.

The program was not meant to be efficient (nor could it be if written by myself) but rather just to make the IC work.

A MAX7219 is an IC that will drive 8 seven segment displays using three lines.

Ken Mathis

;FILE NAME:MAX7219
;Date:June 16, 2004
;Programmer:Ken Mathis
;Purpose of this program is to control several seven segment displays using the MAX7219
;seven segment display driver IC. The seven segment displays are multiplexed with the
;7219 and are common cathode type displays.

;This test code controls only 3 seven segment displays. The code can easily be expanded
;for the max7219 to control up to 8 seven segment displays while consuming only 3 SX
;output pins
;Where appropriate, explanations are provided to account for more than 3 seven segment displays
;This configuration uses the SX internal oscillator as the timimg as shift data
;timing is not critical
;
[noparse][[/noparse]Assembler directives]
ifdef __SASM
·DEVICE·SX18L, STACKX, OPTIONX
·IRC_CAL·IRC_FAST
·FREQ·4_000_000
else
·DEVICE·SX18AC, OPTIONX
endif
DEVICE·TURBO, OSC4MHZ
RESET·START
;
[noparse][[/noparse]Define variables and constants]
org·$07··;$07 is first free variable space
Decode·ds·2· ;assign 2 bytes of space for Decode - 7 & 8
ShtDn·ds·2··· ;assign 2 bytes of space for Shutdown - 9 & A
ScnLmt·ds·2· ;assign 2 bytes of space for Scan Limit - B & C
Inten·ds·2···· ;assign 2 bytes of space for Intensity - D & E
bitcnt·ds·1··· ;assign 1 byte of space for bit counter - F
;dig0, dig1, & dig2 represent three 7 segment displays with a common cathode and
;dig0 is the least significant display
dig0·ds·2······ ;assign 2 bytes of space for Digit 0 - 10 & 11
dig1·ds·2······ ;assign 2 bytes of space for Digit 1 - 12 & 13
dig2·ds·2······ ;assign 2 bytes of space for Digit 2 - 14 & 15
;To display more digits variable manes MUST be added here sequentially
;after dig2 for the code to properly work.

; !!! IF 8 SEVEN SEGMENT DISPLAYS ARE USED, there will be no more room
;for the word counter (wrdcnt) in bank one. To avoid switching banks in
;this circumstance, the upper or lower byte of any of the initialization
;words (Decode, ShtDn, ScnLmt, or Inten) can be reused/reloaded with
;the appropriate value after the initialization is finished. A comment
;will be shown where to reload Decode if needed
wrdcnt·ds·1·;assign 1 byte of space for word counter - 16

;----[noparse][[/noparse]Define symbolic pin names]

data·EQU·rb.1·;data pin connects to pin 1 of 7219
clock·EQU·rb.2·;clock pin connects to 13 of 7219
load·EQU·rb.3·;load pin connects to 12 of 7219
;
[noparse][[/noparse]calls should be placed on first page between org $000 and org $100]--
org·$000
;5uS delay - generated using the delay code generator at sxlist.com
del_5uS
·jmp·$+1
·jmp·$+1
·jmp·$+1
·jmp·$+1
·nop
·nop
·ret
;sub to shift out msbit of each byte into carry
rotate
·rl·ind·;move msbit into carry
·jc·high·;if carry is high jump to high
·clrb·data·;if carry is low ensure data pin is low
·jmp·$+2·;jump 2 lines
high
·setb·data·;make data pin high
·nop··;no operation
·ret
;clock pulse generation to shift data out of SX into max 7219
shiftout
·call·del_5uS·;5 uS set-up time
·setb·clock·;make clock (rb.2) high
·call·del_5uS·;5 uS hold time
·clrb·clock·;make clock low
·ret··;return
;
[noparse][[/noparse]MAIN PROGRAM]
org·$100
Start···;reset point
;
[noparse][[/noparse]I/O port setting]
·mode·$0f·;set mode for port direction
·mov·w,#$0
·mov·!ra,w·; all ra ports output
·mov·w,#$00
·mov·!rb,w·;all rb ports output

;
[noparse][[/noparse]prepare variables for initialization of max7219]
;mov w,#$XX loads the w register with hex value
;mov NAME,w loads value of w into variable name
;Later in this program the initiazation is explained in detail
·mov·w,#$09
·mov·Decode,w
·mov·Inten+1,w
·mov·w,#$0f
·mov·Decode+1,w
·mov·w,#$10
·mov·bitcnt,w
·mov·w,#$0c
·mov·shtdn,w
·mov·w,#$01
·mov·shtdn+1,w
·mov·dig0,w
·mov·w,#$0b
·mov·scnlmt,w
·mov·w,#$02
·mov·scnlmt+1,w
·mov·dig1,w
·mov·w,#$0a
·mov·inten,w
·mov·w,#$03
·mov·dig2,w
·mov·w,#$04
·mov·wrdcnt,w

;point to first register that will hold data to shift out which
;is Decode at address $07. NOTE that this is a SX18 and does not have an RC
;port.
·mov·w,#$07
·mov·fsr,w
;
[noparse][[/noparse]The program currently causes display to load 4 to each digit. To test a
;different value, change four to any digit 0 to 9. Your actual program will load
;dig0+1, dig1+1 and dig2+1 with some dynamic data.
·mov·w,#$04
·mov·dig0+1,w
·mov·dig1+1,w
·mov·dig2+1,w

;
[noparse][[/noparse]MAX7219 Operation]
;The 7219 must first be initialized. Initialization is done by sending serial
;data to the IC. Four 16 bit values sent will complete the initialization.
;To send a 16 bit value load is brought LOW, then each of 16 bits (msb 1st) is
;clocked into the IC, and load is then brought HIGH to complete the shifting
;of 16 bits into the device
;For each word sent to the IC, the most significant byte is the address and the
;lower byte sets the option for each particular function.
;For the descriptions that follow values will be shown as $Xx. The upper case x
;represents the upper nibble and the value is "don't care"
;DECODE MODE - Address $X9
;Options·$X0 = No decoding
;··$X1 = Decode digit 0 (BCD)
;··$XF = Decode digits 0-3
;··$FF = Decode digits 0-7
;Sending $090F sets decode mode to enable digits 0-3 and instructs that the least
;sig nibble is BCD
;SHUTDOWN MODE - Address $XC
;Options·$X0 = Shutdown
;··$X1 = Normal Operation
;Sending $0C01 sets the IC for normal operation
;SCANLIMIT - Address $XB
;Options·$Xx where the least significant nibble sets the number of digits
;··to enable. digit 0, x = 0. digits 0 & 1 x = 1. digits 0, 1, & 2 x = 2
;Sending $0B02 enbables digts 0, 1 & 2
;Sending $0B07 enables all 8 digits
;INTENSITY - Address $XA
;Options·$00 = minimum intensity
;··$FF = maximum intensity
;··See MAX7219 data sheet for resistor selection and current

;----[noparse][[/noparse]set up SX controll pins]
·clrb·data··;make data pin low
·clrb·clock··;make clock pin low
·setb·load··;make load pin high
·call·del_5uS··;wait 5 uS
;----[noparse][[/noparse]Start of routine to send out first 16 bits]
·clrb·load··;enable 7219 to start accepting serial data.
j1
·call·rotate

;call routine to move msbit into carry and set data pin
····;high or low depending on state of bit carried out
·call·shiftout·;call routine to shift data bit to 7219
·dec·bitcnt··;decrement bit counter
·cjne·bitcnt,#8,j2·;check if 8 bits have been sent out
·inc·fsr··;if 8 bits were sent, increment fsr to point to next
····;register
·jmp·$-8··;move back up to call rotate
j2
·cja·bitcnt,#0,j1·;check of bit counter is at zero (16 bits shifted out?)
·setb·load··;if 16 bits shifted out, load them into the 7219
·dec·wrdcnt··;check if the 4 initialization words shifted out
·cja·wrdcnt,#0,j3·;if word counter is above 0, jump to j3
·jmp·$+5··;if the 4 initialization words shifted out jump down 5 lines
j3
·mov·w,#$10··;reload bit counter with 16
·mov·bitcnt,w·;reload bit counter with 16
·inc·fsr··;increment fsr to point to the next register
·jmp·$-$18··;jump up to the "clrb load" instruction to start another
····;sequence of shifting out 16 more bits

;
[noparse][[/noparse]shift actual data into max7219]
;Data is sent to the 7219 in the same manner as the initialization described above.
;load is brought LOW, 16 bits clocked into device and load is brought HIGH to complete
;the loading of one digit.
;For each digit, the upper byte of 16 bits is the address of the digit and the lower
;byte is the value sent to the 7 segment. This value is either BCD or the "word" to control
;each of the 8 segments (decimal point). Remember that DECODE MODE determines how to
;use the lower byte
;For·digit 0 the address is $01
;·digit 1 the address is $02
;·digit 2 the address is $03
;If decode mode was selected sending the 16 bit value of $0207 will tell the IC that
;digit number 1 gets a value of 7

·mov·w,#$10
·mov·fsr,w··;point to first address of digit 0 holding the most sig byte
·mov·bitcnt,w·;load the bit counter with 16
;If using 8 seven segment displays as decribed above, comment out the next two lines
·mov·w,#$03··;since three digits are used in this example, wrdcnt is loaded w/3
·mov·wrdcnt,w
;Use these next two lines if 8 seven segments are used.
;·mov·w,#$08
;·mov·Decode,w
;----[noparse][[/noparse]Start of routine to send out first 16 bits of TEST data]
;The rest of this code is exactly the same as the initialization code, so no comments added here.
;see initialzation above for comments.
·clrb·load
j4
·call·rotate
·call·shiftout
·dec·bitcnt
·cjne·bitcnt,#8,j5
·inc·fsr
·jmp·$-8
j5
·cja·bitcnt,#0,j4
·setb·load
;If using 8 seven segment displays as decribed above, comment out the next two lines
·dec·wrdcnt
·cja·wrdcnt,#0,j6
;Use these next two lines
;·dec·Decode
;·cja·Decode,#0,j6
·jmp·$+5
j6
·mov·w,#$10
·mov·bitcnt,w
·inc·fsr
·jmp·$-$18
·setb·load
·sleep
END

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Ken

Post Edited (KenM) : 11/17/2005 5:27:11 AM GMT

Comments

  • southernbobsouthernbob Posts: 34
    edited 2004-07-25 19:23
    If you use 'code ' statements at the start and end of your code, it won't get all
    jammed together on the screen. It downloads OK. See HELP for how to
    use 'code' statements.

    Here is a sample from your code above.
    ;-----[noparse][[/noparse]Define variables and constants]------------------------------
    org $07  ;$07 is first free variable space
    Decode ds 2  ;assign 2 bytes of space for Decode - 7 & 8
    ShtDn ds 2    ;assign 2 bytes of space for Shutdown - 9 & A
    ScnLmt ds 2  ;assign 2 bytes of space for Scan Limit - B & C
    Inten ds 2     ;assign 2 bytes of space for Intensity - D & E
    bitcnt ds 1    ;assign 1 byte of space for bit counter - F
    ;dig0, dig1, & dig2 represent three 7 segment displays with a common cathode and
    ;dig0 is the least significant display
    dig0 ds 2       ;assign 2 bytes of space for Digit 0 - 10 & 11
    dig1 ds 2       ;assign 2 bytes of space for Digit 1 - 12 & 13
    dig2 ds 2       ;assign 2 bytes of space for Digit 2 - 14 & 15
    
    


    Bob
  • KenMKenM Posts: 657
    edited 2004-07-25 20:18
    This is just a test using "code" statements "

    ·"[noparse][[/noparse]code]<This is a code>[noparse][[/noparse]/code]"

    ·[noparse][[/noparse]code]<This is a code>[noparse][[/noparse]/code]
  • KenMKenM Posts: 657
    edited 2004-07-25 20:20
    Bob,

    Not knowing the first thing about HTML, could you give me an example of the "code" modifiers. I tried what I think should be done, but that did not work as you can see.

    Ken
  • southernbobsouthernbob Posts: 34
    edited 2004-07-25 21:05
    Ken,
    I will have to simulate as follows:
    {code}
    org $07 ;$07 is first free variable space
    Decode ds 2 ;assign 2 bytes of space for Decode - 7 & 8
    ShtDn ds 2 ;assign 2 bytes of space for Shutdown - 9 & A
    {/code}

    Replace the the { } with [noparse][[/noparse] ] . I had to use the { }'s so that that it wouldn't
    take effect.

    With the actual 'code' in place it will look like this;
    org $07  ;$07 is first free variable space
    Decode ds 2  ;assign 2 bytes of space for Decode - 7 & 8
    ShtDn ds 2    ;assign 2 bytes of space for Shutdown - 9 & A
    
    


    Bob
    PS: hope this works!!!!
  • Brian CarpenterBrian Carpenter Posts: 728
    edited 2005-11-15 09:07
    i appologize if this sounds completely ignorant... because it is.... I have the sx28.. will this code work as is?

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔


    It's Only A Stupid Question If You Have Not Googled It First!!
  • KenMKenM Posts: 657
    edited 2005-11-15 15:54
    Yes the code will work with an sx28. The device directives will need to be changed and you need to set the state of the extra I/O pins found on the sx28 (not set to floating inputs)

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Ken
  • ElectronegativityElectronegativity Posts: 311
    edited 2005-11-15 17:50
    Thanks Ken, you saved me a lot of work. burger.gif

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    I wonder if this wire is hot...
  • KenMKenM Posts: 657
    edited 2005-11-17 05:16
    Actually, there is another thing you will need to do to port the SX18 based program to the SX28.

    Below is the code copied and pasted. org $07 should be org $08 and the variable locations are all off by one. See second code box. You cannot freely switch banks though. The programming technique is poor.

    The task is probably much easier using SX/B, which I don't use so I cannot help there.

    I believe there is an example of SX/B controlling a MAX7219.
    ;-----[noparse][[/noparse]Define variables and constants]------------------------------
    org $07 ;$07 is first free variable space
    Decode ds 2 ;assign 2 bytes of space for Decode - 7 & 8
    ShtDn ds 2 ;assign 2 bytes of space for Shutdown - 9 & A
    ScnLmt ds 2 ;assign 2 bytes of space for Scan Limit - B & C
    Inten ds 2 ;assign 2 bytes of space for Intensity - D & E
    bitcnt ds 1 ;assign 1 byte of space for bit counter - F
    
    

    ;-----[noparse][[/noparse]Define variables and constants]------------------------------
    org $08 ;$08 is first free variable space
    Decode ds 2 ;assign 2 bytes of space for Decode - 8 & 9
    ShtDn ds 2 ;assign 2 bytes of space for Shutdown - A & B
    ScnLmt ds 2 ;assign 2 bytes of space for Scan Limit - C & D
    Inten ds 2 ;assign 2 bytes of space for Intensity - E & F
    bitcnt ds 1 ;assign 1 byte of space for bit counter - 10
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Ken
  • PJMontyPJMonty Posts: 983
    edited 2005-11-17 17:53
    Ken and Bob,

    Are you guys not familiar with the formatting buttons that are present every time you reply? Look above the area where you type and you'll see them. In Internet Explorer, they show up as buttons similar to the formatting buttons in Word. In FireFox, they are simple outlines with a single word in them. For IE, use the button on the far right that has the # character in it. In FireFox, use the button with the word "code" on it. You can always manually type in the codes, but the whole reason for the buttons is to avoid making you have to do this.
      Thanks, PeterM

    Ps - I have attached a pair of pictures that show these formatting button in the two browsers.
    448 x 107 - 16K
    411 x 111 - 10K
  • KenMKenM Posts: 657
    edited 2005-11-17 20:13
    Hi Peter.

    Regarding the formatting buttons, what is "wrong" with my posts?

    If you are referring to my original posts in this thread from 7/2004, I was not aware of the formatting code icon at that time.


    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Ken
  • PJMontyPJMonty Posts: 983
    edited 2005-11-18 06:26
    Ken,

    Yeah, I was referring to the 7/25 post. Frankly, I never really look at the dates. I didn't realize this thread was so old. If you already know about the formatting buttons, then my post was superfluous.
      Thanks, PeterM
  • ElectronegativityElectronegativity Posts: 311
    edited 2005-11-18 15:46
    Hi Ken, the Max7219 is a great chip, but it's a bit clunky and expensive.

    The STP16C596 is a cheaper alternative that will light up to 16 LED's, and it comes in an SO-24 package.
    Mouser sells them for $2.52.

    The only problem is that STMicroelectronics has an awful website that fails to provide any idea of how to program it.

    There are pins for serial in, serial out, clock in, latch input, and "input terminal of output enable (active low)".

    Do you think the "latch input" is equivalent to the "load" pin on the MAX7219?
    Can I just clock in 2 bytes with 1' and 0's corresponding to on or off for the 16 pins and then load it by changing the state of the latch pin?

    I have attached the data sheet in case anyone is interested

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    I wonder if this wire is hot...
Sign In or Register to comment.