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

Gestion encodeur V2 basse résolution
F6FCO
Avatar de l’utilisateur
Expert
Expert
Messages : 2857
Âge : 99
Enregistré en : décembre 2017
Localisation : Banlieue sud de Klyntar
Contact :

#1 Message par F6FCO » lun. 23 févr. 2026 10:31

Salut les gens,
Une nouvelle version de gestion d'encodeur que j'utilise sur mon servomoteur CC. Le bras se déplace de 180° (et plus si nécessaire), j'utilise les ticks générés par l'encodeur pour contrôler le déplacement, pour des raisons que j'expliquerai sur le sujet du servomoteur j'ai besoin d'un encodeur basse résolution. Cette version ne compte volontairement qu'un tick sur deux et divise par conséquent la résolution/tour par deux.

Pour ceux qui voudraient se prendre la tête à comprendre le code asm les équations et l'algorithme sont d'une grande aide.

Les équations:

Equations.jpg


L'algorithme:

Algo.jpg


Ce code peut servir à piloter un encodeur pour n'importe quel projet, ici je m'en sert pour mon servomoteur CC.
On retrouve le sens de rotation sur les bits H, AH et immo. On récupère le nombre de ticks générés dans la variable ptr.

Encodeur testés: mécanique chinois et Wurst: 20 crans/tour au toucher, 4 états par crans ---> 80 ticks par tour. J'avais besoin de moins.

De base l'algo pourrait être très simple mais j'ai du le complexifier avec la variable flag: le bras monté sur un moteur gearbox 60rpm se déplace... à 60rpm.
Le pic lui, est cadencé par l'horloge interne à 8Mhz, le temps que l'encodeur monté sur l'axe arrière du moteur 60rpm génère un tick le PIC aura effectué plusieurs millions d'itérations, ce qui modifie ptr à chaque itération, donc la grosse zone. La variable flag limite la modification de ptr à la seule première itération et ignore les autres tant qu'on n'a pas changé d'état sur l'encodeur.

Le code:

Code : Tout sélectionner

; ***********************************************************************************************
;
                     F6FCO
;                 Réglages des fusibles 18f2525
;
;************************************************************************************************

        Errorlevel-302             ; Supprime le message "Ensure that bank bits are correct" 
        list            p
=18f2525    ; processeur utilisé 
        
#include        <p18f2525.inc>    ; Définitions des constantes PIC
    
 CONFIG OSC 
= INTIO67                   ; Oscillateur interne 8MHz 
 
;CONFIG OSC = XT                         ; Oscillateur xtal externe 
 CONFIG IESO 
= OFF                         ; Délai au démarrage (ON/OFF)
 CONFIG BOREN = OFF                        ; Reset si chute de tension (ON/OFF)
 CONFIG PWRT = ON                          ; Délai au démarrage (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:0> les 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 configuré comme entrée
 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 = OFF                        ; 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)


Code : Tout sélectionner

;******************************************************************************
;
                           F6FCO - février 2026;                                            
;             gestion d'un encodeur en quadrature V2
;
;    Cette version ne compte volontairement qu'
un tick sur deux pour 
;     utiliser un encodeur dans une fourchette de 0 255 sans dépassement
;                     de part et d'autre
;
;                horloge 8Mhz interne
;        
;******************************************************************************
;
; IMPORTANT, A SAVOIR !!!
; Les encodeurs mécaniques chinois bon marché d'
Aliexpress génèrent 4 ticks par cran
; 1 tour = 20 crans (pas) = 80 ticks
;
#include<Fusibles 18f2525.asm>


; gestion encodeur
#define pinA         PORTB,0        ; pin A encodeur
#define pinB        PORTB,1        ; pin B encodeur
#define    newA        bits_encodeur,0
#define newB        bits_encodeur,1
#define oldA        bits_encodeur,2
#define oldB        bits_encodeur,3
#define H        bits_gestion,1
#define AH        bits_gestion,2
#define immo        bits_gestion,3

moteur_tourneH        macro
    bcf    driverA
    bsf    driverB
    endm
moteur_tourneAH    macro
    bsf    driverA
    bcf    driverB
    endm
    
moteur_stop    macro
    bcf    driverA
    bcf    driverB
    endm

    CBLOCK 0x00C       
    tmp        
:1        
    w_temp         
:1        ; Sauvegarde du registre W
    status_temp     
:1        ; Sauvegarde du registre STATUS
    Reg_1        
:1
    Reg_2        
:1
    Reg_3        
:1
    
;
    ; --------------------Variables gestion_encodeur
    ptr        
:1        ; nombre de ticks générés
    flag_comptage    
:1        ; utilisé dans gestion_encodeur
    bits_encodeur    
:1        ; bits de gestion
            
; <0> newA
            
; <1> newB
            
; <2> oldA
            
; <3> oldB
            
; <4> 
            
; <5> 
            
; <6> 
            
; <7> 
    bits_gestion    
; <0> 
            
; <1> H
            
; <2> AH
            
; <3> immo
            
; <4> 
            
; <5> 
            
; <6> 
            
; <7> 
    conchita    
:1        ; variable bonne à tout faire
    
; --------------------    
            
    ENDC                                      

    org    0x000             
; Adresse de départ après reset     

    bra        init            

; ------------------------  Routines Interruptions                            
    
;sauvegarder registres    
    org     0x008            
; adresse d'interruption
    movwf   w_temp          ; sauver registre W
    swapf    STATUS,w        ; swap status avec résultat dans w
    movwf    status_temp        ; sauver status swappé
    
    ; Interrupt MSSP
    btfss    PIR1,SSPIF        ; <3>
    bra    restorereg        
    call    intMSSP            ; on vient d'
avoir une int MSSP, on la traite
        
    
;restaurer registres
restorereg
    swapf    status_temp
,w        ; swap ancien status, résultat dans w
    movwf   STATUS            
; restaurer status
    swapf   w_temp
,f        ; Inversion L et H de l'ancien W, sans modifier Z
    swapf   w_temp,w          ; Réinversion de L et H dans W, W restauré sans modifier status
    retfie              ; return from interrupt

intMSSP
    movff    SSPBUF,conchita
    bsf    SSPCON1,CKP        ; on relâche l'
horloge
    bcf    PIR1
,SSPIF        ; <3> raz flag d'interrupt                         
    return
    
    
    
; ------------------------ Init

init
    clrf    EEADR            ; diminue la consommation
    ; init oscillateur
    movlw    0xff            ; Horloge interne 8Mhz
    movwf    OSCCON

        ; init ports
        movlw     0xff
          movwf     ADCON1                ; mode digital
          bcf    ADCON0,ADON        ; <0> CAN désactivé
          
          movlw    0x07
          movwf    CMCON            ; mode comparateur désactivé

    movlw    b'
00000011'        
    movwf    TRISB
    clrf    PORTB
    clrf    LATB
    
    movlw    b'
00110000'        ; rc3/rc4 I2C        
    movwf    TRISC
    clrf    PORTC
    clrf    LATC

    ; init interruptions
    bsf    RCON,IPEN
    bsf    INTCON,GIE        ; <7> int non masquées activées
    bsf    INTCON,PEIE        ; <6> int périphériques non masquées activées
    bsf    PIE1,SSPIE        ; <3> MSSP activé
    bcf    PIR1,SSPIF        ; <3> flag interrupt à zéro
    bsf    SSPCON1,SSPEN        ; <5> rb0 et rb1 en mode SDA/SCL
    
        
    ; mode esclave 7 bits avec interruptions
    bsf    SSPCON1,SSPEN        ; <5>
    bsf    SSPCON1,CKP        ; <4>

    bcf    SSPCON1,SSPM0        ; <0>        
    bsf    SSPCON1,SSPM1        ; <1>
    bsf    SSPCON1,SSPM2        ; <2>
    bcf    SSPCON1,SSPM3        ; <3>

    bsf    SSPCON2,SEN        ; <0> Etirement horloge activé

    ; adresse esclave
    movlw    b'
00010000'    
    movwf    SSPADD
    
    bsf    SSPSTAT,S        ; <3> startbit
    
; ------------------------- initialisation 
    clrf    bits_gestion
    clrf    conchita
    clrf    bits_encodeur
    movlw    d'
128'
    movwf    ptr
    nop
    
testA    ; lecture pinA encodeur
    btfss    pinA
    bra    pinA00
    bsf    newA
    bra    testB
pinA00    bcf    newA

testB    ; lecture pinB encodeur
    btfss    pinB
    bra    pinB00
    bsf    newB
    bra    fin_test_pin
pinB00    bcf    newB
    ; on a maintenant ici l'
état présent de l'encodeur
    ; dans oldA et oldB
fin_test_pin    

    ; vers fichier main_ServoMoteurCC.asm
; -----------------------------------



Code : Tout sélectionner

#include <Init_encodeur V2.asm>
main
    nop
    call    gestion_encodeur
    bra    main


#include <Routines_encodeur V2.asm>

    END


Code : Tout sélectionner


gestion_encodeur
:
    nop
    
; -------------------
    ; mise en mémoire oldA=newA et oldB=newB
    movf    bits_encodeur
,WREG
    rlncf    WREG
,f
    rlncf    WREG
,f
    andlw    b
'00001111'
    movwf    bits_encodeur
    
; oldA=newA  oldB=newB
    nop
    
; ------------------- 
    
; lecture pins encodeur et mise en mem dans newA et newB
    bcf    newA
    bcf    newB
    movff    PORTB
,conchita
    btfsc    conchita
,0
    bsf    newA
    btfsc    conchita
,1
    bsf    newB        
; newB=1
    
; newA=pinA  newB=pinB
    nop

    
; -------------------
    ; teste si b./oldA
ge0    movf    bits_encodeur
,WREG
    andlw    0x0f
    movff    WREG
,conchita
    
;
    movlw    b'1000'
    cpfseq    conchita
    bra    ge1
    movlw    d
'1'
    cpfseq flag_comptage
    bra    ge6
    
ge1    
; teste si /B.oldA
    movf    bits_encodeur
,WREG
    andlw    0x0f
    movff    WREG
,conchita
    
;
    movlw    b'0111'
    cpfseq    conchita
    bra    ge2
    movlw    d
'2'
    cpfseq    flag_comptage
    bra    ge7
    
ge2    
; ------------------
    ; teste si B.oldA
    movf    bits_encodeur
,WREG
    andlw    0x0f
    movff    WREG
,conchita
    
;
    movlw    b'1011'
    cpfseq    conchita
    bra    ge3
    movlw    d
'3'
    cpfseq    flag_comptage
    bra    ge8
    
ge3    
; teste si /B./oldA
    movf    bits_encodeur
,WREG
    andlw    0x0f
    movff    WREG
,conchita
    
;
    movlw    b'0100'
    cpfseq    conchita
    bra    ge4
    movlw    d
'4'
    cpfseq    flag_comptage
    bra    ge9

ge4    
; ------------------
    ; aucunes conditions au-dessus alors on est immobile
    bcf    H
    bcf    AH
    bsf    immo
    bra    ge5
    
ge6    
; -----------------
    ; on tourne sens horaire
    movlw    d
'1'
    movwf    flag_comptage
    bra    ge10
ge7    movlw    d
'2'
    movwf    flag_comptage
ge10    bsf    H
    bcf    AH
    bcf    immo
    incf    ptr
    bra    ge5
    
ge8    
; ----------------
    ; on tourne sens anti-horaire
    movlw    d
'3'
    movwf    flag_comptage
    bra    ge11
ge9    movlw    d
'4'
    movwf    flag_comptage    
ge11    bcf    H
    bsf    AH
    bcf    immo
    decf    ptr    
    
ge5    nop
    return
    
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Une porte nand prend 2 bits en entrée... :eek:

Retourner vers « Langage ASM »

Qui est en ligne

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