flat assembler
Message board for the users of flat assembler.

Index > Non-x86 architectures > [x51] Deal 8051 with max7219

Author
Thread Post new topic Reply to topic
shoorick



Joined: 25 Feb 2005
Posts: 1614
Location: Ukraine
shoorick 02 Jul 2018, 10:14
There are two main applications of max7219 available as modules: driving 8x8 led matrix or driving 7-segment LED display of 8 digits. The last one is what I use.

To drive it we need to declare some constants: max7219 commands and digit combinations:
Code:
;=======================================================================
MAX7219_NOP         := 0
MAX7219_DIGIT0      := 1 
MAX7219_DIGIT1      := 2 
MAX7219_DIGIT2      := 3 
MAX7219_DIGIT3      := 4 
MAX7219_DIGIT4      := 5 
MAX7219_DIGIT5      := 6 
MAX7219_DIGIT6      := 7 
MAX7219_DIGIT7      := 8 
MAX7219_DECODEMODE  := 9 
MAX7219_INTENSITY   :=10 
MAX7219_SCANLIMIT   :=11 
MAX7219_SHUTDOWN    :=12
MAX7219_TEST        :=15 
;-----------------------------------------------------------------------
SEG_H               :=10000000b
SEG_A               :=1000000b
SEG_B               :=100000b
SEG_C               :=10000b
SEG_D               :=1000b
SEG_E               :=100b
SEG_F               :=10b
SEG_G               :=1b
;-----------------------------------------------------------------------
DIG_0 = SEG_A or SEG_B or SEG_C or SEG_D or SEG_E or SEG_F 
DIG_1 = SEG_B or SEG_C 
DIG_2 = SEG_A or SEG_B or SEG_D or SEG_E or SEG_G
DIG_3 = SEG_A or SEG_B or SEG_C or SEG_D or SEG_G
DIG_4 = SEG_B or SEG_C or SEG_F or SEG_G
DIG_5 = SEG_A or SEG_C or SEG_D or SEG_F or SEG_G
DIG_6 = SEG_A or SEG_C or SEG_D or SEG_E or SEG_F or SEG_G
DIG_7 = SEG_A or SEG_B or SEG_C
DIG_8 = SEG_A or SEG_B or SEG_C or SEG_D or SEG_E or SEG_F or SEG_G
DIG_9 = SEG_A or SEG_B or SEG_C or SEG_D or SEG_F or SEG_G
;-----------------------------------------------------------------------
DIG_A = SEG_A or SEG_B or SEG_C or SEG_E or SEG_F or SEG_G
DIG_B = SEG_C or SEG_D or SEG_E or SEG_F or SEG_G
DIG_C = SEG_A or SEG_D or SEG_E or SEG_F
DIG_D = SEG_B or SEG_C or SEG_D or SEG_E or SEG_G
DIG_E = SEG_A or SEG_D or SEG_E or SEG_F or SEG_G
DIG_F = SEG_A or SEG_E or SEG_F or SEG_G
;-----------------------------------------------------------------------
DIG_X = 0
;-----------------------------------------------------------------------
DOT equ SEG_H
;=======================================================================    

Commands desription is better to read in original datasheet. Any additional combinations for exotic custom symbols can be added in similar way.

To send data from i8051 to max7219 we need such procedure:
Code:
;=======================================================================
SPI_DOUT equ P1.7
SPI_DIN  equ P1.6
SPI_CLK  equ P1.5
SPI_LOAD equ P1.4
;-----------------------------------------------------------------------
spi16_send: ; A:B -> spi
    setb    SPI_LOAD
    clr     SPI_CLK
    push    B
    clr     SPI_LOAD
    call    spi_send
    pop     ACC
    call    spi_send
    setb    SPI_LOAD
    ret
;-----------------------------------------------------------------------
spi_send:
    mov     B,#8
.loop:   
    add     A,ACC
    mov     SPI_DOUT,C
    setb    SPI_CLK
    clr     SPI_CLK
    djnz    B,.loop
    ret
;=======================================================================    
- this procedure only writes, but if necessary can be modified to read also. It works ok with AT89S52 running at 24MHz clock, but if you plan to write to some slow device or use faster 8051 clone, then delay probably will required.

After powering on max7219 display must be initialized by sending some commands to set it up:
Code:
screen_init:
    mov  DPTR,#.data
.loop:
    clr  A
    movc A,@A+DPTR
    inc  DPTR
    jz   cls
    mov  B,A
    clr  A
    movc A,@A+DPTR
    inc  DPTR
    xch  A,B
    call spi16_send
    jmp  .loop
.data:
    db MAX7219_TEST,0
    db MAX7219_DECODEMODE,0
    db MAX7219_SCANLIMIT,7
    db MAX7219_INTENSITY,3
    db MAX7219_SHUTDOWN,1
    db 0    


also, user program may contain some procedures to simplify output to LED screen:
Code:
num2led: ; A = 0..15 -> A = 7 segment LED combination
    anl  A,#0Fh
    inc  A
    movc A,@A+PC
    ret
    db DIG_0,DIG_1,DIG_2,DIG_3,DIG_4,DIG_5,DIG_6,DIG_7    
    db DIG_8,DIG_9,DIG_A,DIG_B,DIG_C,DIG_D,DIG_E,DIG_F    
;-----------------------------------------------------------------------
show_sym: ; A - symbol, B - place (0..7)
    xch  A,B 
    add  A,#MAX7219_DIGIT0
    jmp  spi16_send
;-----------------------------------------------------------------------
show_row: ; R0->row start (leftmost symbol); R0,R1,A,B - destroyed
    mov  R1,#8
.loop:
    mov  B,R1
    dec  B
    mov  A,@R0
    call show_sym
    inc  R0
    djnz R1,.loop
    ret    
;-----------------------------------------------------------------------
cls: ; R0 destroyed
    push ACC
    push B
    mov  R0,#MAX7219_DIGIT0
.loop:
    clr  B
    mov  A,R0
    call spi16_send
    inc  R0
    cjne R0,#MAX7219_DIGIT7+1,.loop
    pop  B
    pop  ACC
    ret
;-----------------------------------------------------------------------    

_________________
UNICODE forever!
Post 02 Jul 2018, 10:14
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.