Management of a 8x8 LED matrix by pixel

published: 28 December 2019 / updated 28 December 2019

Lire cette page en français

 

Gestion par pixels

Dans ces deux articles:

nous avons appris à communiquer avec l'afficheur matriciel 8x8 LEDs et afficher des motifs.

Maintenant, voyons comment gérer l'affichage des LEDs comme si c'était des pixels sur un écran, certes un écran de dimension très limitée, c'est à dire 8x8 pixels.

Coordonnées des axes X et Y

Nous avons arbitrairement décidé d'organiser les coordonnées de notre matrice LED 8x8 selon ce schéma:

axes des coordonnées X Y des LEDs sur la matrice 8x8

Cette disposition obéit au sens de lecture, à savoir de gauche à droite sur l'axe X, de haut en bas sur l'axe Y.

Si vous souhaitez utiliser une orientation différente des axes X et Y, nous vous laissons le soin d'adapter le programme en langage FORTH à votre convenance. C'est l'occasion d'un excellent exercice pratique.

-8x8g
marker -8x8g
 
\ c1 register
\ c2 data
: max7219.send ( c1 c2 -- )
    mSS1 slave.select
    swap spi.csend spi.csend 
    mSS1 slave.deselect
  ;
 
: disp.normal   ( -- ) 
    $0c $01 max7219.send ;
: disp.shutdown ( -- ) 
    $0c $00 max7219.send ;
: disp.intensity  ( c -- )  
    $0a swap max7219.send ;
: disp.decode     ( c -- )  
    $09 swap max7219.send ;
: disp.scan.limit ( c -- )  
    $0b swap max7219.send ;
: disp.set.digit  ( cbits cdigit -- ) 
    swap max7219.send ;
 
-square
marker-square
 
ram
\ buffer for manage content of 8x8 LED display
create graphic-array ( --- n )
    %00000000 c,
    %00000000 c,
    %00000000 c,
    %00000000 c,
    %00000000 c,
    %00000000 c,
    %00000000 c,
    %00000000 c,
 
\ clean the display buffer
: clean.buffer ( ---)
    8 for
        0 graphic-array r@ + c!
    next ;
 
\ display content of buffer
: disp.buffer ( ---)
    8 for
        graphic-array r@ + c@ 
        r@ 1+ disp.set.digit
    next ;
 
\ x and y coordinates start to 0: [0..7]
( +--------> x )
( |            )
( v  y         )
 
\ calculate real adress in graphic-array
: pixel.AT ( x y --- mask addr)
    1 swap lshift          \ y shift first bit to transform in byte mask
    swap graphic-array + 
  ;
 
\ turn ON one pixel on ccordiante x y
: pixel.ON ( x y ---)
    pixel.AT mset
  ;
 
\ turn OFF one pixel on ccordinate x y
: pixel.OFF ( x y ---)
    pixel.AT mclr
  ;
 
 
-test
marker -test
 
: set.square ( n ---)   \ n between [1..8]
    clean.buffer
    dup
    for
        0 r@  pixel.ON
        r@ 0 pixel.ON
        dup 1- r@ pixel.ON
        r@ over 1- pixel.ON
    next 
    drop ;
 
: disp.init ( ---)
    spi.init
    disp.normal
    $01 disp.intensity
    $07 disp.scan.limit
    $00 disp.decode
  ;
 
: disp.close ( ---)
    disp.shutdown
    spi.close
  ;
 
: disp ( -- ) \ draw graphic
    clean.buffer
    disp.init
    begin
        8 for
            7 r@ - 1+ set.square
            disp.buffer 
            100 ms
        next
        8 for
            r@ 1+ set.square
            disp.buffer 
            100 ms
        next
    key? until
  ;