Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur l'Assembleur !

Modérateur : mazertoc

Led RGB 5050 WS2812B
Temps-x
Avatar de l’utilisateur
Expert
Expert
Messages : 2595
Enregistré en : juillet 2016
Localisation : Terre

#1 Message par Temps-x » mer. 4 sept. 2019 16:27

Bonjour tout le forum,

J'ai acheté 10 Led RGB WS2812B pour 1,11 euro, elles sont déjà soudé sur le circuit imprimé, avec tout ce qu'il faut pour les alimenter, voici son datasheet

Led RGB 5050 WS2812B
WS2812B(10).jpg

Chaque Led RGB 5050 WS2812B est indépendante, elle fait 10mm de diamètre, et sont connectable entre elle, consommation maximum 0,3 Watts (3×18 mA sous 5 volts.).

WS2812B(dessus & dessous.jpg

Si vous alimentez la Led RGB 5050 WS2812B en 5 volts, elle ne s’allumera pas, car il vous faut envoyer un code de 24 bits sur l'entrée Din, le nombre de couleur représente 16777216 possibilités, le choix des couleurs peuvent être trouvés grâce à un petit utilitaire que je vous pouvez télécharger ICI

Il est conseiller de mettre une résistance de 470 ohms en série entre le microcontrôleur et la Led RGB 5050 WS2812B de tête.

Une résistance de 10kΩ entre Din et GND garantit également que la Led RGB 5050 WS2812B de tête ne reçoit pas un signal incohérent alors que la broche du microcontrôleur n’a pas encore été programmée en sortie.

La sotie Dout sert à connecter une autre Led RGB 5050 WS2812B,

Le protocole de communication

Pour commander la Led RGB 5050 WS2812B il est conseillé d'utiliser le protocole SPI à une vitesse de 800 Kbps, d'autre méthode existe comme le mode bit bang cité plus bas.

Transmission-WS2812B.jpg

Sur les durées il y a une tolérance de plus ou moins de 150ns, ça veut dire qu'une durée de 400ns peut être compris entre 250ns au plus bas et 550ns au plus haut.

La mise en œuvre

Pour m'informer des résultats en temps réelle j'ai utilisé l'écran Nokia 5110, voici son datasheet

J'ai utilisé pour la mise en fonction des Led RGB 5050 WS2812B, un microcontrôleur Pic18F26K22, voici son datasheet

On peut choisir la patte quand veux sur le microcontrôleur, car j'utilise le mode bit bang

Code : Tout sélectionner

#DEFINE din_2  LATA,7                 ; RA7 ==> entrée des données de la Led RGB 5050 WS2812B


J'ai pas utilisé de quartz, juste l’oscillateur interne du Pic qui doit être mis au maximum, c'est à dire à 16 Mhz, de plus il faut activer la PLL
ce qui nous fait une cadence de 64 Mhz oops .

Schéma

Schéma.jpg


Le code

Le code ASM a été écrit avec jens file Editor 3.95

Code : Tout sélectionner

;***********************************************************************************************
;***********************************
 "LED RGB 5050 WS2812B" ************************************
;****************
 "Avec ce code vous pouvez commander 255 LED RGB 5050 WS2812B" ****************
;***********************************************************************************************

    Errorlevel-302                        ; Supprime le message "Ensure that bank bits are correct" 

    list p
=18f26K22                       ; processeur utilisé                  
    
#include <p18f26K22.inc>              ; Définitions des constantes

;***********************************************************************************************

;
 CONFIG11H
     CONFIG FOSC 
= INTIO67 
     CONFIG FCMEN 
= OFF 
     CONFIG IESO 
= OFF
; CONFIG2L
     CONFIG PWRTEN 
= OFF 
     CONFIG BOREN 
= OFF 
     CONFIG BORV 
= 190
; CONFIG2H
     CONFIG WDTEN 
= OFF 
     CONFIG  WDTPS 
= 1
; CONFIG3H
     CONFIG CCP2MX 
= PORTC1 
     CONFIG PBADEN 
= OFF
     CONFIG CCP3MX 
= PORTC6
     CONFIG HFOFST 
= OFF
     CONFIG T3CMX 
= PORTC0
     CONFIG P2BMX 
= PORTC0
     CONFIG MCLRE 
= INTMCLR
; CONFIG4L
     CONFIG STVREN 
= OFF 
     CONFIG LVP 
= OFF 
     CONFIG XINST 
= OFF 
     CONFIG DEBUG 
= OFF
; CONFIG5L
     CONFIG CP0 
= OFF 
     CONFIG CP1 
= OFF 
     CONFIG CP2 
= OFF 
     CONFIG CP3 
= OFF
; CONFIG5H
     CONFIG CPB 
= OFF 
     CONFIG CPD 
= OFF
; CONFIG6L
     CONFIG EBTR0 
= OFF
; CONFIG6H
     CONFIG EBTR1 
= OFF
; CONFIG7L
     CONFIG EBTR2 
= OFF
; CONFIG7H
     CONFIG EBTR3 
= OFF

;*************************************** assignations ***************************************** 

#DEFINE clk    LATA,4                 ; RA4 ==> horloge de synchronisation
#DEFINE din_1  LATA,3                 ; RA3 ==> entrée des données pour écran Nokia 
#DEFINE dc     LATA,2                 ; RA2 ==> sélection du mode : commande = 0 , donnée = 1
#DEFINE ce     LATA,1                 ; RA1 ==> activer ou désactiver la transmission
#DEFINE rst    LATA,0                 ; RA0 ==> reset de l'écran
           
#DEFINE din_2  LATA,7                 ; RA7 ==> entrée des données de la Led RGB 5050 WS2812B
                
;****************************** déclaration des variables *************************************


     CBLOCK H'20'                          ; bank0
  
      loop1        
:1
      loop2        
:1
      loop3        
:1
      loop4        
:1
      loop5        
:1                    
      loop6        
:1    
      loop7        
:1
      loop8        
:1      
      loop9        
:1
      loop10       
:1

      rouge        
:1
      vert         
:1
      bleu         
:1

      couleur      
:1
      bits         
:1

      buzzer       
:1
       
      zero         
:1

      tmps         
:1   
      temps        
:1
    
      res8         
:1
      res16        
:1

      unité        
:
      dizaine      
:1
      centaine     
:1         
      millieme     
:1  
      dix_millieme 
:1

      virgule      
:

      phrase       
:

      lettre       
:1  
      lecture      
:1

      somme        
:1       
      reste        
:
      quotient     
:1      
 
      adresse_low  
:
      adresse_hi   
:1

      donner_low   
:1
      donner_hi    
:
 
    ENDC

;************************* "Macro pour se positionner dans un tableau" ************************* 
tableau MACRO adresse

      movlw UPPER
(adresse)                ; 
      movwf TBLPTRU                       
;

      movlw HIGH(adresse)                 ;
      movwf TBLPTRH                       ; 

      movlw LOW
(adresse)                  ;
      movwf TBLPTRL                 
     
    ENDM
;************************** "Macro pour se positionner sur l'écran" **************************** 
locate MACRO hauteur
,largeur

      movlw hauteur                       
; hauteur de l'écran 0 à 5 
      movwf loop8                         ;
                          
      movlw largeur                       ; largeur de l'
écran 0 à 84
      movwf loop9                         
; 
 
      call position                      
;
      
    ENDM
;************************** "Macro pour afficher le texte sur l'écran" **************************** 
print MACRO longueur
,emplacement

      movlw longueur                      
; longueur de la donnée 
      movwf phrase                        
;  
                                          
;  
      movlw emplacement                   
;  
      movwf lecture                       
; emplacement du départ de la donnée à lire

      call affiche_nokia                 
; 

    ENDM

;************** "Macro pour charger une nouvelle valeur sur une, ou des LED RGB" *************** 
rgb MACRO valeur1
,valeur2,valeur3,led_debut,led_fin
        
      movlw valeur1   
      movwf rouge

       movlw valeur2     
      movwf vert

      movlw valeur3   
      movwf bleu
  
      movlw led_debut
      movwf loop1

      movlw led_fin
      movwf loop2

      call led_charge 

      call led_rgb

      ENDM

;************************** "Macro pour éteindre toutes les LED RGB" *************************** 
led_cls MACRO
 
      call vide_bank

      call led_rgb
   
    ENDM

;****************************** adresse de depart après reset **********************************

    ORG H'0'
      bra debut      

;********************************* interruption haute priorité *********************************

    ORG    H'8'
      retfie 

;********************************* interruption basse priorité *********************************

    ORG     H'18'                                  
      retfie 

debut

;***************** "configuration de la bank sélectionné du microcontrôleur" *******************

      movlw B'00000000'          
      movwf BSR

;******************** "configuration de l'oscillateur du microcontrôleur" ********************** 

      movlw B
'01110100'                   ; oscillateur à 16 Mhz, fréquence stable si PLL (16 * 4)= 64 Mhz
    
;  movlw B'01100100'                  ; oscillateur à 8 Mhz, fréquence stable si PLL (* 4) = 32 Mhz
    
;  movlw B'01010010'                  ; oscillateur à 4 Mhz, fréquence stable  
    
;  movlw B'01000010'                  ; oscillateur à 2 Mhz, fréquence stable  
    
;  movlw B'00110010'                  ; oscillateur à 1 Mhz, fréquence stable  

      movwf OSCCON
      
;**************************** configuration du registre OSCTUNE ********************************

      movlw B'01000000'                   ; bit 6 à 1 : PLL * 4
      movwf OSCTUNE                       
; bit 6 à 0 : PLL désactivé
                                         
;*************************** configuration du registre ANSELA ********************************** 

      movlw B
'00100000'                   ; en mode numérique : 7(RA5)
      movwf ANSELA                        ; en mode E/S       : 2(RA0), 3(RA1), 4(RA2), 5(RA3), 

;**************************** configuration du registre ANSELB ********************************* 

      movlw B
'00000000'                   ; en mode numérique : 
      movwf ANSELB                        
; en mode E/S       : 21(RB0), 22(RB1) 23(RB2), 24(RB3), 25(RB4), 26(RB5)  
             
;**************************** configuration du registre ANSELC ********************************* 

      movlw B
'00000000'                   ; en mode numérique :
      movwf ANSELC                        ; en mode E/S       : 13(RC2),  14(RC3), 15(RC4), 16(RC5), 17(RC6), 18(RC7)  

;*************************** configuration du registre ADCON0 ********************************** 

      movlw B
'00000000'                   ; b0 = ADON mise en service le convertiseur 0 = arrêt : 1 = marche   
      movwf ADCON0                        
; b1 = GO/DONE indique la fin de la conversion analogique, et permet de lancer la conversion
                                          
; b2 à b6 = réglage de la sélection du canal

;*************************** configuration du registre ADCON1 ********************************** 

      movlw B
'00000000'                   ; b2 à b3 = 00 : sélection de la tension de reférence, Vref+ = Vss   
      movwf ADCON1                        
; b0 à b1 = 00 : sélection de la tension de reférence, Vref- = Vdd 
                                          
;*************************** configuration du registre ADCON2 ********************************** 

      movlw B
'00110110'                   ; b0 à b2 = FOSC/64
      movwf ADCON2                        
; b3 à b5 = 16 TAG 
                                          
; 
                                          
; b7 = détermine si le résultat de la conversion
                                          
; sera justifié à droite = 1 ou à gauche = 0  

;*********************** "configuration du pwm du microncontrôleur" ****************************

      movlw    D'255'                          ; réglage du "débordement" de TMR2 
      movwf    PR2                             
; PR2 D'255' donc fréquence à 1950 Hz avec prédiviseur à 4

                                  
      movlw B
'00000101'                      ; "prédiviseur à 4" bit zéro à 1, bit un à 0 
      movwf T2CON                         
; "timer on", bit deux à 1 (mise en route du timer2. 0 : arrêt. 1 : marche)
                                          ; "postdiviseur à 1" bit trois à 0, bit quatre à 0, bit cinq à 0, bit six à 0
                                          
; dans registre de contrôle
                                         
      movlw B
'00001100'                   ; "1100" 4 bits mode pwm 
      movwf CCP1CON                       
; "00" 2 bits pour variation du rapport cyclique(RC2) 
      movwf CCP2CON                       
; "00" 2 bits pour variation du rapport cyclique(RC1) 

;***************** configuration des registres TRISA & TRISB & TRISC & TRISE ******************* 

      movlw B
'00100000'                   ; RA0(2), RA1(3), RA2(4), RA3(5), RA4(6), RA5(7), RA6(10), RA7(9)  
      movwf TRISA                         
; 

      movlw B
'11111111'                   ; RB0(21), RB1(22), RB2(23), RB3(24), RB4(25), RB5(26), RB6(27), RB7(28)
      movwf TRISB                         ; 

      movlw B
'00000000'                   ; RC0(11), RC1(12), RC2(13), RC3(14), RC4(15), RC5(16), RC6(17), RC7(18)     
      movwf TRISC                         
; 

      movlw B
'00001000'                   ; RE3(1) 
      movwf TRISE                         
;

                                          ; VSS(8), VSS(19), VDD(20) 

;**************************** configuration du registre INTCON2 ******************************** 

     movlw B
'00000000'                    ; B7 = 0 résistances en service
     movwf INTCON2                        
;

;****************************
 configuration du registre WPUB *********************************** 
                                        
     movlw B
'11111111'                    ; tirage de résistance sur        : RB0(21), RB1(22), RB2(23), RB3(24), RB4(25), RB5(26), RB6(27), RB7(28)  
     movwf WPUB                           
; pas de tirage de résistance sur :

;****************************
 configuration du registre INTCON *********************************      

    movlw B
'00000000'                     ; 
    movwf INTCON                          
; interruption hors service 

;************************************ départ du programme **************************************

      clrf CCPR1L                         ; sortie du pwm(RC2) réglage de la luminosité des leds sur écran 
      clrf CCPR2L                         
; sortie du pwm(RC1) activation du buzer

      clrf PORTA
      clrf PORTB
      clrf PORTC
   
      clrf LATA
      clrf LATB 
      clrf LATC

;***********************************************************************************************
     
      movlw D
'1'                          ; obligé d'avoir 1 pour la décrémentation de 1 caractère
      movwf phrase                        ;
        
      movlw D'
10'                         ; virgule désactivé
      movwf virgule                       ; 
      
      movlw D'
127'                        ;
      movwf buzzer                        ; pwm 1950 Hz à 50% pour le buzzer (RC1)

;**************************** " témoin sonore de mise en fonction" *****************************

      movlw buzzer                        ; témoin sonore activé (RC1)
      movwf CCPR2L

      rcall _100ms                        ; petite pause de 100 ms 

      clrf CCPR2L                         ; arrêt du témoin sonore (RC1)

;**************************** " témoin visuel de mise en fonction" *****************************

      movlw D'
2'                          ; pour 2 clignotements
      movwf loop5

clignote
      bsf LATC,0   
      rcall _1s
      bcf LATC,0   
      rcall _1s
      decfsz loop5,F
      bra clignote

;***********************************************************************************************

      led_cls                             ; macro : pour éteindre toutes les LED RGB

       call _1s                           ; pause de 1 seconde, pour laisser le temps de voir 

;***********************************************************************************************

       call ini_nokia                     ; initiation de l'
écran Nokia 

       call cls_nokia                     
; efface l'écran, et remets le curseur en début de ligne

;-----------------------------------------------------------------------------------------------

      print D'
70',D'0'                    ; macro : longueur de la donnée, emplacement du départ de la donnée à lire 

;*********************************************************************************************** 
boucle
      locate D'
5',D'0'                    ; macro : se placer à la hauteur de l'écran, se placer à la largeur de l'écran

      print D'
14',D'70'                   ; macro : longueur de la donnée, emplacement du départ de la donnée à lire

      rgb D'
255',D'0',D'0',D'1',D'1'      ; macro : valeur du rouge, valeur du vert, valeur du bleu, début LED, fin LED 
                                          ; rouge
       call _1s                           ; pause de 1 seconde, pour laisser le temps de voir 

;-----------------------------------------------------------------------------------------------
       
      locate D'
5',D'0'                    ; macro : se placer à la hauteur de l'écran, se placer à la largeur de l'écran

      print D'
14',D'84'                   ; macro : longueur de la donnée, emplacement du départ de la donnée à lire 

      rgb D'
0',D'255',D'0',D'2',D'2'      ; macro : valeur du rouge, valeur du vert, valeur du bleu, début LED, fin LED 
                                          ; vert 
       call _1s                           ; pause de 1 seconde, pour laisser le temps de voir 

;-----------------------------------------------------------------------------------------------

      locate D'
5',D'0'                    ; macro : se placer à la hauteur de l'écran, se placer à la largeur de l'écran

      print D'
14',D'98'                   ; macro : longueur de la donnée, emplacement du départ de la donnée à lire

      rgb D'
0',D'0',D'255',D'3',D'3'      ; macro : valeur du rouge, valeur du vert, valeur du bleu, début LED, fin LED 
                                          ; bleu
       call _1s                           ; pause de 1 seconde, pour laisser le temps de voir 

;-----------------------------------------------------------------------------------------------

      locate D'
5',D'0'                    ; macro : se placer à la hauteur de l'écran, se placer à la largeur de l'écran

      print D'
14',D'112'                  ; macro : longueur de la donnée, emplacement du départ de la donnée à lire 

      rgb D'
64',D'0',D'128',D'4',D'4'     ; macro : valeur du rouge, valeur du vert, valeur du bleu, début LED, fin LED 
                                          ; violet
       call _1s                           ; pause de 1 seconde, pour laisser le temps de voir 

;-----------------------------------------------------------------------------------------------

      locate D'
5',D'0'                    ; macro : se placer à la hauteur de l'écran, se placer à la largeur de l'écran

      print D'
14',D'126'                  ; macro : longueur de la donnée, emplacement du départ de la donnée à lire 

      rgb D'
255',D'255',D'0',D'5',D'5'    ; macro : valeur du rouge, valeur du vert, valeur du bleu, début LED, fin LED 
                                          ; jaune 
       call _1s                           ; pause de 1 seconde, pour laisser le temps de voir 

;-----------------------------------------------------------------------------------------------
    
      locate D'
5',D'0'                    ; macro : se placer à la hauteur de l'écran, se placer à la largeur de l'écran

      print D'
14',D'154'                  ; macro : longueur de la donnée, emplacement du départ de la donnée à lire 

      rgb D'
0',D'0',D'0',5,5
       call _1s
      rgb D'
255',D'255',D'0',D'5',D'5'         
       call _1s                                      
      rgb D'
0',D'0',D'0',4,4                                                 
       call _1s                        
      rgb D'
64',D'0',D'128',D'4',D'4'
       call _1s                        
      rgb D'
0',D'0',D'0',3,3                                                
       call _1s                        
      rgb D'
0',D'0',D'255',D'3',D'3'
       call _1s                        
      rgb D'
0',D'0',D'0',2,2                                                  
       call _1s                        
      rgb D'
0',D'255',D'0',D'2',D'2'
       call _1s                        
      rgb D'
0',D'0',D'0',1,1                                                 
       call _1s                        
      rgb D'
255',D'0',D'0',D'1',D'1
       call _1s                        

      locate D'
5',D'0'        

      print D'
14',D'140'      

      rgb D'
0',D'0',D'0',D'1',D'5'   
       call _1s                        

      goto boucle                            

;********************* "envoies les données sur les LED RGB 5050 WS2812B" ********************** 
led_rgb
      
      lfsr FSR0,H'
100'                    ; FSR0 pointe sur le début de la bank1    

      movff POSTINC0,couleur              ; charger la première valeur de la bank1
      
      clrf bits                           ;

      bcf din_2                           ;
      
direction
      btfss couleur,7                     
      bra negatif       
      nop
positif                                   ; envoie 1 = 800 ns + 450 ns
      bsf din_2                           ; 802,5 ns = (13x62,5)  
      incf bits,F
      rlncf couleur,F
      btfsc bits,3 
      movff POSTINC0,couleur              ; 875  = (14x62,5)
      btfsc bits,3  
      clrf bits
      nop
      nop
      nop
      nop
      btfsc FSR0H,2                       ; contrôl si fin de bank3 atteint
      return  
      bcf din_2                           ; 437,5ns = (7x62,5) 
      nop
      bra direction

;-----------------------------------------------------------------------------------------------

negatif                                   ; envoie 0 = 400 ns + 850 ns
      bsf din_2                           ; 375ns = (6x62,5)  
      nop
      nop
      nop
      incf bits,F
      rlncf couleur,F
      bcf din_2                           ; 875  = (14x62,5)
      btfsc bits,3  
      movff POSTINC0,couleur              ; 937,5 = (15x62,5)
      btfsc bits,3  
      clrf bits
      nop
      nop
      btfsc FSR0H,2                       ; contrôl si fin de bank3 atteint
      return
      bra direction
                                       
;************************ "mettre toute la bank1, bank2, bank3 à zéro" ************************* 
vide_bank
      lfsr FSR0,H'
100'                    ; FSR0 pointe sur le début de la bank1      

ch_bank
      clrf POSTINC0                       ; efface l'
octet et pointer sur suivants 
      btfss FSR0H
,2                       ; tester si terminé (FSR0 pointe sur H'400') 
      bra ch_bank                         
; non pas fini

      return

;********************* "mise en mémoire des couleus des LED RGB désignés" ********************** 
led_charge 
      movf loop1
,W  
      xorlw D
'0'
      btfsc STATUS,Z
      return

      movf loop2
,W  
      xorlw D
'0'
      btfsc STATUS,Z
      return
       
      movf loop1
,W
      subwf loop2
,F    
      btfsc STATUS
,Z
      bra arranger                        
; égalité des variables 1 seule LED RGB de soliciter 
      btfss STATUS
,C
      return                              
; résultat négatif, aucune LED RGB de soliciter  
               
arranger
      incf loop2
,F

      lfsr FSR0
,H'100'                    ; FSR0 pointe sur le début de la bank1 

      movf loop1
,W
      mullw D
'3'                          ; multiplier W par 3(3x8 = 24 bits), résultat dans PRODH PRODL

      movlw D
'3'
      subwf PRODL,F                       ;(led * 3)-3)

      movf PRODH,W                        ;
      addwf FSR0H,F                       ;  

      movf PRODL
,W                        ; se placer au début de la led demandé 
      addwf FSR0L
,F                       ;         

charge_bank
      movff vert
,POSTINC0
      movff rouge
,POSTINC0
      movff bleu
,POSTINC0

      decfsz loop2
,F  
      bra charge_bank

      return

;********************* "sélection du canal AN4 du convertisseur numérique" ********************* 
canal_AN4
      bcf ADCON0
,6                        ; b6 = CHS4 sélection du canal RA5/AN4
      bcf ADCON0
,5                        ; b5 = CHS3 sélection du canal RA5/AN4 
      bsf ADCON0
,4                        ; b4 = CHS2 sélection du canal RA5/AN4  
      bcf ADCON0
,3                        ; b3 = CHS1 sélection du canal RA5/AN4
      bcf ADCON0
,2                        ; b2 = CHS0 sélection du canal RA5/AN4

      return    

;*********************************************************************************************** 
scan_numérique
      bsf ADCON0
,ADON                     ; on lance l’acquisition (charge du condensateur)

      nop
      nop
      nop                                 
; pause, temps de charge du condensateur
   
      bsf ADCON0
,GO                       ; lancer la conversion A/D

      btfsc ADCON0
,GO                     ; si le bit GO est à 1 on va à la ligne 1        
      bra 
$-D'2'                          ; convertion n'est pas terminer     

      bcf ADCON0,ADON                     ; fin de conversion, éteindre convertisseur

      movff ADRESH,somme                  ; transférer le résultat dans la variable "somme"

      return

;******************* "initialisation de l'
écran Nokia en mode SPI bit bang" ********************     
ini_nokia
      bsf ce                              ; arrêt  
      nop
      bcf rst                             ; 
      nop
      bsf rst                             ; remise à zéro
;-----------------------------------------------------------------------------------------------                                         
      movlw B'00100001'                   ; commandes étendues du lcd (0x21)
      movwf loop8      
      call spi_command 
;-----------------------------------------------------------------------------------------------
      movlw B'10111001'                   ; réglage du contraste du lcd (0xB1) à (0xBF)
      movwf loop8
      call spi_command
;-----------------------------------------------------------------------------------------------
      movlw B'00100000'                   ; Valider la modification (0x20)
      movwf loop8
      call spi_command
;-----------------------------------------------------------------------------------------------
      movlw B'00001100'                   ; vidéo en mode normal 0x0C ou 0x0D pour mode négatif
      movwf loop8
      rcall spi_command                
;-----------------------------------------------------------------------------------------------               
      movlw B'00000001'                   ; effacer l'écran
      movwf loop8
      rcall spi_command  
;-----------------------------------------------------------------------------------------------

      return

;************************ "
affiche la lettre ou le texte sélectionné" ************************** 
affiche_nokia    
      
      tableau info                        ; macro : qui permets de se positionner à l'adresse demandé

      movf lecture,W                      ;
      addwf TBLPTRL,F                     ;                   

      incf lecture,F                      ; lecture pour le prochain passage 

      tblrd*                              ; effectue la lecture de l’octet pointé par TBLPTR 
                      
      movf TABLAT,W                       ; transfére le caractère récupéredans TABLAT vers W

lettre_nokia                        
      movwf lettre                        ; transfére le caractère récupére dans "
lettre"
      mullw D'5'                          ; multiplier W par 5, résultat dans PRODH PRODL                                        
    
      movlw D'5'                          ; 5 passages pour créer un caractère
      movwf loop5

      tableau alphabet                    ; macro  : qui permets de se positionner à l'adresse demandé
      
      movf PRODH,W                        ;
      addwf TBLPTRH,F                     ;  

      movf PRODL,W                        ;
      addwf TBLPTRL,F                     ;                                
ret2
      tblrd*+                             ; effectue la lecture, et ensuite incrémente TBLPTR

      movff TABLAT,loop8                  ; transfére la donnée récupére dans "
loop8"
      rcall spi_données                   ;

      decfsz loop5,F                      ;
      bra ret2                            ;

      movlw B'00000000'                   ; avance d'un pixel sur la largeur  
      movwf loop8
      rcall spi_données

      decfsz phrase,F                     ; "
phrase" est la longueur du texte
      bra affiche_nokia                   ; 

      incf phrase,F                       ; préparation au cas ou il faudrait lire un caractére  

      return 

;*********************"
efface l'écran & position le curseur au début" ************************** 
cls_nokia

      movlw D'
2'                          ; pour effacement complet de l'écran, soit 504 octets
      movwf loop1

      movlw D
'248'
      movwf loop2

      locate 0
,0                          ; macro de positionnement hauteur, largeur                                            
cls
      movlw B
'00000000' 
      movwf loop8
      rcall spi_données                   
; effacer les données existantes

      decfsz loop2
,F      
      bra cls
      decfsz loop1
,F      
      bra cls
      
      locate 0
,0                          ; macro de positionnement hauteur, largeur   
     
      return

;*******************************"Ecran Nokia 5110, 504 octets" ********************************* 
pixel_nokia 
      movlw D
'2'                          ; pour la lecture complet de l'écran, soit 504 octets
      movwf loop1                         ;

      movlw D'
248'                        ; 
      movwf loop2

lire_graphique
      tblrd*+                             ; effectue la lecture, et ensuite incrémente TBLPTR

      movff TABLAT,loop8                  ; transfére la donnée récupére dans "loop8"
      rcall spi_données                   ;

      decfsz loop2,F
      bra lire_graphique
      decfsz loop1,F
      bra lire_graphique

      return

;*********************************************************************************************** 
lire_bargraphe
      clrf quotient
      clrf reste          

diviser
      movlw D'
3'       
      subwf somme,F 
      btfsc STATUS,Z
      bra difference
      btfsc STATUS,C 
      bra retire
      bra difference
retire
      incf quotient,F
      bra diviser

difference      
      movf quotient,W
      sublw D'
84'
      movwf reste
     
      movf quotient,W      
      xorlw D'
0'
      btfsc STATUS,Z
      bra bar_blanc                                                  

bar_noir  
      movlw B'
01111111
      movwf loop8 
      rcall spi_données                   ; ajouter les données
    
      decfsz quotient,F
      bra bar_noir

      movf reste,W      
      xorlw D'
0'
      btfsc STATUS,Z
      return

bar_blanc      
      movlw B'
00000000
      movwf loop8
      rcall spi_données                   ; effacer les données existantes 
     
      decfsz reste,F
      bra bar_blanc

      return

;*********************************************************************************************** 
spi_command
      bcf dc                              ; DC = 0  en mode commande
      bra envoie                          

;*********************************************************************************************** 
spi_données
      bsf dc                              ; DC = 1 en mode donnée
      bra envoie                          ;     

;*********************************************************************************************** 
envoie
      bcf ce                              ; marche

      movlw D'
8'                          ; envoie de 8 bits 
      movwf loop7
ret3
      btfss loop8,7                       ; 1 lecture sur le bit 7
      bra suite_1
      bcf clk                             ; 
      bsf din_1                           ; envoie 1
      bsf clk                             ;
      bra suite_2
suite_1
      bcf clk                             ; 
      bcf din_1                           ; envoie 0
      bsf clk                             ; 
suite_2
      rlncf loop8,F                       ; rotation des bits à gauche sans carry
      decfsz loop7,F
      bra ret3

      bcf clk                             ; fin de transmission
      bsf ce                              ; arrét

      return

;************************************ "position de y et x" ************************************* 
position                                   
      bsf loop8,6                         ; y = 0, à 5 = B'
01000 Y2 Y1 Y0' hauteur de l'écran
      rcall spi_command                   
; 

      bsf loop9
,7                         ; x = 0, à 83 = B'1 X6 X5 X4 X3 X2 X1 X0' largeur de l'écran
                                          ;  
      movf loop9,W                        ;
      movwf loop8                         ;    
      rcall spi_command                   ;

      return

;************************************** "convertion" ******************************************* 
conversion
           
      clrf unité                  
      clrf dizaine              
      clrf centaine             
      clrf millieme             
      clrf dix_millieme         

; "16 bits"

b16_7
      btfss res16,7
      goto b16_6

      movlw D'
3'                          ; 32768  
      addwf dix_millieme,F
      movlw D'
2'                          ;  2768  
      addwf millieme,F
      movlw D'
7'                          ;   768
      addwf centaine,F                 
      movlw D'
6'                          ;    68
      addwf dizaine,F                 
      movlw D'
8'                          ;     8
      addwf unité,F                 

b16_6
      btfss res16,6
      goto b16_5

      movlw D'
1'                          ; 16384  
      addwf dix_millieme,F
      movlw D'
6'                          ;  6384  
      addwf millieme,F
      movlw D'
3'                          ;   384
      addwf centaine,F                 
      movlw D'
8'                          ;    84
      addwf dizaine,F                 
      movlw D'
4'                          ;     4
      addwf unité,F                 

b16_5
      btfss res16,5
      goto b16_4

      movlw D'
8'                          ; 8192  
      addwf millieme,F
      movlw D'
1'                          ;  192
      addwf centaine,F                 
      movlw D'
9'                          ;   92
      addwf dizaine,F                 
      movlw D'
2'                          ;    2
      addwf unité,F                 

b16_4
      btfss res16,4
      goto b16_3            

      movlw D'
4'                          ; 4096  
      addwf millieme,F
      movlw D'
0'                          ;  096
      addwf centaine,F                 
      movlw D'
9'                          ;   96
      addwf dizaine,F                 
      movlw D'
6'                          ;    6
      addwf unité,F                 

b16_3
      btfss res16,3
      goto b16_2

      movlw D'
2'                          ; 2048  
      addwf millieme,F
      movlw D'
0'                          ;  048
      addwf centaine,F                 
      movlw D'
4'                          ;   48
      addwf dizaine,F                 
      movlw D'
8'                          ;    8
      addwf unité,F                 

b16_2
      btfss res16,2
      goto b16_1

      movlw D'
1'                          ; 1024  
      addwf millieme,F
      movlw D'
0'                          ;  024
      addwf centaine,F                 
      movlw D'
2'                          ;   24
      addwf dizaine,F                 
      movlw D'
4'                          ;    4
      addwf unité,F                 

b16_1
      btfss res16,1
      goto b16_0

      movlw D'
5'                          ;  512
      addwf centaine,F                 
      movlw D'
1'                          ;   12
      addwf dizaine,F                 
      movlw D'
2'                          ;    2
      addwf unité,F                 

b16_0
      btfss res16,0
      goto b8_7

      movlw D'
2'                          ;  256
      addwf centaine,F                 
      movlw D'
5'                          ;   56
      addwf dizaine,F                 
      movlw D'
6'                          ;    6
      addwf unité,F                 

;***********************************************************************************************

; "8 bits"

b8_7
      btfss res8,7
      goto b8_6

      movlw D'
1'                          ;  128
      addwf centaine,F                 
      movlw D'
2'                          ;   28
      addwf dizaine,F                 
      movlw D'
8'                          ;    8
      addwf unité,F                 

b8_6
      btfss res8,6
      goto b8_5            

      movlw D'
6'                          ;   64
      addwf dizaine,F                 
      movlw D'
4'                          ;    4
      addwf unité,F                 

b8_5
      btfss res8,5
      goto b8_4

      movlw D'
3'                          ;   32
      addwf dizaine,F                 
      movlw D'
2'                          ;    2
      addwf unité,F                 

b8_4
      btfss res8,4
      goto b8_3            

      movlw D'
1'                          ;   16
      addwf dizaine,F                    
      movlw D'
6'                          ;    6
      addwf unité,F                 

b8_3
      movlw B'
00001111'                   ; 8, 4, 2, 1
      andwf res8,W    
    
      addwf unité,F     

;-----------------------------------------------------------------------------------------------

      movlw D'
5'                          ; 5 variables à traiter
      movwf loop6
       
      lfsr FSR0,unité-1                   ; pointer  à l'
adresse de la variable "unité-1" 

assembler
      incf FSR0L
,F                        ; variable suivante 
      movf INDF0
,W                        ; récupérer la valeur dans W 
      movwf tmps                          
; transmettre dans la variable "tmps"
 
      incf FSR0L
,F                        ; variable suivante
      movf INDF0
,W                        ; récupérer la valeur dans W 
      movwf temps                         
; transmettre dans la variable "temps"

;***********************************************************************************************
tr0      
      movf tmps
,W
      sublw D
'10'                         ; retir 10 de W
      btfsc STATUS
,Z                      ; 
      goto tr1                            
; 
      btfss STATUS
,C                      ; 
      goto tr1                            
; 
      goto tr2                            
; 
tr1
      movlw D
'10'                         ;
      subwf tmps,F                        ;
      incf temps,F                        ; 
      bra tr0                       

;*********************************************************************************************** 
tr2
      movf temps
,W
      movwf INDF0                         
; nouvelle valeur à cette adresse

      decf FSR0L
,F                        
      movf tmps
,W      
      movwf INDF0                         
; nouvelle valeur à cette adresse

      movlw D
'48'                         ; convertir en format ASCII 
      addwf INDF0
,F                       

      decfsz loop6
,F                      ; variable suivante
      goto assembler                
      
      return

;*********************************************************************************************** 
supprimer_zero

; "suprime les zéros qui sont à gauches" 
     
      movlw D
'5'                        ; 5 variables à traiter
      movwf loop6    
    
      lfsr FSR0
,dix_millieme            ; pointer à l'adresse de la variable "dix_millieme"     

cherche_zero
      movf INDF0,W        
      xorlw D'
48'
      btfss STATUS,Z     
      goto imprime_ecran
      decf FSR0L,F
      decfsz loop6,F
      goto cherche_zero

      movlw '
0'                           ; tout est à zéro
      rcall lettre_nokia
      return 

; "écrit les données sur l'
écran"

imprime_ecran
      movf loop6,W
      xorwf virgule,W                     ; emplacement de la virgule si activé 
      btfss STATUS,Z                      ;
      goto imprime_2

      movlw '.'                           ; on mets la virgule
      rcall lettre_nokia                  ; affiche à l'écran

imprime_2
      movf INDF0,W          
      rcall lettre_nokia            
      decf FSR0L,F
      decfsz loop6,F
      goto imprime_ecran

      return

;****************************** "
pour écrit dans l'eeprom" ************************************* 
ecriture_eeprom
      movf adresse_hi,W                   ; adresse du poid fort
      movwf EEADRH                        ;

      movf adresse_low,W                  ; adresse du poid faible
      movwf EEADR                         ; 

      movf donner_low,W                   ;
      movwf EEDATA                        ; écriture de la donnée
 
      bcf EECON1,EEPGD                    ; préparation à l'
autorisation 
      bcf EECON1
,CFGS                     ; access eeprom

      bsf EECON1
,WREN                     ; Enable writes   
 
      bcf INTCON
,GIE                      ; couper les interruptions

      btfsc INTCON
,GIE                    ; contrôl si les interruptions sont bien coupés
      bra 
$-D'2'                          ; remonte à la ligne 2 jusqu'a coupures des interruptions 

      movlw H'
55'                         ; séquence spécifique (c'est comme ça, il faut le savoir)
      movwf EECON2                        ; séquence spécifique
      movlw H
'AA'                         ; séquence spécifique
      movwf EECON2                        
; séquence spécifique

      bsf EECON1
,WR                       ; lance une opération d'écriture

      btfsc    EECON1,WR                      ; on attend que l'
operation d'ecriture soit finie (de l'ordre de la ms
      bra 
$-D'2'                          ; remonte à la ligne 2 jusqu'a fin d'écriture

      bcf EECON1
, WREN                    ; interdiction de l'écriture

      return

;******************************** "pour lire dans l'
eeprom" ************************************ 
lecture_eeprom
      movf adresse_hi,W                   ; adresse du poid fort
      movwf EEADRH                        ;

      movf adresse_low,W                  ; adresse du poid faible
      movwf EEADR                         ; 

      bcf EECON1,EEPGD                    ; préparation à la lecture
      bcf EECON1,CFGS                     ; access EEPROM
      bsf EECON1,RD                       ; lecture de l'EEPROM

      movf EEDATA,W                       ; la valeur lue dans l'éeprom est placée dans W 
      movwf donner_low                    ; récupération du résultat  

      return

;************************* "
pause de 3 secondes pour horloge de 64 Mhz" ************************       
_3s 
      movlw D'4'
      movwf loop4
temps_3
      rcall _1s
      decfsz loop4,F
      bra temps_3

      return

;************************* "
pause de 1 seconde pour horloge de 64 Mhz" *************************       
_1s 
      movlw D'0'
      movwf loop1
      movlw D'43'
      movwf loop2
      movlw D'82'
      movwf loop3

      decfsz loop1,F
      bra $-D'2'
      decfsz loop2
      bra $-D'6'
      decfsz loop3,F
      bra $-D'10'

      return

;********************* "
pause de 100 millisecondes pour horloge de 64 Mhz" ********************** 
_100ms
      movlw D'228'
      movwf loop1
      movlw D'30'
      movwf loop2
      movlw D'9'
      movwf loop3

      decfsz loop1,F
      bra $-D'2'
      decfsz loop2,F
      bra $-D'6'
      decfsz loop3,F
      bra $-D'10'
   
      return

;********************** "
pause de 10 millisecondes pour horloge de 64 Mhz" **********************
_10ms
      movlw D'201'
      movwf loop1
      movlw D'208'
      movwf loop2

      decfsz loop1,F
      bra $-D'2'
      decfsz loop2,F
      bra $-D'6'

      return

;********************** "
pause de 50 microsecondes pour horloge de 64 Mhz" **********************
_50µs
      movlw D'8'
      movwf loop1
      movlw D'2'
      movwf loop2

      decfsz loop1,F
      bra $-D'2'
      decfsz loop2,F
      bra $-D'6'
      
      nop

      return

;*********************************************************************************************** 
;************************* "
affichage des phrases, 255 octets maximum" *************************
;*********************************************************************************************** 
    ORG H'8E00' 
                    
info
       db "
 LED RGB 5050 "                ; 1
       db "
   WS2812B    "                ; 2
       db "
 Clignotement "                ; 3
       db "
des 3 couleurs"                ; 4
       db "
   primaire   "                ; 5 
       db "
    Rouge     "                ; 6
       db "
     Vert     "                ; 7 
       db "
     Bleu     "                ; 8
       db "
    violet    "                ; 9
       db "
    Jaune     "                ; 10
       db "
    ‚teint    "                ; 11  
       db "
  Bargraphe   "                ; 12

;***********************************************************************************************
;***************************** "
table des caractères ASCII" ************************************
;*********************************************************************************************** 
    ORG H'9000'

alphabet                           
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5F,0x00,0x00,0x00,0x07,0x00,0x07,0x00,0x14
     db 0x7F,0x14,0x7F,0x14,0x24,0x2A,0x7F,0x2A,0x12,0x26,0x16,0x08,0x34,0x32,0x76,0x49
     db 0x55,0x22,0x50,0x00,0x00,0x05,0x03,0x00,0x00,0x1C,0x22,0x41,0x00,0x00,0x41,0x22
     db 0x1C,0x00,0x14,0x08,0x3E,0x08,0x14,0x08,0x08,0x3E,0x08,0x08,0x00,0x50,0x30,0x00
     db 0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x60,0x60,0x00,0x00,0x20,0x10,0x08,0x04,0x02
     db 0x3E,0x51,0x49,0x45,0x3E,0x00,0x42,0x7F,0x40,0x00,0x42,0x61,0x51,0x49,0x46,0x21
     db 0x41,0x45,0x4B,0x31,0x18,0x14,0x12,0x7F,0x10,0x27,0x45,0x45,0x45,0x39,0x3C,0x4A
     db 0x49,0x49,0x30,0x01,0x01,0x79,0x05,0x03,0x36,0x49,0x49,0x49,0x36,0x06,0x49,0x49
     db 0x29,0x1E,0x00,0x36,0x36,0x00,0x00,0x00,0x56,0x36,0x00,0x00,0x00,0x08,0x14,0x22
     db 0x41,0x14,0x14,0x14,0x14,0x14,0x41,0x22,0x14,0x08,0x00,0x02,0x01,0x51,0x09,0x06
     db 0x3E,0x41,0x49,0x55,0x5E,0x7E,0x11,0x11,0x11,0x7E,0x7F,0x49,0x49,0x49,0x36,0x3E
     db 0x41,0x41,0x41,0x22,0x7F,0x41,0x41,0x22,0x1C,0x7F,0x49,0x49,0x49,0x41,0x7F,0x09
     db 0x09,0x09,0x01,0x3E,0x41,0x49,0x49,0x3A,0x7F,0x08,0x08,0x08,0x7F,0x00,0x41,0x7F
     db 0x41,0x00,0x20,0x41,0x41,0x3F,0x00,0x7F,0x08,0x14,0x22,0x41,0x7F,0x40,0x40,0x40
     db 0x40,0x7F,0x02,0x0C,0x02,0x7F,0x7F,0x04,0x08,0x10,0x7F,0x3E,0x41,0x41,0x41,0x3E
     db 0x7F,0x09,0x09,0x09,0x06,0x3E,0x41,0x51,0x21,0x5E,0x7F,0x09,0x19,0x29,0x46,0x46
     db 0x49,0x49,0x49,0x31,0x01,0x01,0x7F,0x01,0x01,0x3F,0x40,0x40,0x40,0x3F,0x1F,0x20
     db 0x40,0x20,0x1F,0x3F,0x40,0x3C,0x40,0x3F,0x63,0x14,0x08,0x14,0x63,0x07,0x08,0x70
     db 0x08,0x07,0x61,0x51,0x49,0x45,0x43,0x00,0x7F,0x41,0x41,0x00,0x02,0x04,0x08,0x10
     db 0x20,0x00,0x41,0x41,0x7F,0x00,0x04,0x02,0x01,0x02,0x04,0x40,0x40,0x40,0x40,0x40
     db 0x00,0x01,0x02,0x04,0x00,0x20,0x54,0x54,0x54,0x78,0x7F,0x48,0x44,0x44,0x38,0x38
     db 0x44,0x44,0x44,0x20,0x38,0x44,0x44,0x48,0x7F,0x38,0x54,0x54,0x54,0x18,0x08,0x7E
     db 0x09,0x01,0x02,0x08,0x54,0x54,0x54,0x3C,0x7F,0x08,0x04,0x04,0x78,0x00,0x44,0x7D
     db 0x40,0x00,0x20,0x40,0x44,0x3D,0x00,0x7F,0x10,0x28,0x44,0x00,0x00,0x41,0x7F,0x40
     db 0x00,0x7C,0x04,0x18,0x04,0x78,0x7C,0x08,0x04,0x04,0x78,0x38,0x44,0x44,0x44,0x38
     db 0x7C,0x14,0x14,0x14,0x08,0x08,0x14,0x14,0x18,0x7C,0x7C,0x08,0x04,0x04,0x08,0x48
     db 0x54,0x54,0x54,0x20,0x04,0x3F,0x44,0x40,0x20,0x3C,0x40,0x40,0x20,0x7C,0x1C,0x20
     db 0x40,0x20,0x1C,0x3C,0x40,0x38,0x40,0x3C,0x44,0x28,0x10,0x28,0x44,0x0C,0x50,0x50
     db 0x50,0x3C,0x44,0x64,0x54,0x4C,0x44,0x00,0x08,0x36,0x41,0x00,0x00,0x00,0x7F,0x00
     db 0x00,0x00,0x41,0x36,0x08,0x00,0x08,0x08,0x2A,0x1C,0x08,0x08,0x1C,0x2A,0x08,0x08
     db 0x1E,0xA1,0xE1,0x21,0x10,0x3D,0x40,0x40,0x20,0x7D,0x38,0x56,0x55,0x54,0x18,0x20
     db 0x56,0x55,0x56,0x78,0x20,0x55,0x54,0x55,0x78,0x20,0x54,0x55,0x56,0x78,0x20,0x54
     db 0x55,0x54,0x78,0x0E,0x51,0x71,0x11,0x08,0x38,0x56,0x55,0x56,0x18,0x38,0x55,0x54
     db 0x55,0x18,0x38,0x54,0x55,0x56,0x18,0x00,0x45,0x7C,0x41,0x00,0x00,0x46,0x7D,0x42
     db 0x00,0x00,0x45,0x7E,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38
     db 0x46,0x45,0x46,0x38,0x38,0x45,0x44,0x45,0x38,0x38,0x45,0x46,0x44,0x38,0x3C,0x42
     db 0x41,0x22,0x7C,0x3C,0x40,0x41,0x22,0x7C,0x0C,0x51,0x50,0x51,0x3C,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x20,0x54,0x56,0x55,0x78,0x00,0x46,0x7D,0x40,0x00,0x38,0x44,0x46,0x45,0x38,0x3C
     db 0x42,0x41,0x20,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x55,0x00,0x55,0x00,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x15,0x16,0x7C,0x16,0x15,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0xF8,0x54,0x54,0x54,0x28,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC,0x40
     db 0x40,0x20,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
     db 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x05,0x02,0x00,0x00,0x38,0x44,0x48
     db 0x30,0x4C,0xF8,0x54,0x54,0x54,0x28,0x38,0x44,0x4C,0x54,0x24,0x28,0x54,0x54,0x44
     db 0x20,0x58,0x64,0x04,0x64,0x58,0x44,0x3C,0x04,0x7C,0x44,0x63,0x55,0x49,0x41,0x41

;*********************************************************************************************** 
;**************************"
affichage d'un graphique N°1" **************************************
;*********************************************************************************************** 
    ORG H'
EEEE'

graphique_1         

;*********************************************************************************************** 
;**************************"affichage d'
un graphique N°2" **************************************
;*********************************************************************************************** 
    ORG H'F0EE'

graphique_2         
;*********************************************************************************************** 
;**************************"
affichage d'un graphique N°3" **************************************
;*********************************************************************************************** 
    ORG H'
F2EE'
   
graphique_3

;*********************************************************************************************** 
;**************************"affichage d'
un graphique N°4" **************************************
;*********************************************************************************************** 
    ORG H'F4EE'
   
graphique_4

;*********************************************************************************************** 
;**************************"
affichage d'un graphique N°5" **************************************
;*********************************************************************************************** 
    ORG H'
F6EE'

graphique_5


    End



Fichier à mettre dans le Pic
WS2812B(Hex).zip

Fichier code
WS2812B(Code).zip

Utilitaire pour trouver les couleurs
Rvb.zip

==> ==> ==> ==> ==> ==> ==> ==> ==> ==> ==> Les fichiers qui sont joints, correspondes aux deuxièmes test


Premier test, avec allumage d'une seule Led RGB WS2812B.

https://youtu.be/RrcsYzlkw_c

Deuxième test avec une série de Led RGB WS2812B, paramétrable indépendant l'une de l'autre, sans modification des autres

https://youtu.be/VyeS7dgyE1A



==> A+
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Modifié en dernier par Temps-x le dim. 14 juin 2020 12:41, modifié 31 fois.
:roll: Les requins, c'est comme le langage ASM, c'est le sommet de la chaîne alimentaire. :wink:

Led RGB 5050 WS2812B
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#2 Message par paulfjujo » mer. 11 sept. 2019 16:00

bonjour Temps-X et à tous,


:+1: un tres beau départ !

Où as-tu commandé tes Leds ?

Temps-X a écrit : Reste à adapté le code pour toute une série de Led RGB 5050 WS2812B


.. pour une version avec 60 leds ?

Ce serait effectivement plus facile de cabler 60 leds WS2812 , en serie pour le signal
et un bus d'alim circulaire , que 60 leds rouges , sur des sorties CD4015
:sifflotte: si tu vois ou je veux en venir !

car bien que l'anneau à 60 led RGB soit deja tout fait, et necessitant que 3 fils seulement ,
le diametre de 170mm est trop petit pour une future horloge avec des afficheurs 7segments de 2,5" ou 4".
au centre.

Q: tes leds à droite, elles te servent à debugger ?
Aide toi, le ciel ou FantasPic t'aidera

Led RGB 5050 WS2812B
Temps-x
Avatar de l’utilisateur
Expert
Expert
Messages : 2595
Enregistré en : juillet 2016
Localisation : Terre

#3 Message par Temps-x » mer. 11 sept. 2019 19:08

Bonsoir paulfjujo, et tout le forum,

paulfjujo a écrit :Source du message Où as-tu commandé tes Leds ?

J'ai commandé mes Led RGB 5050 WS2812B ICI

paulfjujo a écrit :Source du message pour une version avec 60 leds ?


Je viens de finir aujourd'hui, une version pour Euh ... 255 Led RGB 5050 WS2812B, cette version à été mis dans le post #1 avec fichier code, et fichier compilé.

J'ai cru que je n'y arriverais pas, pouah.... , le plus embêtant c'est les temps qui sont très court.

J'explique un peu, malgré mon imperfection en grammaire, j'ai créé une MACRO pour allumer n'importe quelle LED seule ou plusieurs avec couleur au choix

Par exemple : RGB D'255',D'0',D'0',D'3',D'6'

Les trois premier chiffre sont la couleur, Rouge, Vert, bleu le second chiffre est le début de la LED, et le dernier c'est la fin de ta led.

Ce qui donne pour cette exemple : LED numéro 3 en rouge jusqu’à la LED 6, ça ne modifie pas la couleur des autres LED, seule les LED désignés seront affectés.

J'ai aussi créé une MACRO pour éteindre toute les LED .

A titre d'information, il existe 4 types de LED RGB

1) RGB 5050 celle ou il y a aucun circuit, avec 3 LED RVB intégrés dans une seule
2) RGB 5050 WS2801(WS2811) celle ou la puce est soudée sur le circuit avec 3 résistances
3) RGB 5050 WS2812 tension séparer entre la puce et la LED RVB
4) RGB 5050 WS2812B tout est intégrés dans la LED(protection contre les inversions de sens), on peut la reconnaitre car elle a 4 pattes, fonction en 5 volts uniquement, c'est celle que j'ai.

paulfjujo a écrit :Source du message Ce serait effectivement plus facile de cabler 60 leds WS2812 , en serie pour le signal
et un bus d'alim circulaire , que 60 leds rouges , sur des sorties CD4015
:sifflotte: si tu vois ou je veux en venir !


J'ai été voir sur ton site quand j'ai commencé mon étude sur les Led RGB 5050 WS2812B, et j'ai vu ce que tu as fait, :bravo: ta vraiment de la patience, et de la compassion pour ce que tu fais, oops câbler autant de CD4015.....avec toutes ces leds... pour les intéressés voir ICI

:sifflotte: j'ai rien à dire j'ai fait pire que toi, mais bon .......

paulfjujo a écrit :Source du message Q: tes leds à droite, elles te servent à debugger ?


Oui, et, .. elles sont Indispensables pour voir si le microcontrôleur n'est pas planté, très utile, si les deux clignotements se fait pas au démarrage sur la LED rouge, c'est qu'il y a un problème, de plus ça me donne un top départ :wink:

Les autres LED ne sont pas utilisés, c'est au cas ou j'en aurais besoin, j'ai juste un fils à mettre sur la sortie de la patte du microcontrôleur, fait avec un reste de PCB.

J'ai mis une nouvelle vidéo en post #1, bas de la page, tu pourras te rendre compte.

:roll: Je recherche un cobaye pour test de mon code, pour 255 Led RGB 5050 WS2812B :sifflotte:


==> A+
:roll: Les requins, c'est comme le langage ASM, c'est le sommet de la chaîne alimentaire. :wink:

Led RGB 5050 WS2812B
cyril13110
Confirmé
Confirmé
Messages : 724
Âge : 41
Enregistré en : avril 2016
Localisation : 13

#4 Message par cyril13110 » jeu. 14 mai 2020 23:19

Temps-x a écrit :On peut choisir la patte quand veux sur le microcontrôleur, car j'utilise le mode bit bang


Bonsoir Temps-x et bonsoir à tous,

Je m'intéresse à ces leds, j'ai en projet de faire une déco de Noël avec en forme d'étoile.
Je viens de recevoir mes leds et du coup je regarde de plus prêt la programmation.
Si j'en crois la description le mode bit bang n'est rien d'autre qu'une reconstitution de la forme du signal nécessaire pour faire fonctionner les leds ?
J'ai un peut fait des recherche, j'ai bien vue les 2 solutions mais jai quelques soussi de capatage sur le globale.
J'ai bien trouvé les 2 solutions mais la solution avec la communication SPI me semblais la plus facile jusqu'à l'équation logique car je ne vois pas où elle se trouve.
Est ce que ça se fait dans le code ? Ou cest des pics spécifiques qui le font ?
Et le mode bit bang qui semble être une reconstitution de signal mais j'ai du mal à voir comment ça fonctionne vraiment.
Déjà j'ai compris qu'il fallait un pic qui pédale vite pour arriver à générer le signal à 800Khz.
Je vais laisser tomber le 18F2550 et voir ce que j'ai d'autre dans mes tiroirs.

Merci d'avance pour tes lumières

Led RGB 5050 WS2812B
Temps-x
Avatar de l’utilisateur
Expert
Expert
Messages : 2595
Enregistré en : juillet 2016
Localisation : Terre

#5 Message par Temps-x » ven. 15 mai 2020 03:05

Bonsoir cyril13110, et tout le forum,

cyril13110 a écrit :Source du message Si j'en crois la description le mode bit bang n'est rien d'autre qu'une reconstitution de la forme du signal nécessaire pour faire fonctionner les leds ?


Oui c'est exacte, et je te conseille pour ces leds de choisir cette option (mode bit bang) de plus ça le rends compatible pour tout les Pic ayant une vitesse de 64 Mhz

Maintenant à toi de voir, si tu choisis cette option tu seras obliger de passer par ASM, car il faut que ça soit très rapide pour que la LED en prendre compte.

Mon code devrait fonctionner pour 255 leds (mais j'ai pas pu tester, car j'ai pas 255 leds en ma procession) j'ai fait des macros pour le rendre moins pénible sur le langage ASM.

Vue la vitesse du protocole imposé par ces leds il faut écrire en sdram, puis envoyer tous ça d'un seule coup,

Il faut que ton Pic tourne au moins à 64Mhz, de plus ton pic doit avoir une grande capacité de mémoire sdram d'au moins 1000 octets pour 255 leds.

cyril13110 a écrit :Source du message Est ce que ça se fait dans le code ? Ou c'est des pics spécifiques qui le font ?


Non c'est pas des pic spécifique qui le font, tout est dans le code, voici la routine qui le fait.

Code : Tout sélectionner

;********************* "envoies les données sur les LED RGB 5050 WS2812B" ********************** 
led_rgb
      
      lfsr FSR0
,H'100'                    ; FSR0 pointe sur le début de la bank1    

      movff POSTINC0
,couleur              ; charger la première valeur de la bank1
      
      clrf bits                           
;

      bcf din_2                           ;
      
direction
      btfss couleur
,7                     
      bra negatif       
      nop
positif                                   
; envoie 1 = 800 ns + 450 ns
      bsf din_2                           
; 802,5 ns = (13x62,5)  
      incf bits
,F
      rlncf couleur
,F
      btfsc bits
,
      movff POSTINC0
,couleur              ; 875  = (14x62,5)
      btfsc bits,3  
      clrf bits
      nop
      nop
      nop
      nop
      btfsc FSR0H
,2                       ; contrôl si fin de bank3 atteint
      return  
      bcf din_2                           
; 437,5ns = (7x62,5) 
      nop
      bra direction

;-----------------------------------------------------------------------------------------------

negatif                                   ; envoie 0 = 400 ns + 850 ns
      bsf din_2                           
; 375ns = (6x62,5)  
      nop
      nop
      nop
      incf bits
,F
      rlncf couleur
,F
      bcf din_2                           
; 875  = (14x62,5)
      btfsc bits,3  
      movff POSTINC0
,couleur              ; 937,= (15x62,5)
      btfsc bits,3  
      clrf bits
      nop
      nop
      btfsc FSR0H
,2                       ; contrôl si fin de bank3 atteint
      return
      bra direction



cyril13110 a écrit :Source du message Et le mode bit bang qui semble être une reconstitution de signal mais j'ai du mal à voir comment ça fonctionne vraiment.


Bien sur c'est bien une reconstitution du signal, je l'utilise de plus en plus, car ça me laisse la place pour le mode I²C

J'ai commandé 100 Led RGB 5050 WS2812B pour 8 euros, par contre attention, 0,3 watts par LED quand elles sont au maximum de leurs puissance (pour 100 leds ça te fait 6 Ampères)

Si tu veux un coup de main, pas de problème, je te conseille de partir sur un Pic comme Pic18F26K22 (28 pattes) ou Pic18F46k22 (40 pattes)


==> A+
Modifié en dernier par Temps-x le ven. 15 mai 2020 13:34, modifié 1 fois.
:roll: Les requins, c'est comme le langage ASM, c'est le sommet de la chaîne alimentaire. :wink:

Led RGB 5050 WS2812B
cyril13110
Confirmé
Confirmé
Messages : 724
Âge : 41
Enregistré en : avril 2016
Localisation : 13

#6 Message par cyril13110 » ven. 15 mai 2020 10:02

Bonjour à tous,

Merci pour tes explications, je vais aller voir dans ma réserve les pics montant à 64Mhz.
Il va falloir du coup que je regarde comment intégrer un bout de code en ASM dans le compilateur....j'avais tenter une première fois mais javais abandonner car ça m'avais fait des erreurs de compilation.

Led RGB 5050 WS2812B
Temps-x
Avatar de l’utilisateur
Expert
Expert
Messages : 2595
Enregistré en : juillet 2016
Localisation : Terre

#7 Message par Temps-x » ven. 15 mai 2020 13:42

Bonjour cyril13110, et tout le forum,

cyril13110 a écrit :Source du message Il va falloir du coup que je regarde comment intégrer un bout de code en ASM dans le compilateur....j'avais tenter une première fois mais javais abandonner car ça m'avais fait des erreurs de compilation.


Au pire si tu n'arrives pas à intégrer de l'assembleur dans ton langage, je peux te l'écrire tout en ASM.

==> A+
:roll: Les requins, c'est comme le langage ASM, c'est le sommet de la chaîne alimentaire. :wink:

Led RGB 5050 WS2812B
cyril13110
Confirmé
Confirmé
Messages : 724
Âge : 41
Enregistré en : avril 2016
Localisation : 13

#8 Message par cyril13110 » ven. 15 mai 2020 17:43

Temps-x a écrit :Bonjour cyril13110, et tout le forum,

cyril13110 a écrit :Source du message Il va falloir du coup que je regarde comment intégrer un bout de code en ASM dans le compilateur....j'avais tenter une première fois mais javais abandonner car ça m'avais fait des erreurs de compilation.


Au pire si tu n'arrives pas à intégrer de l'assembleur dans ton langage, je peux te l'écrire tout en ASM.

==> A+


Je te remercie pour ta proposition mais avant d'en arriver là je pense que je me casser la tête pour tenter d'y arriver...
Avec ce que tu m'a expliquer, ton code exemple et 2 autre code exemple trouvé sur le net je vais voir ce que je vais pouvoir faire.

Led RGB 5050 WS2812B
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#9 Message par paulfjujo » sam. 16 mai 2020 11:20

bonjour Cyril et à tous


pour inserer de l'asm dans mikorC
exemple

Code : Tout sélectionner


Partie ASM pour generation d
'un "simili bit" de commande à l'etat 1 pour WS2812
PIC à 64MHz 
!

unsigned char LATCx absolute 0x0F8B;

void ONES ()
{
_asm {
BSF _LATCx,5;
NOP;
NOP;
NOP;
NOP;
NOP;
NOP;
NOP;
NOP;
NOP;
BCF _LATCx,5;
NOP;
NOP;
NOP;
NOP;
NOP;
}
}

Partie ASM pour generation d'un "simili bit" de commande à l'etat 0 pour WS2812

void ZEROS 
()
  {
    _asm   {
      BSF _LATCx,5;
      NOP;
      NOP;
      NOP;
      NOP;
      NOP;
      BCF _LATCx,5;
      NOP;
      NOP;
      NOP;
      NOP;
      NOP;
      NOP;
      NOP;
      NOP;
      NOP;
      }
   }
   
   
   usage dans le main 
:
   
      UART1_Write_CText
(" Phase de Test avec SQA analyser : la 1ere led doit s'allumer en Vert \r\n" );
      ZEROS();ZEROS();ZEROS();ZEROS();ONES();ONES();ONES();ONES(); // VERT
      ZEROS();ZEROS(); ZEROS();ZEROS();ZEROS();ZEROS();ZEROS();ZEROS()   ;  // ROUGE
       ZEROS();ZEROS(); ZEROS();ZEROS();ZEROS();ZEROS();ZEROS();ZEROS()   ;  // BLEU
    while(1);
     
   


la partie ASM dans le C est exactement equivalente à l'ASM 100%
verification du Protocole grace à mon analyser IKALOGIC SQA 50MHz
nota : on peut aussi se servir du debugger mikroC , en faisant du pas à pas et usage du WATCH chrono..

et HOP .. ASM et C cohabitent !
Modifié en dernier par paulfjujo le sam. 16 mai 2020 16:02, modifié 1 fois.
Aide toi, le ciel ou FantasPic t'aidera

Led RGB 5050 WS2812B
cyril13110
Confirmé
Confirmé
Messages : 724
Âge : 41
Enregistré en : avril 2016
Localisation : 13

#10 Message par cyril13110 » sam. 16 mai 2020 13:28

Bonjour à tous et bonjour Paulfjujo,

Merci de m'avoir confirmer la possibilité, je vais regarder de plus prêt MikroBasic comment écrire de l'assembleur.
Je vais voir aussi ce que j'ai dans ma reserve comme pic allant jusqu'à 64Mhz et au pire je prends le code de Temps-x et en avant le test....
Je vois tiens au jus.... De cilicium...


Retourner vers « Langage ASM »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 35 invités