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

Soft de commande CNC en asm
F6FCO
Avatar de l’utilisateur
Confirmé
Confirmé
Messages : 778
Âge : 65
Enregistré en : décembre 2017
Localisation : Furtif je suis.
Contact :

#381 Message par F6FCO » jeu. 21 févr. 2019 21:01

Hello tous,
J'ai un peu relu le sujet et j'ai l'impression que mon histoire de tangente pour calculer les pentes était plutôt touffue, voire succinte pour une bonne compréhension.
Je fais ici une explication j'espère plus claire. C'est un sujet important quand on veut faire un peu de robotique parce que la trigo est la clé de pratiquement tous les déplacements, en plus ce n'est pas compliqué.

D'abord petit rappel de ce qu'est une tangente, rien de bien méchant. Dans le cas qui nous intéresse ici on travaille sur le triangle rectangle, la CNC s'y prète bien car on trace soit des verticales, soit des horizontales, soit des pentes, donc quoi qu'on fasse c'est des triangles rectangles. Pour simplifier le discours on ne parlera pas de cercles ici, mais çà vaut pour eux aussi.

triangle trigo.png


Donc un triangle rectangle; il a un angle droit et deux autres angles dont la valeur dépend des cotés du triangle. On prend le cas de l'angle alpha. Dans le triangle il a un coté adjacent (a), un coté opposé (o) et la pente qui se nomme hypothénuse (h). Jusqu'ici rien de compliqué. Niveau CM2 :wink: .

La tangente qu'on écrit tan(alpha) se calcule en divisant le coté opposé par le coté adjacent tan(alpha)=o/a.

Rien qu'avec ces infos on peut maintenant tracer notre pente sur la table de la CNC:

triangle asm.png


Le dessin parle de lui-même, on a les coordonnées XY de départ (Xold, Yold) et les coordonnées d'arrivée (Xnew, Ynew). La pente à tracer est l'hypothénuse h.
Le coté opposé (o) est le deltaY (Ynew-Yold) et le coté adjacent (a) est le deltaX (Xnew-Xold).
Juste deux équations à connaitre:
Calcul de la tangente: tan(alpha)=deltaY/deltaX, ce qui est la même chose que tan(alpha)=o/a.
Et Calcul de Y: Y=tan(alpha)*X

On connait deltaX, on connait maintenant la valeur de la tangente, reste à calculer les différentes valeurs de Y pour dessiner cette fameuse pente.
On incrémente X de 0 à deltaX et pour chaque valeur on calcule Y en faisant Y=X*tan(), on connait maintenant X et Y pour chaque point et on fait bouger les moteurs en conséquence.
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Une porte nand prend 2 bits en entrée... la cochonne !!! 8-)

Soft de commande CNC en asm
F6FCO
Avatar de l’utilisateur
Confirmé
Confirmé
Messages : 778
Âge : 65
Enregistré en : décembre 2017
Localisation : Furtif je suis.
Contact :

#382 Message par F6FCO » sam. 23 févr. 2019 20:08

Eureka !!! elle vient de faire son premier cercle correct. Comme on peut le voir sur le papier çà a été un vrai combat de rue cette affaire :roll:

al60.JPG
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Une porte nand prend 2 bits en entrée... la cochonne !!! 8-)

Soft de commande CNC en asm
venom
Avatar de l’utilisateur
Confirmé
Confirmé
Messages : 583
Âge : 33
Enregistré en : avril 2016
Localisation : Klyntar
Contact :

#383 Message par venom » dim. 24 févr. 2019 07:22

:bravo: En voilà une belle avancée. Bravo F6FCO tu avance bien. Je suis impressionné par le travail que tu effectue. :shock:

Prochaine étape, les spirales :langue:






@++
En fait tout est une question de BIT ? :-D

Soft de commande CNC en asm
Gérard
Avatar de l’utilisateur
Expert
Expert
Messages : 1068
Âge : 60
Enregistré en : septembre 2015
Localisation : Alsace - Haut-Rhin

#384 Message par Gérard » dim. 24 févr. 2019 11:39

Moi aussi je suis impressionné. Et tout ça en asm... Je ne peux que m'incliner.
:bravo: l'artiste.
Le 18 / 04 / 2019 je suis devenu papy de jumeaux, une fille et un garçon. Quel bonheur.

Soft de commande CNC en asm
F6FCO
Avatar de l’utilisateur
Confirmé
Confirmé
Messages : 778
Âge : 65
Enregistré en : décembre 2017
Localisation : Furtif je suis.
Contact :

#385 Message par F6FCO » dim. 24 févr. 2019 14:46

Hello tous les deux, merci pour vos commentaires :wink:

Le programme est à présent fonctionnel et abouti. Je vais certainement encore bricoler encore un peu dessus car vu que je n'ai toujours pas d'atelier il va bien falloir que j'ai un jouet pour m'occuper le soir après la réno :-)

Voici le programme complet:

Code : Tout sélectionner

;----------------------------------------------------------------------------------------------
;                            
4L1C3 Soft de commande CNC pour gravure de PCB
;                                by Jean-Claude Buisson F6FCO
;                        
;                             
Dernière modification le 24 février 2019  
;
;----------------------------------------------------------------------------------------------

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

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

;---------------------------------------------------------------------------------------------
 
CONFIG    OSC XT                        Oscillateur ext 4MHz 
 
;CONFIG    OSC HSPLL                        Oscillateur interne 32Mhz 
 CONFIG    IESO 
OFF                        Oscillateur secondaire refusé (ON/OFF)
 
CONFIG PWRT ON                        Délai au démarrage (ON/OFF)
 
CONFIG BOREN OFF                        Reset si chute de tension (ON/OFF)
 
CONFIG BORV 0                        Tension de reset en 1/10ème Volts 
 CONFIG WDT 
OFF                        Mise hors service du watchdog (ON/OFF)
 
CONFIG PBADEN OFF                    PORTB<4:0les broches sont configurées comme E/S numériques lors de la réinitialisation
 CONFIG LPT1OSC 
OFF                    Timer1 configuré pour un fonctionnement plus puissant
 CONFIG MCLRE 
ON                        Mclr 
 CONFIG STVREN 
ON                        Reset sur débordement de pile (ON/OFF)
 
CONFIG LVP OFF                        Programmation basse tension autorisée (ON/OFF)
 
CONFIG XINST OFF                        L'extension du jeu d'instructions et le mode d'adressage indexé sont désactivés(mode hérité)
 CONFIG DEBUG = ON                        ; Debugger hors service
 CONFIG CP0 = OFF                        ; Code protection sur block 0 (ON/OFF)
 CONFIG CP1 = OFF                        ; Code protection sur block 1 (ON/OFF)
 CONFIG CP2 = OFF                        ; Code protection sur block 2 (ON/OFF)
 CONFIG CPB = OFF                        ; Code protection sur bootblock  (ON/OFF)
 CONFIG CPD = OFF                        ; Code protection sur eeprom (ON/OFF)
 CONFIG WRT0 = OFF                        ; Protection écriture block 0 (ON/OFF)
 CONFIG WRT1 = OFF                        ; Protection écriture block 1 (ON/OFF)
 CONFIG WRT2 = OFF                        ; Protection écriture block 2 (ON/OFF)
 CONFIG WRTB = OFF                        ; Protection écriture bootblock (ON/OFF)
 CONFIG WRTC = OFF                        ; Protection écriture configurations (ON/OFF)
 CONFIG WRTD = OFF                        ; Protection écriture zone eeprom (ON/OFF)
 CONFIG EBTR0 = OFF                        ; Protection lecture de table block 0 (ON/OFF)
 CONFIG EBTR1 = OFF                        ; Protection lecture de table block 1 (ON/OFF)
 CONFIG EBTR2 = OFF                        ; Protection lecture de table block 2 (ON/OFF)
 CONFIG EBTRB = OFF                        ; Protection lecture de table bootblock (ON/OFF)
            
;-------------------------------------- assignations ------------------------------------------

#define    btn_jog_Xmoins    PORTA,0    ; 1
#define    btn_jog_Xplus    PORTA,1    ; 1
#define    btn_jog_Ymoins    PORTA,2    ; 1
#define    btn_jog_Yplus    PORTA,3    ; 1
#define    btn_jog_Zmoins    PORTA,4    ; 1
#define    btn_jog_Zplus    PORTA,5    ; 1

#define capteur_pomZ    PORTB,0    ; 1
#define capteur_pomX    PORTB,1    ; 1
#define capteur_pomY    PORTB,2    ; 1
#define led_pomZ        PORTB,3    ; 0
#define led_pomY        PORTB,4    ; 0
#define cts                PORTB,5    ; 0
#define nc0                PORTB,6 ; x
#define nc1                PORTB,7 ; x

#define    led_popY        PORTC,0 ; 0
#define    led_popZ        PORTC,1 ; 0
#define    btn_run            PORTC,2    ; 1
#define    btn_popX        PORTC,3    ; 1
#define drv_stepY        PORTC,4    ; 0            pulse Y
#define drv_dirY        PORTC,5 ; 0            direction Y
#define Tx                PORTC,6    ; 1
#define Rx                PORTC,7    ; 1 

#define btn_popY        PORTD,0    ; 1
#define btn_popZ        PORTD,1    ; 1
#define drv_stepX        PORTD,2    ; 0            pulse X
#define drv_dirX        PORTD,3    ; 0            direction X
#define drv_stepZ        PORTD,4 ; 0            pulse Z
#define drv_dirZ        PORTD,5 ; 0            direction Z
#define    led_pomX        PORTD,6 ; 0
#define btn_pom            PORTD,7    ; 1
#define    btn_ctrl        PORTE,0 ; 1
#define    btn_fn            PORTE,1 ; 1
#define    led_popX        PORTE,2 ; 0

; ----------------------------------- Constantes ----------------------------------------------

#define limite_maxiX        d'
108'                    ; maxi à droite
#define limite_miniX        0                        ; mini à gauche (POM X)
#define offset_pomX            d'
12'                    ; offset après contact POM X (d'12' maxi)

#define limite_maxiY        d'
120'                    ; maxi devant
#define limite_miniY        0                        ; mini au fond derrière (POM Y)
#define    offset_pomY            d'
30'                    ; offset après contact POM Y (d'30' maxi)


#define limite_maxiZ        d'
30'                      ; tout en haut (POM Z)
#define limite_miniZ        d'
0'                    ; tout en bas
#define    offset_pomZ            d'
1'                    ; offset après contact POM Z (d'10' maxi)

;#define    pas_moteur            200                        ; 1/1 pas
;#define    pas_moteur            400                        ; 1/2 pas
#define    pas_moteur            800                        ; 1/4 pas
;#define    pas_moteur            1600                    ; 1/8 pas

;------------------------------ déclaration des variables -------------------------------------

                 CBLOCK    H'
08'
                     ptr                                ; sert à la raz des variables en init
                    axeX:1                            ; ascii '
Z'
                    coordX:7                        ; coordonnée stockée sur 32 bits
                    espace1                            ; espace
                    axeY                            ; ascii '
Y'
                    coordY:7                        ; coordonnée stockée sur 32 bits
                    espace2                            ; espace
                    axeZ                            ; ascii '
Z'
                    coordZ:7                        ; coordonnée stockée sur 32 bits
                    ptr_train_RCIF                    ; compteur nb octets reçus dans un train
                    coordZ_old:3
                    coordX_old:3
                    coordY_old:3
                    dividende16:2                        ; utilisé par division 16bits
                    diviseur16:2                        ; utilisé par division 16bits
                    quotient16:2                        ; utilisé par division 16bits
                    reste16:2                            ; utilisé par division 16bits
                    
                    dividende48:6
                    diviseur48:6
                    
                    multiplicande32:4                    ; mult 16_16
                    multiplicateur32:4                    ; mult 16_16
                    resultat32:4                        ; mult 16_16
                    result:6                            ; Mult32x16
                    tampon                                ; mult 16_16
                    deltaX:3
                    deltaY:3
                    deltaZ:3
                    translatZ
                    translatX                        ; distance parcourue en X
                    translatY
                     valeur1:3                         ; utilisée par les opérations arithmetiques
                    valeur2:3                        ; utilisée par les opérations arithmetiques
                    valeur3:3                        ; valeur tampon pour les les opérations arithmetiques
                    flagX
                    flagY
                    report16                        ; si carry en dépassement
                    tangente16:2
                    val_popZ
                    val_popX                        ; valeur de la course pop par rapport à l'
origine X
                    val_popY
                    nbmm                            
sert à calculer la distance parcourue sur un nb pulse calculé
                    tampon0
:3                        sert de variable locale
                    tampon1
:3                        sert de variable locale
                    tampon2                            
sert de variable locale
                    tampon3                            
sert de variable locale
                    tamponA                            
sert de variable locale
                    tamponB                            
sert de variable locale
                    flag_fin_gcode
                    Tampon_REC                        
tampon réception
                    Reg_1
                    Reg_2
                    Reg_3
                    Reg_4
                    W_TEMP
                    STATUS_TEMP
                    BSR_TEMP
                    
; --------------                partie musique
                    note
                    duree_note
                    silence
                    led1
                    led2
                    led3
                    led4
                    led5
                    dir
                    axe
                    
                    
                 ENDC
                 
                 CBLOCK H
'100' 
                
ENDC

; ---------------------------------------- macros --------------------------------------------
    
qrt            macro                            Etat hautdemande au PC d'arreter l'émission 
                bsf        cts
            endm
            
qrv            macro                            
Etat basdemande au PC de relancer l'émission
                bcf        cts            
            endm

plongée_Z macro
            bcf        drv_dirZ
            nop
            endm            
remontée_Z macro
            bsf        drv_dirZ
            nop
            endm
            
marche_av_X macro
            bsf        drv_dirX
            nop
            endm            
marche_ar_X macro
            bcf        drv_dirX
            nop
            endm

marche_av_Y macro
            bsf        drv_dirY
            nop
            endm            
marche_ar_Y macro
            bcf        drv_dirY
            nop
            endm

led_popZ_ON macro
            bsf        led_popZ
            endm
led_popZ_OFF macro
            bcf        led_popZ
            endm
            
led_popX_ON macro
            bsf        led_popX
            endm
led_popX_OFF macro
            bcf        led_popX
            endm

led_popY_ON macro
            bsf        led_popY
            endm
led_popY_OFF macro

            bcf        led_popY
            endm

led_pomZ_ON macro
            bsf        led_pomZ
            endm
led_pomZ_OFF macro    
            bcf        led_pomZ
            endm
        
led_pomX_ON macro
            bsf        led_pomX
            endm
led_pomX_OFF macro
            bcf        led_pomX
            endm

led_pomY_ON macro
            bsf        led_pomY
            endm
led_pomY_OFF macro
            bcf        led_pomY
            endm


;--------------------------------- adresse de depart après reset -----------------------------²
            ORG     H'
0'


            bra        init      

;--------------------------------------- interruptions ---------------------------------------

            ORG        H'
08'
interrupt   btfss    PIR1,RCIF                ; registre plein ? si oui on saute à réception
            bra        int1                    ; sinon on sort de l'
interrupt                   
reception        
            nop
            movff    RCREG
,POSTINC0            lecture de RCREG  et mise en mem       
            incf    ptr_train_RCIF            
on a reçu qq chose donc on incrémente le compteur de trains
            btfss    RCSTA
,OERR                test d'une erreur d'overrun
            
goto    int1
            
traitement de l'erreur d'overrun
            bcf        RCSTA
,CREN                on efface le bit OERR
            bsf        RCSTA
,CREN                on relance la réception
int1        
traitement des autres interruptions
            retfie
            
; ------------------------------------- datas --------------------------------------------------------
table précalculée sur 24bits utilisée dans les routines de conversion ascii/hexaplacée volontairement en début de programme pour avoir une adresse fixe 
et ne pas avoir les points d'entrée altérés par les modifs ultérieures du code
;ascii_poids6    db    0x00,0x00,0x00  ,0x0F,0x42,0x40  ,0x1E,0x84,0x80  ,0x2c,0xc6,0xc0  ,0x3d,0x09,0x00  ,0x4c,0x4b,0x40  ,0x5b,0x8d,0x80  ,0x6a,0xcf,0xc0  ,0x7a,0x12,0x00  ,0x89,0x54,0x40    ; multiplication chiffre.0xA.0xA.0xA.0xA.0xA.0xA        
ascii_poids5    db    0x00,0x00,0x00  ,0x01,0x86,0xA0  ,0x03,0x0d,0x40  ,0x04,0x93,0xe0  ,0x06,0x1a,0x80  ,0x07,0xa1,0x20  ,0x09,0x27,0xc0  ,0x0a,0xae,0x60  ,0x0c,0x35,0x00  ,0x0d,0xbb,0xa0    ; multiplication chiffre.0xA.0xA.0xA.0xA.0xA         
ascii_poids4    db    0x00,0x00,0x00  ,0x00,0x27,0x10  ,0x00,0x4e,0x20  ,0x00,0x75,0x30  ,0x00,0x9c,0x40  ,0x00,0xc3,0x50  ,0x00,0xea,0x60  ,0x01,0x11,0x70  ,0x01,0x38,0x80  ,0x01,0x5f,0x90    ; multiplication chiffre.0xA.0xA.0xA.0xA         
ascii_poids3    db    0x00,0x00,0x00  ,0x00,0x03,0xe8  ,0x00,0x07,0xd0  ,0x00,0x0b,0xb8  ,0x00,0x0f,0xa0  ,0x00,0x13,0x88  ,0x00,0x17,0x70  ,0x00,0x1b,0x58  ,0x00,0x1f,0x40  ,0x00,0x23,0x28    ; multiplication chiffre.0xA.0xA.0xA         
ascii_poids2    db    0x00,0x00,0x00  ,0x00,0x00,0x64  ,0x00,0x00,0xc8  ,0x00,0x01,0x2c  ,0x00,0x01,0x90  ,0x00,0x01,0xf4  ,0x00,0x02,0x58  ,0x00,0x02,0xbc  ,0x00,0x03,0x20  ,0x00,0x03,0x84    ; multiplication chiffre.0xA.0xA
ascii_poids1    db    0x00,0x00,0x00  ,0x00,0x00,0x0a  ,0x00,0x00,0x14  ,0x00,0x00,0x1e  ,0x00,0x00,0x28  ,0x00,0x00,0x32  ,0x00,0x00,0x3c  ,0x00,0x00,0x46  ,0x00,0x00,0x50  ,0x00,0x00,0x5a    ; multiplication chiffre.0xA     

;----------------------------------- Initialisations -------------------------------------------------
init
                ;ovlw    b'
01000000'                ; oscillateur interne 8Mhzx4=32Mhz
                ;ovlw    OSCTUNE                    
                movlw    b'
11000000'                ; INTCON (activation des int GIE/GIEH=1, PEIE/GIEL=1)
                movwf    INTCON
                movlw    b'
10000000'                ; RCON (priorités int activées IPEN=1,)
                movwf    RCON
                movlw    b'
00100000'                ; IPR1 (Rx en haute priorité RCIP=1)
                movwf    IPR1
                movlw    b'
00100000'                ; PIE1 (int RX activée RCIE=1)
                movwf    PIE1
                movlw    b'
00100100'                ; TXSTA (Emission USART activée TXEN=1, et mode asynchrone haute vitesse BRGH=1)
                movwf    TXSTA
                movlw    b'
10010000'                ; RCSTA (Utilisation du port série activée SPEN=1, Réception USART activée CREN=1)
                movwf    RCSTA
                movlw    d'
25'                    ; 9600bauds avec sync=O, brgh=1, brg16=0, xtal=4Mhz
                movwf    SPBRG
                bcf        BAUDCON,BRG16            ; réglé à 8bits        
                movlw     B'
00000111'                 
                movwf    TRISB
                movlw     B'
11001100'                
                movwf    TRISC
                movlw     B'
10000011'                  
                movwf    TRISD
                movlw     B'
10000011'                 
                movwf    TRISE
                clrf    PORTB
                clrf    PORTC
                clrf    PORTD
                clrf    PORTE
                ; -----------------   initialisation du PORT A
                clrf    PORTA
                clrf    LATA
                movlw    0xf
                movwf    ADCON1
                movwf    0x07
                movwf    CMCON            
                movlw     0xff                 
                movwf    TRISA

                qrt
            
                ; ---------------- RAZ de la zone variables de axeX à 0x7e
init2            lfsr    FSR0,axeX
                movlw    0x76
                movwf    ptr
raz_var            clrf    POSTINC0
                decf    ptr
                bnz        raz_var
                lfsr    FSR0,axeX                ; on repointe sur la première variable axeX    
                
                movlw    limite_maxiZ        
                movwf    translatZ                ; initialisation axe Z à zéro
                ; prêt pour réception
                
                bcf        led_pomX
                bcf        led_pomY
                bcf        led_pomZ
                ;bra     main
                ;bra     Test_nb_trains
                

;############################################################################################################################
;#                                                                                                                            #
;#                                        Programme principal, appel des procédures                                            #
;#                                                                                                                            #
;############################################################################################################################

main      
            
            marche_av_X                        ; on est en POM donc on force l'
axe en avant
            qrt                                
on coupe la réception UART le temps des initialisations

initialisations_machine    
            
scrutation des claviers    
            
text btn_fonction
            btfss    btn_ctrl
            call    controle    
            btfss    btn_fn
            call    fonction
            
_________________________ POM générales (Prises Origines Machine)
            
btfss    btn_pom                            
            call    POM
            
_________________________ gestion des JOG
            btfss    btn_jog_Xmoins                    
            call    xmoins    
            
jog X plus
            btfss    btn_jog_Xplus                                        
            call    xplus
            
jog Y moins
            btfss    btn_jog_Ymoins                    
            call    ymoins    
            
jog Y plus
            btfss    btn_jog_Yplus                                        
            call    yplus
            
jog Z moins


            btfss    btn_jog_Zmoins                
            call    zmoins    
            
jog Z plus
            btfss    btn_jog_Zplus                                        
            call    zplus
            
_________________________ gestioon des POP
            
pop X
            btfss    btn_popX                                        
            call    popX
            
pop Y
            btfss    btn_popY                                        
            call    popY
            
pop Z
            btfss    btn_popZ                                        
            call    popZ
            
_________________________ RUN   validation de l'interruption rec UART et exécution du gcode
            btfss    btn_run                                        
            bra        run
            ; _________________________ on reboucle tant qu'
un bouton n'a pas été pressé
            bra        initialisations_machine
            
controle    btfss    btn_jog_Zplus
            ;call    F6FCO
            call    zik_lamour
            btfss    btn_popX
            call    descendZ_1centième
            btfss    btn_popY
            call    descendZ_5centièmes
            btfss    btn_popZ
            call    descendZ_1dixième
            return    
            
fonction    btfss    btn_jog_Zmoins
            ;call    _4L1C3
            ;call    zik_partisan
            call    zik_toreador
            btfss    btn_popX
            call    monteZ_1centième
            btfss    btn_popY
            call    monteZ_5centièmes
            btfss    btn_popZ
            call    monteZ_1dixième
            return

            
; --------------------------------------------------- démarrage de l'
usinage  -----------------------------------------------
            
run            avant de lancer le gcode on s'assure que les axes sont bien à leurs origines POP, si non on les ramène à la bonne valeur
            ;call    positionnement_origines_pop
fin_init_machine
            call    tempo
            qrv                                ; POM et POP effectuées on active la réception UART 
            nop
            nop
            nop
            nop
            nop
            nop
            bra        Test_nb_trains

            ; Cette partie ne sert qu'
au débuggage en forçant des valeurs gcode en dur.
            ;
X
            movlw    0x30        

            
movwf    coordX+0
            movlw    0x30        

            
movwf    coordX+1
            movlw    0x30        

            
movwf    coordX+2
            movlw    0x31        

            
movwf    coordX+3
            movlw    0x4e
; ------------ point
            movwf    coordX
+4
            movlw    0x36        

            
movwf    coordX+5
            movlw    0x35        

            
movwf    coordX+6
            
;X_old
            movlw    0x0    

            
movwf    coordX_old+2
            movlw    0xc        

            
movwf    coordX_old+1
            movlw    0xc1        
CC1=3265
            movwf    coordX_old
            
; -----------------------
            ;
Y
            movlw    0x30        

            
movwf    coordY+0
            movlw    0x30        

            
movwf    coordY+1
            movlw    0x30        

            
movwf    coordY+2
            movlw    0x31        

            
movwf    coordY+3
            movlw    0x4e
; ------------ point
            movwf    coordY
+4
            movlw    0x32        

            
movwf    coordY+5
            movlw    0x37        

            
movwf    coordY+6
            
;Y
            movlw    0x0        

            
movwf    coordY_old+2
            movlw    0xc        

            
movwf    coordY_old+1
            movlw    0x9b        
C9b=3227
            movwf    coordY_old
            
; -----------------------        
            ; 
Z
            movlw    0x30        

            
movwf    coordZ+0
            movlw    0x30        

            
movwf    coordZ+1
            movlw    0x32        

            
movwf    coordZ+2
            movlw    0x32        

            
movwf    coordZ+3
            movlw    0x4e
; ------------ point
            movwf    coordZ
+4
            movlw    0x31        

            
movwf    coordZ+5
            movlw    0x35        

            
movwf    coordZ+6
                    
            
Z_old
            movlw    0x00        

            
movwf    coordZ_old+2
            movlw    0x00        

            
movwf    coordZ_old+1
            movlw    0x54        

            
movwf    coordZ_old
            bra        go
            
; ------------------------------------------- Réception des données et gestion des trains -----------------------------------
            
Test_nb_trains    
             
;movlw    d'17'                             compter 17 octets pour un train en 32bits
             movlw    d
'26'                             compter 17 octets pour un train en 32bits
            subwf    ptr_train_RCIF
,w
            btfss    STATUS
,Z
            bra        Test_nb_trains
go            qrt                                        
stop émission
            call    test_fin_gcode                    
test si fin du gcode
            movlw    1
            subwf    flag_fin_gcode
            btfsc    STATUS
,Z
            bra        fin_programme
            clrf    flag_fin_gcode
            
;                                    
            ; ------------------- 
On place ici les appels aux sous-routines de gestion de la machine
            
;                              
            
nop
            call    conversion_decimal_entierX
            nop
            call    conversion_decimal_entierY
            nop
            call    conversion_decimal_entierZ
            nop
            call    conversion_ascii_hexaZ
            nop
            call     conversion_ascii_hexaX            
convertit les données ascii des 3 axes en hexadécimal
            nop
            call    conversion_ascii_hexaY
            nop
            call    calcul_deltaZ
            nop
            
;call    deplaceZ
            nop
            call    calcul_deltaX
            nop
            call    calcul_deltaY
            nop
            call    calcul_tangente                    
            nop
            call     construction_droite
            nop
            call    sauvegarde_coordZ_old
            call     sauvegarde_coordX_old
            call    sauvegarde_coordY_old
            call    tempo                            
sert juste à mieux visionner les séquences sur l'analyseur logique
            nop
            ;
            ; -------------------
            ;
            nop
            nop
            clrf    ptr_train_RCIF    
            lfsr    FSR0,axeX                        ; on repointe sur la première variable axeX    
            qrv                                        ; pret pour réception
            bra     Test_nb_trains
            
test_fin_gcode
            movlw    0x4D                            ; test du '
M' de la fin du gcode (M00000000)
            subwf    axeX,w    
            btfss    STATUS,Z    
            return
            movlw    1
            movwf    flag_fin_gcode
            return
            
fin_programme
            call    pomz
clignotte    call    clignotte_3ledPOP
            call    clignotte_3ledPOM
            btfss    btn_run                                        
            bra        init2

            bra        clignotte
            
;############################################################################################################################
;#                                                                                                                            #
;#                                                                                                                            #
;#                                                    procédures                                                                #
;#                                                                                                                            #
;#                                                                                                                            #
;############################################################################################################################

; ------------------------------------------- Conversion ASCII/hexa X ---------------------------------------------------------
    
conversion_ascii_hexaX
; on commence par transformer chaque poids en décimal en soustrayant 0x30
            movlw    0x30
            subwf    coordX
            subwf    coordX+1
            subwf    coordX+2
            subwf    coordX+3
            subwf    coordX+4
            subwf    coordX+5

; ensuite au lieu de multiplier chaque poids par son multiplicateur approprié on va chercher la valeur finale
; dans la table précalculée
            
            ; le poids0 est à ce stade à la valeur 0
            
            ; le poids5
            movlw    High ascii_poids5  
            movwf    TBLPTRH             ; adresse poid fort de la memoire a lire 
            movlw    Low ascii_poids5
            movwf    TBLPTRL             ; adresse poid faible a lire
            movf    coordX+5,w
            mullw    3
            movf    PRODL,w
            addwf   TBLPTRL             
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+2
            movff    TABLAT,valeur2+2        
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+1
            movff    TABLAT,valeur2+1        
            tblrd*                        ; on lit le poids faible et on le place dans valeur1
            movff    TABLAT,valeur2
                        
            ; le poids4
            movlw    High ascii_poids4   
            movwf    TBLPTRH             ; adresse poid fort de la memoire a lire 
            movlw    Low ascii_poids4
            movwf    TBLPTRL             ; adresse poid faible a lire
            movf    coordX+4,w
            mullw    3
            movf    PRODL,w
            addwf   TBLPTRL             
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+2
            movff    TABLAT,valeur1+2        
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+1
            movff    TABLAT,valeur1+1        
            tblrd*                        ; on lit le poids faible et on le place dans valeur1
            movff    TABLAT,valeur1
            call    addition24
            ; résultat dans valeur2+0,+1,+2
            
            ; le poids3
            movlw    High ascii_poids3   
            movwf    TBLPTRH             ; adresse poid fort de la memoire a lire 
            movlw    Low ascii_poids3
            movwf    TBLPTRL             ; adresse poid faible a lire
            movf    coordX+3,w
            mullw    3
            movf    PRODL,w
            addwf   TBLPTRL             
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+2
            movff    TABLAT,valeur1+2        
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+1
            movff    TABLAT,valeur1+1        
            tblrd*                        ; on lit le poids faible et on le place dans valeur1
            movff    TABLAT,valeur1
            call    addition24
            ; résultat dans valeur2+0,+1,+2
            
            ; le poids2
            movlw    High ascii_poids2   
            movwf    TBLPTRH             ; adresse poid fort de la memoire a lire 
            movlw    Low ascii_poids2
            movwf    TBLPTRL             ; adresse poid faible a lire
            movf    coordX+2,w
            mullw    3
            movf    PRODL,w
            addwf   TBLPTRL             
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+2
            movff    TABLAT,valeur1+2        
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+1
            movff    TABLAT,valeur1+1        
            tblrd*                        ; on lit le poids faible et on le place dans valeur1
            movff    TABLAT,valeur1
            call    addition24
            ; résultat dans valeur2+0,+1,+2
            
            ; le poids1
            movlw    High ascii_poids1   
            movwf    TBLPTRH             ; adresse poid fort de la memoire a lire 
            movlw    Low ascii_poids1
            movwf    TBLPTRL             ; adresse poid faible a lire
            movf    coordX+1,w
            mullw    3
            movf    PRODL,w
            addwf   TBLPTRL             
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+2
            movff    TABLAT,valeur1+2        
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+1
            movff    TABLAT,valeur1+1        
            tblrd*                        ; on lit le poids faible et on le place dans valeur1
            movff    TABLAT,valeur1
            call    addition24
            ; résultat dans valeur2+0,+1,+2

            ; et enfin on additionne le poids 0 (0 à 9, forcément codé sur 1 octet) à tout çà pour obtenir le résultat final
            ; c'
est à dire (poids0*A*A*A*A*A*A) + (poids1*A*A*A*A*A) + (poids2*A*A*A*A) + (poids3*A*A*A) + (poids4*A*A) + (poids5*A) + poids6
            
on avait une valeur ascii de distance codée sur 7 octetson se retrouve avec une valeur hexa codée 
            
sur 3 octets utilisable dans le programme
            movff    coordX
,valeur1
            clrf    valeur1
+1
            clrf    valeur1
+2
            call    addition24    
            
on obtient une valeur 24bits qu'on stocke dans coordX+6, coordX5 et coordX+4    
            movff    valeur2,coordX
            movff    valeur2+1,coordX+1
            movff    valeur2+2,coordX+2
            nop
            clrf    coordX+3
            clrf    coordX+4
            clrf    coordX+5
            clrf    coordX+6
            nop
            return
            
; ------------------------------------------- Conversion ASCII/hexa Y ---------------------------------------------------------
                
conversion_ascii_hexaY
; on commence par transformer chaque poids en décimal en soustrayant 0x30
            movlw    0x30
            subwf    coordY
            subwf    coordY+1
            subwf    coordY+2
            subwf    coordY+3
            subwf    coordY+4
            subwf    coordY+5

; ensuite au lieu de multiplier chaque poids par son multiplicateur approprié on va chercher la valeur finale
; dans la table précalculée
            
            ; le poids0 est à ce stade à la valeur 0
            
            ; le poids5
            movlw    High ascii_poids5   
            movwf    TBLPTRH             ; adresse poid fort de la memoire a lire 
            movlw    Low ascii_poids5
            movwf    TBLPTRL             ; adresse poid faible a lire
            movf    coordY+5,w
            mullw    3
            movf    PRODL,w
            addwf   TBLPTRL             
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+2
            movff    TABLAT,valeur2+2        
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+1
            movff    TABLAT,valeur2+1        
            tblrd*                        ; on lit le poids faible et on le place dans valeur1
            movff    TABLAT,valeur2
                        
            ; le poids4
            movlw    High ascii_poids4   
            movwf    TBLPTRH             ; adresse poid fort de la memoire a lire 
            movlw    Low ascii_poids4
            movwf    TBLPTRL             ; adresse poid faible a lire
            movf    coordY+4,w
            mullw    3
            movf    PRODL,w
            addwf   TBLPTRL             
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+2
            movff    TABLAT,valeur1+2        
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+1
            movff    TABLAT,valeur1+1        
            tblrd*                        ; on lit le poids faible et on le place dans valeur1
            movff    TABLAT,valeur1
            call    addition24
            ; résultat dans valeur2+0,+1,+2
            
            ; le poids3
            movlw    High ascii_poids3   
            movwf    TBLPTRH             ; adresse poid fort de la memoire a lire 
            movlw    Low ascii_poids3
            movwf    TBLPTRL             ; adresse poid faible a lire
            movf    coordY+3,w
            mullw    3
            movf    PRODL,w
            addwf   TBLPTRL             
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+2
            movff    TABLAT,valeur1+2        
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+1
            movff    TABLAT,valeur1+1        
            tblrd*                        ; on lit le poids faible et on le place dans valeur1
            movff    TABLAT,valeur1
            call    addition24
            ; résultat dans valeur2+0,+1,+2
            
            ; le poids2
            movlw    High ascii_poids2   
            movwf    TBLPTRH             ; adresse poid fort de la memoire a lire 
            movlw    Low ascii_poids2
            movwf    TBLPTRL             ; adresse poid faible a lire
            movf    coordY+2,w
            mullw    3
            movf    PRODL,w
            addwf   TBLPTRL             
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+2
            movff    TABLAT,valeur1+2        
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+1
            movff    TABLAT,valeur1+1        
            tblrd*                        ; on lit le poids faible et on le place dans valeur1
            movff    TABLAT,valeur1
            call    addition24
            ; résultat dans valeur2+0,+1,+2
            
            ; le poids1
            movlw    High ascii_poids1   
            movwf    TBLPTRH             ; adresse poid fort de la memoire a lire 
            movlw    Low ascii_poids1
            movwf    TBLPTRL             ; adresse poid faible a lire
            movf    coordY+1,w
            mullw    3
            movf    PRODL,w
            addwf   TBLPTRL             
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+2
            movff    TABLAT,valeur1+2        
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+1
            movff    TABLAT,valeur1+1        
            tblrd*                        ; on lit le poids faible et on le place dans valeur1
            movff    TABLAT,valeur1
            call    addition24
            ; résultat dans valeur2+0,+1,+2

            ; et enfin on additionne le poids 0 (0 à 9, forcément codé sur 1 octet) à tout çà pour obtenir le résultat final
            ; c'
est à dire (poids0*A*A*A*A*A*A) + (poids1*A*A*A*A*A) + (poids2*A*A*A*A) + (poids3*A*A*A) + (poids4*A*A) + (poids5*A) + poids6
            
on avait une valeur ascii de distance codée sur 7 octetson se retrouve avec une valeur hexa codée 
            
sur 3 octets utilisable dans le programme
            movff    coordY
,valeur1
            clrf    valeur1
+1
            clrf    valeur1
+2
            call    addition24    
            
on obtient une valeur 24bits qu'on stocke dans coordX+6, coordX5 et coordX+4    
            movff    valeur2,coordY
            movff    valeur2+1,coordY+1
            movff    valeur2+2,coordY+2
            nop
            clrf    coordY+3
            clrf    coordY+4
            clrf    coordY+5
            clrf    coordY+6
            nop
            return
        
; ------------------------------------------- Conversion ASCII/hexa Z ---------------------------------------------------------
        
conversion_ascii_hexaZ
; on commence par transformer chaque poids en décimal en soustrayant 0x30
            movlw    0x30
            subwf    coordZ
            subwf    coordZ+1
            subwf    coordZ+2
            subwf    coordZ+3
            subwf    coordZ+4
            subwf    coordZ+5

; ensuite au lieu de multiplier chaque poids par son multiplicateur approprié on va chercher la valeur finale
; dans la table précalculée
            
            ; le poids0 est à ce stade à la valeur 0
            
            ; le poids5
            movlw    High ascii_poids5   
            movwf    TBLPTRH             ; adresse poid fort de la memoire a lire 
            movlw    Low ascii_poids5
            movwf    TBLPTRL             ; adresse poid faible a lire
            movf    coordZ+5,w
            mullw    3
            movf    PRODL,w
            addwf   TBLPTRL             
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+2
            movff    TABLAT,valeur2+2        
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+1
            movff    TABLAT,valeur2+1        
            tblrd*                        ; on lit le poids faible et on le place dans valeur1
            movff    TABLAT,valeur2
                        
            ; le poids4
            movlw    High ascii_poids4   
            movwf    TBLPTRH             ; adresse poid fort de la memoire a lire 
            movlw    Low ascii_poids4
            movwf    TBLPTRL             ; adresse poid faible a lire
            movf    coordZ+4,w
            mullw    3
            movf    PRODL,w
            addwf   TBLPTRL             
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+2
            movff    TABLAT,valeur1+2        
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+1
            movff    TABLAT,valeur1+1        
            tblrd*                        ; on lit le poids faible et on le place dans valeur1
            movff    TABLAT,valeur1
            call    addition24
            ; résultat dans valeur2+0,+1,+2
            
            ; le poids3
            movlw    High ascii_poids3   
            movwf    TBLPTRH             ; adresse poid fort de la memoire a lire 
            movlw    Low ascii_poids3
            movwf    TBLPTRL             ; adresse poid faible a lire
            movf    coordZ+3,w
            mullw    3
            movf    PRODL,w
            addwf   TBLPTRL             
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+2
            movff    TABLAT,valeur1+2        
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+1
            movff    TABLAT,valeur1+1        
            tblrd*                        ; on lit le poids faible et on le place dans valeur1
            movff    TABLAT,valeur1
            call    addition24
            ; résultat dans valeur2+0,+1,+2
            
            ; le poids2
            movlw    High ascii_poids2   
            movwf    TBLPTRH             ; adresse poid fort de la memoire a lire 
            movlw    Low ascii_poids2
            movwf    TBLPTRL             ; adresse poid faible a lire
            movf    coordZ+2,w
            mullw    3
            movf    PRODL,w
            addwf   TBLPTRL             
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+2
            movff    TABLAT,valeur1+2        
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+1
            movff    TABLAT,valeur1+1        
            tblrd*                        ; on lit le poids faible et on le place dans valeur1
            movff    TABLAT,valeur1
            call    addition24
            ; résultat dans valeur2+0,+1,+2
            
            ; le poids1
            movlw    High ascii_poids1   
            movwf    TBLPTRH             ; adresse poid fort de la memoire a lire 
            movlw    Low ascii_poids1
            movwf    TBLPTRL             ; adresse poid faible a lire
            movf    coordZ+1,w
            mullw    3
            movf    PRODL,w
            addwf   TBLPTRL             
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+2
            movff    TABLAT,valeur1+2        
            tblrd*+                        ; on lit le poids fort et on le place dans valeur1+1
            movff    TABLAT,valeur1+1        
            tblrd*                        ; on lit le poids faible et on le place dans valeur1
            movff    TABLAT,valeur1
            call    addition24
            ; résultat dans valeur2+0,+1,+2

            ; et enfin on additionne le poids 0 (0 à 9, forcément codé sur 1 octet) à tout çà pour obtenir le résultat final
            ; c'
est à dire (poids0*A*A*A*A*A*A) + (poids1*A*A*A*A*A) + (poids2*A*A*A*A) + (poids3*A*A*A) + (poids4*A*A) + (poids5*A) + poids6
            
on avait une valeur ascii de distance codée sur 7 octetson se retrouve avec une valeur hexa codée 
            
sur 3 octets utilisable dans le programme
            movff    coordZ
,valeur1
            clrf    valeur1
+1
            clrf    valeur1
+2
            call    addition24    
            
on obtient une valeur 24bits qu'on stocke dans coordX+6, coordX5 et coordX+4    
            movff    valeur2,coordZ
            movff    valeur2+1,coordZ+1
            movff    valeur2+2,coordZ+2
            nop
            clrf    coordZ+3
            clrf    coordZ+4
            clrf    coordZ+5
            clrf    coordZ+6
            nop
            return


; -----------------------------------------conversion décimal -> entier X --------------------------------------
conversion_decimal_entierX
; on reçoit les données en inversé par l'
UART,
on réarrange les données en les inversant et en faisant sauter la virgule pour multiplier par 100
            movff    coordX
+5,tampon        
            movff    coordX
,coordX+5            
            movff    coordX
+1,coordX+4
            movff    tampon
,coordX+1            
            movff    coordX
+6,coordX                
            movff    coordX
+2,tampon            
            movff    coordX
+3,coordX+2            
            movff    tampon
,coordX+3    
            clrf    coordX
+6
            
return

; -----------------------------------------
conversion décimal -> entier Y --------------------------------------
conversion_decimal_entierY
            movff    coordY
+5,tampon        
            movff    coordY
,coordY+5            
            movff    coordY
+1,coordY+4
            movff    tampon
,coordY+1            
            movff    coordY
+6,coordY                
            movff    coordY
+2,tampon            
            movff    coordY
+3,coordY+2            
            movff    tampon
,coordY+3    
            clrf    coordY
+6
            
return

; -----------------------------------------
conversion décimal -> entier Z --------------------------------------
conversion_decimal_entierZ
            movff    coordZ
+5,tampon        
            movff    coordZ
,coordZ+5            
            movff    coordZ
+1,coordZ+4
            movff    tampon
,coordZ+1            
            movff    coordZ
+6,coordZ                
            movff    coordZ
+2,tampon            
            movff    coordZ
+3,coordZ+2            
            movff    tampon
,coordZ+3    
            clrf    coordZ
+6
            
return
            
; ---------------------------------------------- 
musique -------------------------------------------------------

            ;
db     axe,valeur_note,durée_note,durée_silence,led1,led2,led3,direction(1=avant/0=arrière)        
            ;
db    'x',.65,.12,.sil,0,0,0,0,1,dir    ;lal
            
;db    'x',.61,.13,.sil,0,0,0,1,0,dir    ;lal#
            
;db    'x',.58,.14,.sil,0,0,0,1,1,dir    ;sil
            
;db    'x',.55,.15,.sil,0,0,1,0,0,dir    ;ut
            
;db    'x',.52,.16,.sil,0,0,1,0,1,dir    ;ut#
            
;db    'x',.49,.17,.sil,0,0,1,1,0,dir    ;re
            
;db    'x',.46,.18,.sil,0,0,1,1,1,dir    ;re#
            
;db    'x',.44,.19,.sil,0,0,0,0,0,dir    ;mi
            
;db    'x',.42,.20,.sil,0,0,0,0,1,dir    ;fa
            
;db    'x',.40,.21,.sil,0,0,0,1,0,dir    ;fa#
            
;db    'x',.38,.22,.sil,0,0,0,1,1,dir    ;sol
            
;db    'x',.36,.23,.sil,0,0,1,0,0,dir    ;sol#
            
;db    'x',.34,.24,.sil,0,0,1,0,1,dir    ;la
            
;db    'x',.32,.25,.sil,0,0,1,1,0,dir    ;la#
            
;db    'x',.30,.26,.sil,0,0,1,1,1,dir     ;si
            
;db    'x',.28,.27,.sil,0,0,0,0,0,dir    ;do
            ;
db    'x',.27,.28,.sil,0,0,0,0,1,dir    ;do#
            
;db    'x',.25,.29,.sil,0,0,0,1,0,dir    ;reh
            
;db    'x',.24,.30,.sil,0,0,0,1,1,dir    ;reh#
            
            
;db    'z',.00,.00,.00,0,0,0,0,0,dir    ;  ;###########   silence (dir=0 on descend, dir=1 on monte)
                            
; ------------------------------------------ CARMENl'amour est un oiseau rebelle -----------------------------------
datas_toreador ;
            ; --------- .40
            db    '
x',.30,.35,.30,0,0,1,1,1,1     ;si        To
            db    '
x',.28,.27,.30,0,0,0,0,0,1        ;do        re
            db    '
x',.30,.26,.30,0,0,1,1,1,1     ;si        a
            db    '
x',.38,.30,.30,0,0,0,1,1,1        ;sol    dor
            ;---------- .10
            db    '
z',.00,.00,.00,0,0,0,0,0,1    ;  ;###########   silence (dir=0 on descend, dir=1 on monte)
            ;---------- .60
            db    '
x',.38,.30,.30,0,0,0,1,1,0        ;sol    en
            db    '
x',.38,.30,.30,0,0,0,1,1,0        ;sol    gar
            db    '
x',.42,.20,.30,0,0,0,0,1,0        ;fa        .
            db    '
x',.38,.30,.30,0,0,0,1,1,0        ;sol    .
            ;db    '
x',.28,.27,.30,0,0,0,0,0,0        ;do        .
            db    '
x',.30,.26,.30,0,0,1,1,1,0     ;si        a
            db    '
x',.38,.30,.30,0,0,0,1,1,0        ;sol    de
            ;---------- .10
            db    '
z',.00,.00,.00,0,0,0,0,0,1    ;  ;###########   silence (dir=0 on descend, dir=1 on monte)
            ;---------- .40
            db    '
x',.28,.27,.30,0,0,0,0,0,1        ;do        To
            db    '
x',.42,.20,.30,0,0,0,0,1,1        ;fa        re
            db    '
x',.30,.26,.30,0,0,1,1,1,1     ;si        a
            db    '
x',.38,.30,.30,0,0,0,1,1,1        ;sol    dor
            ;---------- .10
            db    '
z',.00,.00,.00,0,0,0,0,0,1    ;  ;###########   silence (dir=0 on descend, dir=1 on monte)
            ;---------- .40
            db    '
x',.44,.19,.30,0,0,0,0,0,0        ;mi        To
            db    '
x',.38,.30,.30,0,0,0,1,1,0        ;sol    re
            db    '
x',.42,.20,.30,0,0,0,0,1,0        ;fa        a
            db    '
x',.58,.14,.30,0,0,0,1,1,0        ;sil    dor
            
            ;----------    .10        
            db    '
z',.00,.00,.00,0,0,0,0,0,0    ;  ;###########   silence (dir=0 on descend, dir=1 on monte)
            ;----------




            db    '
x',.42,.20,.30,0,0,0,0,1,1    ;fa        To
            db    '
x',.34,.24,.30,0,0,1,0,1,0    ;la        re
            db    '
x',.38,.22,.30,0,0,0,1,1,0    ;sol    a
            db    '
x',.55,.15,.30,0,0,1,0,0,0    ;ut
            ;----------
            
                        
zik_toreador    
            call    toreador
            led_pomX_OFF
            led_pomY_OFF
            led_pomZ_OFF
            led_popX_OFF
            led_popY_OFF
            led_popZ_OFF
            return    

toreador    movlw    HIGH(datas_toreador)
            movwf    TBLPTRH
            movlw    LOW(datas_toreador)
            movwf    TBLPTRL
            movlw    .220
            movwf    tampon0            ; compteur
            call    loop_zik
            return
; ------------------------------------------ CARMEN, l'
amour est un oiseau rebelle -----------------------------------
datas_lamour ;(.230)
            
db    'x',.25,.30,.50,0,0,0,1,0,1    ;reh    L'a
            db    '
x',.27,.35,.50,0,0,0,0,1,1    ;doh#    mour
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
x',.28,.30,.50,0,0,0,0,0,1    ;doh    est
            db    '
x',.28,.30,.50,0,0,0,0,0,1    ;do        un
            db    '
x',.28,.30,.50,0,0,0,0,0,1    ;do        oi
            db    '
x',.30,.30,.50,0,0,1,1,1,1 ;si        seau
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
x',.30,.27,.50,0,0,1,1,1,1 ;si        re
            db    '
x',.34,.30,.50,0,0,1,0,1,1    ;la        belle
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
x',.34,.24,.50,0,0,1,0,1,0    ;la        que
            db    '
x',.36,.23,.50,0,0,1,0,0,0    ;sol#    nul
            db    '
x',.38,.22,.50,0,0,0,1,1,0    ;sol    ne
            db    '
x',.42,.10,.50,0,0,0,0,1,0    ;fa        peut
            db    '
x',.38,.10,.50,0,0,0,1,1,0    ;sol    peut
            db    '
x',.42,.10,.50,0,0,0,0,1,0    ;fa        peut
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
x',.44,.10,.50,0,0,0,0,0,0    ;mi        ap
            db    '
x',.42,.10,.50,0,0,0,0,1,0    ;fa        ap
            db    '
x',.38,.15,.50,0,0,0,1,1,0    ;sol    pri
            db    '
x',.42,.15,.50,0,0,0,0,1,0    ;fa        voi
            db    '
x',.44,.30,.50,0,0,0,0,0,0    ;mi        ser
            
zik_lamour    call    lamour
            led_pomX_OFF
            led_pomY_OFF
            led_pomZ_OFF
            led_popX_OFF
            led_popY_OFF
            led_popZ_OFF
            return    

lamour        movlw    HIGH(datas_lamour)
            movwf    TBLPTRH
            movlw    LOW(datas_lamour)
            movwf    TBLPTRL
            movlw    .230
            movwf    tampon0            ; compteur
            call    loop_zik
            return
                        
; ---------------------------------------------- 4L1C3 F6FCO en CW ------------------------------------------------
#define tit .4
#define taaa tit*4

datas_4L1C3    ; 4L1C3 (.660)(0x294)
            ; ---------------- 4 (100)
            db    '
x',.55,tit,.50,0,0,1,0,0,1    ;ut    
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
x',.55,tit,.50,0,0,1,0,0,1    ;ut    
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
x',.55,tit,.50,0,0,1,0,0,1    ;ut    
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
x',.55,tit,.50,0,0,1,0,0,1    ;ut    
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
x',.55,taaa,.50,0,0,1,0,0,1;ut
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            ; ---------------- espace (40)
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########        
            ; ---------------- L (70)
            db    '
x',.55,tit,.50,0,0,1,0,0,0    ;ut    
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
x',.55,taaa,.50,0,0,1,0,0,0    ;ut    
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
x',.55,tit,.50,0,0,1,0,0,0    ;ut
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
x',.55,tit,.50,0,0,1,0,0,0    ;ut        
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            ; ---------------- espace (40)
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########        
            ; ---------------- 1 (100)
            db    '
x',.55,tit,.50,0,0,1,0,0,1    ;ut    
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
x',.55,taaa,.50,0,0,1,0,0,1    ;ut    
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
x',.55,taaa,.50,0,0,1,0,0,1    ;ut    
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
x',.55,taaa,.50,0,0,1,0,0,1    ;ut    
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
x',.55,taaa,.50,0,0,1,0,0,1    ;ut    
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            ; ---------------- espace (40)
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########        
            ; ---------------- C (70)
            db    '
x',.55,taaa,.50,0,0,1,0,0,0;ut    
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
x',.55,tit,.50,0,0,1,0,0,0    ;ut        
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
x',.55,taaa,.50,0,0,1,0,0,0;ut        
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
x',.55,tit,.50,0,0,1,0,0,0    ;ut        
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            ; ---------------- espace (40)
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########        
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########        
            ; ---------------- 3 (100)
            db    '
x',.55,tit,.50,0,0,1,0,0,0    ;ut        
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
x',.55,tit,.50,0,0,1,0,0,0    ;ut        
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
x',.55,tit,.50,0,0,1,0,0,0    ;ut        
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
x',.55,taaa,.50,0,0,1,0,0,0    ;ut        
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
x',.55,taaa,.50,0,0,1,0,0,0    ;ut        
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            ; ---------------- espace (40)
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########        
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########        
        
datas_F6FCO    ; F6FCO (.510)(0x01fe)
            ; ---------------- F (70)
            db    '
x',.55,tit,.50,0,0,1,0,0,1    ;ut    
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
x',.55,tit,.50,0,0,1,0,0,1    ;ut    
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
x',.55,taaa,.50,0,0,1,0,0,1;ut
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
x',.55,tit,.50,0,0,1,0,0,1    ;ut        
            ; ---------------- espace (40)
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########        
            ; ---------------- 6 (90)
            db    '
x',.55,taaa,.50,0,0,1,0,0,0;ut    
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
x',.55,tit,.50,0,0,1,0,0,0    ;ut    
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
x',.55,tit,.50,0,0,1,0,0,0    ;ut    
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
x',.55,tit,.50,0,0,1,0,0,0    ;ut    
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
x',.55,tit,.50,0,0,1,0,0,0    ;ut        
            ; ---------------- espace (40)
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########        
            ; ---------------- F (70)
            db    '
x',.55,tit,.50,0,0,1,0,0,1    ;ut        
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
x',.55,tit,.50,0,0,1,0,0,1    ;ut        
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
x',.55,taaa,.50,0,0,1,0,0,1;ut        
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
x',.55,tit,.50,0,0,1,0,0,1    ;ut        
            ; ---------------- espace (40)
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
z',.00,.00,.00,0,0,0,0,0,1    ;###########
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########        
            ; ---------------- C (70)
            db    '
x',.55,taaa,.50,0,0,1,0,0,0;ut    
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
x',.55,tit,.50,0,0,1,0,0,0    ;ut        
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
x',.55,taaa,.50,0,0,1,0,0,0;ut        
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
x',.55,tit,.50,0,0,1,0,0,0    ;ut        
            ; ---------------- espace (40)
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########        
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########
            db    '
z',.00,.00,.00,0,0,0,0,0,1 ;###########        
            ; ---------------- O (50)
            db    '
x',.55,taaa,.50,0,0,1,0,0,1;ut        
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
x',.55,taaa,.50,0,0,1,0,0,1;ut    
            db    '
z',.00,.00,.00,0,0,0,0,0,0 ;###########
            db    '
x',.55,taaa,.50,0,0,1,0,0,1;ut    

F6FCO        call    pomz
            plongée_Z
            movlw    .6
            movwf    tampon2
descendz    call    Zpulses3200
            decf    tampon2
            movf    tampon2,tampon2
            bnz        descendz
            movlw    HIGH(datas_F6FCO)
            movwf    TBLPTRH
            movlw    LOW(datas_F6FCO)
            movwf    TBLPTRL
            movlw    0xfe
            movwf    tampon0            
            movlw    0X1
            movwf    tampon0+1
            call    loop_zik
            led_pomX_OFF
            led_pomY_OFF
            led_pomZ_OFF
            led_popX_OFF
            led_popY_OFF
            led_popZ_OFF
            call    pomz
            return
            
_4L1C3        call    pomz
            plongée_Z
            movlw    .6
            movwf    tampon2
descendzz    call    Zpulses3200
            decf    tampon2
            movf    tampon2,tampon2
            bnz        descendzz
            movlw    HIGH(datas_4L1C3)
            movwf    TBLPTRH
            movlw    LOW(datas_4L1C3)
            movwf    TBLPTRL
            movlw    0x94
            movwf    tampon0            
            movlw    0X2
            movwf    tampon0+1
            call    loop_zik
            led_pomX_OFF
            led_pomY_OFF
            led_pomZ_OFF
            led_popX_OFF
            led_popY_OFF
            led_popZ_OFF
            call    pomz
            return

; ------------------------------------------- chant du partisan --------------------------------------------------
datas_partisan1    ;(15x10)
            db    '
x',.55,.20,.50,0,0,1,0,0,1    ;ut        a
            db    '
x',.42,.30,.50,0,1,0,0,1,1    ;fa        mi
            db    '
x',.42,.20,.15,0,1,0,0,1,1    ;fa        en    
            db    '
x',.38,.22,.15,0,1,0,1,1,1    ;sol    tend    
            db    '
x',.34,.40,.15,0,1,1,0,1,1    ;la        tu
            db    '
x',.34,.24,.15,0,1,1,0,1,0    ;la        le
            db    '
x',.38,.22,.15,0,1,0,1,1,0    ;sol    vol
            db    '
x',.42,.20,.20,0,1,0,0,1,0    ;fa        noir    
            db    '
x',.42,.20,.15,0,1,0,0,1,0    ;faa    des        
            db    '
x',.44,.19,.15,0,1,0,0,0,0    ;mi        cor    
            db    '
x',.49,.25,.15,0,0,1,1,0,0    ;re        beaux
            db    '
x',.55,.15,.25,0,0,1,0,0,1    ;ut        dans
            db    '
x',.44,.19,.15,0,1,0,0,0,1    ;mi        la
            db    '
x',.49,.30,.15,0,0,1,1,0,1    ;re        plai
            db    '
x',.55,.30,.15,0,0,1,0,0,0    ;ut        neuuuu
datas_partisan2    ;(19x10)
            db    '
x',.55,.20,.15,1,0,1,0,0,1    ;ut        Oh
            db    '
x',.34,.40,.15,1,0,0,0,1,0    ;la        hé
            db    '
x',.34,.30,.15,1,0,1,0,1,0    ;la        par
            db    '
x',.30,.30,.15,1,1,0,1,1,1 ;si        ti            
            db    '
x',.28,.40,.100,0,0,0,0,0,1 ;do    san
            db    '
z',.01,.100,.255,0,0,0,0,0,1
            db    '
x',.01,.100,.255,0,0,0,0,0,1
            db    '
x',.28,.20,.15,0,0,1,0,0,0    ;doh    ou
            db    '
x',.30,.20,.15,1,0,0,1,1,0 ;si        vri
            db    '
x',.34,.20,.15,1,1,0,0,1,0    ;la        er
            db    '
x',.38,.20,.15,0,0,0,1,1,0    ;sol    et
            db    '
x',.34,.20,.15,1,0,1,0,1,0    ;la        pa
            db    '
x',.30,.20,.15,1,0,0,1,1,0 ;si        y
            db    '
x',.42,.30,.15,1,0,0,0,1,0    ;fa        san
            db    '
z',.01,.100,.255,0,0,0,0,0,0
            db    '
x',.44,.20,.15,0,1,0,1,0,1    ;mi        c'est
            db    
'x',.38,.20,.15,0,0,0,1,1,1    ;sol    l'a
            db    '
x',.49,.30,.15,1,1,0,1,0,1    ;re        laar
            db    '
x',.55,.30,.15,1,0,1,0,0,1    ;ut        meuuu

zik_partisan
            call    tempo_refrain
            call    partisan1
            call    tempo_refrain
            call    partisan1
            call    tempo_refrain
            call    partisan2
            led_pomX_OFF
            led_pomY_OFF
            led_pomZ_OFF
            led_popX_OFF
            led_popY_OFF
            led_popZ_OFF
            return    

partisan1    movlw    HIGH(datas_partisan1)
            movwf    TBLPTRH
            movlw    LOW(datas_partisan1)
            movwf    TBLPTRL
            movlw    .150
            movwf    tampon0            ; compteur
            call    loop_zik
            return
            
partisan2    movlw    HIGH(datas_partisan2)
            movwf    TBLPTRH
            movlw    LOW(datas_partisan2)
            movwf    TBLPTRL
            movlw    .190
            movwf    tampon0            ; compteur
            call    loop_zik
            return
            
; ------------------------------------------------------------    

loop_zik    tblrd*+
            movff    TABLAT,axe
            tblrd*+
            movff    TABLAT,note
            tblrd*+
            movff    TABLAT,duree_note
            tblrd*+
            movff    TABLAT,silence
            tblrd*+
            movff    TABLAT,led1
            tblrd*+
            movff    TABLAT,led2
            tblrd*+
            movff    TABLAT,led3
            tblrd*+
            movff    TABLAT,led4
            tblrd*+
            movff    TABLAT,led5
            tblrd*+
            movff    TABLAT,dir
            call    direction
            call    del1
            movlw    '
x'
            subwf    axe,w
            bz        jouex
zik1        movlw    '
z'
            subwf    axe,w
            bz        jouez
zik2        movlw    .10
            movwf    ptr
decremente    movff    tampon0,valeur1
            movff    tampon0+1,valeur1+1    
            movlw    .1
            clrf    valeur2+1
            movwf    valeur2
            call    soustraction16
            movff    valeur1,tampon0
            movff    valeur1+1,tampon0+1
            decf    ptr
            bnz        decremente
            movf    tampon0,tampon0
            bnz        loop_zik
            return
            
; ----------------------- direction axe X                                
direction    movlw    .1
            subwf    dir
            bz        marche_ar
            marche_av_X
            plongée_Z
            return
marche_ar    marche_ar_X
            remontée_Z
            return
            
; ----------------------- joue axe Z                            
jouez        movlw    .5
            movwf    tampon3            
jouez1        call    Zpulses320
            decf    tampon3
            movf    tampon3,tampon3
            bnz        jouez1
            bra     zik2

; ----------------------- gestion leds
del1        movlw    .1
            subwf    led1
            bz        allume_led1
            led_pomX_OFF
            bra        del2 
allume_led1    led_pomX_ON    
del2        subwf    led2
            bz        allume_led2
            led_popY_OFF
            bra        del3
allume_led2    led_popY_ON
del3        subwf    led3
            bz        allume_led3
            led_popZ_OFF
            bra        del4
allume_led3    led_popZ_ON
del4        subwf    led4
            bz        allume_led4
            led_popX_OFF
            bra        del5
allume_led4    led_popX_ON
del5        subwf    led5
            bz        allume_led5
            led_pomY_OFF
            return
allume_led5    led_pomY_ON
            return
            
; ----------------------- joue axe X                                
jouex        movf    duree_note,w
            movwf    tamponA
jouex2        movlw    .60
            movwf    tamponB
jouex22        call    Xnote_base
            decf    tamponB
            bz        finjouex
            bra        jouex22
finjouex    decf    tamponA
            bnz        jouex2
            bra        zik1

Xnote_base    bsf        drv_stepX
            call     géné_note
            bcf        drv_stepX
            call     géné_note
            return
            
géné_note    ; détermine la largeur des créneaux  
            movf           note,w
            movwf       Reg_1
            decfsz      Reg_1
               bra         $-2
            return        
            
; ------------------------               
 tempo_refrain
            movlw       .203
            movwf       Reg_1
            movlw       .77
            movwf       Reg_2
            movlw       .252
            movwf       Reg_3
            movlw       .2
            movwf       Reg_4
            decfsz      Reg_1,F
            goto        $-1
            decfsz      Reg_2,F
            goto        $-3
            decfsz      Reg_3,F
            goto        $-5
            decfsz      Reg_4,F
            goto        $-7
            return

; ---------------------------------------------- Déplacements Z -------------------------------------------------------

deplaceZ    ; génère le nombre de pulses sur l'
axe Z
            
avant de générer les pulses on vérifie que le gcode n'est pas terminé en scrutant le flag_fin_gcode
            movf    flag_fin_gcode,w
            sublw    1
            btfsc    STATUS,Z
              return
            movf    deltaZ,deltaZ
            bnz        suitez
            return
suitez        movff    deltaZ,tampon0
            movff    deltaZ+1,tampon0+1
boucleZ        ; on avance de 1mm en Y
            call    Zpulses3200
            movff    tampon0,valeur1
            movff    tampon0+1,valeur1+1
            movlw    1
            movwf    valeur2
            clrf    valeur2+1
            call    soustraction16
            movff    valeur1,tampon0
            movff    valeur1+1,tampon0+1
            movf    tampon0,tampon0
            bnz        boucleZ        
            return

; ---------------------------------------------- Déplacements Z manuel fin ------------------------------------------------

descendZ_1centième
            plongée_Z    
            call    Zpulses32
            call    tempo_10s
            return

descendZ_5centièmes
            plongée_Z    
            call    Zpulses64
            call    tempo_10s
            return
            
descendZ_1dixième
            plongée_Z    
            call    Zpulses320
            call    tempo_10s
            return

monteZ_1centième
            remontée_Z    
            call    Zpulses32
            call    tempo_10s
            return

monteZ_5centièmes
            remontée_Z    
            call    Zpulses64
            call    tempo_10s
            return
            
monteZ_1dixième
            remontée_Z    
            call    Zpulses320
            call    tempo_10s
            return

; ---------------------------------------------- Génération des pulses Z 1/16e de pas-------------------------------------------------------

Zpulses3200    ; 1mm en 1/16pas (1/3200=mm)
            movlw    d'
40'
            movwf    tamponA
Z3200        movlw    d'
80'
            movwf    tamponB
Zm3200        call    Zpulse_base
            decf    tamponB
            bz        Zfin3200
            bra        Zm3200
Zfin3200    decf    tamponA
            bnz        Z3200
            return

; --------------------------------
Zpulses320    ; 1/10e mm en 1/16pas (1/3200=mm)
            movlw    d'
2'
            movwf    tamponA
Z320        movlw    d'
160'
            movwf    tamponB
Zm320        call    Zpulse_base
            decf    tamponB
            bz        Zfin320
            bra        Zm320
Zfin320        decf    tamponA
            bnz        Z320
            return

; --------------------------------
Zpulses64    ;  5/100e mm en 1/16 pas
            movlw    d'
64'
            movwf    tamponB
Zm64        call    Zpulse_base
            decf    tamponB
            bz        Zfin64
            bra        Zm64
Zfin64        return


; --------------------------------
Zpulses32    ; 1/100e mm en 1/16 pas    
            movlw    d'
32'
            movwf    tamponB
Zm32        call    Zpulse_base
            decf    tamponB
            bz        Zfin32
            bra        Zm32
Zfin32        return


; --------------------------------
Zpulse_base    ;  pas de base     
            bsf        drv_stepZ
            call     tempo_18khz
            bcf        drv_stepZ
            call     tempo_18khz
            return


Une porte nand prend 2 bits en entrée... la cochonne !!! 8-)

Soft de commande CNC en asm
F6FCO
Avatar de l’utilisateur
Confirmé
Confirmé
Messages : 778
Âge : 65
Enregistré en : décembre 2017
Localisation : Furtif je suis.
Contact :

#386 Message par F6FCO » dim. 24 févr. 2019 14:47

J'ai été obligé de tronquer le programme en deux parties car çà faisait plus de 91000 caractères et le forum n'autorise que 60 000 par post.
La fin du programme:

Code : Tout sélectionner

; ---------------------------------------------- Génération des pulses Y 1/16e de pas-------------------------------------------------------

Ypulses3200    ; 1mm en 1/16pas (1/3200=mm)
            movlw    d'40'
            movwf    tamponA
Y3200        movlw    d
'80'
            movwf    tamponB
Ym3200        call    Ypulse_base
            decf    tamponB
            bz        Yfin3200
            bra        Ym3200
Yfin3200    decf    tamponA
            bnz        Y3200
            return

; --------------------------------
Ypulses320    ; 1/10e mm en 1/16pas (1/3200=mm)
            movlw    d'2'
            movwf    tamponA
Y320        movlw    d
'160'
            movwf    tamponB
Ym320        call    Ypulse_base
            decf    tamponB
            bz        Yfin320
            bra        Ym320
Yfin320        decf    tamponA
            bnz        Y320
            return

; --------------------------------
Ypulses64    ;  5/100e mm en 1/16 pas
            movlw    d
'64'
            movwf    tamponB
Ym64        call    Ypulse_base
            decf    tamponB
            bz        Yfin64
            bra        Ym64
Yfin64        return


; --------------------------------
Ypulses32    ; 1/100e mm en 1/16 pas    
            movlw    d
'32'
            movwf    tamponB
Ym32        call    Ypulse_base
            decf    tamponB
            bz        Yfin32
            bra        Ym32
Yfin32        return


; --------------------------------
Ypulse_base    ;  pas de base     
            bsf        drv_stepY
            call     tempo_18khz
            bcf        drv_stepY
            call     tempo_18khz
            return
; ---------------------------------------------- Génération des pulses 1/8e de pas-------------------------------------------------------

;
pulses1600    ; 1mm en 1/8pas (1/1600=0.000625mm)
;
            movlw    d'20'
;            movwf    tamponA
;Z1600        movlw    d'80'
;            movwf    tamponB
;Zm1600        call    pulse_base
;            decf    tamponB
;            bz        Zfin1600
;            bra        Zm1600
;Zfin1600    decf    tamponA
;            bnz        Z1600
;            return

; --------------------------------
;
pulses160    ;  1/10e mm en 1/8 pas
;            movlw    d'160'
;            movwf    tamponB
;Zm160        call    pulse_base
;            decf    tamponB
;            bz        Zfin160
;            bra        Zm160
;Zfin160        return

; --------------------------------
;
pulses80    ;  5/100e mm en 1/8 pas
;            movlw    d'160'
;            movwf    tamponB
;Zm80        call    pulse_base
;            decf    tamponB
;            bz        Zfin80
;            bra        Zm80
;Zfin80        return


; --------------------------------
;
pulses16    ; 1/100e mm en 1/8 pas    
;            movlw    d'16'
;            movwf    tamponB
;Zm16        call    pulse_base
;            decf    tamponB
;            bz        Zfin16
;            bra        Zm16
;Zfin16        return


; --------------------------------
;
pulse_base    ;  pas de base 0,00125mm (1,25µ)    
;            bsf        drv_stepZ
;            call     tempo_9khz
;            bcf        drv_stepZ
;            call     tempo_9khz
;            return

; ----------------------------------------------- Calcul delta X ---------------------------------------------------------------

calcul_deltaX
            
; comparaison octet HSB
            movf    coordX_old
+2,w
            subwf    coordX
+2,w
            bz        cx0                
; les deux nombres sont égaux, on passe à la comparaison de l'octer MSB
            btfss    STATUS,C        ; on saute si C=1    
            bra        coordX_old_fort ; on branche si  Z=0 et C=0            
            bra        coordX_fort        ; on branche si Z=0 et C=1
            ; comparaion octet MSB
cx0            movf    coordX_old+1,w
            subwf    coordX+1,w
            bz        cx1
            btfss    STATUS,C        ; on saute si C=1
            bra        coordX_old_fort    ; on branche si  Z=0 et C=0
            bra        coordX_fort        ; on branche si Z=0 et C=1
            ; comparaion octet LSB            
cx1            movf    coordX_old,w
            subwf    coordX,w
            bz        coordX_fort
            btfss    STATUS,C        ; on saute si C=1
            bra        coordX_old_fort
            
            
coordX_fort    marche_av_X
            movff    coordX,valeur1
            movff    coordX+1,valeur1+1
            movff    coordX+2,valeur1+2
            movff    coordX_old,valeur2
            movff    coordX_old+1,valeur2+1
            movff    coordX_old+2,valeur2+2
            call    soustraction24
            bra        stock_resultX        
coordX_old_fort
            marche_ar_X
            movff    coordX_old,valeur1
            movff    coordX_old+1,valeur1+1
            movff    coordX_old+2,valeur1+2
            movff    coordX,valeur2
            movff    coordX+1,valeur2+1
            movff    coordX+2,valeur2+2
            call    soustraction24
stock_resultX
            ; Résultat sur 24bits dans valeur2, valeur2+1 et valeur2+2
            ; et on stocke le résultat dans deltaZ
            movff    valeur1+0,deltaX+0
            movff    valeur1+1,deltaX+1
            movff    valeur1+2,deltaX+2
fin_soustractX
            return

; ----------------------------------------------- Calcul delta Y ---------------------------------------------------------------

calcul_deltaY
            ; comparaison octet HSB
            movf    coordY_old+2,w
            subwf    coordY+2,w
            bz        cy0                ; les deux nombres sont égaux, on passe à la comparaison de l'
octer MSB
            btfss    STATUS
,C        ; on saute si C=1    
            bra        coordY_old_fort 
; on branche si  Z=0 et C=0            
            bra        coordY_fort        
; on branche si Z=0 et C=1
            
; comparaion octet MSB
cy0            movf    coordY_old
+1,w
            subwf    coordY
+1,w
            bz        cy1
            btfss    STATUS
,C        ; on saute si C=1
            bra        coordY_old_fort    
; on branche si  Z=0 et C=0
            bra        coordY_fort        
; on branche si Z=0 et C=1
            
; comparaion octet LSB            
cy1            movf    coordY_old
,w
            subwf    coordY
,w
            bz        coordY_fort
            btfss    STATUS
,C        ; on saute si C=1
            bra        coordY_old_fort
            
coordY_fort    marche_av_Y
            movff    coordY
,valeur1
            movff    coordY
+1,valeur1+1
            movff    coordY
+2,valeur1+2
            movff    coordY_old
,valeur2
            movff    coordY_old
+1,valeur2+1
            movff    coordY_old
+2,valeur2+2
            call    soustraction24
            bra        stock_resultY        
coordY_old_fort
            marche_ar_Y
            movff    coordY_old
,valeur1
            movff    coordY_old
+1,valeur1+1
            movff    coordY_old
+2,valeur1+2
            movff    coordY
,valeur2
            movff    coordY
+1,valeur2+1
            movff    coordY
+2,valeur2+2
            call    soustraction24
stock_resultY
            
; Résultat sur 24bits dans valeur2, valeur2+1 et valeur2+2
            
; et on stocke le résultat dans deltaZ
            movff    valeur1
+0,deltaY+0
            movff    valeur1
+1,deltaY+1
            movff    valeur1
+2,deltaY+2
fin_soustractY
            return

; ----------------------------------------------- Calcul delta Z ---------------------------------------------------------------

calcul_deltaZ
            
; comparaison octet HSB
            movf    coordZ_old
+2,w
            subwf    coordZ
+2,w
            bz        cz0                
; les deux nombres sont égaux, on passe à la comparaison de l'octer MSB
            btfss    STATUS,C        ; on saute si C=1    
            bra        coordZ_old_fort ; on branche si  Z=0 et C=0            
            bra        coordZ_fort        ; on branche si Z=0 et C=1
            ; comparaion octet MSB
cz0            movf    coordZ_old+1,w
            subwf    coordZ+1,w
            bz        cz1
            btfss    STATUS,C        ; on saute si C=1
            bra        coordZ_old_fort    ; on branche si  Z=0 et C=0
            bra        coordZ_fort        ; on branche si Z=0 et C=1
            ; comparaion octet LSB            
cz1            movf    coordZ_old,w
            subwf    coordZ,w
            bz        coordZ_fort
            btfss    STATUS,C        ; on saute si C=1
            bra        coordZ_old_fort
            
coordZ_fort    remontée_Z
            movff    coordZ,valeur1
            movff    coordZ+1,valeur1+1
            movff    coordZ+2,valeur1+2
            movff    coordZ_old,valeur2
            movff    coordZ_old+1,valeur2+1
            movff    coordZ_old+2,valeur2+2
            call    soustraction24
            bra        stock_resultZ        
coordZ_old_fort
            plongée_Z
            movff    coordZ_old,valeur1
            movff    coordZ_old+1,valeur1+1
            movff    coordZ_old+2,valeur1+2
            movff    coordZ,valeur2
            movff    coordZ+1,valeur2+1
            movff    coordZ+2,valeur2+2
            call    soustraction24
stock_resultZ
            ; Résultat sur 24bits dans valeur2, valeur2+1 et valeur2+2
            ; et on stocke le résultat dans deltaZ
            movff    valeur1+0,deltaZ+0
            movff    valeur1+1,deltaZ+1
            movff    valeur1+2,deltaZ+2
fin_soustractZ
            return
            
; ---------------------------------------------- Génération des pulses X 1/16e de pas-------------------------------------------------------

Xpulses3200    ; 1mm en 1/16pas (1/3200=mm)
            movlw    d'
40'
            movwf    tamponA
X3200        movlw    d'
80'
            movwf    tamponB
Xm3200        call    Xpulse_base
            decf    tamponB
            bz        Xfin3200
            bra        Xm3200
Xfin3200    decf    tamponA
            bnz        X3200
            return

; --------------------------------
Xpulses1600    ; 0,5mm en 1/16pas (1/3200=mm)
            movlw    d'
20'
            movwf    tamponA
X1600        movlw    d'
80'
            movwf    tamponB
Xm1600        call    Xpulse_base
            decf    tamponB
            bz        Xfin1600
            bra        Xm1600
Xfin1600    decf    tamponA
            bnz        X1600
            return

; --------------------------------
Xpulses320    ; 1/10e mm en 1/16pas (1/3200=mm)
            movlw    d'
2'
            movwf    tamponA
X320        movlw    d'
160'
            movwf    tamponB
Xm320        call    Xpulse_base
            decf    tamponB
            bz        Xfin320
            bra        Xm320
Xfin320        decf    tamponA
            bnz        X320
            return

; --------------------------------
Xpulses64    ;  5/100e mm en 1/16 pas
            movlw    d'
64'
            movwf    tamponB
Xm64        call    Xpulse_base
            decf    tamponB
            bz        Xfin64
            bra        Xm64
Xfin64        return

; --------------------------------
Xpulses32    ; 1/100e mm en 1/16 pas    
            movlw    d'
32'
            movwf    tamponB
Xm32        call    Xpulse_base
            decf    tamponB
            bz        Xfin32
            bra        Xm32
Xfin32        return


; --------------------------------
Xpulse_base    ;  pas de base     ; 1/3200=0,00031mm = 0,3µ
            bsf        drv_stepX
            call     tempo_18khz
            bcf        drv_stepX
            call     tempo_18khz
            return

; ---------------------------------------------- calcul tangente -------------------------------------------------------
calcul_tangente    
            ; on commence par multiplier le deltaY par pas_moteur
            nop
            movff    deltaY,multiplicande32
            movff    deltaY+1,multiplicande32+1
            movff    deltaY+2,multiplicande32+2
            movlw    0x0c
            movwf    multiplicateur32+1
            movlw    0x80
            movwf    multiplicateur32
            nop
            lfsr    FSR0,multiplicateur32
            lfsr    FSR1,multiplicande32
            nop
            call    Mult32x16    ; résultat dans la variable 48bits result:6
            nop
            
            ; calcul de la tangente en divisant (deltaY*pas_moteur)/deltaX 
            movff    result,dividende48
            movff    result+1,dividende48+1
            movff    result+2,dividende48+2
            movff    result+3,dividende48+3
            movff    result+4,dividende48+4
            movff    result+5,dividende48+5
            movff    deltaX,diviseur48
            movff    deltaX+1,diviseur48+1
            movff    deltaX+2,diviseur48+2
            nop
            call    div48_24
            nop
            movff    dividende48,valeur1
            movff    dividende48+1,valeur1+1
            movff    dividende48+2,valeur1+2
            nop
            ; on ajoute 1 pour correction de l'
erreur d'arrondi
            clrf    valeur2+1
            clrf    valeur2+2
            movlw    1
            movwf    valeur2
            call    addition24
            movff    valeur2,tangente16
            movff    valeur2+1,tangente16+1
            nop
            return
            
            
            movff    valeur2,dividende16
            movff    valeur2+1,dividende16+1
            movlw    d'
10'
            movwf    diviseur16
            clrf    diviseur16+1
            call    division16
            nop
            movff    quotient16,tangente16
            movff    quotient16+1,tangente16+1
            nop
            return

; ---------------------------------------------- construction droite -------------------------------------------------------
construction_droite
            ; 4 cas de figure:
            ; si deltaX =0 et deltaY <>0     -> trace ligne verticale
            ; si deltaX <>0 et deltaY =0    -> trace ligne horizontale
            ; si deltaX <>0 et deltaY <>0    -> trace pente
            ; si deltaX =0 et deltaY =0     -> on sort de la routine sans rien tracer    
            nop
            movlw    1
            movwf    flagX            
            movwf    flagY
            movf    deltaX+2,deltaX+2
            bnz        cd0
            movf    deltaX+1,deltaX+1
            
            bnz        cd0
            movf    deltaX+0,deltaX+0
            bnz        cd0
            clrf    flagX
cd0            movf    deltaY+2,deltaY+2
            bnz        cd1
            movf    deltaY+1,deltaY+1
            bnz        cd1
            movf    deltaY+0,deltaY+0
            bnz        cd1
            clrf    flagY
cd1            movf    flagX,flagX
            bnz        cd2
            movf    flagY,flagY
            bnz        cd3
            return
cd2            movf    flagY,flagY
            bnz        cd4
            bra        construction_horizontale
cd3            bra        construction_verticale
cd4            

            ; ______________________________________________________
construction_pente
            
            ; la tangente est dans valeur2
            ; on divise la tangente par 100
            ; si elle est négative le quotient de la division sera nul, alors on force la tangente à 1
            movff    valeur2,dividende16
            movff    valeur2+1,dividende16+1
            movlw    .100
            movwf    diviseur16
            clrf    diviseur16+1
            call    division16
            movf    quotient16,quotient16
            btfsc    STATUS,Z
            incf    quotient16
            
            
            
            nop
            movff    deltaX,tampon0        ; on charge deltaX dans le tampon de décrémentation
            movff    deltaX+1,tampon0+1
            nop
bouclePX    ; on avance de 0.01mm en X
            nop
            call    Xpulses32
            ; ---------------------- calcul de Y, on va éxécuter tangente fois le micro-pas de base
            movff    quotient16,tampon1
            movff    quotient16+1,tampon1+1        
bouclePY    ; on avance de 1,25µm en Y
            call    Ypulse_base
            ; -- on décrémente tampon1
            movff    tampon1,valeur1
            movff    tampon1+1,valeur1+1
            clrf    valeur2+1
            movlw    0x1
            movwf    valeur2
            nop
            call    soustraction16
            movff    valeur1,tampon1
            movff    valeur1+1,tampon1+1
            nop
            ; -- on teste si tampon1 est à zéro sinon on boucle
            movf    tampon1+1,tampon1+1
            bnz        bouclePY
            movf    tampon1,tampon1
            bnz        bouclePY
            ; ---------------------- 
            ; decrémentation de tampon0 (X)
            movff    tampon0,valeur1
            movff    tampon0+1,valeur1+1
            clrf    valeur2+1
            movlw    0x1
            movwf    valeur2
            nop
            call    soustraction16
            movff    valeur1,tampon0
            movff    valeur1+1,tampon0+1
            nop
            movf    tampon0+1,tampon0+1
            bnz        bouclePX
            movf    tampon0,tampon0
            bnz        bouclePX
            nop
            return    
            ; ______________________________________________________
            
construction_verticale
            nop
            movff    deltaY,tampon0
            movff    deltaY+1,tampon0+1
boucleV        ; on avance de 1mm en Y
            call    Ypulses32
            movff    tampon0,valeur1
            movff    tampon0+1,valeur1+1
            movlw    1
            movwf    valeur2
            clrf    valeur2+1
            nop
            call    soustraction16
            nop
            movff    valeur1,tampon0
            movff    valeur1+1,tampon0+1
            movf    tampon0+1,tampon0+1
            bnz        boucleV
            movf    tampon0+0,tampon0+0
            bnz        boucleV        
            nop
            return

            ; ______________________________________________________
            
construction_horizontale
            nop
            nop
            movff    deltaX,tampon0
            movff    deltaX+1,tampon0+1
boucleH        ; on avance de 1mm en Y
            call    Xpulses32
            movff    tampon0,valeur1
            movff    tampon0+1,valeur1+1
            movlw    1
            movwf    valeur2
            clrf    valeur2+1
            nop
            call    soustraction16
            nop
            movff    valeur1,tampon0
            movff    valeur1+1,tampon0+1
            movf    tampon0+1,tampon0+1
            bnz        boucleH
            movf    tampon0+0,tampon0+0
            bnz        boucleH        
            nop
            return

            
; ----------------------------------- Clignotement des leds POP en fin de programme -----------------------------------------    

clignotte_3ledPOP
            led_popX_ON
            led_popY_ON
            led_popZ_ON
            call    tempo_clign_led
            led_popX_OFF
            led_popY_OFF
            led_popZ_OFF
            call    tempo_clign_led
            return

; ----------------------------------- Clignotement des leds POM en fin de programme -----------------------------------------    

clignotte_3ledPOM
            led_pomX_ON
            led_pomY_ON
            led_pomZ_ON
            call    tempo_clign_led
            led_pomX_OFF
            led_pomY_OFF
            led_pomZ_OFF
            call    tempo_clign_led
            return

; ----------------------------------- avant de commencer l'
usinage on place la broche aux origines POP ----------------------    
    
positionnement_origines_pop
test_originespopX
            
; il faut auparavant déterminer si la broche est positionnée avant ou après la pop
            
; pour cela on soustrait translatX - val_popX, si la valeur obtenue est négative on 
            
; est trop loin donc on règle l'axe en translation avant
            ; si la valeur est nulle on est en pop et on saute
            ; sinon on passe en translation arrière
            nop
            movf    val_popX,w
            subwf    translatX,w
            bn        avantX
            bz        fin_testoriginespopX
arriereX    marche_ar_X
            call    Xpulses320
            decf    translatX
            bra        test_originespopX    
avantX        marche_av_X
            call    Xpulses320
            incf    translatX
            bra        test_originespopX                
fin_testoriginespopX
        
test_originespopY
            ; il faut auparavant déterminer si la broche est positionnée avant ou après la pop
            ; pour cela on soustrait translatY - val_popY, si la valeur obtenue est négative on 
            ; est trop loin donc on règle l'
axe en translation avant
            
; si la valeur est nulle on est en pop et on saute
            
; sinon on passe en translation arrière
            nop
            movf    val_popY
,w
            subwf    translatY
,w
            bn        avantY
            bz        fin_testoriginespopY    
arriereY    marche_ar_Y
            call    Ypulses320
            decf    translatY
            bra        test_originespopY    
avantY        marche_av_Y
            call    Ypulses320
            incf    translatY
            bra        test_originespopY                
fin_testoriginespopY    

test_originespopZ
            
; il faut auparavant déterminer si la broche est positionnée avant ou après la pop
            
; pour cela on soustrait translatZ - val_popZ, si la valeur obtenue est négative on 
            
; est trop loin donc on règle l'axe en remontée
            ; si la valeur est nulle on est en pop et on saute
            ; sinon on passe en descente
            movf    val_popZ,w
            subwf    translatZ,w
            bn        monteZ
            bz        fin_testoriginespop
            ; donc on est au-dessus de la pop Z, on passe en descente
descendZ    plongée_Z
            call    Zpulses3200
            decf     translatZ
            bra        test_originespopZ
monteZ        remontée_Z
            call    Zpulses3200
            incf    translatZ
            bra        test_originespopZ            
fin_testoriginespop
            return        

; ------------------------------------------------- JOG X ------------------------------------------------------------------

            ; ici on va vérifier si on est en limite mini
            ; on décrémente translatX à chaque mm parcouru
            ; on effectue la soustraction 0-translatX, tant que translatX est supérieur à zéro on jog
            ; sinon c'
est qu'on est arrivé à zéro et on sort
xmoins        marche_ar_X                ; on passe en marche arrière, le capteur d'
origine étant situé à gauche du X
            clrf    tampon3
            movf    translatX
,w                                
            subwf    tampon3
,w        ; on vérifie si translatX est à zéro                
            bn        moinsx            
; si négatif on peut aller jogger
            return                    
; sinon on sort
            
; c'est négatif donc on jog                
moinsx        btfsc    btn_jog_Xmoins    
            return
            call    Xpulses3200
            decf    translatX
            return
                                    
xplus        ; ici on va vérifier si on est en limite maxi
            ; on soustrait d'
130' (limit maxi) à translatX 
            ; si négatif on continue le jog
            ; on sort si la soustraction est égale à zéro 
            marche_av_X                ; jog en avant
            movlw    limite_maxiX    ; on charge d'
130' (limite maxi) dans W                            
            subwf    translatX,w        ; qu'
on soustrait à translatX                    
            bn        plusx            
; si négatif on va jogger
            bnz        plusx            
; et on sort si la soustraction est égale à zéro, donc qu'on est arrivé en limite maxi    
            return                    
plusx        btfsc    btn_jog_Xplus    
            return
            call    Xpulses3200
            incf    translatX
            return

; ------------------------------------------------- JOG Y ------------------------------------------------------------------

ymoins        marche_ar_Y        ; jog en arrière
            clrf    tampon3
            movf    translatY,w                                
            subwf    tampon3,w                        
            bn        moinsy            ; si négatif on peut aller jogger
            return                    ; sinon on sort
moinsy        btfsc    btn_jog_Ymoins    
            return
            call    Ypulses3200
            decf    translatY
            return
                                    
yplus        marche_av_Y        ; jog en avant
            movlw    limite_maxiY    ; on charge d'
130' (limite maxi) dans W                            
            subwf    translatY,w        ; qu'
on soustrait à translatX                    
            bn        plusy            
; si négatif on va jogger
            bnz        plusy            
; et on sort si la soustraction est égale à zéro, donc qu'on est arrivé en limite maxi    
            return                    
plusy        btfsc    btn_jog_Yplus    
            return
            call    Ypulses3200
            incf    translatY
            return
            
; ------------------------------------------------- JOG Z ------------------------------------------------------------------

            ; ici on va vérifier si on est en limite mini
            ; on décrémente translatX à chaque mm parcouru
            ; on effectue la soustraction limite translatZ-0, tant que translatz est supérieur à zéro on jog
            ; sinon c'
est qu'on est arrivé au mini et on sort
zmoins        plongée_Z                        ; descente
            clrf    tampon3
            movf    translatZ,w                                
            subwf    tampon3,w                        
            bn        moinsz                    ; si négatif on peut aller jogger
            return                            ; sinon on sort
moinsz        btfsc    btn_jog_Zmoins    
            return
            call    Zpulses3200
            decf    translatZ
            return
                                    
zplus        ; ici on va vérifier si on est en limite maxi
            ; on soustrait d'
30' (limit maxi) à translatZ 
            ; si négatif on continue le jog
            ; on sort si la soustraction est égale à zéro 
            remontée_Z                        ; montée
            movlw    limite_maxiZ            ; on charge d'
130' (limite maxi) dans W                            
            subwf    translatZ,w                ; qu'
on soustrait à translatZ                    
            bn        plusz                    
; si négatif on va jogger
            bnz        plusz                    
; et on sort si la soustraction est égale à zéro, donc qu'on est arrivé en limite maxi    
            return                    
plusz        btfsc    btn_jog_Zplus    
            return
            call    Zpulses3200
            incf    translatZ
            return

; ------------------------------------------------- POM générales ------------------------------------------------------------------
            
POM            call    pomz                            ; Prise Origine Z Machine (toujours en premier)
            call    tempo
            call     pomx                            ; Prise Origine X Machine 
            call    tempo
            call    pomy                            ; Prise Origine Y Machine 
            call    tempo
            return
                
; ------------------------------------------------- POM X ------------------------------------------------------------------

pomx        marche_ar_X                                ; on passe en marche arrière, le capteur d'
origine étant situé à gauche du X
            call    Xpulse_base    
            btfsc    capteur_pomX
            bra        pomx
            
; POM faite, petit jog jusqu'à la limite mini qui a été définie par essais
            call    tempo                            ; juste pour marquer l'
arret entre la pom et la mise en place
            movlw    offset_pomX
            movwf    tampon0
pomxa        call    Xpulses3200
            decf    tampon0
            bnz        pomxa
            bsf        led_pomX        
            clrf    translatX                        
; initialisation axe X à zéro
            marche_av_X                                
; on vient de faire la POM donc on force la translation en avant
            
;bsf        drv_dirX
            return
            
; ------------------------------------------------- POM Y ------------------------------------------------------------------

pomy        marche_ar_Y                                ; on passe en marche arrière, le capteur d'origine étant situé à gauche du Y
            call    Ypulse_base    
            btfsc    capteur_pomY
            bra        pomy
            ; POM faite, petit jog jusqu'
à la limite mini qui a été définie par essais
            call    tempo                            
; juste pour marquer l'arret entre la pom et la mise en place
            movlw    offset_pomY                            ; pour aller se positionner au maxi après le capteur
            movwf    tampon0
pomya        call    Ypulses3200
            decf    tampon0
            bnz        pomya
            bsf        led_pomY
            clrf    translatY                        ; initialisation axe Y à zéro
            marche_av_Y    
            return
            
; ------------------------------------------------- POM Z ------------------------------------------------------------------

pomz        remontée_Z                        ; on passe en marche arrière (montée), le capteur d'
origine étant situé en haut du Z
            call    Zpulse_base    
            btfsc    capteur_pomZ
            bra        pomz
            
; POM faite, petit jog jusqu'à la limite maxi qui a été définie par essais
            call    tempo                    ; juste pour marquer l'
arret entre la pom et la mise en place
            
;movlw    d'14'
            movlw    offset_pomZ
            movwf    tampon0
pomza        call    Zpulses3200
            decf    tampon0
            bnz        pomza
            bsf        led_pomZ
            movlw    limite_maxiZ
            movwf    translatZ                
; initialisation axe Z à limit maxi
            plongée_Z                        
; descente
            return

; ------------------------------------------------- POP X ------------------------------------------------------------------

popX        nop
            movff    translatX
,val_popX
            bsf        led_popX
            return
            
; ------------------------------------------------- POP Y ------------------------------------------------------------------
            
popY        nop
            movff    translatY
,val_popY
            bsf        led_popY
            return
            
; ------------------------------------------------- POP Z ------------------------------------------------------------------

popZ        nop
            movff    translatZ
,val_popZ
            bsf        led_popZ
            return

; ------------------------------------------ Sauvegardes --> _old --------------------------------------------------------

sauvegarde_coordX_old                ; sauvegarde les coordX dans coordX_old
            movff    coordX
+0,coordX_old+0
            movff    coordX
+1,coordX_old+1
            movff    coordX
+2,coordX_old+2
            return
            
sauvegarde_coordY_old                
; sauvegarde les coordY dans coordY_old
            movff    coordY
+0,coordY_old+0
            movff    coordY
+1,coordY_old+1
            movff    coordY
+2,coordY_old+2
            return
            
sauvegarde_coordZ_old                
; sauvegarde les coordZ dans coordZ_old
            movff    coordZ
+0,coordZ_old+0
            movff    coordZ
+1,coordZ_old+1
            movff    coordZ
+2,coordZ_old+2
            return
    
; ----------------------------------------------------- divisions -------------------------------------------------------

;********************************************************************
;
                Division sur entiers 16bits _ F6FCO                  *
;
     Il faut préalablement déclarer les variables sur 16 bits         *
;
         dividende16, diviseur16, quotient16    et reste16                *
;
                                                                    *
;
 poids faible dans dividende16                                        *
;
 poids fort de la valeur à diviser dans dividende16+1,               *
;
                                                                    *
;
 poids faible dans diviseur16                                        *
;
 poids fort du diviseur dans diviseur16+1                            *
;
                                                                    *
;
 Le résultat sera dans quotient16 et quotient16+1                     *   
; Le reste sera dans reste16 et reste16+1                            *        
;                                                                    *
;
 Cette division utilise la routine soustraction16                     *    
; il faut donc aussi avoir déclaré les variables sur                 *                                            
;                 16 bits valeur1 et valeur2                                *
;********************************************************************
   
division16    
; on vérifie si c'est une division par zéro, si c'est le cas on charge le dividende dans le quotient.
            ; dividende/0=dividende, pas cohérent mathématiquement mais nécessaire dans le projet en cas de ligne
            
; horizontale (Y=0) ou verticale (X=0).
            movf    diviseur16,diviseur16
            btfss    STATUS
,Z
            bra        div16
div_zero    movf    diviseur16
+1,diviseur16+1
            btfsc    STATUS
,Z
            bra        div_quot
div16        
; on initialise quotient=0
            clrf    quotient16
            clrf    quotient16
+1
            
; reste=dividende
            movff    dividende16
,reste16
            movff    dividende16
+1,reste16+1
div16_1        movf    reste16
+1,w
            subwf    diviseur16
+1,w
            
; test si poids fort reste>diviseur ?
            btfss    STATUS,C                    
            bra        div16_3
            
; test si poids fort reste=diviseur ? sinon on sort
div16_4        bz        div16_2
findiv16    return
div16_2        
; test si poids faible reste>=diviseur
            movff    reste16
,WREG
            subwf    diviseur16
,w
            btfss    STATUS
,C
            bra        div16_3
            bz        div16_3
            bra        findiv16
div16_3        
; reste=dividende-diviseur
            nop
            movff    reste16
,valeur1
            movff    reste16
+1,valeur1+1
            movff    diviseur16
,valeur2
            movff    diviseur16
+1,valeur2+1
            call    soustraction16            
; résultat dans valeur1, valeur1+1
            movff    valeur1
+1,reste16+1
            movff    valeur1
,reste16
            
; quotient +1
            bcf        STATUS
,C
            movlw    1
            addwf    quotient16
            
; on additionne le carry dans le poids fort
            movf    STATUS
,C
            andlw    0x1
            addwf    quotient16
+1
            bra        div16_1
div_quot    
; en cas de division par zéro on charge le dividende dans le quotient
            movff    dividende16
,quotient16
            movff    dividende16
+1,quotient16+1
            return
            
;========================================================================================
;
    Unsigned 48/24 bit division  (approx 967 to 1447 cycles)
;
     déclarer variables tampon:1 dividende48:6, diviseur48:6
;
;
    Inputs:    Dividende     -> dividende48+5 à dividende48 (48 bits)
;
            Diviseur    -> diviseur48+2 à diviseur (24 bits)
;
    Temporary:    compteur     -> tampon
;    Output:    Quotient     -> dividende48+5 à dividende48 (48 bits)
;
            Reste         -> dans diviseur+5 à diviseur+(24 bits)
;
            by Peter G. Harrison
;========================================================================================
div48_24    movlw    d'48'        ; 48-bit divide by 24-bit
            movwf    tampon
            clrf    diviseur48
+5        ; Clear remainder
            clrf    diviseur48
+4
            clrf    diviseur48
+3
divdlp        bcf    STATUS
,C     ; Set quotient bit to 0, shift left dividend & quotient
            rlcf    dividende48        
; low byte
            rlcf    dividende48
+1
            rlcf    dividende48
+2
            rlcf    dividende48
+3
            rlcf    dividende48
+4
            rlcf    dividende48
+5        ; most significant bit into carry
            rlcf    diviseur48
+3        ; and then into partial remainder
            rlcf    diviseur48
+4
            rlcf    diviseur48
+5
            bc        subtdiv        
; If overflow then remainder must be > divisor
;After subtraction, if Z set then check less significant bytes. If Z not set and C 
;is set, partial remainder > divisor, so can subtract and set result bit in acc2
            movf    diviseur48
+2,w    ; Compare high bytes of partial remainder and divisor
            subwf    diviseur48
+5,w
            bnz        test_gt        
; bytes not equal, so check if remainder > divisor
            movf    diviseur48
+1,w    ; middle bytes of partial remainder and divisor
            subwf    diviseur48
+4,w
            bnz        test_gt        
; bytes not equal, so check if remainder > divisor
            movf    diviseur48
,w    ; 
            subwf    diviseur48
+3,w    ; 
test_gt        bnc    rmdrlt        
; carry set if partial remainder > divisor
subtdiv        movf    diviseur48
,w    ; Subtract divisor from partial remainder
            subwf    diviseur48
+3,f
            movf    diviseur48
+1,w
            subwfb    diviseur48
+4,f
            movf    diviseur48
+2,w
            subwfb    diviseur48
+5,f
            bsf        dividende48
,0    ; Set quotient bit to 1
;                ; Quotient replaces dividend which is lost
rmdrlt        decfsz    tampon
            bra        divdlp
            return

            
; ----------------------------------------------------- soustractions -------------------------------------------------------

;********************************************************************
;
             Soustraction sur entiers 16bits                        *
;
     Il faut préalablement déclarer des variables sur 16 bits         *
;
             valeur1:- valeur2:2                                    *
;
                                                                    *
;
 nombre fort:                                                        *        
; valeur1: poids faible                                                *
;
 valeur1+1: poids fort                                                *

;
 nombre faible à soustraire :                                        *
;
 valeur2: poids faible                                                  * 
; valeur2+1: poids fort                                                *
;
                                                                    *  
; Appeler la procédure soustraction16 et le résultat de             *
;
 valeur1-valeur2 sur 16bits sera dans les 2 octets de valeur1           *
;********************************************************************
   
soustraction16
            movf    valeur2
,w
            subwf    valeur1
            movf    valeur2
+1,w
            subwfb    valeur1
+1
            movf    valeur2
+2,w
            subwfb    valeur1
+2
            return
            
;********************************************************************
;
               Soustraction sur entiers 24bits                     *
;
     Il faut prélablement déclarer les variables sur 32bits            * 
;             valeur1:3    et valeur2:3                                *
;
                                                                    *
;
 Placer le poids fort de la première valeur dans valeur1+3            *
;
 et les poids plus faibles dans valeur1+2, valeur+1, valeur        *
;
                                                                    *
;
 Placer le poids fort de la valeur à soustraire dans valeur2+3        *
;
 et les poids faibles dans valeur2+2, valeur2+1, valeur2           * 
;                                                                    *  
; Appeler la procédure soustraction24 et le résultat de             *
;
 valeur1-valeur2 sur 24bits sera dans les 3 octets de valeur1         *
;********************************************************************
soustraction24
            movf    valeur2
,w
            subwf    valeur1
            movf    valeur2
+1,w
            subwfb    valeur1
+1
            movf    valeur2
+2,w
            subwfb    valeur1
+2
            movf    valeur2
+3,w
            subwfb    valeur1
+3
            return

; ----------------------------------------------------- addition 16bits -------------------------------------------------------
    
;********************************************************************
;
                   Addition sur 16bits      F6FCO                        *
;
     Il faut préalablement déclarer des variables sur 16 bits         *
;
             valeur1:2 et valeur2:2                                    *
;
                                                                    *
;
 Placer le poids faible de la première valeur dans valeur1            *
;
 et le poids fort dans valeur1+1                                    *
;
 Placer le poids faible de la valeur à additionner dans valeur2    *
;
 et le poids fort dans valeur2+1                                   *   
; Appeler la procédure addition16 et le résultat de                     *
;
 valeur1+valeur2 sur 16bits sera dans les 2 octets de valeur2           *
;********************************************************************
addition16        movf    valeur1,W
                addwf    valeur2
,f
                
; on additionne le carry dans le poids fort
                movf    STATUS
,W
                andlw    0x1
                addwf    valeur2
+1,f
                movf    valeur1
+1,W
                addwf    valeur2
+1,f
                return    

; ----------------------------------------------------- addition 24bits -------------------------------------------------------

;********************************************************************
;
                   Addition sur entiers 24bits      F6FCO                *
;
     Il faut préalablement déclarer des variables sur 24 bits         *
;
             valeur1:, valeur2:3 et report16                        *
;
                                                                    *
;
 Premier nombre:                                                    *
;
 poids faible dans valeur1                                            *
;
 poids forts dans valeur1+1 et +2                                    *
;
                                                                    *
;
 Deuxième nombre:                                                   * 
; poids faible dans valeur2                                            *
;
 poids forts dans valeur2+1 et +2                                    *  
;                                                                    *
;
 Appeler la procédure addition16 et le résultat de                     *
;
 valeur1+valeur2 sur 16bits sera dans les 2 octets de valeur2           *
;
 Si dépassement des 16 bits, le carry sera dans report16            *
;********************************************************************
addition24
            movf    valeur1
,w
            addwf    valeur2
            movf    valeur1
+1,w
            addwfc    valeur2
+1
            movf    valeur1
+2,w
            addwfc    valeur2
+2
            
; s'il y a carry il sera stocké dans report16
            movf    STATUS,w
            andlw    0x1
            movwf    report16
            return    

; ----------------------------------------------------- multiplications -------------------------------------------------------

;========================================================================================
; Unsigned 16 * 16 bit multiplication 
; déclarer variables tampon:1 multiplicande32:4, multiplicateur32:1, tampon:1
;
; multiplicande32+1: multiplicande32 * multiplicateur32+1:multiplicateur32
; résultat dans multiplicateur32+3 à multiplicateur32
; affected register: tampon
; 28cycles
;            by Peter G. Harrison
;========================================================================================
mult16_16    movf    multiplicateur32+1,w
            mulwf   multiplicande32+1            
            movff   PRODH,multiplicateur32+3    
            movff   PRODL,multiplicateur32+2
            movf    multiplicateur32,w
            mulwf   multiplicande32                
            movff   PRODH,tampon
            movff   PRODL,multiplicateur32
            mulwf   multiplicande32+1            
            movf    PRODL,w
            addwf   tampon,f                    
            movf    PRODH,w                        
            addwfc  multiplicateur32+2,f
            clrf    WREG
            addwfc  multiplicateur32+3,f
            movf    multiplicateur32+1,w
            mulwf   multiplicande32                
            movf    PRODL,w                        
            addwf   tampon,w                    
            movwf   multiplicateur32+1
            movf    PRODH,w                        
            addwfc  multiplicateur32+2,f
            clrf    WREG
            addwfc  multiplicateur32+3,f
            return
            
;******************************************************************************
;Mult32x16            by VegiPete
;Multiply a 32 bit number by a 16 bit number (low byte in low memory)
;FSR0 points to the 16 bit number
;FSR1 points to the 32 bit number
;FSRs are unchanged
;WREG,PRODL,PRODH changed
;Puts the 48 bit result in result
;Algorithm merely sums the 8 partial products, however, the
;order is chosen to minimize left over carry bits
;******************************************************************************
Mult32x16
            clrf    result+4
            clrf    result+5

            movf    POSTINC1,w
            movf    POSTINC1,w
            movf    POSTDEC1,w        ;source32+2
            mulwf    INDF0            ;source16+0
            movff    PRODL,result+2
            movff    PRODH,result+3

            movf    POSTINC1,w        ;source32+1
            mulwf    POSTINC0        ;source16+0
            movff    PRODL,result+1
            movf    PRODH,w
            addwf    result+2,f

            movf    POSTDEC1,w        ;source32+2
            mulwf    INDF0            ;source16+1
            movf    PRODL,w
            addwfc    result+3,f
            movf    PRODH,w
            addwfc    result+4,f        ;maybe carry
            btfsc    STATUS,C
            incf    result+5,f

            movf    POSTDEC1,w
            movf    POSTINC1,w        ;source32+0
            mulwf    POSTDEC0        ;source16+1
            movf    PRODL,w
            addwf    result+1,f
            movf    PRODH,w
            addwfc    result+2,f

            movf    POSTINC1,w
            movf    POSTINC1,w
            movf    POSTDEC1,w        ;source32+3
            mulwf    INDF0            ;source16+0
            movf    PRODL,w
            addwfc    result+3,f
            movf    PRODH,w
            addwfc    result+4,f        ;maybe carry
            btfsc    STATUS,C
            incf    result+5,f

            movf    POSTDEC1,w
            movf    POSTDEC1,w
            movf    POSTINC1,w        ;source32+0
            mulwf    POSTINC0        ;source16+0
            movff    PRODL,result+0
            movf    PRODH,w
            addwf    result+1,f

            movf    POSTINC1,w        ;source32+1
            mulwf    INDF0            ;source16+1
            movf    PRODL,w
            addwfc    result+2,f
            movf    PRODH,w
            addwfc    result+3,f

            movf    POSTINC1,w
            movf    POSTDEC1,w        ;source32+3
            mulwf    POSTDEC0        ;source16+1
            movf    PRODL,w
            addwfc    result+4,f
            movf    PRODH,w
            addwfc    result+5,f        ;should be no carry
    
            movf    POSTDEC1,w
            movf    POSTDEC1,w        ;move pointer back to start
            return


; ----------------------------------------------- Temporisations ----------------------------------------------------------

tempo_4.6khz  ; pas de base en 1/4pas
; Délai 100 Cycles de la machine
; Durée du délai 100 microsecond
; Fréquence de l'
oscillateur 4 MHZ
                movlw       .33
                movwf       Reg_1
                decfsz      Reg_1
                bra         
$-2
                return                
                
tempo_9khz    
; pas de base en 1/8pas
; Délai 50 Cycles de la machine
; Durée du délai 50 microsecond
; Fréquence de l'oscillateur 4 MHZ
                movlw       .16
                movwf       Reg_1
                decfsz      Reg_1,F
                goto        $-1
                nop
                return

tempo_18khz    ; pas de base en 1/16pas
; Délai 25 Cycles de la machine
; Durée du délai 25 microsecond
; Fréquence de l'
oscillateur 4 MHZ
                movlw       .8
                    movwf       Reg_1
                decfsz      Reg_1
,F
                goto        
$-1
                return

tempo
; Délai 2 000 000 Cycles de la machine
; Durée du délai 2000 millisecond
; Fréquence de l'oscillateur 4 MHZ
                movlw       .93
                movwf       Reg_1
                movlw       .38
                movwf       Reg_2
                movlw       .11
                movwf       Reg_3
                decfsz      Reg_1,F
                goto        $-1
                decfsz      Reg_2,F
                goto        $-3
                decfsz      Reg_3,F
                goto        $-5
                nop
                nop
                return
                
tempo_clign_led
; Délai 20 000 000 Cycles de la machine
; Durée du délai 4000 millisecond
; Fréquence de l'
oscillateur 20 MHZ
            movlw       .193
            movwf       Reg_1
            movlw       .118
            movwf       Reg_2
            movlw       .102
            movwf       Reg_3
            decfsz      Reg_1
,F
            goto        
$-1
            decfsz      Reg_2
,F
            goto        
$-3
            decfsz      Reg_3
,F
            goto        
$-5
           return

tempo_200ms
; Délai 200 000 Cycles de la machine
; Durée du délai 200 millisecond
; Fréquence de l'oscillateur 4 MHZ

            movlw       .186
            movwf       Reg_1
            movlw       .4
            movwf       Reg_2
            movlw       .2
            movwf       Reg_3
            decfsz      Reg_1,F
            goto        $-1
            decfsz      Reg_2,F
            goto        $-3
            decfsz      Reg_3,F
            goto        $-5
            nop
            return              

tempo_1s
; Délai 1 000 000 Cycles de la machine
; Durée du délai 1000 millisecond
; Fréquence de l'
oscillateur 4 MHZ

            movlw       .173
            movwf       Reg_1
            movlw       .19
            movwf       Reg_2
            movlw       .6
            movwf       Reg_3
            decfsz      Reg_1
,F
            goto        
$-1
            decfsz      Reg_2
,F
            goto        
$-3
            decfsz      Reg_3
,F
            goto        
$-5
            nop
            nop
            return

tempo_10s
; Délai 10 000 000 Cycles de la machine
; Durée du délai 10000 millisecond
; Fréquence de l'oscillateur 4 MHZ

            movlw       .223
            movwf       Reg_1
            movlw       .187
            movwf       Reg_2
            movlw       .51
            movwf       Reg_3
            decfsz      Reg_1,F
            goto        $-1
            decfsz      Reg_2,F
            goto        $-3
            decfsz      Reg_3,F
            goto        $-5
            nop
            nop
            return
            
          END
      


Une porte nand prend 2 bits en entrée... la cochonne !!! 8-)

Soft de commande CNC en asm
Temps-x
Avatar de l’utilisateur
Expert
Expert
Messages : 1162
Enregistré en : juillet 2016
Localisation : Terre

#387 Message par Temps-x » dim. 24 févr. 2019 15:55

Bonsoir F6FCO, et tout le forum

:bravo: pour ta persévérance.




:sifflotte: sans commentaire

Code : Tout sélectionner


  movlw    0x30
            subwf    coordX
            subwf    coordX
+1
            subwf    coordX
+2
            subwf    coordX
+3
            subwf    coordX
+4
            subwf    coordX
+5


:sifflotte: ............

Code : Tout sélectionner


  movlw    0x30
            subwf    coordX
,F
            subwf    coordX
+1,F
            subwf    coordX
+2,F
            subwf    coordX
+3,F
            subwf    coordX
+4,F
            subwf    coordX
+5,F


Bon je te le redis pour une dernière fois, après si tu as des erreurs dans ton code tu t’amuseras à les chercher. :roll:

Il y en a d'autre, regarde dans le fichier erreur.

A++
Modifié en dernier par Temps-x le dim. 24 févr. 2019 21:22, modifié 3 fois.
Quand la souris nargue le chat, c'est que son trou n'est pas loin.

Soft de commande CNC en asm
F6FCO
Avatar de l’utilisateur
Confirmé
Confirmé
Messages : 778
Âge : 65
Enregistré en : décembre 2017
Localisation : Furtif je suis.
Contact :

#388 Message par F6FCO » dim. 24 févr. 2019 18:28

:sifflotte:
J'le ferai plus promis, là pour l'instant elle tourne sans bug mais je vais quand même corriger.

Pour ceux que çà intéresse toute la description du projet, machine et programme est sur cette page: http://f6fco.pagesperso-orange.fr/4L1C3.htm
Une porte nand prend 2 bits en entrée... la cochonne !!! 8-)

Soft de commande CNC en asm
Temps-x
Avatar de l’utilisateur
Expert
Expert
Messages : 1162
Enregistré en : juillet 2016
Localisation : Terre

#389 Message par Temps-x » lun. 4 mars 2019 19:30

Bonsoir F6FCO, et tout le forum,

J'ai été voir sur ta page, je trouve que c'est très bien résumé :bravo:

Bon maintenant il faut mettre le Gcode sur carte SD, et le faire lire par notre PIC :sifflotte:

==> A++
Quand la souris nargue le chat, c'est que son trou n'est pas loin.

Soft de commande CNC en asm
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 1286
Âge : 68
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#390 Message par paulfjujo » lun. 4 mars 2019 20:57

Bonsoir F6FCO et à tous,


Un supper boulot avec détails et compte-rendu illustré ...
de quoi nous motiver ...

Bravo :bravo:
Aides toi, le ciel ou Fantastpic t'aideras


Retourner vers « Langage ASM »

Qui est en ligne

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